G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsWeightMapper.h
Go to the documentation of this file.
1
14#pragma once
15
16#include <gsCore/gsExport.h>
18
19namespace gismo
20{
21
22template<class T>
23class gsWeightMapper
24{
25public:
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;
37public:
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
126public:
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
208public:
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
248public:
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
275public:
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
367public:
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
482private:
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
Sparse matrix class, based on gsEigen::SparseMatrix.
Definition gsSparseMatrix.h:139
#define index_t
Definition gsConfig.h:32
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Handles shared library creation and other class attributes.
This is the main header file that collects wrappers of Eigen for linear algebra.
EIGEN_STRONG_INLINE mult_expr< E1, E2 > const operator*(_expr< E1 > const &u, _expr< E2 > const &v)
Multiplication operator for expressions.
Definition gsExpressions.h:4559
The G+Smo namespace, containing all definitions for the library.
The Iterator struct Provides fast read access to the mapper data. The implementation guarantees that ...
Definition gsWeightMapper.h:56
Iterator begin() const
end
Definition gsWeightMapper.h:117
Iterator end() const
end
Definition gsWeightMapper.h:112
const weightType & weight() const
weight
Definition gsWeightMapper.h:102
const indexType & index() const
index
Definition gsWeightMapper.h:107