vnl_real_npolynomial.cxx
Go to the documentation of this file.
1 // This is core/vnl/vnl_real_npolynomial.cxx
2 //:
3 // \file
4 // \brief a degree n real polynomial
5 // \author Marc Pollefeys, ESAT-VISICS, K.U.Leuven, 12-08-97
6 //
7 // Implements a polynomial with N variables
8 
9 #include <iostream>
10 #include <sstream>
11 #include <cassert>
12 #include "vnl_real_npolynomial.h"
13 
14 //: Constructor
15 // \verbatim
16 // coeffs = vnl_vector<double>(nterms)
17 // polyn = vnl_matrix<int>(nterms,nvar)
18 // Example: A*x^3 + B*x*y + C*y^2 + D*x*y^2
19 // nvar = 2;
20 // nterms = 4;
21 // coeffs = [A B C D]';
22 // polyn = [3 0]
23 // [1 1]
24 // [0 2]
25 // [1 2];
26 // \endverbatim
27 
29  : coeffs_(c)
30  , polyn_(p)
31  , nvar_(p.cols())
32  , nterms_(p.rows())
33  , ideg_(p.max_value())
34 {
35  assert(c.size() == p.rows());
36  simplify();
37 }
38 
39 //: Combine terms with identical exponents (i.e., identical rows in polyn_).
40 // Remove terms with zero coefficient, also at the end of the vector.
42 {
43  for (unsigned int row1=0; row1<nterms_; ++row1)
44  for (unsigned int row2=row1+1; row2<nterms_; ++row2) {
45  unsigned int col=0;
46  while (col<nvar_ && polyn_(row1,col) == polyn_(row2,col)) ++col;
47  if (col < nvar_) continue; // not all exponents are identical
48  coeffs_(row1) += coeffs_(row2); coeffs_(row2) = 0;
49  }
50  while (nterms_ > 0 && coeffs_(nterms_-1)==0) --nterms_;
51  for (unsigned int row=0; row<nterms_; ++row)
52  if (coeffs_(row) == 0) {
53  --nterms_; // decrement nterms, and move last element to vacant place:
54  coeffs_(row) = coeffs_(nterms_);
55  for (unsigned int i=0; i<nvar_; ++i)
56  polyn_(row,i) = polyn_(nterms_,i);
57  }
58  // Now physically remove those rows that became "invisible":
59  if (nterms_ < polyn_.rows())
60  this->set(coeffs_.extract(nterms_), polyn_.extract(nterms_,nvar_));
61 }
62 
64 {
65  double s=0;
66  for (unsigned int i=0; i<nterms_; i++){
67  double t=coeffs_(i);
68  for (unsigned int j=0; j<nvar_; j++)
69  t*=xn(j,polyn_(i,j));
70  s+=t;
71  }
72  return s;
73 }
74 
76 {
78 
79  for (unsigned int j=0; j<nvar_; j++){
80  xn(j,0)=1;
81  for (unsigned int i=1; i<ideg_+1; i++)
82  xn(j,i)=xn(j,i-1)*x(j);
83  }
84  return eval(xn);
85 }
86 
87 double vnl_real_npolynomial::deval(const vnl_vector<double>& x, unsigned int var)
88 {
89  return deriv(var).eval(x);
90 }
91 
93 {
95 
96  for (unsigned int j=0; j<nvar_; j++) {
97  dx(j) = deriv(j).eval(x);
98  }
99  return dx;
100 }
101 
103 {
106 
107  for (unsigned int i = 0; i < nterms_; i++) {
108  if (polyn_(i,unk) > 0) {
109  p(i,unk) = p(i,unk) - 1;
110  c(i) = coeffs_(i)*polyn_(i,unk);
111  }
112  else {
113  c(i) = coeffs_(i);
114  }
115  }
116 
117  return vnl_real_npolynomial(c,p);
118 }
119 
121 {
122  coeffs_= c;
123  polyn_ = p;
124  nvar_ = p.cols();
125  nterms_ = p.rows();
126  ideg_ = p.max_value();
127 }
128 
129 unsigned int vnl_real_npolynomial::degree() const
130 {
131  unsigned int d=0;
132  for (unsigned int i=0; i<nterms_; i++)
133  {
134  unsigned int dt=0;
135  for (unsigned int j=0; j<nvar_; j++)
136  dt+=polyn_(i,j);
137  if (dt>d) d=dt;
138  }
139  return d;
140 }
141 
142 std::vector<unsigned int> vnl_real_npolynomial::degrees() const
143 {
144  std::vector<unsigned int> d(nvar_);
145  for (unsigned int j=0; j<nvar_; ++j)
146  {
147  d[j]=0;
148  for (unsigned int i=0; i<nterms_; ++i)
149  if (polyn_(i,j)>d[j]) d[j]=polyn_(i,j);
150  }
151  return d;
152 }
153 
155 {
157  for (unsigned int i=0; i<nterms_; ++i) coef(i) = - coeffs_(i);
158 
160 
161  return vnl_real_npolynomial(coef, poly);
162 }
163 
165 {
166  assert(nvar_ == P.nvar_); // both polynomials must have the same variables
167 
169  unsigned int i = 0; for (; i<nterms_; ++i) coef(i) = coeffs_(i);
170  for (unsigned int j=0; j<P.nterms_; ++i,++j) coef(i) = P.coeffs_(j);
171 
173  for (i=0; i<nterms_; ++i)
174  for (unsigned int k=0; k<nvar_; ++k)
175  poly(i,k) = polyn_(i,k);
176  for (unsigned int j=0; j<P.nterms_; ++i,++j)
177  for (unsigned int k=0; k<nvar_; ++k)
178  poly(i,k) = P.polyn_(j,k);
179 
180  return vnl_real_npolynomial(coef, poly);
181 }
182 
184 {
185  vnl_vector<double> coef(nterms_+1);
186  for (unsigned int i=0; i<nterms_; ++i)
187  coef(i) = coeffs_(i);
188  coef(nterms_) = P;
189 
191  for (unsigned int i=0; i<nterms_; ++i)
192  for (unsigned int k=0; k<nvar_; ++k)
193  poly(i,k) = polyn_(i,k);
194  for (unsigned int k=0; k<nvar_; ++k)
195  poly(nterms_,k) = 0;
196 
197  return vnl_real_npolynomial(coef, poly);
198 }
199 
201 {
202  assert(nvar_ == P.nvar_); // both polynomials must have the same variables
203 
205  unsigned int i = 0; for (; i<nterms_; ++i) coef(i) = coeffs_(i);
206  for (unsigned int j=0; j<P.nterms_; ++i,++j) coef(i) = - P.coeffs_(j);
207 
209  for (i=0; i<nterms_; ++i)
210  for (unsigned int k=0; k<nvar_; ++k)
211  poly(i,k) = polyn_(i,k);
212  for (unsigned int j=0; j<P.nterms_; ++i,++j)
213  for (unsigned int k=0; k<nvar_; ++k)
214  poly(i,k) = P.polyn_(j,k);
215 
216  return vnl_real_npolynomial(coef, poly);
217 }
218 
220 {
221  assert(nvar_ == P.nvar_); // both polynomials must have the same variables
222 
224  unsigned int k = 0;
225  for (unsigned int i=0; i<nterms_; ++i)
226  for (unsigned int j=0; j<P.nterms_; ++j,++k)
227  coef(k) = coeffs_(i) * P.coeffs_(j);
228 
230  k = 0;
231  for (unsigned int i=0; i<nterms_; ++i)
232  for (unsigned int j=0; j<P.nterms_; ++j,++k)
233  for (unsigned int l=0; l<nvar_; ++l)
234  poly(k,l) = polyn_(i,l) + P.polyn_(j,l);
235 
236  return vnl_real_npolynomial(coef, poly);
237 }
238 
240 {
242  for (unsigned int i=0; i<nterms_; ++i)
243  coef(i) = coeffs_(i) * P;
244 
246 
247  return vnl_real_npolynomial(coef, poly);
248 }
249 
250 std::ostream& operator<<(std::ostream& os, vnl_real_npolynomial const& P)
251 {
252  return os << P.asString() << std::endl;
253 }
255  *this = (*this) + rhs;
256  return *this;
257 }
259  *this = (*this) - rhs;
260  return *this;
261 }
263  *this = (*this) * rhs;
264  return *this;
265 }
267 {
268  std::ostringstream os;
269  if (nvar_ <= 3)
270  for (unsigned int i=0; i<nterms_; ++i)
271  {
272  if (i>0) os << ' ';
273  if (i>0 && coeffs_(i) >= 0) os << "+ ";
274  double abs_coef = coeffs_(i);
275  if (coeffs_(i) < 0) { abs_coef = -abs_coef; os << "- "; }
276  if (abs_coef != 1) os << abs_coef << ' ';
277  unsigned int totaldeg = 0;
278  if (nvar_ > 0 && polyn_(i,0) > 0) { os << 'X'; totaldeg += polyn_(i,0); }
279  if (nvar_ > 0 && polyn_(i,0) > 1) os << '^' << polyn_(i,0) << ' ';
280  if (nvar_ > 1 && polyn_(i,1) > 0) { os << 'Y'; totaldeg += polyn_(i,1); }
281  if (nvar_ > 1 && polyn_(i,1) > 1) os << '^' << polyn_(i,1) << ' ';
282  if (nvar_ > 2 && polyn_(i,2) > 0) { os << 'Z'; totaldeg += polyn_(i,2); }
283  if (nvar_ > 2 && polyn_(i,2) > 1) os << '^' << polyn_(i,2) << ' ';
284  if (totaldeg == 0 && abs_coef == 1) os << abs_coef;
285  }
286  else
287  for (unsigned int i=0; i<nterms_; ++i)
288  {
289  if (i>0) os << ' ';
290  if (i>0 && coeffs_(i) >= 0) os << "+ ";
291  double abs_coef = coeffs_(i);
292  if (coeffs_(i) < 0) { abs_coef = -abs_coef; os << "- "; }
293  if (abs_coef != 1) os << abs_coef << ' ';
294  unsigned int totaldeg = 0;
295  for (unsigned int j=0; j<nvar_; ++j) {
296  if (polyn_(i,j) > 0) os << 'X' << j;
297  if (polyn_(i,j) > 1) os << '^' << polyn_(i,j) << ' ';
298  totaldeg += polyn_(i,j);
299  }
300  if (totaldeg == 0 && abs_coef == 1) os << abs_coef;
301  }
302  return os.str();
303 }
unsigned int cols() const
Return the number of columns.
Definition: vnl_matrix.h:183
double deval(const vnl_vector< double > &x, unsigned int i)
Evaluate the derivative of the polynomial at x with respect to the ith variable.
unsigned int nterms_
number of terms of polynomial.
unsigned int nvar_
number of variables = # columns of polyn_.
std::string asString() const
Return the textual representation of this polynomial.
vnl_matrix< T > extract(unsigned r, unsigned c, unsigned top=0, unsigned left=0) const
Extract a sub-matrix of size r x c, starting at (top,left).
Definition: vnl_matrix.hxx:728
void set(const vnl_vector< double > &c, const vnl_matrix< unsigned int > &p)
Set vector of coefficients of each product.
size_t size() const
Return the length, number of elements, dimension of this vector.
Definition: vnl_vector.h:126
vnl_real_npolynomial operator *(vnl_real_npolynomial const &) const
vnl_real_npolynomial & operator-=(vnl_real_npolynomial const &rhs)
vnl_real_npolynomial deriv(unsigned int i)
Differentiate the polynomial with respect to the ith variable.
vnl_real_npolynomial & operator *=(vnl_real_npolynomial const &rhs)
std::ostream & operator<<(std::ostream &s, vnl_decnum const &r)
decimal output.
Definition: vnl_decnum.h:393
vnl_vector< T > extract(size_t len, size_t start=0) const
Returns a subvector specified by the start index and length. O(n).
Definition: vnl_vector.hxx:497
T max_value() const
Return maximum value of elements.
Definition: vnl_matrix.h:535
unsigned int degree() const
Return the degree (highest total power of all terms) of the polynomial.
unsigned int ideg_
max. degree of polynomial.
std::vector< unsigned int > degrees() const
Return the degrees (highest power of all terms) in each of the variables.
vnl_real_npolynomial & operator+=(vnl_real_npolynomial const &rhs)
void simplify()
Combine terms with identical exponents (i.e., identical rows in polyn_).
double eval(const vnl_vector< double > &x)
Evaluate the polynomial at x.
real polynomial in N variables.
vnl_real_npolynomial operator-() const
unsigned int rows() const
Return the number of rows.
Definition: vnl_matrix.h:179
vnl_matrix< unsigned int > polyn_
degrees of every term for every variable.
vnl_vector< double > coeffs_
coefficients.
contains class for polynomials with N variables
vnl_real_npolynomial operator+(vnl_real_npolynomial const &) const