Yalantis/uCrop · error · CImgArgumentException

solve_tridiagonal(): Instance and tridiagonal matrix (%u,%u,

Error message

solve_tridiagonal(): Instance and tridiagonal matrix (%u,%u,%u,%u,%p) have incompatible dimensions.

What it means

CImg::solve_tridiagonal() solves AX=B using the Thomas algorithm, where A is encoded as an n x 3 matrix (three diagonals as columns) and B is *this of size n. It throws CImgArgumentException when A._width!=3 or A._height!=this->size(), i.e. the tridiagonal encoding or system size is wrong.

Source

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

        sum = (*this)(i);
        for (int j = i + 1; j<N; ++j) sum-=A(j,i)*(*this)(j);
        (*this)(i) = (T)(sum/A(i,i));
      }
      return *this;
    }

    //! Solve a tridiagonal system of linear equations.
    /**
       \param A Coefficients of the tridiagonal system.
       A is a tridiagonal matrix A = [ b0,c0,0,...; a1,b1,c1,0,... ; ... ; ...,0,aN,bN ],
       stored as a 3 columns matrix
       \note Solve AX=B where \c B=*this, using the Thomas algorithm.
    **/
    template<typename t>
    CImg<T>& solve_tridiagonal(const CImg<t>& A) {
      const unsigned int siz = (unsigned int)size();
      if (A._width!=3 || A._height!=siz)
        throw CImgArgumentException(_cimg_instance
                                    "solve_tridiagonal(): Instance and tridiagonal 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;
      const Ttfloat eps = 1e-4f;
      CImg<Ttfloat> B = A.get_column(1), V(*this,false);
      for (int i = 1; i<(int)siz; ++i) {
        const Ttfloat m = A(0,i)/(B[i - 1]?B[i - 1]:eps);
        B[i] -= m*A(2,i - 1);
        V[i] -= m*V[i - 1];
      }
      (*this)[siz - 1] = (T)(V[siz - 1]/(B[siz - 1]?B[siz - 1]:eps));
      for (int i = (int)siz - 2; i>=0; --i) (*this)[i] = (T)((V[i] - A(2,i)*(*this)[i + 1])/(B[i]?B[i]:eps));
      return *this;
    }

    //! Solve a tridiagonal system of linear equations \newinstance.

View on GitHub (pinned to f788b534b4)

Solutions

  1. Repack A into the required n x 3 layout (columns = lower diagonal, main diagonal, upper diagonal).
  2. Make the instance (B) contain exactly A._height elements.
  3. Check before calling: if (A.width()==3 && (ulongT)A.height()==b.size()) b.solve_tridiagonal(A);

Example fix

// before
CImg<float> A(n,n); // full matrix -> throws
b.solve_tridiagonal(A);
// after
CImg<float> A(n,3); // 3 diagonals per row
A(0,1)=a1; A(k,0)=sub; A(k,1)=diag; A(k,2)=super; ...
b.solve_tridiagonal(A);
Defensive patterns

Strategy: validation

Validate before calling

bool ok = (A.width()==3) && (A.height()==(int)b.size()) && b.depth()==1 && b.spectrum()==1; if (ok) b.solve_tridiagonal(A);

Type guard

bool isTridiagonalEncoding(const CImg<T>& A, const CImg<T>& b){ return A.width()==3 && (ulongT)A.height()==b.size(); }

Try / catch

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

Prevention

When it happens

Trigger: Passing A as a full n x n matrix instead of the n x 3 diagonal encoding; passing an n x 3 matrix whose n differs from the instance's total element count; passing an empty A.

Common situations: Misunderstanding the compact storage format (sub/diag/super diagonals in the 3 columns); building B as a vector whose length does not match n.

Related errors


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