Yalantis/uCrop · warning

solve(): LAPACK library function dgetrf_() returned error co

Error message

solve(): LAPACK library function dgetrf_() returned error code %d.

What it means

CImg::solve() solves A*X = B by LU-factoring A with LAPACK dgetrf_(); a nonzero INFO means the factorization failed because the matrix is singular (zero pivot) or an argument was invalid. CImg warns, leaves the solution column zeroed, and continues rather than throwing.

Source

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

            (*this)(k,0) = (T)x; (*this)(k,1) = (T)((v - c*x)/d);
          }
        return *this;
      }

      if (A._width==A._height) { // Square linear system
#ifdef cimg_use_lapack
        char TRANS = 'N';
        int INFO, N = _height, LWORK = 4*N, *const IPIV = new int[N];
        Ttfloat
          *const lapA = new Ttfloat[N*N],
          *const lapB = new Ttfloat[N],
          *const WORK = new Ttfloat[LWORK];
        cimg_forXY(A,k,l) lapA[k*N + l] = (Ttfloat)(A(k,l));
        cimg_forX(*this,i) {
          cimg_forY(*this,j) lapB[j] = (Ttfloat)((*this)(i,j));
          cimg::getrf(N,lapA,IPIV,INFO);
          if (INFO)
            cimg::warn(_cimg_instance
                       "solve(): LAPACK library function dgetrf_() returned error code %d.",
                       cimg_instance,
                       INFO);
          else {
            cimg::getrs(TRANS,N,lapA,IPIV,lapB,INFO);
            if (INFO)
              cimg::warn(_cimg_instance
                         "solve(): LAPACK library function dgetrs_() returned error code %d.",
                         cimg_instance,
                         INFO);
          }
          if (!INFO) cimg_forY(*this,j) (*this)(i,j) = (T)(lapB[j]); else cimg_forY(*this,j) (*this)(i,j) = (T)0;
        }
        delete[] IPIV; delete[] lapA; delete[] lapB; delete[] WORK;
#else
        CImg<Ttfloat> lu(A,false);
        CImg<Ttfloat> indx;
        bool d;

View on GitHub (pinned to f788b534b4)

Solutions

  1. Check that A is square and that B's rows equal A's rows before calling solve()
  2. Test A for singularity (determinant/rank) and regularize (A + eps*I) if needed
  3. Use double precision to survive near-singular systems
  4. Fall back to the least-squares path (sgels) or a pseudo-inverse when the system has no unique solution
  5. Verify the solution is not the zero-filled fallback before using it

Example fix

// before
CImg<float> x = B.solve(A);
// after
if (std::fabs(A.determinant()) < 1e-12) {
  for (int i = 0; i < A.width(); ++i) A(i,i) += 1e-8f; // Tikhonov regularization
}
CImg<float> x = B.solve(A);
Defensive patterns

Strategy: validation

Validate before calling

bool solvable(const CImg<float>& A, const CImg<float>& B) {
  return A.width() == A.height() && B.height() == A.height() &&
         std::fabs(A.determinant()) > 1e-12f;
}

Prevention

When it happens

Trigger: Calling solve() on a square system whose coefficient matrix A is singular or rank-deficient; passing mismatched dimensions between this (B) and A.

Common situations: Solving systems with duplicated/dependent equations; poorly conditioned matrices from noisy data; constructing A with wrong dimensions so LAPACK sees an invalid N.

Related errors


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