Medial Code Documentation
Loading...
Searching...
No Matches
TriangularMatrix.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
5// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
6//
7// This Source Code Form is subject to the terms of the Mozilla
8// Public License v. 2.0. If a copy of the MPL was not distributed
9// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10
11#ifndef EIGEN_TRIANGULARMATRIX_H
12#define EIGEN_TRIANGULARMATRIX_H
13
14namespace Eigen {
15
16namespace internal {
17
18template<int Side, typename TriangularType, typename Rhs> struct triangular_solve_retval;
19
20}
21
27template<typename Derived> class TriangularBase : public EigenBase<Derived>
28{
29 public:
30
31 enum {
37
46
47 };
48 typedef typename internal::traits<Derived>::Scalar Scalar;
49 typedef typename internal::traits<Derived>::StorageKind StorageKind;
50 typedef typename internal::traits<Derived>::StorageIndex StorageIndex;
51 typedef typename internal::traits<Derived>::FullMatrixType DenseMatrixType;
52 typedef DenseMatrixType DenseType;
53 typedef Derived const& Nested;
54
56 inline TriangularBase() { eigen_assert(!((Mode&UnitDiag) && (Mode&ZeroDiag))); }
57
59 inline Index rows() const { return derived().rows(); }
61 inline Index cols() const { return derived().cols(); }
63 inline Index outerStride() const { return derived().outerStride(); }
65 inline Index innerStride() const { return derived().innerStride(); }
66
67 // dummy resize function
68 void resize(Index rows, Index cols)
69 {
70 EIGEN_UNUSED_VARIABLE(rows);
71 EIGEN_UNUSED_VARIABLE(cols);
72 eigen_assert(rows==this->rows() && cols==this->cols());
73 }
74
76 inline Scalar coeff(Index row, Index col) const { return derived().coeff(row,col); }
78 inline Scalar& coeffRef(Index row, Index col) { return derived().coeffRef(row,col); }
79
82 template<typename Other>
84 EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, Other& other)
85 {
86 derived().coeffRef(row, col) = other.coeff(row, col);
87 }
88
90 inline Scalar operator()(Index row, Index col) const
91 {
92 check_coordinates(row, col);
93 return coeff(row,col);
94 }
95 EIGEN_DEVICE_FUNC
96 inline Scalar& operator()(Index row, Index col)
97 {
98 check_coordinates(row, col);
99 return coeffRef(row,col);
100 }
101
102 #ifndef EIGEN_PARSED_BY_DOXYGEN
103 EIGEN_DEVICE_FUNC
104 inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
105 EIGEN_DEVICE_FUNC
106 inline Derived& derived() { return *static_cast<Derived*>(this); }
107 #endif // not EIGEN_PARSED_BY_DOXYGEN
108
109 template<typename DenseDerived>
110 EIGEN_DEVICE_FUNC
111 void evalTo(MatrixBase<DenseDerived> &other) const;
112 template<typename DenseDerived>
113 EIGEN_DEVICE_FUNC
114 void evalToLazy(MatrixBase<DenseDerived> &other) const;
115
116 EIGEN_DEVICE_FUNC
117 DenseMatrixType toDenseMatrix() const
118 {
119 DenseMatrixType res(rows(), cols());
120 evalToLazy(res);
121 return res;
122 }
123
124 protected:
125
126 void check_coordinates(Index row, Index col) const
127 {
128 EIGEN_ONLY_USED_FOR_DEBUG(row);
129 EIGEN_ONLY_USED_FOR_DEBUG(col);
130 eigen_assert(col>=0 && col<cols() && row>=0 && row<rows());
131 const int mode = int(Mode) & ~SelfAdjoint;
132 EIGEN_ONLY_USED_FOR_DEBUG(mode);
133 eigen_assert((mode==Upper && col>=row)
134 || (mode==Lower && col<=row)
135 || ((mode==StrictlyUpper || mode==UnitUpper) && col>row)
136 || ((mode==StrictlyLower || mode==UnitLower) && col<row));
137 }
138
139 #ifdef EIGEN_INTERNAL_DEBUGGING
140 void check_coordinates_internal(Index row, Index col) const
141 {
142 check_coordinates(row, col);
143 }
144 #else
145 void check_coordinates_internal(Index , Index ) const {}
146 #endif
147
148};
149
167namespace internal {
168template<typename MatrixType, unsigned int _Mode>
169struct traits<TriangularView<MatrixType, _Mode> > : traits<MatrixType>
170{
172 typedef typename remove_reference<MatrixTypeNested>::type MatrixTypeNestedNonRef;
174 typedef typename MatrixType::PlainObject FullMatrixType;
175 typedef MatrixType ExpressionType;
176 enum {
177 Mode = _Mode,
178 FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
179 Flags = (MatrixTypeNestedCleaned::Flags & (HereditaryBits | FlagsLvalueBit) & (~(PacketAccessBit | DirectAccessBit | LinearAccessBit)))
180 };
181};
182}
183
184template<typename _MatrixType, unsigned int _Mode, typename StorageKind> class TriangularViewImpl;
185
186template<typename _MatrixType, unsigned int _Mode> class TriangularView
187 : public TriangularViewImpl<_MatrixType, _Mode, typename internal::traits<_MatrixType>::StorageKind >
188{
189 public:
190
192 typedef typename internal::traits<TriangularView>::Scalar Scalar;
193 typedef _MatrixType MatrixType;
194
195 protected:
196 typedef typename internal::traits<TriangularView>::MatrixTypeNested MatrixTypeNested;
197 typedef typename internal::traits<TriangularView>::MatrixTypeNestedNonRef MatrixTypeNestedNonRef;
198
200
201 public:
202
203 typedef typename internal::traits<TriangularView>::StorageKind StorageKind;
204 typedef typename internal::traits<TriangularView>::MatrixTypeNestedCleaned NestedExpression;
205
206 enum {
207 Mode = _Mode,
209 TransposeMode = (Mode & Upper ? Lower : 0)
210 | (Mode & Lower ? Upper : 0)
211 | (Mode & (UnitDiag))
212 | (Mode & (ZeroDiag)),
213 IsVectorAtCompileTime = false
214 };
215
216 // FIXME This, combined with const_cast_derived in transpose() leads to a const-correctness loophole
218 explicit inline TriangularView(MatrixType& matrix) : m_matrix(matrix)
219 {}
220
221 using Base::operator=;
222 TriangularView& operator=(const TriangularView &other)
223 { return Base::operator=(other); }
224
227 inline Index rows() const { return m_matrix.rows(); }
230 inline Index cols() const { return m_matrix.cols(); }
231
234 const NestedExpression& nestedExpression() const { return m_matrix; }
235
238 NestedExpression& nestedExpression() { return *const_cast<NestedExpression*>(&m_matrix); }
239
243 inline const ConjugateReturnType conjugate() const
244 { return ConjugateReturnType(m_matrix.conjugate()); }
245
249 inline const AdjointReturnType adjoint() const
250 { return AdjointReturnType(m_matrix.adjoint()); }
251
256 {
257 EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
258 typename MatrixType::TransposeReturnType tmp(m_matrix.const_cast_derived());
259 return TransposeReturnType(tmp);
260 }
261
266 {
267 return ConstTransposeReturnType(m_matrix.transpose());
268 }
269
270 template<typename Other>
272 inline const Solve<TriangularView, Other>
273 solve(const MatrixBase<Other>& other) const
274 { return Solve<TriangularView, Other>(*this, other.derived()); }
275
276 // workaround MSVC ICE
277 #if EIGEN_COMP_MSVC
278 template<int Side, typename Other>
279 EIGEN_DEVICE_FUNC
280 inline const internal::triangular_solve_retval<Side,TriangularView, Other>
281 solve(const MatrixBase<Other>& other) const
282 { return Base::template solve<Side>(other); }
283 #else
284 using Base::solve;
285 #endif
286
297
305
306
310 Scalar determinant() const
311 {
312 if (Mode & UnitDiag)
313 return 1;
314 else if (Mode & ZeroDiag)
315 return 0;
316 else
317 return m_matrix.diagonal().prod();
318 }
319
320 protected:
321
322 MatrixTypeNested m_matrix;
323};
324
334template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_MatrixType,_Mode,Dense>
335 : public TriangularBase<TriangularView<_MatrixType, _Mode> >
336{
337 public:
338
341 typedef typename internal::traits<TriangularViewType>::Scalar Scalar;
342
343 typedef _MatrixType MatrixType;
344 typedef typename MatrixType::PlainObject DenseMatrixType;
345 typedef DenseMatrixType PlainObject;
346
347 public:
348 using Base::evalToLazy;
349 using Base::derived;
350
351 typedef typename internal::traits<TriangularViewType>::StorageKind StorageKind;
352
353 enum {
354 Mode = _Mode,
356 };
357
361 inline Index outerStride() const { return derived().nestedExpression().outerStride(); }
365 inline Index innerStride() const { return derived().nestedExpression().innerStride(); }
366
368 template<typename Other>
371 internal::call_assignment_no_alias(derived(), other.derived(), internal::add_assign_op<Scalar>());
372 return derived();
373 }
375 template<typename Other>
378 internal::call_assignment_no_alias(derived(), other.derived(), internal::sub_assign_op<Scalar>());
379 return derived();
380 }
381
384 TriangularViewType& operator*=(const typename internal::traits<MatrixType>::Scalar& other) { return *this = derived().nestedExpression() * other; }
387 TriangularViewType& operator/=(const typename internal::traits<MatrixType>::Scalar& other) { return *this = derived().nestedExpression() / other; }
388
391 void fill(const Scalar& value) { setConstant(value); }
394 TriangularViewType& setConstant(const Scalar& value)
395 { return *this = MatrixType::Constant(derived().rows(), derived().cols(), value); }
398 TriangularViewType& setZero() { return setConstant(Scalar(0)); }
401 TriangularViewType& setOnes() { return setConstant(Scalar(1)); }
402
407 inline Scalar coeff(Index row, Index col) const
408 {
409 Base::check_coordinates_internal(row, col);
410 return derived().nestedExpression().coeff(row, col);
411 }
412
417 inline Scalar& coeffRef(Index row, Index col)
418 {
419 EIGEN_STATIC_ASSERT_LVALUE(TriangularViewType);
420 Base::check_coordinates_internal(row, col);
421 return derived().nestedExpression().const_cast_derived().coeffRef(row, col);
422 }
423
425 template<typename OtherDerived>
428
430 template<typename OtherDerived>
433
434#ifndef EIGEN_PARSED_BY_DOXYGEN
436 TriangularViewType& operator=(const TriangularViewImpl& other)
437 { return *this = other.derived().nestedExpression(); }
438
440 template<typename OtherDerived>
443
445 template<typename OtherDerived>
448#endif
449
451 template<typename OtherDerived>
455 {
456 return Product<TriangularViewType,OtherDerived>(derived(), rhs.derived());
457 }
458
460 template<typename OtherDerived> friend
464 {
465 return Product<OtherDerived,TriangularViewType>(lhs.derived(),rhs.derived());
466 }
467
489 template<int Side, typename Other>
492 solve(const MatrixBase<Other>& other) const;
493
501 template<int Side, typename OtherDerived>
503 void solveInPlace(const MatrixBase<OtherDerived>& other) const;
504
505 template<typename OtherDerived>
507 void solveInPlace(const MatrixBase<OtherDerived>& other) const
508 { return solveInPlace<OnTheLeft>(other); }
509
511 template<typename OtherDerived>
513#ifdef EIGEN_PARSED_BY_DOXYGEN
514 void swap(TriangularBase<OtherDerived> &other)
515#else
517#endif
518 {
519 EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
520 call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
521 }
522
525 template<typename OtherDerived>
527 void swap(MatrixBase<OtherDerived> const & other)
528 {
529 EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
530 call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
531 }
532
533 template<typename RhsType, typename DstType>
535 EIGEN_STRONG_INLINE void _solve_impl(const RhsType &rhs, DstType &dst) const {
536 if(!(internal::is_same<RhsType,DstType>::value && internal::extract_data(dst) == internal::extract_data(rhs)))
537 dst = rhs;
538 this->solveInPlace(dst);
539 }
540
541 template<typename ProductType>
542 EIGEN_DEVICE_FUNC
543 EIGEN_STRONG_INLINE TriangularViewType& _assignProduct(const ProductType& prod, const Scalar& alpha);
544};
545
546/***************************************************************************
547* Implementation of triangular evaluation/assignment
548***************************************************************************/
549
550// FIXME should we keep that possibility
551template<typename MatrixType, unsigned int Mode>
552template<typename OtherDerived>
553inline TriangularView<MatrixType, Mode>&
554TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const MatrixBase<OtherDerived>& other)
555{
556 internal::call_assignment_no_alias(derived(), other.derived(), internal::assign_op<Scalar>());
557 return derived();
558}
559
560// FIXME should we keep that possibility
561template<typename MatrixType, unsigned int Mode>
562template<typename OtherDerived>
563void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const MatrixBase<OtherDerived>& other)
564{
565 internal::call_assignment_no_alias(derived(), other.template triangularView<Mode>());
566}
567
568
569
570template<typename MatrixType, unsigned int Mode>
571template<typename OtherDerived>
572inline TriangularView<MatrixType, Mode>&
573TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const TriangularBase<OtherDerived>& other)
574{
575 eigen_assert(Mode == int(OtherDerived::Mode));
576 internal::call_assignment(derived(), other.derived());
577 return derived();
578}
579
580template<typename MatrixType, unsigned int Mode>
581template<typename OtherDerived>
582void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const TriangularBase<OtherDerived>& other)
583{
584 eigen_assert(Mode == int(OtherDerived::Mode));
585 internal::call_assignment_no_alias(derived(), other.derived());
586}
587
588/***************************************************************************
589* Implementation of TriangularBase methods
590***************************************************************************/
591
594template<typename Derived>
595template<typename DenseDerived>
597{
599 {
601 evalToLazy(other_evaluated);
602 other.derived().swap(other_evaluated);
603 }
604 else
605 evalToLazy(other.derived());
606}
607
608/***************************************************************************
609* Implementation of TriangularView methods
610***************************************************************************/
611
612/***************************************************************************
613* Implementation of MatrixBase methods
614***************************************************************************/
615
627template<typename Derived>
628template<unsigned int Mode>
629typename MatrixBase<Derived>::template TriangularViewReturnType<Mode>::Type
634
636template<typename Derived>
637template<unsigned int Mode>
638typename MatrixBase<Derived>::template ConstTriangularViewReturnType<Mode>::Type
643
649template<typename Derived>
650bool MatrixBase<Derived>::isUpperTriangular(const RealScalar& prec) const
651{
652 using std::abs;
653 RealScalar maxAbsOnUpperPart = static_cast<RealScalar>(-1);
654 for(Index j = 0; j < cols(); ++j)
655 {
656 Index maxi = (std::min)(j, rows()-1);
657 for(Index i = 0; i <= maxi; ++i)
658 {
659 RealScalar absValue = abs(coeff(i,j));
661 }
662 }
663 RealScalar threshold = maxAbsOnUpperPart * prec;
664 for(Index j = 0; j < cols(); ++j)
665 for(Index i = j+1; i < rows(); ++i)
666 if(abs(coeff(i, j)) > threshold) return false;
667 return true;
668}
669
675template<typename Derived>
676bool MatrixBase<Derived>::isLowerTriangular(const RealScalar& prec) const
677{
678 using std::abs;
679 RealScalar maxAbsOnLowerPart = static_cast<RealScalar>(-1);
680 for(Index j = 0; j < cols(); ++j)
681 for(Index i = j; i < rows(); ++i)
682 {
683 RealScalar absValue = abs(coeff(i,j));
685 }
686 RealScalar threshold = maxAbsOnLowerPart * prec;
687 for(Index j = 1; j < cols(); ++j)
688 {
689 Index maxi = (std::min)(j, rows()-1);
690 for(Index i = 0; i < maxi; ++i)
691 if(abs(coeff(i, j)) > threshold) return false;
692 }
693 return true;
694}
695
696
697/***************************************************************************
698****************************************************************************
699* Evaluators and Assignment of triangular expressions
700***************************************************************************
701***************************************************************************/
702
703namespace internal {
704
705
706// TODO currently a triangular expression has the form TriangularView<.,.>
707// in the future triangular-ness should be defined by the expression traits
708// such that Transpose<TriangularView<.,.> > is valid. (currently TriangularBase::transpose() is overloaded to make it work)
709template<typename MatrixType, unsigned int Mode>
710struct evaluator_traits<TriangularView<MatrixType,Mode> >
711{
714
715 // 1 if assignment A = B assumes aliasing when B is of type T and thus B needs to be evaluated into a
716 // temporary; 0 if not.
717 static const int AssumeAliasing = 0;
718};
719
720template<typename MatrixType, unsigned int Mode>
722 : evaluator<typename internal::remove_all<MatrixType>::type>
723{
726 unary_evaluator(const XprType &xpr) : Base(xpr.nestedExpression()) {}
727};
728
729// Additional assignment kinds:
733
734
735template<typename Kernel, unsigned int Mode, int UnrollCount, bool ClearOpposite> struct triangular_assignment_loop;
736
737
743template<int UpLo, int Mode, int SetOpposite, typename DstEvaluatorTypeT, typename SrcEvaluatorTypeT, typename Functor, int Version = Specialized>
744class triangular_dense_assignment_kernel : public generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version>
745{
746protected:
748 typedef typename Base::DstXprType DstXprType;
749 typedef typename Base::SrcXprType SrcXprType;
750 using Base::m_dst;
751 using Base::m_src;
752 using Base::m_functor;
753public:
754
755 typedef typename Base::DstEvaluatorType DstEvaluatorType;
756 typedef typename Base::SrcEvaluatorType SrcEvaluatorType;
757 typedef typename Base::Scalar Scalar;
759
760
761 EIGEN_DEVICE_FUNC triangular_dense_assignment_kernel(DstEvaluatorType &dst, const SrcEvaluatorType &src, const Functor &func, DstXprType& dstExpr)
762 : Base(dst, src, func, dstExpr)
763 {}
764
765#ifdef EIGEN_INTERNAL_DEBUGGING
766 EIGEN_DEVICE_FUNC void assignCoeff(Index row, Index col)
767 {
768 eigen_internal_assert(row!=col);
769 Base::assignCoeff(row,col);
770 }
771#else
772 using Base::assignCoeff;
773#endif
774
775 EIGEN_DEVICE_FUNC void assignDiagonalCoeff(Index id)
776 {
777 if(Mode==UnitDiag && SetOpposite) m_functor.assignCoeff(m_dst.coeffRef(id,id), Scalar(1));
778 else if(Mode==ZeroDiag && SetOpposite) m_functor.assignCoeff(m_dst.coeffRef(id,id), Scalar(0));
779 else if(Mode==0) Base::assignCoeff(id,id);
780 }
781
782 EIGEN_DEVICE_FUNC void assignOppositeCoeff(Index row, Index col)
783 {
784 eigen_internal_assert(row!=col);
785 if(SetOpposite)
786 m_functor.assignCoeff(m_dst.coeffRef(row,col), Scalar(0));
787 }
788};
789
790template<int Mode, bool SetOpposite, typename DstXprType, typename SrcXprType, typename Functor>
791EIGEN_DEVICE_FUNC void call_triangular_assignment_loop(const DstXprType& dst, const SrcXprType& src, const Functor &func)
792{
793 eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
794
795 typedef evaluator<DstXprType> DstEvaluatorType;
796 typedef evaluator<SrcXprType> SrcEvaluatorType;
797
798 DstEvaluatorType dstEvaluator(dst);
799 SrcEvaluatorType srcEvaluator(src);
800
802 DstEvaluatorType,SrcEvaluatorType,Functor> Kernel;
803 Kernel kernel(dstEvaluator, srcEvaluator, func, dst.const_cast_derived());
804
805 enum {
806 unroll = DstXprType::SizeAtCompileTime != Dynamic
807 && SrcEvaluatorType::CoeffReadCost < HugeCost
808 && DstXprType::SizeAtCompileTime * SrcEvaluatorType::CoeffReadCost / 2 <= EIGEN_UNROLLING_LIMIT
809 };
810
811 triangular_assignment_loop<Kernel, Mode, unroll ? int(DstXprType::SizeAtCompileTime) : Dynamic, SetOpposite>::run(kernel);
812}
813
814template<int Mode, bool SetOpposite, typename DstXprType, typename SrcXprType>
815EIGEN_DEVICE_FUNC void call_triangular_assignment_loop(const DstXprType& dst, const SrcXprType& src)
816{
817 call_triangular_assignment_loop<Mode,SetOpposite>(dst, src, internal::assign_op<typename DstXprType::Scalar>());
818}
819
823
824
825template< typename DstXprType, typename SrcXprType, typename Functor, typename Scalar>
826struct Assignment<DstXprType, SrcXprType, Functor, Triangular2Triangular, Scalar>
827{
828 EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
829 {
830 eigen_assert(int(DstXprType::Mode) == int(SrcXprType::Mode));
831
833 }
834};
835
836template< typename DstXprType, typename SrcXprType, typename Functor, typename Scalar>
837struct Assignment<DstXprType, SrcXprType, Functor, Triangular2Dense, Scalar>
838{
839 EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
840 {
842 }
843};
844
845template< typename DstXprType, typename SrcXprType, typename Functor, typename Scalar>
846struct Assignment<DstXprType, SrcXprType, Functor, Dense2Triangular, Scalar>
847{
848 EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
849 {
851 }
852};
853
854
855template<typename Kernel, unsigned int Mode, int UnrollCount, bool SetOpposite>
857{
858 // FIXME: this is not very clean, perhaps this information should be provided by the kernel?
859 typedef typename Kernel::DstEvaluatorType DstEvaluatorType;
860 typedef typename DstEvaluatorType::XprType DstXprType;
861
862 enum {
863 col = (UnrollCount-1) / DstXprType::RowsAtCompileTime,
864 row = (UnrollCount-1) % DstXprType::RowsAtCompileTime
865 };
866
867 typedef typename Kernel::Scalar Scalar;
868
870 static inline void run(Kernel &kernel)
871 {
873
874 if(row==col)
875 kernel.assignDiagonalCoeff(row);
876 else if( ((Mode&Lower) && row>col) || ((Mode&Upper) && row<col) )
877 kernel.assignCoeff(row,col);
878 else if(SetOpposite)
879 kernel.assignOppositeCoeff(row,col);
880 }
881};
882
883// prevent buggy user code from causing an infinite recursion
884template<typename Kernel, unsigned int Mode, bool SetOpposite>
886{
888 static inline void run(Kernel &) {}
889};
890
891
892
893// TODO: experiment with a recursive assignment procedure splitting the current
894// triangular part into one rectangular and two triangular parts.
895
896
897template<typename Kernel, unsigned int Mode, bool SetOpposite>
899{
900 typedef typename Kernel::Scalar Scalar;
902 static inline void run(Kernel &kernel)
903 {
904 for(Index j = 0; j < kernel.cols(); ++j)
905 {
906 Index maxi = (std::min)(j, kernel.rows());
907 Index i = 0;
908 if (((Mode&Lower) && SetOpposite) || (Mode&Upper))
909 {
910 for(; i < maxi; ++i)
911 if(Mode&Upper) kernel.assignCoeff(i, j);
912 else kernel.assignOppositeCoeff(i, j);
913 }
914 else
915 i = maxi;
916
917 if(i<kernel.rows()) // then i==j
918 kernel.assignDiagonalCoeff(i++);
919
920 if (((Mode&Upper) && SetOpposite) || (Mode&Lower))
921 {
922 for(; i < kernel.rows(); ++i)
923 if(Mode&Lower) kernel.assignCoeff(i, j);
924 else kernel.assignOppositeCoeff(i, j);
925 }
926 }
927 }
928};
929
930} // end namespace internal
931
934template<typename Derived>
935template<typename DenseDerived>
937{
938 other.derived().resize(this->rows(), this->cols());
939 internal::call_triangular_assignment_loop<Derived::Mode,(Derived::Mode&SelfAdjoint)==0 /* SetOpposite */>(other.derived(), derived().nestedExpression());
940}
941
942namespace internal {
943
944// Triangular = Product
945template< typename DstXprType, typename Lhs, typename Rhs, typename Scalar>
946struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::assign_op<Scalar>, Dense2Triangular, Scalar>
947{
949 static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar> &)
950 {
951 dst.setZero();
952 dst._assignProduct(src, 1);
953 }
954};
955
956// Triangular += Product
957template< typename DstXprType, typename Lhs, typename Rhs, typename Scalar>
958struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::add_assign_op<Scalar>, Dense2Triangular, Scalar>
959{
961 static void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<Scalar> &)
962 {
963 dst._assignProduct(src, 1);
964 }
965};
966
967// Triangular -= Product
968template< typename DstXprType, typename Lhs, typename Rhs, typename Scalar>
969struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::sub_assign_op<Scalar>, Dense2Triangular, Scalar>
970{
972 static void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<Scalar> &)
973 {
974 dst._assignProduct(src, -1);
975 }
976};
977
978} // end namespace internal
979
980} // end namespace Eigen
981
982#endif // EIGEN_TRIANGULARMATRIX_H
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:50
Expression of the product of two arbitrary matrices or vectors.
Definition Product.h:111
Pseudo expression representing a solving operation.
Definition Solve.h:63
Base class for triangular part in a matrix.
Definition TriangularMatrix.h:28
@ SizeAtCompileTime
This is equal to the number of coefficients, i.e.
Definition TriangularMatrix.h:38
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, Other &other)
Definition TriangularMatrix.h:84
EIGEN_DEVICE_FUNC TriangularViewType & setOnes()
Definition TriangularMatrix.h:401
EIGEN_DEVICE_FUNC void swap(TriangularBase< OtherDerived > const &other)
Swaps the coefficients of the common triangular parts of two matrices.
Definition TriangularMatrix.h:516
EIGEN_DEVICE_FUNC TriangularViewType & operator+=(const DenseBase< Other > &other)
Definition TriangularMatrix.h:370
EIGEN_DEVICE_FUNC const Product< TriangularViewType, OtherDerived > operator*(const MatrixBase< OtherDerived > &rhs) const
Efficient triangular matrix times vector/matrix product.
Definition TriangularMatrix.h:454
EIGEN_DEVICE_FUNC Scalar & coeffRef(Index row, Index col)
Definition TriangularMatrix.h:417
EIGEN_DEVICE_FUNC void swap(MatrixBase< OtherDerived > const &other)
Definition TriangularMatrix.h:527
EIGEN_DEVICE_FUNC const internal::triangular_solve_retval< Side, TriangularViewType, Other > solve(const MatrixBase< Other > &other) const
friend EIGEN_DEVICE_FUNC const Product< OtherDerived, TriangularViewType > operator*(const MatrixBase< OtherDerived > &lhs, const TriangularViewImpl &rhs)
Efficient vector/matrix times triangular matrix product.
Definition TriangularMatrix.h:463
EIGEN_DEVICE_FUNC TriangularViewType & operator/=(const typename internal::traits< MatrixType >::Scalar &other)
Definition TriangularMatrix.h:387
EIGEN_DEVICE_FUNC void lazyAssign(const TriangularBase< OtherDerived > &other)
EIGEN_DEVICE_FUNC void solveInPlace(const MatrixBase< OtherDerived > &other) const
"in-place" version of TriangularView::solve() where the result is written in other
EIGEN_DEVICE_FUNC Scalar coeff(Index row, Index col) const
Definition TriangularMatrix.h:407
EIGEN_DEVICE_FUNC TriangularViewType & operator=(const MatrixBase< OtherDerived > &other)
Shortcut for.
EIGEN_DEVICE_FUNC TriangularViewType & operator*=(const typename internal::traits< MatrixType >::Scalar &other)
Definition TriangularMatrix.h:384
EIGEN_DEVICE_FUNC TriangularViewType & setConstant(const Scalar &value)
Definition TriangularMatrix.h:394
EIGEN_DEVICE_FUNC TriangularViewType & setZero()
Definition TriangularMatrix.h:398
EIGEN_DEVICE_FUNC void fill(const Scalar &value)
Definition TriangularMatrix.h:391
EIGEN_DEVICE_FUNC Index outerStride() const
Definition TriangularMatrix.h:361
EIGEN_DEVICE_FUNC void lazyAssign(const MatrixBase< OtherDerived > &other)
EIGEN_DEVICE_FUNC TriangularViewType & operator=(const TriangularBase< OtherDerived > &other)
Assigns a triangular matrix to a triangular part of a dense matrix.
EIGEN_DEVICE_FUNC TriangularViewType & operator-=(const DenseBase< Other > &other)
Definition TriangularMatrix.h:377
EIGEN_DEVICE_FUNC Index innerStride() const
Definition TriangularMatrix.h:365
Definition TriangularMatrix.h:184
Expression of a triangular part in a matrix.
Definition TriangularMatrix.h:188
EIGEN_DEVICE_FUNC const ConstTransposeReturnType transpose() const
Definition TriangularMatrix.h:265
EIGEN_DEVICE_FUNC const NestedExpression & nestedExpression() const
Definition TriangularMatrix.h:234
EIGEN_DEVICE_FUNC Index rows() const
Definition TriangularMatrix.h:227
EIGEN_DEVICE_FUNC Scalar determinant() const
Definition TriangularMatrix.h:310
EIGEN_DEVICE_FUNC TransposeReturnType transpose()
Definition TriangularMatrix.h:255
EIGEN_DEVICE_FUNC SelfAdjointView< MatrixTypeNestedNonRef, Mode > selfadjointView()
Definition TriangularMatrix.h:292
EIGEN_DEVICE_FUNC const SelfAdjointView< MatrixTypeNestedNonRef, Mode > selfadjointView() const
This is the const version of selfadjointView()
Definition TriangularMatrix.h:300
EIGEN_DEVICE_FUNC NestedExpression & nestedExpression()
Definition TriangularMatrix.h:238
EIGEN_DEVICE_FUNC const AdjointReturnType adjoint() const
Definition TriangularMatrix.h:249
EIGEN_DEVICE_FUNC Index cols() const
Definition TriangularMatrix.h:230
EIGEN_DEVICE_FUNC const ConjugateReturnType conjugate() const
Definition TriangularMatrix.h:243
Definition AssignEvaluator.h:539
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Index row, Index col)
Assign src(row,col) to dst(row,col) through the assignment functor.
Definition AssignEvaluator.h:571
Definition svm.cpp:205
@ StrictlyLower
View matrix as a lower triangular matrix with zeros on the diagonal.
Definition Constants.h:216
@ UnitDiag
Matrix has ones on the diagonal; to be used in combination with #Lower or #Upper.
Definition Constants.h:208
@ StrictlyUpper
View matrix as an upper triangular matrix with zeros on the diagonal.
Definition Constants.h:218
@ UnitLower
View matrix as a lower triangular matrix with ones on the diagonal.
Definition Constants.h:212
@ ZeroDiag
Matrix has zeros on the diagonal; to be used in combination with #Lower or #Upper.
Definition Constants.h:210
@ SelfAdjoint
Used in BandMatrix and SelfAdjointView to indicate that the matrix is self-adjoint.
Definition Constants.h:220
@ UnitUpper
View matrix as an upper triangular matrix with ones on the diagonal.
Definition Constants.h:214
@ Lower
View matrix as a lower triangular matrix.
Definition Constants.h:204
@ Upper
View matrix as an upper triangular matrix.
Definition Constants.h:206
const unsigned int PacketAccessBit
Short version: means the expression might be vectorized.
Definition Constants.h:88
const unsigned int LinearAccessBit
Short version: means the expression can be seen as 1D vector.
Definition Constants.h:124
const unsigned int EvalBeforeAssigningBit
Definition Constants.h:70
const unsigned int DirectAccessBit
Means that the underlying array of coefficients can be directly accessed as a plain strided array.
Definition Constants.h:149
const unsigned int LvalueBit
Means the expression has a coeffRef() method, i.e.
Definition Constants.h:138
Definition Constants.h:511
The type used to identify a dense storage.
Definition Constants.h:490
Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor Matrix...
Definition EigenBase.h:29
Eigen::Index Index
The interface type of indices.
Definition EigenBase.h:37
Definition Constants.h:516
Definition AssignEvaluator.h:677
Definition AssignEvaluator.h:684
Definition TriangularMatrix.h:732
Definition Constants.h:525
Definition TriangularMatrix.h:731
Definition TriangularMatrix.h:730
Definition AssignmentFunctors.h:42
Definition AssignmentFunctors.h:21
Definition CoreEvaluators.h:75
Definition CoreEvaluators.h:82
Definition XprHelper.h:628
Definition Meta.h:39
Definition XprHelper.h:235
Definition XprHelper.h:222
Definition AssignmentFunctors.h:63
Definition AssignmentFunctors.h:140
Definition ForwardDeclarations.h:17
Definition TriangularMatrix.h:857
Definition SolveTriangular.h:203
Definition Meta.h:30
Definition CoreEvaluators.h:56