Yalantis/uCrop · error · CImgInstanceException
eigen(): Eigenvalues computation of general matrices is limi
Error message
eigen(): Eigenvalues computation of general matrices is limited to 2x2 matrices.
What it means
CImg's eigen() computes eigenvalues/eigenvectors of a matrix treated as a general (non-symmetric) matrix, but the closed-form algorithm shipped in this header only implements the 2x2 case. For any other width the library throws CImgInstanceException rather than iterating numerically.
Source
Thrown at ucrop/src/main/jni/CImg.h:33174
const double a = (*this)[0], b = (*this)[1], c = (*this)[2], d = (*this)[3], e = a + d;
double f = e*e - 4*(a*d - b*c);
if (f<0) cimg::warn(_cimg_instance
"eigen(): Complex eigenvalues found.",
cimg_instance);
f = std::sqrt(f);
const double
l1 = 0.5*(e - f),
l2 = 0.5*(e + f),
b2 = b*b,
norm1 = std::sqrt(cimg::sqr(l2 - a) + b2),
norm2 = std::sqrt(cimg::sqr(l1 - a) + b2);
val[0] = (t)l2;
val[1] = (t)l1;
if (norm1>0) { vec(0,0) = (t)(b/norm1); vec(0,1) = (t)((l2 - a)/norm1); } else { vec(0,0) = 1; vec(0,1) = 0; }
if (norm2>0) { vec(1,0) = (t)(b/norm2); vec(1,1) = (t)((l1 - a)/norm2); } else { vec(1,0) = 1; vec(1,1) = 0; }
} break;
default :
throw CImgInstanceException(_cimg_instance
"eigen(): Eigenvalues computation of general matrices is limited "
"to 2x2 matrices.",
cimg_instance);
}
}
return *this;
}
//! Compute eigenvalues and eigenvectors of the instance image, viewed as a matrix.
/**
\return A list of two images <tt>[val; vec]</tt>, whose meaning is similar as in eigen(CImg<t>&,CImg<t>&) const.
**/
CImgList<Tfloat> get_eigen() const {
CImgList<Tfloat> res(2);
eigen(res[0],res[1]);
return res;
}
View on GitHub (pinned to f788b534b4)
Solutions
- Restrict general eigen() calls to 2x2 matrices, or reshape/decompose your problem into 2x2 blocks
- For symmetric matrices of any size, call symmetric_eigen(val, vec) instead, which supports NxN
- Implement an external eigensolver (e.g. Eigen, LAPACK via JNI) for general NxN matrices
- Guard the call: if (m.width() != 2) use an alternative solver before calling eigen()
Example fix
// before CImg<float> A(3,3); CImg<float> val, vec; A.eigen(val, vec); // throws // after CImg<float> val, vec; if (A.width() == 2 && A.height() == 2) A.eigen(val, vec); else A.symmetric_eigen(val, vec); // for symmetric NxN
Defensive patterns
Strategy: validation
Validate before calling
if (m.width() == 2 && m.height() == 2) { m.eigen(val, vec); } else { /* use symmetric_eigen or external solver */ } Type guard
bool isGeneralEigenSupported(const CImg<T>& m) { return m.width() == 2 && m.height() == 2 && m.depth() == 1 && m.spectrum() == 1; } Try / catch
try { m.eigen(val, vec); } catch (CImgInstanceException& e) { /* fall back to symmetric_eigen or external library */ } Prevention
- Only call eigen() on 2x2 general matrices
- Prefer symmetric_eigen() for symmetric NxN matrices
- Document the 2x2 limitation where eigen() is wrapped
When it happens
Trigger: Calling CImg<T>::eigen()/get_eigen() (or symmetric_eigen dispatch path) on an instance whose _width is not 2 (e.g. a 3x3 or NxN general matrix).
Common situations: Using eigen() on a 3x3 covariance or rotation matrix expecting LAPACK-like behavior; confusing eigen() with symmetric_eigen(), which supports arbitrary square sizes; upgrading CImg versions where general-N eigen support is absent.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- eigen(): Complex eigenvalues found.
- operator*(): Invalid multiplication of instance by specified
- eigen(): Instance is not a square matrix.
- SVD(): Instance has invalid dimensions (depth or channels di
- invert(): LAPACK function dgetrf_() returned error code %d.
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/71b8d8b483e633d6.
Report an issue: GitHub.