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
- Repack A into the required n x 3 layout (columns = lower diagonal, main diagonal, upper diagonal).
- Make the instance (B) contain exactly A._height elements.
- 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
- Encode the tridiagonal matrix as n x 3 (sub, main, super diagonals), never as a full n x n matrix
- Match B's element count to the number of rows of the encoded A
- Document the compact storage convention in team code
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
- det(): Instance is not a square matrix.
- cross(): Instance and/or specified image (%u,%u,%u,%u,%p) ar
- invert(): Instance is not a matrix.
- solve(): Instance and specified matrix (%u,%u,%u,%u,%p) have
- eigen(): Instance is not a square matrix.
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/9f9d31b77c25e2aa.
Report an issue: GitHub.