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
55 EIGEN_DEVICE_FUNC
56 inline TriangularBase() { eigen_assert(!((int(Mode) & int(UnitDiag)) && (int(Mode) & int(ZeroDiag)))); }
57
58 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
59 inline Index rows() const EIGEN_NOEXCEPT { return derived().rows(); }
60 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
61 inline Index cols() const EIGEN_NOEXCEPT { return derived().cols(); }
62 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
63 inline Index outerStride() const EIGEN_NOEXCEPT { return derived().outerStride(); }
64 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
65 inline Index innerStride() const EIGEN_NOEXCEPT { return derived().innerStride(); }
66
67 // dummy resize function
68 EIGEN_DEVICE_FUNC
69 void resize(Index rows, Index cols)
70 {
71 EIGEN_UNUSED_VARIABLE(rows);
72 EIGEN_UNUSED_VARIABLE(cols);
73 eigen_assert(rows==this->rows() && cols==this->cols());
74 }
75
76 EIGEN_DEVICE_FUNC
77 inline Scalar coeff(Index row, Index col) const { return derived().coeff(row,col); }
78 EIGEN_DEVICE_FUNC
79 inline Scalar& coeffRef(Index row, Index col) { return derived().coeffRef(row,col); }
80
83 template<typename Other>
84 EIGEN_DEVICE_FUNC
85 EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, Other& other)
86 {
87 derived().coeffRef(row, col) = other.coeff(row, col);
88 }
89
90 EIGEN_DEVICE_FUNC
91 inline Scalar operator()(Index row, Index col) const
92 {
93 check_coordinates(row, col);
94 return coeff(row,col);
95 }
96 EIGEN_DEVICE_FUNC
97 inline Scalar& operator()(Index row, Index col)
98 {
99 check_coordinates(row, col);
100 return coeffRef(row,col);
101 }
102
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
108 template<typename DenseDerived>
109 EIGEN_DEVICE_FUNC
111 template<typename DenseDerived>
112 EIGEN_DEVICE_FUNC
114
115 EIGEN_DEVICE_FUNC
116 DenseMatrixType toDenseMatrix() const
117 {
118 DenseMatrixType res(rows(), cols());
119 evalToLazy(res);
120 return res;
121 }
122
123 protected:
124
125 void check_coordinates(Index row, Index col) const
126 {
127 EIGEN_ONLY_USED_FOR_DEBUG(row);
128 EIGEN_ONLY_USED_FOR_DEBUG(col);
129 eigen_assert(col>=0 && col<cols() && row>=0 && row<rows());
130 const int mode = int(Mode) & ~SelfAdjoint;
131 EIGEN_ONLY_USED_FOR_DEBUG(mode);
132 eigen_assert((mode==Upper && col>=row)
133 || (mode==Lower && col<=row)
134 || ((mode==StrictlyUpper || mode==UnitUpper) && col>row)
135 || ((mode==StrictlyLower || mode==UnitLower) && col<row));
136 }
137
138 #ifdef EIGEN_INTERNAL_DEBUGGING
139 void check_coordinates_internal(Index row, Index col) const
140 {
141 check_coordinates(row, col);
142 }
143 #else
144 void check_coordinates_internal(Index , Index ) const {}
145 #endif
146
147};
148
166namespace internal {
167template<typename MatrixType, unsigned int _Mode>
168struct traits<TriangularView<MatrixType, _Mode> > : traits<MatrixType>
169{
171 typedef typename remove_reference<MatrixTypeNested>::type MatrixTypeNestedNonRef;
172 typedef typename remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned;
173 typedef typename MatrixType::PlainObject FullMatrixType;
174 typedef MatrixType ExpressionType;
175 enum {
176 Mode = _Mode,
177 FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
178 Flags = (MatrixTypeNestedCleaned::Flags & (HereditaryBits | FlagsLvalueBit) & (~(PacketAccessBit | DirectAccessBit | LinearAccessBit)))
179 };
180};
181}
182
183template<typename _MatrixType, unsigned int _Mode, typename StorageKind> class TriangularViewImpl;
184
185template<typename _MatrixType, unsigned int _Mode> class TriangularView
186 : public TriangularViewImpl<_MatrixType, _Mode, typename internal::traits<_MatrixType>::StorageKind >
187{
188 public:
189
191 typedef typename internal::traits<TriangularView>::Scalar Scalar;
192 typedef _MatrixType MatrixType;
193
194 protected:
195 typedef typename internal::traits<TriangularView>::MatrixTypeNested MatrixTypeNested;
196 typedef typename internal::traits<TriangularView>::MatrixTypeNestedNonRef MatrixTypeNestedNonRef;
197
198 typedef typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type MatrixConjugateReturnType;
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 EIGEN_DEVICE_FUNC
217 explicit inline TriangularView(MatrixType& matrix) : m_matrix(matrix)
218 {}
219
220 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TriangularView)
221
222
223 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
224 inline Index rows() const EIGEN_NOEXCEPT { return m_matrix.rows(); }
226 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
227 inline Index cols() const EIGEN_NOEXCEPT { return m_matrix.cols(); }
228
230 EIGEN_DEVICE_FUNC
231 const NestedExpression& nestedExpression() const { return m_matrix; }
232
234 EIGEN_DEVICE_FUNC
235 NestedExpression& nestedExpression() { return m_matrix; }
236
239 EIGEN_DEVICE_FUNC
240 inline const ConjugateReturnType conjugate() const
241 { return ConjugateReturnType(m_matrix.conjugate()); }
242
246 template<bool Cond>
247 EIGEN_DEVICE_FUNC
250 {
252 return ReturnType(m_matrix.template conjugateIf<Cond>());
253 }
254
257 EIGEN_DEVICE_FUNC
258 inline const AdjointReturnType adjoint() const
259 { return AdjointReturnType(m_matrix.adjoint()); }
260
263 EIGEN_DEVICE_FUNC
265 {
266 EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
267 typename MatrixType::TransposeReturnType tmp(m_matrix);
268 return TransposeReturnType(tmp);
269 }
270
273 EIGEN_DEVICE_FUNC
275 {
276 return ConstTransposeReturnType(m_matrix.transpose());
277 }
278
279 template<typename Other>
280 EIGEN_DEVICE_FUNC
282 solve(const MatrixBase<Other>& other) const
283 { return Solve<TriangularView, Other>(*this, other.derived()); }
284
285 // workaround MSVC ICE
286 #if EIGEN_COMP_MSVC
287 template<int Side, typename Other>
288 EIGEN_DEVICE_FUNC
289 inline const internal::triangular_solve_retval<Side,TriangularView, Other>
290 solve(const MatrixBase<Other>& other) const
291 { return Base::template solve<Side>(other); }
292 #else
293 using Base::solve;
294 #endif
295
300 EIGEN_DEVICE_FUNC
306
308 EIGEN_DEVICE_FUNC
314
315
318 EIGEN_DEVICE_FUNC
319 Scalar determinant() const
320 {
321 if (Mode & UnitDiag)
322 return 1;
323 else if (Mode & ZeroDiag)
324 return 0;
325 else
326 return m_matrix.diagonal().prod();
327 }
328
329 protected:
330
331 MatrixTypeNested m_matrix;
332};
333
343template<typename _MatrixType, unsigned int _Mode> class TriangularViewImpl<_MatrixType,_Mode,Dense>
344 : public TriangularBase<TriangularView<_MatrixType, _Mode> >
345{
346 public:
347
350 typedef typename internal::traits<TriangularViewType>::Scalar Scalar;
351
352 typedef _MatrixType MatrixType;
353 typedef typename MatrixType::PlainObject DenseMatrixType;
354 typedef DenseMatrixType PlainObject;
355
356 public:
357 using Base::evalToLazy;
358 using Base::derived;
359
360 typedef typename internal::traits<TriangularViewType>::StorageKind StorageKind;
361
362 enum {
363 Mode = _Mode,
365 };
366
369 EIGEN_DEVICE_FUNC
370 inline Index outerStride() const { return derived().nestedExpression().outerStride(); }
373 EIGEN_DEVICE_FUNC
374 inline Index innerStride() const { return derived().nestedExpression().innerStride(); }
375
377 template<typename Other>
378 EIGEN_DEVICE_FUNC
380 internal::call_assignment_no_alias(derived(), other.derived(), internal::add_assign_op<Scalar,typename Other::Scalar>());
381 return derived();
382 }
384 template<typename Other>
385 EIGEN_DEVICE_FUNC
387 internal::call_assignment_no_alias(derived(), other.derived(), internal::sub_assign_op<Scalar,typename Other::Scalar>());
388 return derived();
389 }
390
392 EIGEN_DEVICE_FUNC
393 TriangularViewType& operator*=(const typename internal::traits<MatrixType>::Scalar& other) { return *this = derived().nestedExpression() * other; }
395 EIGEN_DEVICE_FUNC
396 TriangularViewType& operator/=(const typename internal::traits<MatrixType>::Scalar& other) { return *this = derived().nestedExpression() / other; }
397
399 EIGEN_DEVICE_FUNC
400 void fill(const Scalar& value) { setConstant(value); }
402 EIGEN_DEVICE_FUNC
403 TriangularViewType& setConstant(const Scalar& value)
404 { return *this = MatrixType::Constant(derived().rows(), derived().cols(), value); }
406 EIGEN_DEVICE_FUNC
407 TriangularViewType& setZero() { return setConstant(Scalar(0)); }
409 EIGEN_DEVICE_FUNC
410 TriangularViewType& setOnes() { return setConstant(Scalar(1)); }
411
415 EIGEN_DEVICE_FUNC
416 inline Scalar coeff(Index row, Index col) const
417 {
418 Base::check_coordinates_internal(row, col);
419 return derived().nestedExpression().coeff(row, col);
420 }
421
425 EIGEN_DEVICE_FUNC
426 inline Scalar& coeffRef(Index row, Index col)
427 {
428 EIGEN_STATIC_ASSERT_LVALUE(TriangularViewType);
429 Base::check_coordinates_internal(row, col);
430 return derived().nestedExpression().coeffRef(row, col);
431 }
432
434 template<typename OtherDerived>
435 EIGEN_DEVICE_FUNC
437
439 template<typename OtherDerived>
440 EIGEN_DEVICE_FUNC
442
443 EIGEN_DEVICE_FUNC
444 TriangularViewType& operator=(const TriangularViewImpl& other)
445 { return *this = other.derived().nestedExpression(); }
446
447 template<typename OtherDerived>
449 EIGEN_DEPRECATED EIGEN_DEVICE_FUNC
451
452 template<typename OtherDerived>
454 EIGEN_DEPRECATED EIGEN_DEVICE_FUNC
456
458 template<typename OtherDerived>
459 EIGEN_DEVICE_FUNC
462 {
463 return Product<TriangularViewType,OtherDerived>(derived(), rhs.derived());
464 }
465
467 template<typename OtherDerived> friend
468 EIGEN_DEVICE_FUNC
471 {
472 return Product<OtherDerived,TriangularViewType>(lhs.derived(),rhs.derived());
473 }
474
498 template<int Side, typename Other>
500 solve(const MatrixBase<Other>& other) const;
501
511 template<int Side, typename OtherDerived>
512 EIGEN_DEVICE_FUNC
513 void solveInPlace(const MatrixBase<OtherDerived>& other) const;
514
515 template<typename OtherDerived>
516 EIGEN_DEVICE_FUNC
517 void solveInPlace(const MatrixBase<OtherDerived>& other) const
518 { return solveInPlace<OnTheLeft>(other); }
519
521 template<typename OtherDerived>
522 EIGEN_DEVICE_FUNC
524 {
525 EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
526 call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
527 }
528
530 template<typename OtherDerived>
532 EIGEN_DEPRECATED EIGEN_DEVICE_FUNC
533 void swap(MatrixBase<OtherDerived> const & other)
534 {
535 EIGEN_STATIC_ASSERT_LVALUE(OtherDerived);
536 call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
537 }
538
539 template<typename RhsType, typename DstType>
540 EIGEN_DEVICE_FUNC
541 EIGEN_STRONG_INLINE void _solve_impl(const RhsType &rhs, DstType &dst) const {
542 if(!internal::is_same_dense(dst,rhs))
543 dst = rhs;
544 this->solveInPlace(dst);
545 }
546
547 template <typename ProductType>
548 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE TriangularViewType& _assignProduct(const ProductType& prod, const Scalar& alpha,
549 bool beta);
550
551 protected:
552 EIGEN_DEFAULT_COPY_CONSTRUCTOR(TriangularViewImpl)
553 EIGEN_DEFAULT_EMPTY_CONSTRUCTOR_AND_DESTRUCTOR(TriangularViewImpl)
554
555};
556
557/***************************************************************************
558* Implementation of triangular evaluation/assignment
559***************************************************************************/
560
561#ifndef EIGEN_PARSED_BY_DOXYGEN
562// FIXME should we keep that possibility
563template<typename MatrixType, unsigned int Mode>
564template<typename OtherDerived>
565EIGEN_DEVICE_FUNC inline TriangularView<MatrixType, Mode>&
566TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const MatrixBase<OtherDerived>& other)
567{
568 internal::call_assignment_no_alias(derived(), other.derived(), internal::assign_op<Scalar,typename OtherDerived::Scalar>());
569 return derived();
570}
571
572// FIXME should we keep that possibility
573template<typename MatrixType, unsigned int Mode>
574template<typename OtherDerived>
575EIGEN_DEVICE_FUNC void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const MatrixBase<OtherDerived>& other)
576{
577 internal::call_assignment_no_alias(derived(), other.template triangularView<Mode>());
578}
579
580
581
582template<typename MatrixType, unsigned int Mode>
583template<typename OtherDerived>
584EIGEN_DEVICE_FUNC inline TriangularView<MatrixType, Mode>&
585TriangularViewImpl<MatrixType, Mode, Dense>::operator=(const TriangularBase<OtherDerived>& other)
586{
587 eigen_assert(Mode == int(OtherDerived::Mode));
588 internal::call_assignment(derived(), other.derived());
589 return derived();
590}
591
592template<typename MatrixType, unsigned int Mode>
593template<typename OtherDerived>
594EIGEN_DEVICE_FUNC void TriangularViewImpl<MatrixType, Mode, Dense>::lazyAssign(const TriangularBase<OtherDerived>& other)
595{
596 eigen_assert(Mode == int(OtherDerived::Mode));
597 internal::call_assignment_no_alias(derived(), other.derived());
598}
599#endif
600
601/***************************************************************************
602* Implementation of TriangularBase methods
603***************************************************************************/
604
607template<typename Derived>
608template<typename DenseDerived>
610{
611 evalToLazy(other.derived());
612}
613
614/***************************************************************************
615* Implementation of TriangularView methods
616***************************************************************************/
617
618/***************************************************************************
619* Implementation of MatrixBase methods
620***************************************************************************/
621
633template<typename Derived>
634template<unsigned int Mode>
635EIGEN_DEVICE_FUNC
636typename MatrixBase<Derived>::template TriangularViewReturnType<Mode>::Type
641
643template<typename Derived>
644template<unsigned int Mode>
645EIGEN_DEVICE_FUNC
646typename MatrixBase<Derived>::template ConstTriangularViewReturnType<Mode>::Type
651
657template<typename Derived>
658bool MatrixBase<Derived>::isUpperTriangular(const RealScalar& prec) const
659{
660 RealScalar maxAbsOnUpperPart = static_cast<RealScalar>(-1);
661 for(Index j = 0; j < cols(); ++j)
662 {
663 Index maxi = numext::mini(j, rows()-1);
664 for(Index i = 0; i <= maxi; ++i)
665 {
666 RealScalar absValue = numext::abs(coeff(i,j));
668 }
669 }
670 RealScalar threshold = maxAbsOnUpperPart * prec;
671 for(Index j = 0; j < cols(); ++j)
672 for(Index i = j+1; i < rows(); ++i)
673 if(numext::abs(coeff(i, j)) > threshold) return false;
674 return true;
675}
676
682template<typename Derived>
683bool MatrixBase<Derived>::isLowerTriangular(const RealScalar& prec) const
684{
685 RealScalar maxAbsOnLowerPart = static_cast<RealScalar>(-1);
686 for(Index j = 0; j < cols(); ++j)
687 for(Index i = j; i < rows(); ++i)
688 {
689 RealScalar absValue = numext::abs(coeff(i,j));
691 }
692 RealScalar threshold = maxAbsOnLowerPart * prec;
693 for(Index j = 1; j < cols(); ++j)
694 {
695 Index maxi = numext::mini(j, rows()-1);
696 for(Index i = 0; i < maxi; ++i)
697 if(numext::abs(coeff(i, j)) > threshold) return false;
698 }
699 return true;
700}
701
702
703/***************************************************************************
704****************************************************************************
705* Evaluators and Assignment of triangular expressions
706***************************************************************************
707***************************************************************************/
708
709namespace internal {
710
711
712// TODO currently a triangular expression has the form TriangularView<.,.>
713// in the future triangular-ness should be defined by the expression traits
714// such that Transpose<TriangularView<.,.> > is valid. (currently TriangularBase::transpose() is overloaded to make it work)
715template<typename MatrixType, unsigned int Mode>
721
722template<typename MatrixType, unsigned int Mode>
724 : evaluator<typename internal::remove_all<MatrixType>::type>
725{
728 EIGEN_DEVICE_FUNC
729 unary_evaluator(const XprType &xpr) : Base(xpr.nestedExpression()) {}
730};
731
732// Additional assignment kinds:
736
737
738template<typename Kernel, unsigned int Mode, int UnrollCount, bool ClearOpposite> struct triangular_assignment_loop;
739
740
746template<int UpLo, int Mode, int SetOpposite, typename DstEvaluatorTypeT, typename SrcEvaluatorTypeT, typename Functor, int Version = Specialized>
747class triangular_dense_assignment_kernel : public generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version>
748{
749protected:
751 typedef typename Base::DstXprType DstXprType;
752 typedef typename Base::SrcXprType SrcXprType;
753 using Base::m_dst;
754 using Base::m_src;
755 using Base::m_functor;
756public:
757
758 typedef typename Base::DstEvaluatorType DstEvaluatorType;
759 typedef typename Base::SrcEvaluatorType SrcEvaluatorType;
760 typedef typename Base::Scalar Scalar;
762
763
764 EIGEN_DEVICE_FUNC triangular_dense_assignment_kernel(DstEvaluatorType &dst, const SrcEvaluatorType &src, const Functor &func, DstXprType& dstExpr)
765 : Base(dst, src, func, dstExpr)
766 {}
767
768#ifdef EIGEN_INTERNAL_DEBUGGING
769 EIGEN_DEVICE_FUNC void assignCoeff(Index row, Index col)
770 {
771 eigen_internal_assert(row!=col);
772 Base::assignCoeff(row,col);
773 }
774#else
775 using Base::assignCoeff;
776#endif
777
778 EIGEN_DEVICE_FUNC void assignDiagonalCoeff(Index id)
779 {
780 if(Mode==UnitDiag && SetOpposite) m_functor.assignCoeff(m_dst.coeffRef(id,id), Scalar(1));
781 else if(Mode==ZeroDiag && SetOpposite) m_functor.assignCoeff(m_dst.coeffRef(id,id), Scalar(0));
782 else if(Mode==0) Base::assignCoeff(id,id);
783 }
784
785 EIGEN_DEVICE_FUNC void assignOppositeCoeff(Index row, Index col)
786 {
787 eigen_internal_assert(row!=col);
788 if(SetOpposite)
789 m_functor.assignCoeff(m_dst.coeffRef(row,col), Scalar(0));
790 }
791};
792
793template<int Mode, bool SetOpposite, typename DstXprType, typename SrcXprType, typename Functor>
794EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
795void call_triangular_assignment_loop(DstXprType& dst, const SrcXprType& src, const Functor &func)
796{
797 typedef evaluator<DstXprType> DstEvaluatorType;
798 typedef evaluator<SrcXprType> SrcEvaluatorType;
799
800 SrcEvaluatorType srcEvaluator(src);
801
802 Index dstRows = src.rows();
803 Index dstCols = src.cols();
804 if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
806 DstEvaluatorType dstEvaluator(dst);
807
809 DstEvaluatorType,SrcEvaluatorType,Functor> Kernel;
810 Kernel kernel(dstEvaluator, srcEvaluator, func, dst.const_cast_derived());
811
812 enum {
813 unroll = DstXprType::SizeAtCompileTime != Dynamic
814 && SrcEvaluatorType::CoeffReadCost < HugeCost
815 && DstXprType::SizeAtCompileTime * (int(DstEvaluatorType::CoeffReadCost) + int(SrcEvaluatorType::CoeffReadCost)) / 2 <= EIGEN_UNROLLING_LIMIT
816 };
817
818 triangular_assignment_loop<Kernel, Mode, unroll ? int(DstXprType::SizeAtCompileTime) : Dynamic, SetOpposite>::run(kernel);
819}
820
821template<int Mode, bool SetOpposite, typename DstXprType, typename SrcXprType>
822EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
823void call_triangular_assignment_loop(DstXprType& dst, const SrcXprType& src)
824{
825 call_triangular_assignment_loop<Mode,SetOpposite>(dst, src, internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar>());
826}
827
831
832
833template< typename DstXprType, typename SrcXprType, typename Functor>
834struct Assignment<DstXprType, SrcXprType, Functor, Triangular2Triangular>
835{
836 EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
837 {
838 eigen_assert(int(DstXprType::Mode) == int(SrcXprType::Mode));
839
841 }
842};
843
844template< typename DstXprType, typename SrcXprType, typename Functor>
845struct Assignment<DstXprType, SrcXprType, Functor, Triangular2Dense>
846{
847 EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
848 {
850 }
851};
852
853template< typename DstXprType, typename SrcXprType, typename Functor>
854struct Assignment<DstXprType, SrcXprType, Functor, Dense2Triangular>
855{
856 EIGEN_DEVICE_FUNC static void run(DstXprType &dst, const SrcXprType &src, const Functor &func)
857 {
859 }
860};
861
862
863template<typename Kernel, unsigned int Mode, int UnrollCount, bool SetOpposite>
865{
866 // FIXME: this is not very clean, perhaps this information should be provided by the kernel?
867 typedef typename Kernel::DstEvaluatorType DstEvaluatorType;
868 typedef typename DstEvaluatorType::XprType DstXprType;
869
870 enum {
871 col = (UnrollCount-1) / DstXprType::RowsAtCompileTime,
872 row = (UnrollCount-1) % DstXprType::RowsAtCompileTime
873 };
874
875 typedef typename Kernel::Scalar Scalar;
876
877 EIGEN_DEVICE_FUNC
878 static inline void run(Kernel &kernel)
879 {
881
882 if(row==col)
883 kernel.assignDiagonalCoeff(row);
884 else if( ((Mode&Lower) && row>col) || ((Mode&Upper) && row<col) )
885 kernel.assignCoeff(row,col);
886 else if(SetOpposite)
887 kernel.assignOppositeCoeff(row,col);
888 }
889};
890
891// prevent buggy user code from causing an infinite recursion
892template<typename Kernel, unsigned int Mode, bool SetOpposite>
894{
895 EIGEN_DEVICE_FUNC
896 static inline void run(Kernel &) {}
897};
898
899
900
901// TODO: experiment with a recursive assignment procedure splitting the current
902// triangular part into one rectangular and two triangular parts.
903
904
905template<typename Kernel, unsigned int Mode, bool SetOpposite>
907{
908 typedef typename Kernel::Scalar Scalar;
909 EIGEN_DEVICE_FUNC
910 static inline void run(Kernel &kernel)
911 {
912 for(Index j = 0; j < kernel.cols(); ++j)
913 {
914 Index maxi = numext::mini(j, kernel.rows());
915 Index i = 0;
916 if (((Mode&Lower) && SetOpposite) || (Mode&Upper))
917 {
918 for(; i < maxi; ++i)
919 if(Mode&Upper) kernel.assignCoeff(i, j);
920 else kernel.assignOppositeCoeff(i, j);
921 }
922 else
923 i = maxi;
924
925 if(i<kernel.rows()) // then i==j
926 kernel.assignDiagonalCoeff(i++);
927
928 if (((Mode&Upper) && SetOpposite) || (Mode&Lower))
929 {
930 for(; i < kernel.rows(); ++i)
931 if(Mode&Lower) kernel.assignCoeff(i, j);
932 else kernel.assignOppositeCoeff(i, j);
933 }
934 }
935 }
936};
937
938} // end namespace internal
939
942template<typename Derived>
943template<typename DenseDerived>
945{
946 other.derived().resize(this->rows(), this->cols());
947 internal::call_triangular_assignment_loop<Derived::Mode, (int(Derived::Mode) & int(SelfAdjoint)) == 0 /* SetOpposite */>(other.derived(), derived().nestedExpression());
948}
949
950namespace internal {
951
952// Triangular = Product
953template< typename DstXprType, typename Lhs, typename Rhs, typename Scalar>
954struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
955{
957 static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,typename SrcXprType::Scalar> &)
958 {
959 Index dstRows = src.rows();
960 Index dstCols = src.cols();
961 if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
963
964 dst._assignProduct(src, Scalar(1), false);
965 }
966};
967
968// Triangular += Product
969template< typename DstXprType, typename Lhs, typename Rhs, typename Scalar>
970struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::add_assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
971{
973 static void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<Scalar,typename SrcXprType::Scalar> &)
974 {
975 dst._assignProduct(src, Scalar(1), true);
976 }
977};
978
979// Triangular -= Product
980template< typename DstXprType, typename Lhs, typename Rhs, typename Scalar>
981struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::sub_assign_op<Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, Dense2Triangular>
982{
984 static void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<Scalar,typename SrcXprType::Scalar> &)
985 {
986 dst._assignProduct(src, Scalar(-1), true);
987 }
988};
989
990} // end namespace internal
991
992} // end namespace Eigen
993
994#endif // EIGEN_TRIANGULARMATRIX_H
EIGEN_DEVICE_FUNC void resize(Index newSize)
Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods...
Definition DenseBase.h:246
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:75
Base class for triangular part in a matrix.
Definition TriangularMatrix.h:28
EIGEN_DEVICE_FUNC void evalTo(MatrixBase< DenseDerived > &other) const
Assigns a triangular or selfadjoint matrix to a dense matrix.
Definition TriangularMatrix.h:609
@ SizeAtCompileTime
This is equal to the number of coefficients, i.e.
Definition TriangularMatrix.h:38
EIGEN_DEVICE_FUNC void evalToLazy(MatrixBase< DenseDerived > &other) const
Assigns a triangular or selfadjoint matrix to a dense matrix.
Definition TriangularMatrix.h:944
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, Other &other)
Definition TriangularMatrix.h:85
EIGEN_DEVICE_FUNC TriangularViewType & setOnes()
Definition TriangularMatrix.h:410
EIGEN_DEVICE_FUNC void swap(TriangularBase< OtherDerived > const &other)
Swaps the coefficients of the common triangular parts of two matrices.
Definition TriangularMatrix.h:523
EIGEN_DEVICE_FUNC TriangularViewType & operator+=(const DenseBase< Other > &other)
Definition TriangularMatrix.h:379
EIGEN_DEVICE_FUNC const Product< TriangularViewType, OtherDerived > operator*(const MatrixBase< OtherDerived > &rhs) const
Efficient triangular matrix times vector/matrix product.
Definition TriangularMatrix.h:461
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC void swap(MatrixBase< OtherDerived > const &other)
Shortcut for.
Definition TriangularMatrix.h:533
EIGEN_DEVICE_FUNC Scalar & coeffRef(Index row, Index col)
Definition TriangularMatrix.h:426
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:470
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC void lazyAssign(const MatrixBase< OtherDerived > &other)
EIGEN_DEVICE_FUNC TriangularViewType & operator/=(const typename internal::traits< MatrixType >::Scalar &other)
Definition TriangularMatrix.h:396
const internal::triangular_solve_retval< Side, TriangularViewType, Other > solve(const MatrixBase< Other > &other) const
EIGEN_DEVICE_FUNC void solveInPlace(const MatrixBase< OtherDerived > &other) const
"in-place" version of TriangularView::solve() where the result is written in other
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC void lazyAssign(const TriangularBase< OtherDerived > &other)
EIGEN_DEVICE_FUNC Scalar coeff(Index row, Index col) const
Definition TriangularMatrix.h:416
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:393
EIGEN_DEVICE_FUNC TriangularViewType & setConstant(const Scalar &value)
Definition TriangularMatrix.h:403
EIGEN_DEVICE_FUNC TriangularViewType & setZero()
Definition TriangularMatrix.h:407
EIGEN_DEVICE_FUNC void fill(const Scalar &value)
Definition TriangularMatrix.h:400
EIGEN_DEVICE_FUNC Index outerStride() const
Definition TriangularMatrix.h:370
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:386
EIGEN_DEVICE_FUNC Index innerStride() const
Definition TriangularMatrix.h:374
Definition TriangularMatrix.h:183
Expression of a triangular part in a matrix.
Definition TriangularMatrix.h:187
EIGEN_DEVICE_FUNC const ConstTransposeReturnType transpose() const
Definition TriangularMatrix.h:274
EIGEN_DEVICE_FUNC const NestedExpression & nestedExpression() const
Definition TriangularMatrix.h:231
EIGEN_DEVICE_FUNC Scalar determinant() const
Definition TriangularMatrix.h:319
EIGEN_DEVICE_FUNC TransposeReturnType transpose()
Definition TriangularMatrix.h:264
EIGEN_DEVICE_FUNC SelfAdjointView< MatrixTypeNestedNonRef, Mode > selfadjointView()
Definition TriangularMatrix.h:301
EIGEN_DEVICE_FUNC const SelfAdjointView< MatrixTypeNestedNonRef, Mode > selfadjointView() const
This is the const version of selfadjointView()
Definition TriangularMatrix.h:309
EIGEN_DEVICE_FUNC NestedExpression & nestedExpression()
Definition TriangularMatrix.h:235
EIGEN_DEVICE_FUNC const AdjointReturnType adjoint() const
Definition TriangularMatrix.h:258
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Definition TriangularMatrix.h:224
EIGEN_DEVICE_FUNC internal::conditional< Cond, ConjugateReturnType, ConstTriangularView >::type conjugateIf() const
Definition TriangularMatrix.h:249
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
Definition TriangularMatrix.h:227
EIGEN_DEVICE_FUNC const ConjugateReturnType conjugate() const
Definition TriangularMatrix.h:240
Definition AssignEvaluator.h:619
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:652
Definition svm.cpp:205
@ StrictlyLower
View matrix as a lower triangular matrix with zeros on the diagonal.
Definition Constants.h:221
@ UnitDiag
Matrix has ones on the diagonal; to be used in combination with #Lower or #Upper.
Definition Constants.h:213
@ StrictlyUpper
View matrix as an upper triangular matrix with zeros on the diagonal.
Definition Constants.h:223
@ UnitLower
View matrix as a lower triangular matrix with ones on the diagonal.
Definition Constants.h:217
@ ZeroDiag
Matrix has zeros on the diagonal; to be used in combination with #Lower or #Upper.
Definition Constants.h:215
@ SelfAdjoint
Used in BandMatrix and SelfAdjointView to indicate that the matrix is self-adjoint.
Definition Constants.h:225
@ UnitUpper
View matrix as an upper triangular matrix with ones on the diagonal.
Definition Constants.h:219
@ Lower
View matrix as a lower triangular matrix.
Definition Constants.h:209
@ Upper
View matrix as an upper triangular matrix.
Definition Constants.h:211
const unsigned int PacketAccessBit
Short version: means the expression might be vectorized.
Definition Constants.h:94
const unsigned int LinearAccessBit
Short version: means the expression can be seen as 1D vector.
Definition Constants.h:130
const unsigned int DirectAccessBit
Means that the underlying array of coefficients can be directly accessed as a plain strided array.
Definition Constants.h:155
const unsigned int LvalueBit
Means the expression has a coeffRef() method, i.e.
Definition Constants.h:144
Namespace containing all symbols from the Eigen library.
Definition LDLT.h:16
const int HugeCost
This value means that the cost to evaluate an expression coefficient is either very expensive or cann...
Definition Constants.h:44
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:74
const int Dynamic
This value means that a positive quantity (e.g., a size) is not known at compile-time,...
Definition Constants.h:22
Definition Constants.h:528
The type used to identify a dense storage.
Definition Constants.h:507
Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor Matrix...
Definition EigenBase.h:30
Eigen::Index Index
The interface type of indices.
Definition EigenBase.h:39
Definition Constants.h:533
Definition AssignEvaluator.h:817
Definition AssignEvaluator.h:824
Definition TriangularMatrix.h:735
Definition Constants.h:542
Definition TriangularMatrix.h:734
Definition TriangularMatrix.h:733
Definition AssignmentFunctors.h:46
Definition AssignmentFunctors.h:21
Definition CoreEvaluators.h:80
Definition CoreEvaluators.h:91
Definition XprHelper.h:660
Definition XprHelper.h:282
Definition AssignmentFunctors.h:67
Definition AssignmentFunctors.h:142
Definition ForwardDeclarations.h:17
Definition TriangularMatrix.h:865
Definition SolveTriangular.h:208
Definition Meta.h:96
Definition CoreEvaluators.h:65