mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Add LU::transpose().solve() and LU::adjoint().solve() API.
This commit is contained in:
@@ -29,6 +29,7 @@ struct storage_kind_to_evaluator_kind {
|
||||
template<typename StorageKind> struct storage_kind_to_shape;
|
||||
|
||||
template<> struct storage_kind_to_shape<Dense> { typedef DenseShape Shape; };
|
||||
template<> struct storage_kind_to_shape<SolverStorage> { typedef SolverShape Shape; };
|
||||
template<> struct storage_kind_to_shape<PermutationStorage> { typedef PermutationShape Shape; };
|
||||
template<> struct storage_kind_to_shape<TranspositionsStorage> { typedef TranspositionsShape Shape; };
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ public:
|
||||
typedef typename internal::ref_selector<XprType>::type XprTypeNested;
|
||||
typedef typename internal::remove_all<XprTypeNested>::type XprTypeNestedCleaned;
|
||||
typedef typename internal::ref_selector<Inverse>::type Nested;
|
||||
typedef typename internal::remove_all<XprType>::type NestedExpression;
|
||||
|
||||
explicit Inverse(const XprType &xpr)
|
||||
: m_xpr(xpr)
|
||||
@@ -62,25 +63,16 @@ protected:
|
||||
XprTypeNested m_xpr;
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* Specialization of the Inverse expression for dense expressions.
|
||||
* Direct access to the coefficients are discared.
|
||||
* FIXME this intermediate class is probably not needed anymore.
|
||||
*/
|
||||
template<typename XprType>
|
||||
class InverseImpl<XprType,Dense>
|
||||
: public MatrixBase<Inverse<XprType> >
|
||||
// Generic API dispatcher
|
||||
template<typename XprType, typename StorageKind>
|
||||
class InverseImpl
|
||||
: public internal::generic_xpr_base<Inverse<XprType> >::type
|
||||
{
|
||||
typedef Inverse<XprType> Derived;
|
||||
|
||||
public:
|
||||
|
||||
typedef MatrixBase<Derived> Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
||||
typedef typename internal::remove_all<XprType>::type NestedExpression;
|
||||
|
||||
typedef typename internal::generic_xpr_base<Inverse<XprType> >::type Base;
|
||||
typedef typename XprType::Scalar Scalar;
|
||||
private:
|
||||
|
||||
|
||||
Scalar coeff(Index row, Index col) const;
|
||||
Scalar coeff(Index i) const;
|
||||
};
|
||||
|
||||
@@ -34,12 +34,11 @@ template<typename Decomposition, typename RhsType,typename StorageKind> struct s
|
||||
template<typename Decomposition, typename RhsType>
|
||||
struct solve_traits<Decomposition,RhsType,Dense>
|
||||
{
|
||||
typedef typename Decomposition::MatrixType MatrixType;
|
||||
typedef Matrix<typename RhsType::Scalar,
|
||||
MatrixType::ColsAtCompileTime,
|
||||
Decomposition::ColsAtCompileTime,
|
||||
RhsType::ColsAtCompileTime,
|
||||
RhsType::PlainObject::Options,
|
||||
MatrixType::MaxColsAtCompileTime,
|
||||
Decomposition::MaxColsAtCompileTime,
|
||||
RhsType::MaxColsAtCompileTime> PlainObject;
|
||||
};
|
||||
|
||||
@@ -145,6 +144,28 @@ struct Assignment<DstXprType, Solve<DecType,RhsType>, internal::assign_op<Scalar
|
||||
}
|
||||
};
|
||||
|
||||
// Specialization for "dst = dec.transpose().solve(rhs)"
|
||||
template<typename DstXprType, typename DecType, typename RhsType, typename Scalar>
|
||||
struct Assignment<DstXprType, Solve<Transpose<const DecType>,RhsType>, internal::assign_op<Scalar>, Dense2Dense, Scalar>
|
||||
{
|
||||
typedef Solve<Transpose<const DecType>,RhsType> SrcXprType;
|
||||
static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar> &)
|
||||
{
|
||||
src.dec().nestedExpression().template _solve_impl_transposed<false>(src.rhs(), dst);
|
||||
}
|
||||
};
|
||||
|
||||
// Specialization for "dst = dec.adjoint().solve(rhs)"
|
||||
template<typename DstXprType, typename DecType, typename RhsType, typename Scalar>
|
||||
struct Assignment<DstXprType, Solve<CwiseUnaryOp<internal::scalar_conjugate_op<typename DecType::Scalar>, const Transpose<const DecType> >,RhsType>, internal::assign_op<Scalar>, Dense2Dense, Scalar>
|
||||
{
|
||||
typedef Solve<CwiseUnaryOp<internal::scalar_conjugate_op<typename DecType::Scalar>, const Transpose<const DecType> >,RhsType> SrcXprType;
|
||||
static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar> &)
|
||||
{
|
||||
src.dec().nestedExpression().nestedExpression().template _solve_impl_transposed<true>(src.rhs(), dst);
|
||||
}
|
||||
};
|
||||
|
||||
} // end namepsace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
130
Eigen/src/Core/SolverBase.h
Normal file
130
Eigen/src/Core/SolverBase.h
Normal file
@@ -0,0 +1,130 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2015 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_SOLVERBASE_H
|
||||
#define EIGEN_SOLVERBASE_H
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
/** \class SolverBase
|
||||
* \brief A base class for matrix decomposition and solvers
|
||||
*
|
||||
* \tparam Derived the actual type of the decomposition/solver.
|
||||
*
|
||||
* Any matrix decomposition inheriting this base class provide the following API:
|
||||
*
|
||||
* \code
|
||||
* MatrixType A, b, x;
|
||||
* DecompositionType dec(A);
|
||||
* x = dec.solve(b); // solve A * x = b
|
||||
* x = dec.transpose().solve(b); // solve A^T * x = b
|
||||
* x = dec.adjoint().solve(b); // solve A' * x = b
|
||||
* \endcode
|
||||
*
|
||||
* \warning Currently, any other usage of transpose() and adjoint() are not supported and will produce compilation errors.
|
||||
*
|
||||
* \sa class PartialPivLU, class FullPivLU
|
||||
*/
|
||||
template<typename Derived>
|
||||
class SolverBase : public EigenBase<Derived>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef EigenBase<Derived> Base;
|
||||
typedef typename internal::traits<Derived>::Scalar Scalar;
|
||||
typedef Scalar CoeffReturnType;
|
||||
|
||||
enum {
|
||||
RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
|
||||
ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
|
||||
SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime,
|
||||
internal::traits<Derived>::ColsAtCompileTime>::ret),
|
||||
MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime,
|
||||
MaxSizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::MaxRowsAtCompileTime,
|
||||
internal::traits<Derived>::MaxColsAtCompileTime>::ret),
|
||||
IsVectorAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime == 1
|
||||
|| internal::traits<Derived>::MaxColsAtCompileTime == 1
|
||||
};
|
||||
|
||||
/** Default constructor */
|
||||
SolverBase()
|
||||
{}
|
||||
|
||||
~SolverBase()
|
||||
{}
|
||||
|
||||
using Base::derived;
|
||||
|
||||
/** \returns an expression of the solution x of \f$ A x = b \f$ using the current decomposition of A.
|
||||
*/
|
||||
template<typename Rhs>
|
||||
inline const Solve<Derived, Rhs>
|
||||
solve(const MatrixBase<Rhs>& b) const
|
||||
{
|
||||
eigen_assert(derived().rows()==b.rows() && "solve(): invalid number of rows of the right hand side matrix b");
|
||||
return Solve<Derived, Rhs>(derived(), b.derived());
|
||||
}
|
||||
|
||||
/** \internal the return type of transpose() */
|
||||
typedef typename internal::add_const<Transpose<const Derived> >::type ConstTransposeReturnType;
|
||||
/** \returns an expression of the transposed of the factored matrix.
|
||||
*
|
||||
* A typical usage is to solve for the transposed problem A^T x = b:
|
||||
* \code x = dec.transpose().solve(b); \endcode
|
||||
*
|
||||
* \sa adjoint(), solve()
|
||||
*/
|
||||
inline ConstTransposeReturnType transpose() const
|
||||
{
|
||||
return ConstTransposeReturnType(derived());
|
||||
}
|
||||
|
||||
/** \internal the return type of adjoint() */
|
||||
typedef typename internal::conditional<NumTraits<Scalar>::IsComplex,
|
||||
CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, ConstTransposeReturnType>,
|
||||
ConstTransposeReturnType
|
||||
>::type AdjointReturnType;
|
||||
/** \returns an expression of the adjoint of the factored matrix
|
||||
*
|
||||
* A typical usage is to solve for the adjoint problem A' x = b:
|
||||
* \code x = dec.adjoint().solve(b); \endcode
|
||||
*
|
||||
* For real scalar types, this function is equivalent to transpose().
|
||||
*
|
||||
* \sa transpose(), solve()
|
||||
*/
|
||||
inline AdjointReturnType adjoint() const
|
||||
{
|
||||
return AdjointReturnType(derived().transpose());
|
||||
}
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename Derived>
|
||||
struct generic_xpr_base<Derived, MatrixXpr, SolverStorage>
|
||||
{
|
||||
typedef SolverBase<Derived> type;
|
||||
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_SOLVERBASE_H
|
||||
@@ -39,7 +39,7 @@ struct traits<Transpose<MatrixType> > : public traits<MatrixType>
|
||||
MaxRowsAtCompileTime = MatrixType::MaxColsAtCompileTime,
|
||||
MaxColsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
|
||||
FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
|
||||
Flags0 = MatrixTypeNestedPlain::Flags & ~(LvalueBit | NestByRefBit),
|
||||
Flags0 = traits<MatrixTypeNestedPlain>::Flags & ~(LvalueBit | NestByRefBit),
|
||||
Flags1 = Flags0 | FlagsLvalueBit,
|
||||
Flags = Flags1 ^ RowMajorBit,
|
||||
InnerStrideAtCompileTime = inner_stride_at_compile_time<MatrixType>::ret,
|
||||
|
||||
@@ -492,6 +492,9 @@ struct Dense {};
|
||||
/** The type used to identify a general sparse storage. */
|
||||
struct Sparse {};
|
||||
|
||||
/** The type used to identify a general solver (foctored) storage. */
|
||||
struct SolverStorage {};
|
||||
|
||||
/** The type used to identify a permutation storage. */
|
||||
struct PermutationStorage {};
|
||||
|
||||
@@ -506,6 +509,7 @@ struct ArrayXpr {};
|
||||
|
||||
// An evaluator must define its shape. By default, it can be one of the following:
|
||||
struct DenseShape { static std::string debugName() { return "DenseShape"; } };
|
||||
struct SolverShape { static std::string debugName() { return "SolverShape"; } };
|
||||
struct HomogeneousShape { static std::string debugName() { return "HomogeneousShape"; } };
|
||||
struct DiagonalShape { static std::string debugName() { return "DiagonalShape"; } };
|
||||
struct BandShape { static std::string debugName() { return "BandShape"; } };
|
||||
|
||||
@@ -132,6 +132,7 @@ template<typename MatrixType> struct CommaInitializer;
|
||||
template<typename Derived> class ReturnByValue;
|
||||
template<typename ExpressionType> class ArrayWrapper;
|
||||
template<typename ExpressionType> class MatrixWrapper;
|
||||
template<typename Derived> class SolverBase;
|
||||
template<typename XprType> class InnerIterator;
|
||||
|
||||
namespace internal {
|
||||
|
||||
Reference in New Issue
Block a user