1 /** @file gsAffineFunction.hpp
2
3 @brief Implements an affine function.
4
5 This file is part of the G+Smo library.
6
7 This Source Code Form is subject to the terms of the Mozilla Public
8 License, v. 2.0. If a copy of the MPL was not distributed with this
9 file, You can obtain one at http://mozilla.org/MPL/2.0/.
10
11 Author(s): A. Bressan
12 Created on: 2014-11-27
13 */
14
15 namespace gismo {
16
17 template <typename T>
gsAffineFunction(const gsVector<index_t> & dir,const gsVector<bool> & o,const gsMatrix<T> & box1,const gsMatrix<T> & box2)18 gsAffineFunction<T>::gsAffineFunction(const gsVector<index_t> &dir, const gsVector<bool> &o, const gsMatrix<T> &box1, const gsMatrix<T> &box2)
19 {
20 GISMO_ASSERT(box1.rows()==box2.rows(),
21 "The two boxes must be subset of Rn for the same n (same number of rows)");
22 GISMO_ASSERT(box1.cols()==2 && 2==box2.cols(),
23 "The two boxes must be described by the lower and upper corner, the matrices must have two columns");
24
25 const index_t dim = box1.rows();
26 const gsVector<T> size1 = box1.col(1) - box1.col(0);
27 const gsVector<T> size2 = box2.col(1) - box2.col(0);
28 m_mat.setZero(dim,dim);
29 m_trans.resize(dim);
30 for (index_t i=0; i<dim; ++i)
31 {
32 const T ratio = size1[i]==0 ? T(1) : size2(dir[i])/size1[i];
33 m_mat(dir(i),i) = o[i] ? ratio : -ratio;
34 m_trans(dir(i)) = o[i] ? box2(dir[i],0) : box2(dir[i],1);
35 }
36 m_trans -= m_mat * box1.col(0);
37 }
38
39
40 template <typename T>
gsAffineFunction(const gsMatrix<T> mat,const gsVector<T> trans)41 gsAffineFunction<T>::gsAffineFunction(const gsMatrix<T> mat, const gsVector<T> trans)
42 : m_mat(mat), m_trans(trans)
43 {
44 GISMO_ASSERT(m_mat.rows()==m_trans.rows(),
45 "Incompatible linear map and translation in affine map");
46 }
47
48 template <typename T>
domainDim() const49 short_t gsAffineFunction<T>::domainDim() const
50 {
51 return m_mat.cols();
52 }
53
54 template <typename T>
targetDim() const55 short_t gsAffineFunction<T>::targetDim() const
56 {
57 return m_mat.rows();
58 }
59
60 template <typename T>
eval_into(const gsMatrix<T> & u,gsMatrix<T> & result) const61 void gsAffineFunction<T>::eval_into(const gsMatrix<T>& u, gsMatrix<T>& result) const
62 {
63 result = (m_mat*u).colwise()+m_trans;
64 }
65
66 template <typename T>
eval_component_into(const gsMatrix<T> & u,const index_t comp,gsMatrix<T> & result) const67 void gsAffineFunction<T>::eval_component_into(const gsMatrix<T>& u,
68 const index_t comp,
69 gsMatrix<T>& result) const
70 {
71 gsMatrix<T> temp;
72 eval_into(u,temp);
73 result=temp.row(comp);
74 }
75
76 template <typename T>
deriv_into(const gsMatrix<T> & u,gsMatrix<T> & result) const77 void gsAffineFunction<T>::deriv_into(const gsMatrix<T>& u, gsMatrix<T>& result) const
78 {
79 result.resize(m_mat.rows()* m_mat.cols(), u.cols());
80 if (!u.cols())
81 {
82 return;
83 }
84 for (index_t col=0;col<m_mat.cols();++col)
85 {
86 result.block(m_mat.rows()*col,0,m_mat.rows(),1)=m_mat.col(col);
87 }
88 for (index_t col=1; col<result.cols();++col)
89 {
90 result.col(col)=result.col(0);
91 }
92 }
93
94 template <typename T>
deriv2_into(const gsMatrix<T> & u,gsMatrix<T> & result) const95 void gsAffineFunction<T>::deriv2_into( const gsMatrix<T>& u, gsMatrix<T>& result ) const
96 {
97 const index_t rows = domainDim()*domainDim()*targetDim();
98 result.setZero(rows,u.cols());
99 }
100
101
102
103 } // namespace gismo
104