G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsTensorTools.h
Go to the documentation of this file.
1
14#pragma once
15
17
20
21namespace gismo
22{
23
26template <int d>
28{
29 int result = 0;
30 unsigned stride = 1;
31 for (index_t i = 0; i < idx.size(); ++i)
32 {
33 result += stride * idx[i];
34 stride *= sz[i];
35 }
36 return result;
37}
38
49template <short_t d, typename T>
53{
54 typedef typename gsSparseMatrix<T,RowMajor>::iterator InnerIt;
55 gsSparseEntries<T> entries;
56 gsVector<unsigned, d> oldSize, newSize, v, v_old;
57
58 for (unsigned i = 0; i < d; ++i)
59 {
60 oldSize[i] = static_cast<unsigned>(B[i].innerSize());
61 newSize[i] = static_cast<unsigned>(B[i].outerSize());
62 }
63
64 std::vector<InnerIt> it(d);
65
66 // iterate over all new tensor indices
67 v.setZero();
68 index_t newIdx = 0;
69 do {
70 // set up iterators over component contributions
71 for (unsigned i = 0; i < d; ++i)
72 it[i] = B[i].begin(v[i]);
73
74 // iterate over the component contributions
75 bool more;
76 do {
77 // get the old tensor index
78 T contrib = (T)(1);
79 for (unsigned i = 0; i < d; ++i)
80 {
81 contrib *= it[i].value();
82 v_old[i] = it[i].index();
83 }
84
85 const index_t oldIdx = fromTensorIndex<d>(v_old, oldSize);
86 entries.add( newIdx, oldIdx, contrib );
87
88 // advance iterators
89 more = true;
90 for (unsigned i = 0; i < d; ++i)
91 {
92 ++it[i]; // increase current dimension
93 if (it[i]) // current dimension not yet exhausted?
94 break;
95 else // current dimension exhausted
96 {
97 if (i == d - 1) // was it the last one?
98 more = false; // then all elements exhausted
99 else
100 it[i] = B[i].begin(v[i]); // otherwise, reset this to start and increase the next dimension
101 }
102 }
103 } while (more);
104 } while (++newIdx, nextLexicographic(v, newSize));
105
106 GISMO_ASSERT( newIdx == (index_t) newSize.prod(), "Iteration did not complete as expected." );
107
108 transfer.resize( newSize.prod(), oldSize.prod() );
109 transfer.setFrom( entries );
110 transfer.makeCompressed();
111}
112
114template<typename VectIn, typename VectOut> inline
115void tensorStrides(const VectIn & sz, VectOut & strides)
116{
117 strides.derived().resize(sz.size());
118 strides[0] = 1;
119 for ( index_t i=1; i != sz.size(); ++i )
120 strides[i] = strides[i-1] * sz[i-1];
121}
122
128template <typename T, int d>
129void swapTensorDirection( int k1, int k2,
131 gsMatrix<T> & coefs)
132{
133 GISMO_ASSERT( sz.prod() == coefs.rows(),
134 "Input error, sizes do not match: "<<sz.prod()<<"!="<< coefs.rows() );
135 GISMO_ASSERT( k1<d && k2 < d && k1>=0 && k2>=0,
136 "Invalid directions: "<< k1 <<", "<< k2 );
137
138 if ( k1 == k2 )
139 return; //Nothing to do
140
141 /*
142 gsVector<int,d> perm = gsVector<int,d>::LinSpaced(d,0,d-1);
143 std::swap(perm[k1],perm[k2] );
144 permuteTensorVector(perm,sz,coefs);
145 return;
146 */
147
148 gsGridIterator<index_t,CUBE,d> it(sz);
149
150 std::swap( sz[k1], sz[k2] );
151 gsVector<index_t,d> perstr;
152 tensorStrides(sz, perstr);
153 std::swap(perstr[k1], perstr[k2] );
154
155 gsMatrix<T> tmp(coefs.rows(), coefs.cols() );
156
157 for(index_t r=0; it; ++it, ++r)
158 tmp.row(perstr.dot(*it)) = coefs.row(r);
159
160 coefs.swap(tmp);
161}
162
168template <typename T, int d>
171 gsMatrix<T> & coefs)
172{
173 GISMO_ASSERT( sz.prod() == coefs.rows(),
174 "Input error, sizes do not match: "<<sz.prod()<<"!="<< coefs.rows() );
175 GISMO_ASSERT( perm.sum() == sz.size()*(sz.size()-1)/2,
176 "Error in the permutation: "<< perm.transpose());
177
178 if ( perm == gsVector<index_t>::LinSpaced(sz.size(),0,sz.size()-1) )
179 return; //Nothing to do
180
181 typename gsVector<index_t>::PermutationWrap P(perm);
182 gsGridIterator<index_t,CUBE,d> it(sz);
183
184 sz = P * sz;
185 gsVector<index_t,d> perstr;
186 tensorStrides(sz, perstr);
187 perstr = P * perstr;
188
189 // check: is it better to create a big permutation to apply to coefs ?
190 gsMatrix<T> tmp(coefs.rows(), coefs.cols() );
191
192 for(index_t r=0; it; ++it, ++r)
193 tmp.row(perstr.dot(*it)) = coefs.row(r);
194
195 coefs.swap(tmp);
196}
197
200template <typename T, int d>
201void flipTensorVector(const int dir,
202 const gsVector<index_t,d> & sz,
203 gsMatrix<T> & coefs)
204{
205 GISMO_ASSERT( sz.prod() == coefs.rows(),
206 "Input error, sizes do not match: "<<sz.prod()<<"!="<< coefs.rows() );
207
208 gsVector<index_t,d> perstr = sz;
209 perstr[dir] /= 2;
210 gsGridIterator<index_t,CUBE,d> it(perstr);
211 tensorStrides(sz, perstr);//reuse
212 const index_t cc = sz[dir] - 1;
213
214 for(; it; ++it)
215 {
216 const index_t i1 = perstr.dot(*it);
217 const index_t i2 = i1 + (cc - 2 * it->at(dir)) * perstr[dir];
218 coefs.row( i1 ).swap( coefs.row( i2 ) );
219 }
220}
221
222} // namespace gismo
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
Class that provides a container for triplets (i,j,value) to be filled in a sparse matrix.
Definition gsSparseMatrix.h:34
Iterator over the non-zero entries of a sparse matrix.
Definition gsSparseMatrix.h:74
Sparse matrix class, based on gsEigen::SparseMatrix.
Definition gsSparseMatrix.h:139
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
void tensorCombineTransferMatrices(gsSparseMatrix< T, RowMajor > B[d], gsSparseMatrix< T, RowMajor > &transfer)
Combine component-wise transfer matrices into a transfer matrix for the tensor product basis.
Definition gsTensorTools.h:50
void swapTensorDirection(int k1, int k2, gsVector< index_t, d > &sz, gsMatrix< T > &coefs)
Definition gsTensorTools.h:129
void flipTensorVector(const int dir, const gsVector< index_t, d > &sz, gsMatrix< T > &coefs)
Flips tensor directions in place.
Definition gsTensorTools.h:201
void permuteTensorVector(const gsVector< index_t, d > &perm, gsVector< index_t, d > &sz, gsMatrix< T > &coefs)
Definition gsTensorTools.h:169
bool nextLexicographic(Vec &cur, const Vec &size)
Iterates through a tensor lattice with the given size. Updates cur and returns true if another entry ...
Definition gsCombinatorics.h:196
Provides combinatorial unitilies.
#define index_t
Definition gsConfig.h:32
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Provides iteration over integer or numeric points in a (hyper-)cube.
This is the main header file that collects wrappers of Eigen for linear algebra.
The G+Smo namespace, containing all definitions for the library.
void tensorStrides(const VectIn &sz, VectOut &strides)
Helper to compute the strides of a d-tensor.
Definition gsTensorTools.h:115
int fromTensorIndex(const gsVector< unsigned, d > &idx, const gsVector< unsigned, d > &sz)
Helper function to compute a lexicographically numbered index from tensor indices.
Definition gsTensorTools.h:27