G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsMonomialPoly.h
1 #pragma once
2 
3 #include <gsCore/gsGeometry.h>
4 #include <gsPolynomial/gsMonomialBasis.h>
5 
6 namespace gismo
7 {
8 
19 // replaces appeareances of \a oldStr with \a newStr inside the string
20 // \a str
21 inline void stringReplace(std::string& str,
22  const std::string& oldStr,
23  const std::string& newStr)
24 {
25  size_t pos = 0;
26  while((pos = str.find(oldStr, pos)) != std::string::npos)
27  {
28  str.replace(pos, oldStr.length(), newStr);
29  pos += newStr.length();
30  }
31 }
32 
33 
34 template<class T>
35 class gsMonomialPoly : public gsGeoTraits<1,T>::GeometryBase
36 {
37 public:
38  typedef gsMonomialBasis<T> Basis;
39 
40  typedef typename gsGeoTraits<1,T>::GeometryBase Base;
41 
43  typedef memory::shared_ptr< gsMonomialPoly > Ptr;
44 
46  typedef memory::unique_ptr< gsMonomialPoly > uPtr;
47 
48  using Base::m_coefs;
49 
50  // Default constructor
51  //gsMonomialPoly() {}
52 
55  explicit gsMonomialPoly(const gsMatrix<T> & coefs, int p = -1) :
56  Base(Basis(p==-1?coefs.rows()-1:p), coefs )
57  { }
58 
59  explicit gsMonomialPoly(const std::string & str, std::string var = "x")
60  {this->set_str(str,var);}
61 
63  gsMonomialPoly(const Basis & basis, const gsMatrix<T> & coefs ) :
64  Base( basis, coefs )
65  { }
66 
68  virtual std::ostream &print(std::ostream &os) const
69  {
70  const int p = deg();
71  if (isConstant())
72  {
73  os << "gsMonomialPoly (constant): "<< m_coefs.at(0);
74  return os;
75  }
76  else
77  {
78  os << "gsMonomialPoly (deg="<<p<<"): ";
79  for (index_t i = p; i!=0; --i)
80  {
81  if ( 0 != m_coefs.at(i) )
82  {
83  if (i!=p) os << (m_coefs.at(i) > 0 ? "+" : "-");
84  const T a = math::abs(m_coefs.at(i));
85  if (1!=a) os << a <<"*";
86  if (1!=i) os<<"x^"<<i; else os<<"x";
87  }
88  }
89  if ( 0 != m_coefs.at(0) )
90  os <<(m_coefs.at(0)>0?"+":"")<<m_coefs.at(0);
91  return os;
92  }
93  }
94 
95  GISMO_BASIS_ACCESSORS
96 
97  GISMO_CLONE_FUNCTION(gsMonomialPoly)
98 
99  int deg() const { return basis().deg();}
100 
102  bool isNull() const
103  {
104  return (m_coefs.array() == 0).all();
105  }
106 
108  bool isConstant() const
109  {
110  return (m_coefs.bottomRows(deg()).array() == 0).all();
111  }
112 
114  bool isMonic() const
115  {
116  return (1 == leadCoeff()).all();
117  }
118 
120  T leadCoeff()
121  {
122  GISMO_ASSERT(1==m_coefs.cols(), "to do");
123  GISMO_ASSERT(!isNull(), "Poly is zero");
124  int lead = deg();// right-most non-zero
125  while ( 0==m_coefs.at(lead) ) --lead;
126  return m_coefs.at(lead);
127  }
128 
130  T trailCoeff()
131  {
132  GISMO_ASSERT(1==m_coefs.cols(), "to do");
133  return m_coefs.at(0);
134  }
135 
136 
141  void asBezier(gsBezier<T> & bezier) const // convert functions ?
142  {
143  const int p = this->deg();
144  const int n = this->geoDim();
145  gsBernsteinBasis<T> bbasis(0, 1, p);
146 
147  gsMatrix<T> diff_table(p+1,p+1); // difference table
148  gsMatrix<T> coefs_bezier(bbasis.size(), n);
149 
150  // Loop over the dimension of the coefficients
151  const gsMatrix<T> & coefs = m_coefs;
152  for(index_t j=0; j!=n; j++)
153  {
154  // Load monomial coefficients into the left column and scale them
155  diff_table.col(0)=coefs.col(j);
156  for(int i=1; i<=p-1; i++)
157  diff_table(i,0) /= binomial(p, i);
158 
159  // Compute difference table backwards
160  for(int column=p-1; column>=0; column--)
161  for(int row=1; row<=p-column; row++)
162  diff_table(column, row)=diff_table(column+1,row-1)+diff_table(column,row-1);
163 
164  // Extract Bernstein coefficients from the the top row
165  coefs_bezier.col(j)=diff_table.row(0).transpose();
166  }
167 
168  // Generate Bernstein polynomial with the computed coefficients
169  bezier = gsBezier<T>(bbasis, give(coefs_bezier));
170  }
171 
172 protected:
173 
174  void set_str(const std::string & str, std::string var = "x");
175 };
176 
177 template<class T>
178 void gsMonomialPoly<T>::set_str(const std::string & str, std::string var)
179 {
180  // step 1. Normalize
181  std::string poly(" ");
182  for ( std::string::const_iterator it=str.begin(); it!=str.end(); ++it)
183  {
184  if (*it==var[0]) // var=char..
185  {
186  if (*poly.rbegin() != '*' ) poly += "1*";
187  poly += "x";
188  if ( (it+1==str.end() || *(it+1)!='^') ) poly += "^1";
189  }
190  else if (*it=='+') poly += " ";
191  else if (*it=='-') poly += " -";
192  else if (*it!=' ') poly += *it;
193  }
194 
195  // step 2. Read in
196  std::string t;
197  std::istringstream term, in(poly);
198  T cf;
199  std::vector<T> vcf(1,0);
200  unsigned ex;
201  std::vector<unsigned> vex(1,0);
202 
203  while (in >> t)
204  {
205  //gsInfo << "|"<< t <<"|\n";
206  if (t.find("x")!=std::string::npos)
207  {
208  stringReplace(t, "*x^", " ");
209  term.clear();term.str(t);
210  if (!gsGetValue(term, cf)) gsWarn<<"Error parsing coefficient.\n";
211  if (!gsGetInt (term, ex)) gsWarn<<"Error parsing exponent.\n";
212  vcf.push_back(cf);
213  vex.push_back(ex);
214  }
215  else
216  {
217  term.clear();term.str(t);
218  if (!gsGetValue(term, cf)) gsWarn<<"Error parsing constant coefficient.\n";
219  vcf.push_back(cf);
220  vex.push_back(0);
221  }
222  }
223 
224  // step 3. Write polynomial coefficients
225  GISMO_ASSERT(NULL==this->m_basis, "to do");
226  this->m_basis = new Basis(*std::max_element(vex.begin(), vex.end()));
227  m_coefs.setZero(deg()+1, 1);
228  for (size_t i = 0; i!= vex.size(); ++i)
229  m_coefs.at( vex[i] ) += vcf[i];
230 }
231 
232 } // namespace gismo
gsMatrix< T > m_coefs
Coefficient matrix of size coefsSize() x geoDim()
Definition: gsGeometry.h:624
Z binomial(const Z n, const Z r)
Computes the binomial expansion coefficient binomial(n,r)
Definition: gsCombinatorics.h:69
S give(S &x)
Definition: gsMemory.h:266
Provides declaration of Geometry abstract interface.
#define index_t
Definition: gsConfig.h:32
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
T at(index_t i) const
Returns the i-th element of the vectorization of the matrix.
Definition: gsMatrix.h:211
void stringReplace(std::string &str, const std::string &oldStr, const std::string &newStr)
An univariate polynomial in monomial basis.
Definition: gsMonomialPoly.h:21
#define gsWarn
Definition: gsDebug.h:50
EIGEN_STRONG_INLINE abs_expr< E > abs(const E &u)
Absolute value.
Definition: gsExpressions.h:4486
virtual const gsBasis< T > & basis() const =0
Returns a const reference to the basis of the geometry.
short_t geoDim() const
Dimension n of the absent physical space.
Definition: gsGeometry.h:292
gsMatrix< T > & coefs()
Definition: gsGeometry.h:340