diff options
Diffstat (limited to 'Eigen/src/Core/InverseProduct.h')
-rwxr-xr-x | Eigen/src/Core/InverseProduct.h | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/Eigen/src/Core/InverseProduct.h b/Eigen/src/Core/InverseProduct.h index 87f426af5..cfab54228 100755 --- a/Eigen/src/Core/InverseProduct.h +++ b/Eigen/src/Core/InverseProduct.h @@ -25,8 +25,12 @@ #ifndef EIGEN_INVERSEPRODUCT_H #define EIGEN_INVERSEPRODUCT_H +template<typename XprType> struct ei_is_part { enum {value=false}; }; +template<typename XprType, unsigned int Mode> struct ei_is_part<Part<XprType,Mode> > { enum {value=true}; }; + template<typename Lhs, typename Rhs, - int TriangularPart = (int(Lhs::Flags) & LowerTriangularBit) + int TriangularPart = ei_is_part<Lhs>::value ? -1 // this is to solve ambiguous specializations + : (int(Lhs::Flags) & LowerTriangularBit) ? Lower : (int(Lhs::Flags) & UpperTriangularBit) ? Upper @@ -35,6 +39,16 @@ template<typename Lhs, typename Rhs, > struct ei_trisolve_selector; +// transform a Part xpr to a Flagged xpr +template<typename Lhs, unsigned int LhsMode, typename Rhs, int TriangularPart, int StorageOrder> +struct ei_trisolve_selector<Part<Lhs,LhsMode>,Rhs,TriangularPart,StorageOrder> +{ + static void run(const Part<Lhs,LhsMode>& lhs, Rhs& other) + { + ei_trisolve_selector<Flagged<Lhs,LhsMode,0>,Rhs>::run(lhs._expression(), other); + } +}; + // forward substitution, row-major template<typename Lhs, typename Rhs> struct ei_trisolve_selector<Lhs,Rhs,Lower,RowMajor> @@ -102,12 +116,12 @@ struct ei_trisolve_selector<Lhs,Rhs,Lower,ColMajor> int blockyEnd = (std::max(size-5,0)/4)*4; for(int i=0; i<blockyEnd;) { - int startBlock = i; - int endBlock = startBlock+4; - Matrix<Scalar,4,1> btmp; /* Let's process the 4x4 sub-matrix as usual. * btmp stores the diagonal coefficients used to update the remaining part of the result. */ + int startBlock = i; + int endBlock = startBlock+4; + Matrix<Scalar,4,1> btmp; for (;i<endBlock;++i) { if(!(Lhs::Flags & UnitDiagBit)) @@ -135,8 +149,10 @@ struct ei_trisolve_selector<Lhs,Rhs,Lower,ColMajor> { if(!(Lhs::Flags & UnitDiagBit)) other.coeffRef(i,c) /= lhs.coeff(i,i); - // NOTE we cannot use lhs.col(i).end(size-i-1) because Part::coeffRef gets called by .col() to - // get the address of the start of the row + + /* NOTE we cannot use lhs.col(i).end(size-i-1) because Part::coeffRef gets called by .col() to + * get the address of the start of the row + */ other.col(c).end(size-i-1) -= other.coeffRef(i,c) * Block<Lhs,Dynamic,1>(lhs, i+1,i, size-i-1,1); } if(!(Lhs::Flags & UnitDiagBit)) @@ -146,6 +162,7 @@ struct ei_trisolve_selector<Lhs,Rhs,Lower,ColMajor> }; // backward substitution, col-major +// see the previous specialization for details on the algorithm template<typename Lhs, typename Rhs> struct ei_trisolve_selector<Lhs,Rhs,Upper,ColMajor> { |