TMB Documentation  v1.9.11
spmat.hpp
Go to the documentation of this file.
1 // Copyright (C) 2013-2015 Kasper Kristensen
2 // License: GPL-2
3 
8 namespace tmbutils {
9 
11 template<class Type>
12 Eigen::SparseMatrix<Type> asSparseMatrix(SEXP M){
13  int *i=INTEGER(R_do_slot(M,Rf_install("i")));
14  int *j=INTEGER(R_do_slot(M,Rf_install("j")));
15  double *x=REAL(R_do_slot(M,Rf_install("x")));
16  int n=LENGTH(R_do_slot(M,Rf_install("x")));
17  int *dim=INTEGER(R_do_slot(M,Rf_install("Dim")));
18  typedef Eigen::Triplet<Type> T;
19  std::vector<T> tripletList;
20  for(int k=0;k<n;k++){
21  tripletList.push_back(T(i[k],j[k],x[k]));
22  }
23  Eigen::SparseMatrix<Type> mat(dim[0],dim[1]);
24  mat.setFromTriplets(tripletList.begin(), tripletList.end());
25  return mat;
26 }
27 
38 template<class Type>
39 bool isStructuralZero(Type x) {
40  return (x == Type(0)) && (! CppAD::Variable(x));
41 }
42 
52 template<class Type>
53 Eigen::SparseMatrix<Type> asSparseMatrix(matrix<Type> x){
54  typedef Eigen::Triplet<Type> T;
55  std::vector<T> tripletList;
56  for(int i=0;i<x.rows();i++)
57  for(int j=0;j<x.cols();j++)
58  if( ! isStructuralZero(x(i,j)) )
59  tripletList.push_back(T(i,j,x(i,j)));
60  Eigen::SparseMatrix<Type> mat(x.rows(),x.cols());
61  mat.setFromTriplets(tripletList.begin(), tripletList.end());
62  return mat;
63 }
64 
75 template<class Type>
76 Eigen::SparseVector<Type> asSparseVector(vector<Type> x){
77  typedef Eigen::Triplet<Type> T;
78  std::vector<T> tripletList;
79  Eigen::SparseVector<Type> mat(x.rows());
80  for(int i=0;i<x.rows();i++)
81  if( ! isStructuralZero(x(i)) )
82  mat.coeffRef(i)=x(i);
83  return mat;
84 }
85 
87 template <class Type>
88 Eigen::SparseMatrix<Type> kronecker(Eigen::SparseMatrix<Type> x,
89  Eigen::SparseMatrix<Type> y){
90  typedef Eigen::Triplet<Type> T;
91  typedef typename Eigen::SparseMatrix<Type>::InnerIterator Iterator;
92  std::vector<T> tripletList;
93  int n1=x.rows(),n2=x.cols(),n3=y.rows(),n4=y.cols();
94  int i,j,k,l;
95  // Loop over nonzeros of x
96  for (int cx=0; cx<x.outerSize(); cx++)
97  for (Iterator itx(x,cx); itx; ++itx)
98  // Loop over nonzeros of y
99  for (int cy=0; cy<y.outerSize(); cy++)
100  for (Iterator ity(y,cy); ity; ++ity)
101  {
102  i=itx.row();
103  j=itx.col();
104  k=ity.row();
105  l=ity.col();
106  tripletList.push_back(T(i*n3+k,j*n4+l, itx.value()*ity.value() ));
107  }
108  Eigen::SparseMatrix<Type> mat(n1*n3,n2*n4);
109  mat.setFromTriplets(tripletList.begin(), tripletList.end());
110  return mat;
111 }
112 
114 template <class Type>
116  matrix<Type> I_(A_.rows(),A_.cols());
117  I_.setIdentity();
118  /* Sparse representations */
119  Eigen::SparseMatrix<Type> A=asSparseMatrix(A_);
120  Eigen::SparseMatrix<Type> I=asSparseMatrix(I_);
121  /* Kronecker */
122  Eigen::SparseMatrix<Type> AxA=kronecker(A,A);
123  Eigen::SparseMatrix<Type> IxI=kronecker(I,I);
124  matrix<Type> vecI=I_.vec().matrix();
125  Eigen::SparseMatrix<Type> C=IxI-AxA;
126  /* Solve system C*vecV=vecI.
127  Note: No assumptions on symmetry or eigenvalue-range of C. Therefore
128  rewrite it as (C'*C)*vecV=(C*vecI). Since (C'*C) is symmetric, the
129  LDL'-factorization can be applied.
130  */
131  Eigen::SimplicialLDLT< Eigen::SparseMatrix<Type> > ldlt(C.transpose()*C);
132  matrix<Type> z = ldlt.solve(C.transpose()*vecI);
133  matrix<Type> V(A_.rows(),A_.cols());
134  for(int i=0;i<z.size();i++)V(i)=z(i);
135  return V;
136 }
137 
139 template <class Type>
140 matrix<Type> invertSparseMatrix(Eigen::SparseMatrix<Type> A){
141  matrix<Type> I(A.rows(),A.cols());
142  I.setIdentity();
143  Eigen::SimplicialLDLT< Eigen::SparseMatrix<Type> > ldlt(A);
144  matrix<Type> ans = ldlt.solve(I);
145  return ans;
146 }
147 
148 }
Eigen::SparseVector< Type > asSparseVector(vector< Type > x)
Create sparse vector from dense vector.
Definition: spmat.hpp:76
vector< Type > vec()
Definition: tmbutils.hpp:121
matrix< Type > discrLyap(matrix< Type > A_)
Definition: spmat.hpp:115
bool isStructuralZero(Type x)
Test if a scalar is a structural zero.
Definition: spmat.hpp:39
Eigen::SparseMatrix< Type > asSparseMatrix(SEXP M)
Definition: spmat.hpp:12
Matrix class used by TMB.
Definition: tmbutils.hpp:102
matrix< Type > invertSparseMatrix(Eigen::SparseMatrix< Type > A)
Definition: spmat.hpp:140
Vector class used by TMB.
Definition: tmbutils.hpp:18
Matrix< scalartype, n1 *n3, n2 *n4 > kronecker(Matrix< scalartype, n1, n2 > x, Matrix< scalartype, n3, n4 > y)
Kronecker product of two matrices.
Definition: kronecker.hpp:12
Utility functions for TMB (automatically included)
Definition: concat.hpp:5
License: GPL v2