TriangularSolver.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_SPARSETRIANGULARSOLVER_H
11 #define EIGEN_SPARSETRIANGULARSOLVER_H
12 
13 namespace Eigen {
14 
15 namespace internal {
16 
17 template<typename Lhs, typename Rhs, int Mode,
18  int UpLo = (Mode & Lower)
19  ? Lower
20  : (Mode & Upper)
21  ? Upper
22  : -1,
23  int StorageOrder = int(traits<Lhs>::Flags) & RowMajorBit>
25 
26 // forward substitution, row-major
27 template<typename Lhs, typename Rhs, int Mode>
29 {
30  typedef typename Rhs::Scalar Scalar;
33  static void run(const Lhs& lhs, Rhs& other)
34  {
35  LhsEval lhsEval(lhs);
36  for(Index col=0 ; col<other.cols() ; ++col)
37  {
38  for(Index i=0; i<lhs.rows(); ++i)
39  {
40  Scalar tmp = other.coeff(i,col);
41  Scalar lastVal(0);
42  Index lastIndex = 0;
43  for(LhsIterator it(lhsEval, i); it; ++it)
44  {
45  lastVal = it.value();
46  lastIndex = it.index();
47  if(lastIndex==i)
48  break;
49  tmp -= lastVal * other.coeff(lastIndex,col);
50  }
51  if (Mode & UnitDiag)
52  other.coeffRef(i,col) = tmp;
53  else
54  {
55  eigen_assert(lastIndex==i);
56  other.coeffRef(i,col) = tmp/lastVal;
57  }
58  }
59  }
60  }
61 };
62 
63 // backward substitution, row-major
64 template<typename Lhs, typename Rhs, int Mode>
66 {
67  typedef typename Rhs::Scalar Scalar;
70  static void run(const Lhs& lhs, Rhs& other)
71  {
72  LhsEval lhsEval(lhs);
73  for(Index col=0 ; col<other.cols() ; ++col)
74  {
75  for(Index i=lhs.rows()-1 ; i>=0 ; --i)
76  {
77  Scalar tmp = other.coeff(i,col);
78  Scalar l_ii(0);
79  LhsIterator it(lhsEval, i);
80  while(it && it.index()<i)
81  ++it;
82  if(!(Mode & UnitDiag))
83  {
84  eigen_assert(it && it.index()==i);
85  l_ii = it.value();
86  ++it;
87  }
88  else if (it && it.index() == i)
89  ++it;
90  for(; it; ++it)
91  {
92  tmp -= it.value() * other.coeff(it.index(),col);
93  }
94 
95  if (Mode & UnitDiag) other.coeffRef(i,col) = tmp;
96  else other.coeffRef(i,col) = tmp/l_ii;
97  }
98  }
99  }
100 };
101 
102 // forward substitution, col-major
103 template<typename Lhs, typename Rhs, int Mode>
105 {
106  typedef typename Rhs::Scalar Scalar;
109  static void run(const Lhs& lhs, Rhs& other)
110  {
111  LhsEval lhsEval(lhs);
112  for(Index col=0 ; col<other.cols() ; ++col)
113  {
114  for(Index i=0; i<lhs.cols(); ++i)
115  {
116  Scalar& tmp = other.coeffRef(i,col);
117  if (tmp!=Scalar(0)) // optimization when other is actually sparse
118  {
119  LhsIterator it(lhsEval, i);
120  while(it && it.index()<i)
121  ++it;
122  if(!(Mode & UnitDiag))
123  {
124  eigen_assert(it && it.index()==i);
125  tmp /= it.value();
126  }
127  if (it && it.index()==i)
128  ++it;
129  for(; it; ++it)
130  other.coeffRef(it.index(), col) -= tmp * it.value();
131  }
132  }
133  }
134  }
135 };
136 
137 // backward substitution, col-major
138 template<typename Lhs, typename Rhs, int Mode>
140 {
141  typedef typename Rhs::Scalar Scalar;
144  static void run(const Lhs& lhs, Rhs& other)
145  {
146  LhsEval lhsEval(lhs);
147  for(Index col=0 ; col<other.cols() ; ++col)
148  {
149  for(Index i=lhs.cols()-1; i>=0; --i)
150  {
151  Scalar& tmp = other.coeffRef(i,col);
152  if (tmp!=Scalar(0)) // optimization when other is actually sparse
153  {
154  if(!(Mode & UnitDiag))
155  {
156  // TODO replace this by a binary search. make sure the binary search is safe for partially sorted elements
157  LhsIterator it(lhsEval, i);
158  while(it && it.index()!=i)
159  ++it;
160  eigen_assert(it && it.index()==i);
161  other.coeffRef(i,col) /= it.value();
162  }
163  LhsIterator it(lhsEval, i);
164  for(; it && it.index()<i; ++it)
165  other.coeffRef(it.index(), col) -= tmp * it.value();
166  }
167  }
168  }
169  }
170 };
171 
172 } // end namespace internal
173 
174 #ifndef EIGEN_PARSED_BY_DOXYGEN
175 
176 template<typename ExpressionType,unsigned int Mode>
177 template<typename OtherDerived>
178 void TriangularViewImpl<ExpressionType,Mode,Sparse>::solveInPlace(MatrixBase<OtherDerived>& other) const
179 {
180  eigen_assert(derived().cols() == derived().rows() && derived().cols() == other.rows());
181  eigen_assert((!(Mode & ZeroDiag)) && bool(Mode & (Upper|Lower)));
182 
183  enum { copy = internal::traits<OtherDerived>::Flags & RowMajorBit };
184 
185  typedef typename internal::conditional<copy,
187  OtherCopy otherCopy(other.derived());
188 
190 
191  if (copy)
192  other = otherCopy;
193 }
194 #endif
195 
196 // pure sparse path
197 
198 namespace internal {
199 
200 template<typename Lhs, typename Rhs, int Mode,
201  int UpLo = (Mode & Lower)
202  ? Lower
203  : (Mode & Upper)
204  ? Upper
205  : -1,
206  int StorageOrder = int(Lhs::Flags) & (RowMajorBit)>
208 
209 // forward substitution, col-major
210 template<typename Lhs, typename Rhs, int Mode, int UpLo>
212 {
213  typedef typename Rhs::Scalar Scalar;
216  static void run(const Lhs& lhs, Rhs& other)
217  {
218  const bool IsLower = (UpLo==Lower);
219  AmbiVector<Scalar,StorageIndex> tempVector(other.rows()*2);
220  tempVector.setBounds(0,other.rows());
221 
222  Rhs res(other.rows(), other.cols());
223  res.reserve(other.nonZeros());
224 
225  for(Index col=0 ; col<other.cols() ; ++col)
226  {
227  // FIXME estimate number of non zeros
228  tempVector.init(.99/*float(other.col(col).nonZeros())/float(other.rows())*/);
229  tempVector.setZero();
230  tempVector.restart();
231  for (typename Rhs::InnerIterator rhsIt(other, col); rhsIt; ++rhsIt)
232  {
233  tempVector.coeffRef(rhsIt.index()) = rhsIt.value();
234  }
235 
236  for(Index i=IsLower?0:lhs.cols()-1;
237  IsLower?i<lhs.cols():i>=0;
238  i+=IsLower?1:-1)
239  {
240  tempVector.restart();
241  Scalar& ci = tempVector.coeffRef(i);
242  if (ci!=Scalar(0))
243  {
244  // find
245  typename Lhs::InnerIterator it(lhs, i);
246  if(!(Mode & UnitDiag))
247  {
248  if (IsLower)
249  {
250  eigen_assert(it.index()==i);
251  ci /= it.value();
252  }
253  else
254  ci /= lhs.coeff(i,i);
255  }
256  tempVector.restart();
257  if (IsLower)
258  {
259  if (it.index()==i)
260  ++it;
261  for(; it; ++it)
262  tempVector.coeffRef(it.index()) -= ci * it.value();
263  }
264  else
265  {
266  for(; it && it.index()<i; ++it)
267  tempVector.coeffRef(it.index()) -= ci * it.value();
268  }
269  }
270  }
271 
272 
273  // FIXME compute a reference value to filter zeros
274  for (typename AmbiVector<Scalar,StorageIndex>::Iterator it(tempVector/*,1e-12*/); it; ++it)
275  {
276 // std::cerr << "fill " << it.index() << ", " << col << "\n";
277 // std::cout << it.value() << " ";
278  // FIXME use insertBack
279  res.insert(it.index(), col) = it.value();
280  }
281 // std::cout << "tempVector.nonZeros() == " << int(count) << " / " << (other.rows()) << "\n";
282  }
283  res.finalize();
284  other = res.markAsRValue();
285  }
286 };
287 
288 } // end namespace internal
289 
290 #ifndef EIGEN_PARSED_BY_DOXYGEN
291 template<typename ExpressionType,unsigned int Mode>
292 template<typename OtherDerived>
293 void TriangularViewImpl<ExpressionType,Mode,Sparse>::solveInPlace(SparseMatrixBase<OtherDerived>& other) const
294 {
295  eigen_assert(derived().cols() == derived().rows() && derived().cols() == other.rows());
296  eigen_assert( (!(Mode & ZeroDiag)) && bool(Mode & (Upper|Lower)));
297 
298 // enum { copy = internal::traits<OtherDerived>::Flags & RowMajorBit };
299 
300 // typedef typename internal::conditional<copy,
301 // typename internal::plain_matrix_type_column_major<OtherDerived>::type, OtherDerived&>::type OtherCopy;
302 // OtherCopy otherCopy(other.derived());
303 
305 
306 // if (copy)
307 // other = otherCopy;
308 }
309 #endif
310 
311 } // end namespace Eigen
312 
313 #endif // EIGEN_SPARSETRIANGULARSOLVER_H
Eigen::internal::sparse_solve_triangular_selector< Lhs, Rhs, Mode, Upper, ColMajor >::run
static void run(const Lhs &lhs, Rhs &other)
Definition: TriangularSolver.h:144
gtsam.examples.DogLegOptimizerExample.int
int
Definition: DogLegOptimizerExample.py:111
Eigen::internal::Lhs
@ Lhs
Definition: TensorContractionMapper.h:19
Eigen::internal::AmbiVector::Iterator
Definition: AmbiVector.h:284
Eigen
Namespace containing all symbols from the Eigen library.
Definition: jet.h:637
Eigen::internal::sparse_solve_triangular_selector< Lhs, Rhs, Mode, Upper, RowMajor >::Scalar
Rhs::Scalar Scalar
Definition: TriangularSolver.h:67
col
m col(1)
gtsam.examples.DogLegOptimizerExample.type
type
Definition: DogLegOptimizerExample.py:111
Eigen::internal::sparse_solve_triangular_selector< Lhs, Rhs, Mode, Upper, RowMajor >::LhsEval
evaluator< Lhs > LhsEval
Definition: TriangularSolver.h:68
eigen_assert
#define eigen_assert(x)
Definition: Macros.h:1037
Eigen::RowMajorBit
const unsigned int RowMajorBit
Definition: Constants.h:66
Eigen::internal::sparse_solve_triangular_selector< Lhs, Rhs, Mode, Lower, ColMajor >::LhsEval
evaluator< Lhs > LhsEval
Definition: TriangularSolver.h:107
Eigen::internal::sparse_solve_triangular_selector< Lhs, Rhs, Mode, Lower, RowMajor >::LhsIterator
evaluator< Lhs >::InnerIterator LhsIterator
Definition: TriangularSolver.h:32
Eigen::internal::sparse_solve_triangular_selector< Lhs, Rhs, Mode, Upper, ColMajor >::LhsEval
evaluator< Lhs > LhsEval
Definition: TriangularSolver.h:142
Eigen::Upper
@ Upper
Definition: Constants.h:211
type
Definition: pytypes.h:1525
copy
int EIGEN_BLAS_FUNC() copy(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
Definition: level1_impl.h:29
Eigen::RowMajor
@ RowMajor
Definition: Constants.h:321
res
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
Definition: PartialRedux_count.cpp:3
Eigen::internal::AmbiVector::restart
void restart()
Definition: AmbiVector.h:164
Eigen::internal::sparse_solve_triangular_sparse_selector< Lhs, Rhs, Mode, UpLo, ColMajor >
Definition: TriangularSolver.h:211
rows
int rows
Definition: Tutorial_commainit_02.cpp:1
Eigen::internal::sparse_solve_triangular_selector< Lhs, Rhs, Mode, Lower, ColMajor >::Scalar
Rhs::Scalar Scalar
Definition: TriangularSolver.h:106
Eigen::internal::sparse_solve_triangular_selector< Lhs, Rhs, Mode, Lower, ColMajor >::run
static void run(const Lhs &lhs, Rhs &other)
Definition: TriangularSolver.h:109
Eigen::internal::sparse_solve_triangular_sparse_selector< Lhs, Rhs, Mode, UpLo, ColMajor >::run
static void run(const Lhs &lhs, Rhs &other)
Definition: TriangularSolver.h:216
Eigen::internal::sparse_solve_triangular_selector< Lhs, Rhs, Mode, Lower, RowMajor >::run
static void run(const Lhs &lhs, Rhs &other)
Definition: TriangularSolver.h:33
Eigen::ZeroDiag
@ ZeroDiag
Definition: Constants.h:215
Eigen::internal::sparse_solve_triangular_selector< Lhs, Rhs, Mode, Upper, RowMajor >::LhsIterator
evaluator< Lhs >::InnerIterator LhsIterator
Definition: TriangularSolver.h:69
Eigen::internal::AmbiVector::setBounds
void setBounds(Index start, Index end)
Definition: AmbiVector.h:42
Eigen::internal::plain_matrix_type_column_major::type
Matrix< typename traits< T >::Scalar, Rows, Cols,(MaxRows==1 &&MaxCols!=1) ? RowMajor :ColMajor, MaxRows, MaxCols > type
Definition: XprHelper.h:391
Eigen::internal::AmbiVector::init
void init(double estimatedDensity)
Definition: AmbiVector.h:138
Eigen::internal::sparse_solve_triangular_selector< Lhs, Rhs, Mode, Upper, ColMajor >::LhsIterator
evaluator< Lhs >::InnerIterator LhsIterator
Definition: TriangularSolver.h:143
gtsam.examples.DogLegOptimizerExample.run
def run(args)
Definition: DogLegOptimizerExample.py:21
Eigen::internal::evaluator< Lhs >
Eigen::Lower
@ Lower
Definition: Constants.h:209
Eigen::internal::AmbiVector::coeffRef
Scalar & coeffRef(Index i)
Definition: AmbiVector.h:187
Eigen::internal::sparse_solve_triangular_sparse_selector< Lhs, Rhs, Mode, UpLo, ColMajor >::Scalar
Rhs::Scalar Scalar
Definition: TriangularSolver.h:213
Eigen::internal::AmbiVector::setZero
void setZero()
Definition: AmbiVector.h:171
Eigen::internal::sparse_solve_triangular_selector
Definition: TriangularSolver.h:24
Eigen::internal::traits
Definition: ForwardDeclarations.h:17
Eigen::internal::sparse_solve_triangular_sparse_selector
Definition: TriangularSolver.h:207
Eigen::internal::sparse_solve_triangular_selector< Lhs, Rhs, Mode, Upper, RowMajor >::run
static void run(const Lhs &lhs, Rhs &other)
Definition: TriangularSolver.h:70
Eigen::internal::sparse_solve_triangular_selector< Lhs, Rhs, Mode, Lower, RowMajor >::Scalar
Rhs::Scalar Scalar
Definition: TriangularSolver.h:30
Eigen::internal::Rhs
@ Rhs
Definition: TensorContractionMapper.h:18
Eigen::internal::sparse_solve_triangular_selector< Lhs, Rhs, Mode, Lower, ColMajor >::LhsIterator
evaluator< Lhs >::InnerIterator LhsIterator
Definition: TriangularSolver.h:108
internal
Definition: BandTriangularSolver.h:13
Eigen::ColMajor
@ ColMajor
Definition: Constants.h:319
cols
int cols
Definition: Tutorial_commainit_02.cpp:1
Eigen::internal::promote_index_type
Definition: XprHelper.h:120
Eigen::internal::sparse_solve_triangular_sparse_selector< Lhs, Rhs, Mode, UpLo, ColMajor >::StorageIndex
promote_index_type< typename traits< Lhs >::StorageIndex, typename traits< Rhs >::StorageIndex >::type StorageIndex
Definition: TriangularSolver.h:215
Eigen::internal::AmbiVector
Definition: AmbiVector.h:23
i
int i
Definition: BiCGSTAB_step_by_step.cpp:9
pybind_wrapper_test_script.other
other
Definition: pybind_wrapper_test_script.py:42
Eigen::internal::sparse_solve_triangular_selector< Lhs, Rhs, Mode, Lower, RowMajor >::LhsEval
evaluator< Lhs > LhsEval
Definition: TriangularSolver.h:31
Scalar
SCALAR Scalar
Definition: bench_gemm.cpp:46
Eigen::UnitDiag
@ UnitDiag
Definition: Constants.h:213
Eigen::Index
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74
Eigen::internal::sparse_solve_triangular_selector< Lhs, Rhs, Mode, Upper, ColMajor >::Scalar
Rhs::Scalar Scalar
Definition: TriangularSolver.h:141


gtsam
Author(s):
autogenerated on Sun Dec 22 2024 04:18:14