// 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.

#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
