G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsKroneckerOp.hpp
Go to the documentation of this file.
1
14namespace gismo
15{
16
18template <typename T>
19void gsKroneckerOp<T>::apply(const std::vector<typename gsLinearOperator<T>::Ptr> & ops, const gsMatrix<T> & input, gsMatrix<T> & x)
20{
21 GISMO_ASSERT( !ops.empty(), "Zero-term Kronecker product" );
22 const index_t nrOps = ops.size();
23
24 if (nrOps == 1) // deal with single-operator case efficiently
25 {
26 ops[0]->apply(input, x);
27 return;
28 }
29
30 //index_t rows = 1; // we don't compute rows as we do not need it
31 index_t sz = 1;
32
33 for (index_t i = 0; i < nrOps; ++i)
34 {
35 //rows *= ops[i]->rows();
36 sz *= ops[i]->cols();
37 }
38
39 GISMO_ASSERT (sz == input.rows(), "The input matrix has wrong size.");
40 const index_t n = input.cols();
41
42 // Note: algorithm relies on col-major matrices
43 gsMatrix<T, Dynamic, Dynamic, ColMajor> q0, q1;
44 gsMatrix<T> temp;
45
46 // size: sz x n
47 q0 = input;
48
49 for (index_t i = nrOps - 1; i >= 0; --i)
50 {
51
52 const index_t cols_i = ops[i]->cols();
53 const index_t rows_i = ops[i]->rows();
54 const index_t r_i = sz / cols_i;
55
56 // Re-order right-hand sides
57 q0.resize(cols_i, n * r_i);
58
59 // Apply operator
60 ops[i]->apply(q0, temp);
61 GISMO_ASSERT (temp.rows() == rows_i && temp.cols() == n * r_i, "The linear operator returned a matrix with unexpected size.");
62
63 // Transpose solution component-wise
64 if (n == 1)
65 q1 = temp.transpose();
66 else
67 {
68 q1.resize(r_i, n * rows_i);
69 for (index_t k = 0; k != n; ++k)
70 q1.middleCols(k*rows_i, rows_i) = temp.middleCols(k*r_i, r_i).transpose();
71 }
72
73 q1.swap( q0 ); // move solution as next right-hand side
74 sz = ( sz / cols_i) * rows_i; // update now the dimensionality such that in the end sz = rows
75 //sz % cols_i == 0, since sz *= ops[i]->cols();
76 }
77
78 //GISMO_ASSERT (sz == rows, "Internal error."); // see one above
79
80 q0.resize(sz, n);
81 x.swap( q0 );
82}
84
85template <typename T>
86void gsKroneckerOp<T>::apply(const gsMatrix<T> & input, gsMatrix<T> & x) const
87{
88 apply(m_ops, input, x);
89}
90
91template <typename T>
93{
94 index_t rows = 1;
95 for (size_t i = 0; i < m_ops.size(); ++i)
96 rows *= m_ops[i]->rows();
97 return rows;
98}
99
100template <typename T>
102{
103 index_t cols = 1;
104 for (size_t i = 0; i < m_ops.size(); ++i)
105 cols *= m_ops[i]->cols();
106 return cols;
107}
108
109
110}
virtual index_t rows() const
Returns the number of rows of the operator.
Definition gsKroneckerOp.hpp:92
virtual void apply(const gsMatrix< T > &input, gsMatrix< T > &x) const
apply the operator on the input vector and store the result in x
Definition gsKroneckerOp.hpp:86
virtual index_t cols() const
Returns the number of columns of the operator.
Definition gsKroneckerOp.hpp:101
memory::shared_ptr< gsLinearOperator > Ptr
Shared pointer for gsLinearOperator.
Definition gsLinearOperator.h:33
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
#define index_t
Definition gsConfig.h:32
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
The G+Smo namespace, containing all definitions for the library.