Yalantis/uCrop · error · CImgInstanceException

eigen(): Eigenvalues computation of general matrices is…

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.

Solutions

  1. Restrict general eigen() calls to 2x2 matrices, or reshape/decompose your problem into 2x2 blocks
  2. For symmetric matrices of any size, call symmetric_eigen(val, vec) instead, which supports NxN
  3. Implement an external eigensolver (e.g. Eigen, LAPACK via JNI) for general NxN matrices
  4. 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

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


AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08). Data as JSON: /api/errors/71b8d8b483e633d6. Report an issue: GitHub.

Appendix: 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)