G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsMonomialPoly.h
1#pragma once
2
3#include <gsCore/gsGeometry.h>
4#include <gsPolynomial/gsMonomialBasis.h>
5
6namespace gismo
7{
8
19// replaces appeareances of \a oldStr with \a newStr inside the string
20// \a str
21inline 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
34template<class T>
35class gsMonomialPoly : public gsGeoTraits<1,T>::GeometryBase
36{
37public:
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
172protected:
173
174 void set_str(const std::string & str, std::string var = "x");
175};
176
177template<class T>
178void 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 > & coefs()
Definition gsGeometry.h:340
short_t geoDim() const
Dimension n of the absent physical space.
Definition gsGeometry.h:292
virtual const gsBasis< T > & basis() const =0
Returns a const reference to the basis of the geometry.
gsMatrix< T > m_coefs
Coefficient matrix of size coefsSize() x geoDim()
Definition gsGeometry.h:629
unsigned binomial()
Returns binomial(n,r) as a compile time constant.
Definition gsCombinatorics.h:125
void stringReplace(std::string &str, const std::string &oldStr, const std::string &newStr)
An univariate polynomial in monomial basis.
Definition gsMonomialPoly.h:21
#define index_t
Definition gsConfig.h:32
#define gsWarn
Definition gsDebug.h:50
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Provides declaration of Geometry abstract interface.
The G+Smo namespace, containing all definitions for the library.
S give(S &x)
Definition gsMemory.h:266