Yalantis/uCrop · warning
symmetric_eigen(): LAPACK library function dsyev_() returned
Error message
symmetric_eigen(): LAPACK library function dsyev_() returned error code %d.
What it means
CImg::symmetric_eigen() computes eigenvalues/eigenvectors of a symmetric matrix via LAPACK dsyev_(); nonzero INFO means the eigen-decomposition failed to converge or received an invalid argument. CImg warns and leaves val/vec unset rather than throwing.
Source
Thrown at ucrop/src/main/jni/CImg.h:33233
val[0] = (t)l2;
val[1] = (t)l1;
if (n>0) { vec[0] = (t)(b/n); vec[2] = (t)((l2 - a)/n); } else { vec[0] = 1; vec[2] = 0; }
vec[1] = -vec[2];
vec[3] = vec[0];
return *this;
}
#ifdef cimg_use_lapack
char JOB = 'V', UPLO = 'U';
int N = _width, LWORK = 4*N, INFO;
Tfloat
*const lapA = new Tfloat[N*N],
*const lapW = new Tfloat[N],
*const WORK = new Tfloat[LWORK];
cimg_forXY(*this,k,l) lapA[k*N + l] = (Tfloat)((*this)(k,l));
cimg::syev(JOB,UPLO,N,lapA,lapW,WORK,LWORK,INFO);
if (INFO)
cimg::warn(_cimg_instance
"symmetric_eigen(): LAPACK library function dsyev_() returned error code %d.",
cimg_instance,
INFO);
if (!INFO) {
cimg_forY(val,i) val(i) = (T)lapW[N - 1 -i];
cimg_forXY(vec,k,l) vec(k,l) = (T)(lapA[(N - 1 - k)*N + l]);
} else { val.fill(0); vec.fill(0); }
delete[] lapA; delete[] lapW; delete[] WORK;
#else
CImg<t> V(_width,_width);
Tfloat M = 0, m = (Tfloat)min_max(M), maxabs = cimg::max((Tfloat)1,cimg::abs(m),cimg::abs(M));
(CImg<Tfloat>(*this,false)/=maxabs).SVD(vec,val,V,false);
if (maxabs!=1) val*=maxabs;
bool is_ambiguous = false;
float eig = 0;
cimg_forY(val,p) { // Check for ambiguous casesView on GitHub (pinned to f788b534b4)
Solutions
- Symmetrize the matrix explicitly before the call: A = (A + A.get_transpose())/2
- Check for NaN/Inf entries and sanitize the input matrix
- Verify the matrix is square and non-empty
- Use double precision and scale the matrix to improve convergence
- Provide a fallback (e.g. Jacobi eigen implementation) if dsyev_ keeps failing
Example fix
// before CImg<float> val, vec; A.symmetric_eigen(val, vec); // after CImg<float> S = (A + A.get_transpose())*0.5f; if (S.isnan().sum() > 0) S.nanf(0); // or reject input CImg<float> val, vec; S.symmetric_eigen(val, vec);
Defensive patterns
Strategy: validation
Validate before calling
bool readyForEigen(const CImg<float>& A) {
if (A.width() != A.height() || A.width() == 0) return false;
for (int i = 0; i < A.width(); ++i)
for (int j = 0; j < A.height(); ++j)
if (std::isnan(A(i,j)) || std::isinf(A(i,j))) return false;
return true;
} Prevention
- Always symmetrize (A + A^T)/2 before symmetric_eigen()
- Screen inputs for NaN/Inf
- Scale very large/small magnitude matrices
- Keep a fallback eigensolver for non-converging cases
When it happens
Trigger: Calling symmetric_eigen() on a matrix that is not actually symmetric (dsyev only reads one triangle, garbage in the other can cause divergence), non-square input, or extremely ill-conditioned matrices.
Common situations: Building covariance matrices with asymmetric accumulation bugs; NaN/Inf entries in the matrix; NDK LAPACK builds with mismatched dsyev_ ABI.
Related errors
- eigen(): Instance is not a square matrix.
- eigen(): Eigenvalues computation of general matrices is limi
- invert(): LAPACK function dgetrf_() returned error code %d.
- invert(): LAPACK function dgetri_() returned error code %d.
- solve(): LAPACK library function dgetrf_() returned error co
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/10fbe4080c504ff7.
Report an issue: GitHub.