G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsWeightMapper.h
Go to the documentation of this file.
1 
14 #pragma once
15 
16 #include <gsCore/gsExport.h>
17 #include <gsCore/gsLinearAlgebra.h>
18 
19 namespace gismo
20 {
21 
22 template<class T>
23 class gsWeightMapper
24 {
25 public:
26  typedef T weightType;
27  typedef index_t indexType; //indices of gsMatrix
28 
29  typedef gsSparseMatrix<weightType,gsEigen::RowMajor,indexType> LToGMatrix;
30  typedef gsSparseMatrix<weightType,gsEigen::ColMajor,indexType> GToLMatrix;
31 
32  typedef std::vector<indexType> IndexContainer;
33  typedef std::vector<indexType>::const_iterator CIndexIter;
34  typedef std::vector<weightType> WeightContainer;
35  typedef typename std::vector<weightType>::const_iterator CWeightIter;
36  typedef typename LToGMatrix::InnerIterator InIterMat;
37 public:
55  struct Iterator
56  {
57  friend class gsWeightMapper;
58  private:
59  const weightType *m_beg;
60  const weightType *m_end;
61  const weightType *m_value;
62  const indexType *m_index;
63  Iterator(const weightType *beg,const weightType *end,const indexType *ind,const weightType *value=NULL)
64  : m_beg(beg), m_end(end), m_value(value?value:beg), m_index(ind)
65  {}
66  template<int ordering>
67  Iterator( const gsSparseMatrix<weightType,ordering,indexType> &matrix, indexType outerId)
68  {
69  m_beg=matrix.valuePtr()+matrix.outerIndexPtr()[outerId];
70  m_end=matrix.valuePtr()+matrix.outerIndexPtr()[outerId+1];
71  m_value=m_beg;
72  m_index=matrix.innerIndexPtr()+matrix.outerIndexPtr()[outerId];
73  }
74  public:
75  Iterator()
76  : m_beg(NULL),m_end(NULL),m_value(NULL),m_index(NULL)
77  {
78  }
79 
80  typedef std::bidirectional_iterator_tag iterator_category; //or another tag
81 
82  operator const weightType*() {return m_value;}
83  operator const indexType*() {return m_index;}
84 
85  // assignement shoud be implicitly generated by the compiler // Iterator& operator=(const Iterator& other) {m_value=other.m_value; m_index=other.m_index; return *this;}
86  bool operator==(const Iterator& other) const {return m_value==other.m_value && m_index==other.m_index;}
87  bool operator!=(const Iterator& other) const {return !this->operator==(other);}
88 
89  Iterator& operator++() {++m_value;++m_index; return *this;}
90  Iterator& operator--() {--m_value;--m_index; return *this;}
91  Iterator& operator+=(ptrdiff_t a) {m_value+=a; m_index+=a; return *this;}
92  Iterator operator+ (ptrdiff_t a) const {return Iterator(m_beg,m_end, m_index+a, m_value+a);}
93  Iterator& operator-=(ptrdiff_t a) {m_value-=a; m_index-=a; return *this;}
94  Iterator operator- (ptrdiff_t a) const {return Iterator(m_beg,m_end, m_index-a,m_value-a);}
95 
96  const weightType& operator*() const {return *m_value;}
97 
102  const weightType& weight() const {return *m_value;}
107  const indexType& index() const {return *m_index;}
112  Iterator end() const {return Iterator(m_beg,m_end,m_index,m_end);}
117  Iterator begin() const {return Iterator(m_beg,m_end,m_index,m_beg);}
118 
119  operator bool() {return m_value<m_end && m_value>=m_beg;}
120 
121  };
122 
124  // operators and constructors
126 public:
127  gsWeightMapper()
128  { m_optimizationMatrix=NULL; }
129 
130  gsWeightMapper(indexType sourceSize,indexType targetSize)
131  {
132  m_matrix.resize(sourceSize,targetSize);
133  m_optimizationMatrix=NULL;
134  }
135 
136  virtual ~gsWeightMapper()
137  {
138  if(m_optimizationMatrix)
139  delete m_optimizationMatrix;
140  }
141 
142  gsWeightMapper(const gsWeightMapper& other)
143  : m_matrix(other.m_matrix)
144  {
145  m_optimizationMatrix=NULL;
146  optimize(other.getOptimizationFlags());
147  }
148 
149  gsWeightMapper(const gsSparseMatrix<weightType,gsEigen::RowMajor,indexType> & other)
150  {
151  m_optimizationMatrix=NULL;
152  *this=other;
153  }
154 
155  gsWeightMapper(const gsSparseMatrix<weightType,gsEigen::ColMajor,indexType> & other)
156  {
157  m_optimizationMatrix=NULL;
158  *this=other;
159  }
160 
161  gsWeightMapper& operator=(const gsWeightMapper & other)
162  {
163  removeOptimization();
164  m_matrix=other.m_matrix;
165  optimize(other.getOptimizationFlags());
166  return *this;
167  }
168 
169  template<typename MatrixT>
170  gsWeightMapper& operator*=(const MatrixT &other)
171  {
172  removeOptimization();
173  // EIGEN problem
174  // force a temporary because otherwise
175  // permutation matrices do not work
176  m_matrix=(m_matrix*other).eval();
177  return *this;
178  }
179 
180  template<typename MatrixT>
181  gsWeightMapper operator*(const MatrixT &other)
182  {
183  gsWeightMapper result;
184  result.m_matrix=m_matrix*other;
185  return result;
186  }
187 
188  template<typename MatrixT>
189  gsWeightMapper& operator=(const MatrixT &other)
190  {
191  removeOptimization();
192  m_matrix=other;
193  optimize();
194  return *this;
195  }
196 
197  operator const LToGMatrix& ()
198  { return m_matrix; }
199 
200  const LToGMatrix& asMatrix() const
201  { return m_matrix; }
202 
203  LToGMatrix& asMatrix()
204  { return m_matrix; }
206  // functions for working with the mapper
208 public:
209 
211  void setEntry(indexType source, indexType target, weightType weight=1)
212  {
213  removeOptimization();
214  m_matrix.at(source,target)=weight;
215  }
216 
218  weightType getWeight(indexType source, indexType target) const
219  { return m_matrix.at(source,target); }
220 
222  indexType getNrOfSources() const
223  { return m_matrix.rows(); }
224 
226  indexType getNrOfTargets() const
227  { return m_matrix.cols(); }
228 
230  bool sourceIsId(indexType source) const
231  {
232  IndexContainer indices;
233  sourceToTarget(source,indices);
234  return (indices.size()==1 && math::almostEqual<14>(m_matrix.at(source,indices[0]),T(1.0)));
235  }
236 
238  bool targetIsId(indexType target) const
239  {
240  IndexContainer indices;
241  targetToSource(target,indices);
242  return (indices.size()==1 && math::almostEqual<14>(m_matrix.at(indices[0],target),T(1.0)));
243  }
244 
246  // functions for transforming the coefficients
248 public:
249 
255  void mapToSourceCoefs(gsMatrix<weightType> const & targetCoefs,gsMatrix<weightType> & sourceCoefs) const
256  {
257  // from target to source it's just a multiplication
258  GISMO_ASSERT(targetCoefs.rows()==m_matrix.cols(),"Wrong coefficient size!");
259  sourceCoefs.noalias()=m_matrix * targetCoefs;
260  }
261 
270  void mapToTargetCoefs(gsMatrix<weightType> const & sourceCoefs,gsMatrix<weightType> & targetCoefs) const;
271 
273  // functions for applying the map between target and source
275 public:
276 
283  void sourceToTarget(IndexContainer const & source,IndexContainer & target) const
284  {
285  target.reserve( source.size() );
286  target.clear();
287  IndexContainer res_i;
288  for(size_t i = 0;i<source.size();i++)
289  {
290  //just call sourceToTarget for single bfs for all given sources
291  sourceToTarget(source[i],res_i);
292  target.insert(target.end(), res_i.begin(), res_i.end());
293  }
294  //get rid of duplicates and sort them
295  sort( target.begin(), target.end() );
296  target.erase( unique( target.begin(), target.end() ), target.end() );
297  }
298 
306  void sourceToTarget(indexType source,IndexContainer & target) const
307  {
308  WeightContainer weights;
309  sourceToTarget(source,target,weights);
310  }
311 
320  void sourceToTarget(indexType source, IndexContainer & target, WeightContainer & weights) const;
321 
328  void targetToSource(IndexContainer const & target, IndexContainer & source) const
329  {
330  source.clear();
331  IndexContainer res_i;
332  for(size_t i = 0;i<target.size();i++)
333  {
334  //just call targetToSource for single bfs for all given targets
335  targetToSource(target[i],res_i);
336  source.insert(source.end(), res_i.begin(), res_i.end());
337  }
338  //get rid of duplicates and sort them
339  sort( source.begin(), source.end() );
340  source.erase( unique( source.begin(), source.end() ), source.end() );
341  }
342 
349  void targetToSource(indexType target, IndexContainer & source) const
350  {
351  WeightContainer weights;
352  targetToSource(target,source,weights);
353  }
354 
362  void targetToSource(indexType target, IndexContainer & source, WeightContainer & weights) const;
363 
365  // functions for fast access to the mapping data
367 public:
375  enum optimizeFlags
376  {
377  optSourceToTarget = 1U<<0,
378  optTargetToSource = 1U<<1
379  };
380 
393  void optimize (size_t flags=optSourceToTarget) const
394  {
395  flags|= flags & optTargetToSource ? optSourceToTarget : 0;
396  flags = flags & ~getOptimizationFlags();
397  if(flags & optSourceToTarget)
398  {
399  m_matrix.prune(1,T(10)*std::numeric_limits<weightType>::epsilon());
400  m_matrix.makeCompressed();
401  }
402  if(flags & optTargetToSource)
403  {
404  this->m_optimizationMatrix=new GToLMatrix();
405  *m_optimizationMatrix=m_matrix;
406  m_optimizationMatrix->prune(1,T(10)*std::numeric_limits<weightType>::epsilon());
407  m_optimizationMatrix->makeCompressed();
408  }
409  }
410 
412  size_t getOptimizationFlags() const
413  {
414  size_t flags=0;
415  flags |= m_matrix.isCompressed() ? optSourceToTarget : 0;
416  flags |= m_optimizationMatrix ? optTargetToSource : 0;
417  return flags;
418  }
419 
426  Iterator fastTargetToSource(indexType target) const
427  {
428  GISMO_ASSERT(m_optimizationMatrix,"optimize() must be called on the mapper with fastTargetToSource flag before using this function.");
429  GISMO_ASSERT(target<m_matrix.cols() && 0<=target,"index out of bounds");
430  return Iterator(*m_optimizationMatrix,target);
431  }
439  Iterator fastSourceToTarget(indexType source) const
440  {
441  GISMO_ASSERT(m_matrix.isCompressed(),"optimize() must be called on the mapper with fastSourceToTarget flag before using this function.");
442  GISMO_ASSERT(source<m_matrix.rows() && 0<=source,"index "<<source<<" out of bounds (matrix.rows() = "<<m_matrix.rows());
443  return Iterator(m_matrix,source);
444  }
445 
446 
453  void fastSourceToTarget(IndexContainer const & source,IndexContainer & target) const;
454 
461  void fastTargetToSource(IndexContainer const & target,IndexContainer & source) const;
462 
463 
471  void getLocalMap (IndexContainer const & source, IndexContainer const & target, gsMatrix<T> &map) const;
472 
479  void getLocalMap (IndexContainer const & source, gsMatrix<T> &map) const;
480 
481 
482 private:
483  void removeOptimization() {if(m_optimizationMatrix) delete m_optimizationMatrix; m_optimizationMatrix=NULL;}
484  mutable GToLMatrix *m_optimizationMatrix;
485  mutable LToGMatrix m_matrix;
486 };//gsWeightMapper
487 
488 }//namespace gismo
489 
490 #ifndef GISMO_BUILD_LIB
491 #include GISMO_HPP_HEADER(gsWeightMapper.hpp)
492 #endif
Iterator end() const
end
Definition: gsWeightMapper.h:112
#define index_t
Definition: gsConfig.h:32
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
Handles shared library creation and other class attributes.
Sparse matrix class, based on gsEigen::SparseMatrix.
Definition: gsSparseMatrix.h:140
Iterator begin() const
end
Definition: gsWeightMapper.h:117
EIGEN_STRONG_INLINE mult_expr< E1, E2 > const operator*(_expr< E1 > const &u, _expr< E2 > const &v)
Multiplication operator for expressions.
Definition: gsExpressions.h:4561
const weightType & weight() const
weight
Definition: gsWeightMapper.h:102
const indexType & index() const
index
Definition: gsWeightMapper.h:107
This is the main header file that collects wrappers of Eigen for linear algebra.
The Iterator struct Provides fast read access to the mapper data. The implementation guarantees that ...
Definition: gsWeightMapper.h:55
EIGEN_STRONG_INLINE add_expr< E1, E2 > const operator+(_expr< E1 > const &u, _expr< E2 > const &v)
Addition operator for expressions.
Definition: gsExpressions.h:4609