Yalantis/uCrop · error · CImgArgumentException

solve(): Instance and specified matrix (%u,%u,%u,%u,%p) have

Error message

solve(): Instance and specified matrix (%u,%u,%u,%u,%p) have incompatible dimensions.

What it means

CImg::solve() solves AX = B where B is *this and A is the argument; for a valid linear system both must be 2D single-channel matrices and share the same number of rows (_height==A._height). It throws CImgArgumentException listing A's dimensions when any of these preconditions fails.

Source

Thrown at ucrop/src/main/jni/CImg.h:32968

      cimg_forX(V,x) {
        const Tfloat s = S(x), invs = lambda?1/(lambda + s):s>eps?1/s:0;
        cimg_forY(V,y) V(x,y)*=invs;
      }
      return V*U.transpose();
    }

    //! Solve a system of linear equations.
    /**
       \param A Matrix of the linear system.
       \param use_LU In case of non square system (least-square solution),
                     choose between SVD (\c false) or LU (\c true) solver.
                     LU solver is faster for large matrices, but numerically less stable.
       \note Solve \c AX = B where \c B=*this.
    **/
    template<typename t>
    CImg<T>& solve(const CImg<t>& A, const bool use_LU=false) {
      if (_depth!=1 || _spectrum!=1 || _height!=A._height || A._depth!=1 || A._spectrum!=1)
        throw CImgArgumentException(_cimg_instance
                                    "solve(): Instance and specified matrix (%u,%u,%u,%u,%p) have "
                                    "incompatible dimensions.",
                                    cimg_instance,
                                    A._width,A._height,A._depth,A._spectrum,A._data);
      typedef _cimg_Ttfloat Ttfloat;

      if (A.size()==1) return (*this)/=A[0];
      if (A._width==2 && A._height==2 && _height==2) { // 2x2 linear system
        const double a = (double)A[0], b = (double)A[1], c = (double)A[2], d = (double)A[3],
          fa = std::fabs(a), fb = std::fabs(b), fc = std::fabs(c), fd = std::fabs(d),
          det = a*d - b*c, fM = cimg::max(fa,fb,fc,fd);
        if (fM==fa)
          cimg_pragma_openmp(parallel for cimg_openmp_if(_width>=256))
          cimg_forX(*this,k) {
            const double u = (double)(*this)(k,0), v = (double)(*this)(k,1), y = (a*v - c*u)/det;
            (*this)(k,0) = (T)((u - b*y)/a); (*this)(k,1) = (T)y;
          } else if (fM==fc)
          cimg_pragma_openmp(parallel for cimg_openmp_if(_width>=256))

View on GitHub (pinned to f788b534b4)

Solutions

  1. Ensure A and b are both (w,h,1,1) with matching h: b.assign(A._height, k).
  2. Check dims before solving: if (A.height()==b.height() && A.depth()==1 && A.spectrum()==1) b.solve(A);
  3. Use get_solve() for a non-mutating variant and verify dimensions on the copy first.

Example fix

// before
CImg<float> A(3,4); // 4 rows
CImg<float> b(1,3); // 3 rows -> throws
b.solve(A);
// after
CImg<float> b(1,4); // matches A._height
b.solve(A);
Defensive patterns

Strategy: validation

Validate before calling

bool solvable = b.depth()==1 && b.spectrum()==1 && A.depth()==1 && A.spectrum()==1 && b.height()==A.height(); if (solvable) b.solve(A);

Type guard

bool solvableSystem(const CImg<T>& A, const CImg<T>& b){ return A.depth()==1 && A.spectrum()==1 && b.depth()==1 && b.spectrum()==1 && b.height()==A.height(); }

Try / catch

try { b.solve(A); } catch (CImgArgumentException& e) { std::cerr << e.what() << '\n'; }

Prevention

When it happens

Trigger: Calling b.solve(A) where A and b have different heights, or where either operand has depth>1 or spectrum>1.

Common situations: Building the RHS vector with the wrong number of rows for the system matrix; passing a color or volumetric image as A or B; mixing a column-vector B (n x 1) with an A of different height.

Related errors


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