10 #ifndef EIGEN_SPARSE_SELFADJOINTVIEW_H
11 #define EIGEN_SPARSE_SELFADJOINTVIEW_H
29 template<
typename Lhs,
typename Rhs,
int UpLo>
30 class SparseSelfAdjointTimeDenseProduct;
32 template<
typename Lhs,
typename Rhs,
int UpLo>
33 class DenseTimeSparseSelfAdjointProduct;
37 template<
typename MatrixType,
unsigned int UpLo>
38 struct traits<SparseSelfAdjointView<MatrixType,UpLo> > : traits<MatrixType> {
41 template<
int SrcUpLo,
int DstUpLo,
typename MatrixType,
int DestOrder>
42 void permute_symm_to_symm(
const MatrixType& mat, SparseMatrix<typename MatrixType::Scalar,DestOrder,typename MatrixType::Index>& _dest,
const typename MatrixType::Index* perm = 0);
44 template<
int UpLo,
typename MatrixType,
int DestOrder>
45 void permute_symm_to_fullsymm(
const MatrixType& mat, SparseMatrix<typename MatrixType::Scalar,DestOrder,typename MatrixType::Index>& _dest,
const typename MatrixType::Index* perm = 0);
50 :
public EigenBase<SparseSelfAdjointView<MatrixType,UpLo> >
54 typedef typename MatrixType::Scalar Scalar;
55 typedef typename MatrixType::Index Index;
57 typedef typename MatrixType::Nested MatrixTypeNested;
58 typedef typename internal::remove_all<MatrixTypeNested>::type _MatrixTypeNested;
62 eigen_assert(rows()==cols() &&
"SelfAdjointView is only for squared matrices");
65 inline Index rows()
const {
return m_matrix.rows(); }
66 inline Index cols()
const {
return m_matrix.cols(); }
69 const _MatrixTypeNested& matrix()
const {
return m_matrix; }
70 _MatrixTypeNested& matrix() {
return m_matrix.const_cast_derived(); }
77 template<
typename OtherDerived>
78 SparseSparseProduct<typename OtherDerived::PlainObject, OtherDerived>
81 return SparseSparseProduct<typename OtherDerived::PlainObject, OtherDerived>(*
this, rhs.
derived());
89 template<
typename OtherDerived>
friend
90 SparseSparseProduct<OtherDerived, typename OtherDerived::PlainObject >
93 return SparseSparseProduct<OtherDerived, typename OtherDerived::PlainObject>(lhs.
derived(), rhs);
97 template<
typename OtherDerived>
98 SparseSelfAdjointTimeDenseProduct<MatrixType,OtherDerived,UpLo>
101 return SparseSelfAdjointTimeDenseProduct<MatrixType,OtherDerived,UpLo>(m_matrix, rhs.derived());
105 template<
typename OtherDerived>
friend
106 DenseTimeSparseSelfAdjointProduct<OtherDerived,MatrixType,UpLo>
109 return DenseTimeSparseSelfAdjointProduct<OtherDerived,_MatrixTypeNested,UpLo>(lhs.derived(), rhs.m_matrix);
120 template<
typename DerivedU>
126 internal::permute_symm_to_fullsymm<UpLo>(m_matrix, _dest);
129 template<
typename DestScalar>
void evalTo(DynamicSparseMatrix<DestScalar,ColMajor,Index>& _dest)
const
132 SparseMatrix<DestScalar,ColMajor,Index> tmp(_dest.rows(),_dest.cols());
133 internal::permute_symm_to_fullsymm<UpLo>(m_matrix, tmp);
140 return SparseSymmetricPermutationProduct<_MatrixTypeNested,UpLo>(m_matrix, perm);
143 template<
typename SrcMatrixType,
int SrcUpLo>
144 SparseSelfAdjointView& operator=(
const SparseSymmetricPermutationProduct<SrcMatrixType,SrcUpLo>& permutedMatrix)
146 permutedMatrix.evalTo(*
this);
151 SparseSelfAdjointView& operator=(
const SparseSelfAdjointView& src)
153 PermutationMatrix<Dynamic> pnull;
154 return *
this = src.twistedBy(pnull);
157 template<
typename SrcMatrixType,
unsigned int SrcUpLo>
158 SparseSelfAdjointView& operator=(
const SparseSelfAdjointView<SrcMatrixType,SrcUpLo>& src)
160 PermutationMatrix<Dynamic> pnull;
161 return *
this = src.twistedBy(pnull);
170 typename MatrixType::Nested m_matrix;
171 mutable VectorI m_countPerRow;
172 mutable VectorI m_countPerCol;
179 template<
typename Derived>
180 template<
unsigned int UpLo>
181 const SparseSelfAdjointView<Derived, UpLo> SparseMatrixBase<Derived>::selfadjointView()
const
186 template<
typename Derived>
187 template<
unsigned int UpLo>
188 SparseSelfAdjointView<Derived, UpLo> SparseMatrixBase<Derived>::selfadjointView()
197 template<
typename MatrixType,
unsigned int UpLo>
198 template<
typename DerivedU>
199 SparseSelfAdjointView<MatrixType,UpLo>&
202 SparseMatrix<Scalar,MatrixType::Flags&RowMajorBit?RowMajor:ColMajor> tmp = u * u.adjoint();
204 m_matrix.const_cast_derived() = tmp.template triangularView<UpLo>();
206 m_matrix.const_cast_derived() += alpha * tmp.template triangularView<UpLo>();
216 template<
typename Lhs,
typename Rhs,
int UpLo>
217 struct traits<SparseSelfAdjointTimeDenseProduct<Lhs,Rhs,UpLo> >
218 : traits<ProductBase<SparseSelfAdjointTimeDenseProduct<Lhs,Rhs,UpLo>, Lhs, Rhs> >
220 typedef Dense StorageKind;
224 template<
typename Lhs,
typename Rhs,
int UpLo>
225 class SparseSelfAdjointTimeDenseProduct
226 :
public ProductBase<SparseSelfAdjointTimeDenseProduct<Lhs,Rhs,UpLo>, Lhs, Rhs>
229 EIGEN_PRODUCT_PUBLIC_INTERFACE(SparseSelfAdjointTimeDenseProduct)
231 SparseSelfAdjointTimeDenseProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs)
234 template<
typename Dest>
void scaleAndAddTo(Dest& dest,
const Scalar& alpha)
const
236 EIGEN_ONLY_USED_FOR_DEBUG(alpha);
238 eigen_assert(alpha==Scalar(1) &&
"alpha != 1 is not implemented yet, sorry");
239 typedef typename internal::remove_all<Lhs>::type _Lhs;
240 typedef typename _Lhs::InnerIterator LhsInnerIterator;
245 || ( (UpLo&
Upper) && !LhsIsRowMajor)
246 || ( (UpLo&
Lower) && LhsIsRowMajor),
247 ProcessSecondHalf = !ProcessFirstHalf
249 for (Index j=0; j<m_lhs.outerSize(); ++j)
251 LhsInnerIterator i(m_lhs,j);
252 if (ProcessSecondHalf)
254 while (i && i.index()<j) ++i;
255 if(i && i.index()==j)
257 dest.row(j) += i.value() * m_rhs.row(j);
261 for(; (ProcessFirstHalf ? i && i.index() < j : i) ; ++i)
263 Index a = LhsIsRowMajor ? j : i.index();
264 Index b = LhsIsRowMajor ? i.index() : j;
265 typename Lhs::Scalar v = i.value();
266 dest.row(a) += (v) * m_rhs.row(b);
267 dest.row(b) += numext::conj(v) * m_rhs.row(a);
269 if (ProcessFirstHalf && i && (i.index()==j))
270 dest.row(j) += i.value() * m_rhs.row(j);
275 SparseSelfAdjointTimeDenseProduct&
operator=(
const SparseSelfAdjointTimeDenseProduct&);
279 template<
typename Lhs,
typename Rhs,
int UpLo>
280 struct traits<DenseTimeSparseSelfAdjointProduct<Lhs,Rhs,UpLo> >
281 : traits<ProductBase<DenseTimeSparseSelfAdjointProduct<Lhs,Rhs,UpLo>, Lhs, Rhs> >
285 template<
typename Lhs,
typename Rhs,
int UpLo>
286 class DenseTimeSparseSelfAdjointProduct
287 :
public ProductBase<DenseTimeSparseSelfAdjointProduct<Lhs,Rhs,UpLo>, Lhs, Rhs>
290 EIGEN_PRODUCT_PUBLIC_INTERFACE(DenseTimeSparseSelfAdjointProduct)
292 DenseTimeSparseSelfAdjointProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs)
295 template<
typename Dest>
void scaleAndAddTo(Dest& ,
const Scalar& )
const
301 DenseTimeSparseSelfAdjointProduct&
operator=(
const DenseTimeSparseSelfAdjointProduct&);
309 template<
typename MatrixType,
int UpLo>
310 struct traits<SparseSymmetricPermutationProduct<MatrixType,UpLo> > : traits<MatrixType> {
313 template<
int UpLo,
typename MatrixType,
int DestOrder>
314 void permute_symm_to_fullsymm(
const MatrixType& mat, SparseMatrix<typename MatrixType::Scalar,DestOrder,typename MatrixType::Index>& _dest,
const typename MatrixType::Index* perm)
316 typedef typename MatrixType::Index Index;
317 typedef typename MatrixType::Scalar Scalar;
318 typedef SparseMatrix<Scalar,DestOrder,Index> Dest;
319 typedef Matrix<Index,Dynamic,1> VectorI;
321 Dest& dest(_dest.derived());
323 StorageOrderMatch = int(Dest::IsRowMajor) == int(MatrixType::IsRowMajor)
326 Index size = mat.rows();
330 dest.resize(size,size);
331 for(Index j = 0; j<size; ++j)
333 Index jp = perm ? perm[j] : j;
334 for(
typename MatrixType::InnerIterator it(mat,j); it; ++it)
336 Index i = it.index();
339 Index ip = perm ? perm[i] : i;
341 count[StorageOrderMatch ? jp : ip]++;
344 else if(( UpLo==
Lower && r>c) || ( UpLo==
Upper && r<c))
351 Index nnz = count.sum();
354 dest.resizeNonZeros(nnz);
355 dest.outerIndexPtr()[0] = 0;
356 for(Index j=0; j<size; ++j)
357 dest.outerIndexPtr()[j+1] = dest.outerIndexPtr()[j] + count[j];
358 for(Index j=0; j<size; ++j)
359 count[j] = dest.outerIndexPtr()[j];
362 for(Index j = 0; j<size; ++j)
364 for(
typename MatrixType::InnerIterator it(mat,j); it; ++it)
366 Index i = it.index();
370 Index jp = perm ? perm[j] : j;
371 Index ip = perm ? perm[i] : i;
375 Index k = count[StorageOrderMatch ? jp : ip]++;
376 dest.innerIndexPtr()[k] = StorageOrderMatch ? ip : jp;
377 dest.valuePtr()[k] = it.value();
381 Index k = count[ip]++;
382 dest.innerIndexPtr()[k] = ip;
383 dest.valuePtr()[k] = it.value();
385 else if(( (UpLo&
Lower)==Lower && r>c) || ( (UpLo&
Upper)==Upper && r<c))
387 if(!StorageOrderMatch)
389 Index k = count[jp]++;
390 dest.innerIndexPtr()[k] = ip;
391 dest.valuePtr()[k] = it.value();
393 dest.innerIndexPtr()[k] = jp;
394 dest.valuePtr()[k] = numext::conj(it.value());
400 template<
int _SrcUpLo,
int _DstUpLo,
typename MatrixType,
int DstOrder>
401 void permute_symm_to_symm(
const MatrixType& mat, SparseMatrix<typename MatrixType::Scalar,DstOrder,typename MatrixType::Index>& _dest,
const typename MatrixType::Index* perm)
403 typedef typename MatrixType::Index Index;
404 typedef typename MatrixType::Scalar Scalar;
405 SparseMatrix<Scalar,DstOrder,Index>& dest(_dest.derived());
406 typedef Matrix<Index,Dynamic,1> VectorI;
409 StorageOrderMatch = int(SrcOrder) == int(DstOrder),
410 DstUpLo = DstOrder==
RowMajor ? (_DstUpLo==Upper ? Lower :
Upper) : _DstUpLo,
411 SrcUpLo = SrcOrder==
RowMajor ? (_SrcUpLo==Upper ? Lower : Upper) : _SrcUpLo
414 Index size = mat.rows();
417 dest.resize(size,size);
418 for(Index j = 0; j<size; ++j)
420 Index jp = perm ? perm[j] : j;
421 for(
typename MatrixType::InnerIterator it(mat,j); it; ++it)
423 Index i = it.index();
424 if((
int(SrcUpLo)==
int(Lower) && i<j) || (
int(SrcUpLo)==
int(Upper) && i>j))
427 Index ip = perm ? perm[i] : i;
428 count[int(DstUpLo)==int(Lower) ? (std::min)(ip,jp) : (std::max)(ip,jp)]++;
431 dest.outerIndexPtr()[0] = 0;
432 for(Index j=0; j<size; ++j)
433 dest.outerIndexPtr()[j+1] = dest.outerIndexPtr()[j] + count[j];
434 dest.resizeNonZeros(dest.outerIndexPtr()[size]);
435 for(Index j=0; j<size; ++j)
436 count[j] = dest.outerIndexPtr()[j];
438 for(Index j = 0; j<size; ++j)
441 for(
typename MatrixType::InnerIterator it(mat,j); it; ++it)
443 Index i = it.index();
444 if((
int(SrcUpLo)==
int(Lower) && i<j) || (
int(SrcUpLo)==
int(Upper) && i>j))
447 Index jp = perm ? perm[j] : j;
448 Index ip = perm? perm[i] : i;
450 Index k = count[int(DstUpLo)==int(Lower) ? (std::min)(ip,jp) : (std::max)(ip,jp)]++;
451 dest.innerIndexPtr()[k] = int(DstUpLo)==int(Lower) ? (std::max)(ip,jp) : (std::min)(ip,jp);
453 if(!StorageOrderMatch) std::swap(ip,jp);
454 if( ((
int(DstUpLo)==
int(Lower) && ip<jp) || (
int(DstUpLo)==
int(Upper) && ip>jp)))
455 dest.valuePtr()[k] = numext::conj(it.value());
457 dest.valuePtr()[k] = it.value();
464 template<
typename MatrixType,
int UpLo>
465 class SparseSymmetricPermutationProduct
466 :
public EigenBase<SparseSymmetricPermutationProduct<MatrixType,UpLo> >
469 typedef typename MatrixType::Scalar Scalar;
470 typedef typename MatrixType::Index Index;
472 typedef PermutationMatrix<Dynamic,Dynamic,Index> Perm;
474 typedef Matrix<Index,Dynamic,1> VectorI;
475 typedef typename MatrixType::Nested MatrixTypeNested;
476 typedef typename internal::remove_all<MatrixTypeNested>::type _MatrixTypeNested;
478 SparseSymmetricPermutationProduct(
const MatrixType& mat,
const Perm& perm)
479 : m_matrix(mat), m_perm(perm)
482 inline Index rows()
const {
return m_matrix.rows(); }
483 inline Index cols()
const {
return m_matrix.cols(); }
485 template<
typename DestScalar,
int Options,
typename DstIndex>
486 void evalTo(SparseMatrix<DestScalar,Options,DstIndex>& _dest)
const
489 SparseMatrix<DestScalar,(Options&RowMajor)==RowMajor ? ColMajor : RowMajor, DstIndex> tmp;
490 internal::permute_symm_to_fullsymm<UpLo>(m_matrix,tmp,m_perm.indices().data());
494 template<
typename DestType,
unsigned int DestUpLo>
void evalTo(SparseSelfAdjointView<DestType,DestUpLo>& dest)
const
496 internal::permute_symm_to_symm<UpLo,DestUpLo>(m_matrix,dest.matrix(),m_perm.indices().data());
500 MatrixTypeNested m_matrix;
507 #endif // EIGEN_SPARSE_SELFADJOINTVIEW_H
SparseSparseProduct< typename OtherDerived::PlainObject, OtherDerived > operator*(const SparseMatrixBase< OtherDerived > &rhs) const
Definition: SparseSelfAdjointView.h:79
Definition: Constants.h:167
A versatible sparse matrix representation.
Definition: SparseMatrix.h:85
Pseudo expression to manipulate a triangular sparse matrix as a selfadjoint matrix.
Definition: SparseSelfAdjointView.h:49
Definition: Constants.h:264
Definition: Constants.h:169
SparseSelfAdjointView & rankUpdate(const SparseMatrixBase< DerivedU > &u, const Scalar &alpha=Scalar(1))
Definition: EigenBase.h:26
friend DenseTimeSparseSelfAdjointProduct< OtherDerived, MatrixType, UpLo > operator*(const MatrixBase< OtherDerived > &lhs, const SparseSelfAdjointView &rhs)
Definition: SparseSelfAdjointView.h:107
Base class of any sparse matrices or sparse expressions.
Definition: ForwardDeclarations.h:239
SparseSymmetricPermutationProduct< _MatrixTypeNested, UpLo > twistedBy(const PermutationMatrix< Dynamic, Dynamic, Index > &perm) const
Definition: SparseSelfAdjointView.h:138
Derived & derived()
Definition: EigenBase.h:34
internal::traits< Derived >::Index Index
The type of indices.
Definition: DenseBase.h:60
friend SparseSparseProduct< OtherDerived, typename OtherDerived::PlainObject > operator*(const SparseMatrixBase< OtherDerived > &lhs, const SparseSelfAdjointView &rhs)
Definition: SparseSelfAdjointView.h:91
Definition: Constants.h:266
const unsigned int RowMajorBit
Definition: Constants.h:53
SparseSelfAdjointTimeDenseProduct< MatrixType, OtherDerived, UpLo > operator*(const MatrixBase< OtherDerived > &rhs) const
Definition: SparseSelfAdjointView.h:99
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:48
Derived & operator=(const MatrixBase &other)
Definition: Assign.h:562