// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>
// Copyright (C) 2012 Desire Nuentsa <desire.nuentsa_wakam@inria.fr>
//
// This code initially comes from MINPACK whose original authors are:
// Copyright Jorge More - Argonne National Laboratory
// Copyright Burt Garbow - Argonne National Laboratory
// Copyright Ken Hillstrom - Argonne National Laboratory
//
// This Source Code Form is subject to the terms of the Minpack license
// (a BSD-like license) described in the campaigned CopyrightMINPACK.txt file.
// SPDX-License-Identifier: MPL-2.0 AND LicenseRef-MINPACK

#ifndef EIGEN_LMQRSOLV_H
#define EIGEN_LMQRSOLV_H

// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {

namespace internal {

template <typename Scalar, int Rows, int Cols, typename PermIndex>
void lmqrsolv(Matrix<Scalar, Rows, Cols> &s, const PermutationMatrix<Dynamic, Dynamic, PermIndex> &iPerm,
              const Matrix<Scalar, Dynamic, 1> &diag, const Matrix<Scalar, Dynamic, 1> &qtb,
              Matrix<Scalar, Dynamic, 1> &x, Matrix<Scalar, Dynamic, 1> &sdiag) {
  /* Local variables */
  Index i, j, k;
  Scalar temp;
  Index n = s.cols();
  Matrix<Scalar, Dynamic, 1> wa(n);
  JacobiRotation<Scalar> givens;

  /* Function Body */
  // the following will only change the lower triangular part of s, including
  // the diagonal, though the diagonal is restored afterward

  /*     copy r and (q transpose)*b to preserve input and initialize s. */
  /*     in particular, save the diagonal elements of r in x. */
  x = s.diagonal();
  wa = qtb;

  s.topLeftCorner(n, n).template triangularView<StrictlyLower>() = s.topLeftCorner(n, n).transpose();
  /*     eliminate the diagonal matrix d using a givens rotation. */
  for (j = 0; j < n; ++j) {
    /*        prepare the row of d to be eliminated, locating the */
    /*        diagonal element using p from the qr factorization. */
    const PermIndex l = iPerm.indices()(j);
    if (diag[l] == 0.) break;
    sdiag.tail(n - j).setZero();
    sdiag[j] = diag[l];

    /*        the transformations to eliminate the row of d */
    /*        modify only a single element of (q transpose)*b */
    /*        beyond the first n, which is initially zero. */
    Scalar qtbpj = 0.;
    for (k = j; k < n; ++k) {
      /*           determine a givens rotation which eliminates the */
      /*           appropriate element in the current row of d. */
      givens.makeGivens(-s(k, k), sdiag[k]);

      /*           compute the modified diagonal element of r and */
      /*           the modified element of ((q transpose)*b,0). */
      s(k, k) = givens.c() * s(k, k) + givens.s() * sdiag[k];
      temp = givens.c() * wa[k] + givens.s() * qtbpj;
      qtbpj = -givens.s() * wa[k] + givens.c() * qtbpj;
      wa[k] = temp;

      /*           accumulate the transformation in the row of s. */
      for (i = k + 1; i < n; ++i) {
        temp = givens.c() * s(i, k) + givens.s() * sdiag[i];
        sdiag[i] = -givens.s() * s(i, k) + givens.c() * sdiag[i];
        s(i, k) = temp;
      }
    }
  }

  /*     solve the triangular system for z. if the system is */
  /*     singular, then obtain a least squares solution. */
  Index nsing;
  for (nsing = 0; nsing < n && sdiag[nsing] != 0; nsing++) {
  }

  wa.tail(n - nsing).setZero();
  s.topLeftCorner(nsing, nsing).transpose().template triangularView<Upper>().solveInPlace(wa.head(nsing));

  // restore
  sdiag = s.diagonal();
  s.diagonal() = x;

  /* permute the components of z back to components of x. */
  x = iPerm * wa;
}

template <typename Scalar, int Options_, typename Index>
void lmqrsolv(SparseMatrix<Scalar, Options_, Index> &s, const PermutationMatrix<Dynamic, Dynamic> &iPerm,
              const Matrix<Scalar, Dynamic, 1> &diag, const Matrix<Scalar, Dynamic, 1> &qtb,
              Matrix<Scalar, Dynamic, 1> &x, Matrix<Scalar, Dynamic, 1> &sdiag) {
  /* Local variables */
  typedef SparseMatrix<Scalar, RowMajor, Index> FactorType;
  Index i, j, k, l;
  Scalar temp;
  Index n = s.cols();
  Matrix<Scalar, Dynamic, 1> wa(n);
  JacobiRotation<Scalar> givens;

  /* Function Body */
  // the following will only change the lower triangular part of s, including
  // the diagonal, though the diagonal is restored afterward

  /*     copy r and (q transpose)*b to preserve input and initialize R. */
  wa = qtb;
  FactorType R(s);
  // Eliminate the diagonal matrix d using a givens rotation
  for (j = 0; j < n; ++j) {
    // Prepare the row of d to be eliminated, locating the
    // diagonal element using p from the qr factorization
    l = iPerm.indices()(j);
    if (diag(l) == Scalar(0)) break;
    sdiag.tail(n - j).setZero();
    sdiag[j] = diag[l];
    // the transformations to eliminate the row of d
    // modify only a single element of (q transpose)*b
    // beyond the first n, which is initially zero.

    Scalar qtbpj = 0;
    // Browse the nonzero elements of row j of the upper triangular s
    for (k = j; k < n; ++k) {
      typename FactorType::InnerIterator itk(R, k);
      for (; itk; ++itk) {
        if (itk.index() < k)
          continue;
        else
          break;
      }
      // At this point, we have the diagonal element R(k,k)
      //  Determine a givens rotation which eliminates
      //  the appropriate element in the current row of d
      givens.makeGivens(-itk.value(), sdiag(k));

      // Compute the modified diagonal element of r and
      // the modified element of ((q transpose)*b,0).
      itk.valueRef() = givens.c() * itk.value() + givens.s() * sdiag(k);
      temp = givens.c() * wa(k) + givens.s() * qtbpj;
      qtbpj = -givens.s() * wa(k) + givens.c() * qtbpj;
      wa(k) = temp;

      // Accumulate the transformation in the remaining k row/column of R
      for (++itk; itk; ++itk) {
        i = itk.index();
        temp = givens.c() * itk.value() + givens.s() * sdiag(i);
        sdiag(i) = -givens.s() * itk.value() + givens.c() * sdiag(i);
        itk.valueRef() = temp;
      }
    }
  }

  // Solve the triangular system for z. If the system is
  // singular, then obtain a least squares solution
  Index nsing;
  for (nsing = 0; nsing < n && sdiag(nsing) != 0; nsing++) {
  }

  wa.tail(n - nsing).setZero();
  //     x = wa;
  wa.head(nsing) = R.topLeftCorner(nsing, nsing).template triangularView<Upper>().solve /*InPlace*/ (wa.head(nsing));

  sdiag = R.diagonal();
  // Permute the components of z back to components of x
  x = iPerm * wa;
}
}  // end namespace internal

}  // end namespace Eigen

#endif  // EIGEN_LMQRSOLV_H
