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