Yalantis/uCrop · error · CImgArgumentException

invert(): Specified lambda (%g) should be >=0.

Error message

invert(): Specified lambda (%g) should be >=0.

What it means

CImg::invert() accepts a lambda parameter used only for the Moore-Penrose pseudoinverse of non-square matrices, as a regularization term in A^t(A^t.A + lambda.Id)^-1. It throws CImgArgumentException when lambda is negative, because a negative regularization constant is mathematically invalid.

Source

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

    CImg<_cimg_Tt> get_cross(const CImg<t>& img) const {
      return CImg<_cimg_Tt>(*this).cross(img);
    }

    //! Invert the instance image, viewed as a matrix.
    /**
       If the instance matrix is not square, the Moore-Penrose pseudo-inverse is computed instead.
       \param use_LU Choose the inverting algorithm. Can be:
       - \c true: LU solver (faster but sometimes less precise).
       - \c false: SVD solver (more precise but slower).
       \param lambda is used only in the Moore-Penrose pseudoinverse for estimating A^t.(A^t.A + lambda.Id)^-1.
    **/
    CImg<T>& invert(const bool use_LU=false, const float lambda=0) {
      if (_depth!=1 || _spectrum!=1)
        throw CImgInstanceException(_cimg_instance
                                    "invert(): Instance is not a matrix.",
                                    cimg_instance);
      if (lambda<0)
        throw CImgArgumentException(_cimg_instance
                                    "invert(): Specified lambda (%g) should be >=0.",
                                    cimg_instance);

      if (_width!=_height) return get_invert(use_LU,lambda).move_to(*this); // Non-square matrix: Pseudoinverse

      // Square matrix.
      const double dete = _width>3?-1.:det();
      if (dete!=0. && _width==2) {
        const double
          a = _data[0], c = _data[1],
          b = _data[2], d = _data[3];
        _data[0] = (T)(d/dete); _data[1] = (T)(-c/dete);
        _data[2] = (T)(-b/dete); _data[3] = (T)(a/dete);
      } else if (dete!=0. && _width==3) {
        const double
          a = _data[0], d = _data[1], g = _data[2],
          b = _data[3], e = _data[4], h = _data[5],
          c = _data[6], f = _data[7], i = _data[8];

View on GitHub (pinned to f788b534b4)

Solutions

  1. Pass lambda >= 0 (or use the default 0).
  2. Clamp: img.invert(use_LU, std::max(0.0f, lambda)).
  3. Use the default overload img.invert() if no regularization is needed.
  4. Note the argument order: invert(use_LU, lambda).

Example fix

// before
img.invert(false, -1e-3f); // negative lambda
// after
float lambda = std::max(0.0f, computedLambda);
img.invert(false, lambda);
Defensive patterns

Strategy: validation

Validate before calling

if (!(lambda >= 0)) lambda = 0; // guard NaN and negatives
img.invert(useLU, lambda);

Try / catch

try { img.invert(useLU, lambda); } catch (CImgArgumentException& e) { std::cerr << e.what() << '\n'; }

Prevention

When it happens

Trigger: Calling img.invert(use_LU, lambda) with a negative float, e.g. an uninitialized/NaN-adjacent variable, a computed damping term that underflowed negative, or swapped arguments.

Common situations: Computing lambda from data (e.g. scaled noise estimate) that can be negative; typo passing -1 as a sentinel; confusing lambda with another tuning parameter.

Related errors


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