// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2014 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef EIGEN_SOLVEWITHGUESS_H
#define EIGEN_SOLVEWITHGUESS_H

namespace Eigen {

template<typename Decomposition, typename RhsType, typename GuessType> class SolveWithGuess;
  
/** \class SolveWithGuess
  * \ingroup IterativeLinearSolvers_Module
  *
  * \brief Pseudo expression representing a solving operation
  *
  * \tparam Decomposition the type of the matrix or decomposion object
  * \tparam Rhstype the type of the right-hand side
  *
  * This class represents an expression of A.solve(B)
  * and most of the time this is the only way it is used.
  *
  */
namespace internal {


template<typename Decomposition, typename RhsType, typename GuessType>
struct traits<SolveWithGuess<Decomposition, RhsType, GuessType> >
  : traits<Solve<Decomposition,RhsType> >
{};

}


template<typename Decomposition, typename RhsType, typename GuessType>
class SolveWithGuess : public internal::generic_xpr_base<SolveWithGuess<Decomposition,RhsType,GuessType>, MatrixXpr, typename internal::traits<RhsType>::StorageKind>::type
{
public:
  typedef typename RhsType::Index Index;
  typedef typename internal::traits<SolveWithGuess>::Scalar Scalar;
  typedef typename internal::traits<SolveWithGuess>::PlainObject PlainObject;
  typedef typename internal::generic_xpr_base<SolveWithGuess<Decomposition,RhsType,GuessType>, MatrixXpr, typename internal::traits<RhsType>::StorageKind>::type Base;
  
  SolveWithGuess(const Decomposition &dec, const RhsType &rhs, const GuessType &guess)
    : m_dec(dec), m_rhs(rhs), m_guess(guess)
  {}
  
  EIGEN_DEVICE_FUNC Index rows() const { return m_dec.cols(); }
  EIGEN_DEVICE_FUNC Index cols() const { return m_rhs.cols(); }

  EIGEN_DEVICE_FUNC const Decomposition& dec()   const { return m_dec; }
  EIGEN_DEVICE_FUNC const RhsType&       rhs()   const { return m_rhs; }
  EIGEN_DEVICE_FUNC const GuessType&     guess() const { return m_guess; }

protected:
  const Decomposition &m_dec;
  const RhsType       &m_rhs;
  const GuessType     &m_guess;
  
private:
  Scalar coeff(Index row, Index col) const;
  Scalar coeff(Index i) const;
};

namespace internal {

// Evaluator of SolveWithGuess -> eval into a temporary
template<typename Decomposition, typename RhsType, typename GuessType>
struct evaluator<SolveWithGuess<Decomposition,RhsType, GuessType> >
  : public evaluator<typename SolveWithGuess<Decomposition,RhsType,GuessType>::PlainObject>::type
{
  typedef SolveWithGuess<Decomposition,RhsType,GuessType> SolveType;
  typedef typename SolveType::PlainObject PlainObject;
  typedef typename evaluator<PlainObject>::type Base;
  
  typedef evaluator type;
  typedef evaluator nestedType;

  evaluator(const SolveType& solve)
    : m_result(solve.rows(), solve.cols())
  {
    ::new (static_cast<Base*>(this)) Base(m_result);
    solve.dec()._solve_with_guess_impl(solve.rhs(), m_result, solve().guess());
  }
  
protected:  
  PlainObject m_result;
};

// Specialization for "dst = dec.solveWithGuess(rhs)"
// NOTE we need to specialize it for Dense2Dense to avoid ambiguous specialization error and a Sparse2Sparse specialization must exist somewhere
template<typename DstXprType, typename DecType, typename RhsType, typename GuessType, typename Scalar>
struct Assignment<DstXprType, SolveWithGuess<DecType,RhsType,GuessType>, internal::assign_op<Scalar>, Dense2Dense, Scalar>
{
  typedef SolveWithGuess<DecType,RhsType,GuessType> SrcXprType;
  static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar> &)
  {
    // FIXME shall we resize dst here?
    dst = src.guess();
    src.dec()._solve_with_guess_impl(src.rhs(), dst/*, src.guess()*/);
  }
};

} // end namepsace internal

} // end namespace Eigen

#endif // EIGEN_SOLVEWITHGUESS_H
