SLIP  1.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MultivariatePolynomial.hpp
Go to the documentation of this file.
1 /*
2  * Copyright(c):
3  * Signal Image and Communications (SIC) Department
4  * http://www.sic.sp2mi.univ-poitiers.fr/
5  * - University of Poitiers, France http://www.univ-poitiers.fr
6  * - XLIM Institute UMR CNRS 7252 http://www.xlim.fr/
7  *
8  * and
9  *
10  * D2 Fluid, Thermic and Combustion
11  * - University of Poitiers, France http://www.univ-poitiers.fr
12  * - PPRIME Institute - UPR CNRS 3346 http://www.pprime.fr
13  * - ISAE-ENSMA http://www.ensma.fr
14  *
15  * Contributor(s):
16  * The SLIP team,
17  * Benoit Tremblais <tremblais_AT_sic.univ-poitiers.fr>,
18  * Laurent David <laurent.david_AT_lea.univ-poitiers.fr>,
19  * Ludovic Chatellier <ludovic.chatellier_AT_univ-poitiers.fr>,
20  * Lionel Thomas <lionel.thomas_AT_univ-poitiers.fr>,
21  * Denis Arrivault <arrivault_AT_sic.univ-poitiers.fr>,
22  * Julien Dombre <julien.dombre_AT_univ-poitiers.fr>.
23  *
24  * Description:
25  * The Simple Library of Image Processing (SLIP) is a new image processing
26  * library. It is written in the C++ language following as much as possible
27  * the ISO/ANSI C++ standard. It is consequently compatible with any system
28  * satisfying the ANSI C++ complience. It works on different Unix , Linux ,
29  * Mircrosoft Windows and Mac OS X plateforms. SLIP is a research library that
30  * was created by the Signal, Image and Communications (SIC) departement of
31  * the XLIM, UMR 7252 CNRS Institute in collaboration with the Fluids, Thermic
32  * and Combustion departement of the P', UPR 3346 CNRS Institute of the
33  * University of Poitiers.
34  *
35  * The SLIP Library source code has been registered to the APP (French Agency
36  * for the Protection of Programs) by the University of Poitiers and CNRS,
37  * under registration number IDDN.FR.001.300034.000.S.P.2010.000.21000.
38 
39  * http://www.sic.sp2mi.univ-poitiers.fr/slip/
40  *
41  * This software is governed by the CeCILL-C license under French law and
42  * abiding by the rules of distribution of free software. You can use,
43  * modify and/ or redistribute the software under the terms of the CeCILL-C
44  * license as circulated by CEA, CNRS and INRIA at the following URL
45  * http://www.cecill.info.
46  * As a counterpart to the access to the source code and rights to copy,
47  * modify and redistribute granted by the license, users are provided only
48  * with a limited warranty and the software's author, the holder of the
49  * economic rights, and the successive licensors have only limited
50  * liability.
51  *
52  * In this respect, the user's attention is drawn to the risks associated
53  * with loading, using, modifying and/or developing or reproducing the
54  * software by the user in light of its specific status of free software,
55  * that may mean that it is complicated to manipulate, and that also
56  * therefore means that it is reserved for developers and experienced
57  * professionals having in-depth computer knowledge. Users are therefore
58  * encouraged to load and test the software's suitability as regards their
59  * requirements in conditions enabling the security of their systems and/or
60  * data to be ensured and, more generally, to use and operate it in the
61  * same conditions as regards security.
62  *
63  * The fact that you are presently reading this means that you have had
64  * knowledge of the CeCILL-C license and that you accept its terms.
65  */
66 
67 
68 
75 #ifndef SLIP_MULTIVARIATEPOLYNOMIAL_HPP
76 #define SLIP_MULTIVARIATEPOLYNOMIAL_HPP
77 
78 #include <iostream>
79 #include <iterator>
80 #include <cassert>
81 #include <numeric>
82 #include <algorithm>
83 #include <map>
84 #include <cmath>
85 #include <complex>
86 #include <string>
87 #include "Block.hpp"
88 #include "Array2d.hpp"
89 #include "Polynomial.hpp"
90 #include "linear_least_squares.hpp"
91 #include "statistics.hpp"
92 #include "polynomial_algo.hpp"
93 
94 #include <boost/serialization/access.hpp>
95 #include <boost/serialization/split_member.hpp>
96 #include <boost/serialization/complex.hpp>
97 #include <boost/serialization/version.hpp>
98 #include <boost/serialization/base_object.hpp>
99 #include <boost/serialization/map.hpp>
100 
101 namespace slip
102 {
103 template <std::size_t DIM>
104 struct Monomial;
105 
106 template <std::size_t DIM>
107 std::ostream& operator<<(std::ostream & out,
108  const Monomial<DIM>& m);
109 
110 template <std::size_t DIM>
111 bool operator==(const Monomial<DIM>& x,
112  const Monomial<DIM>& y);
113 
114 template <std::size_t DIM>
115 bool operator!=(const Monomial<DIM>& x,
116  const Monomial<DIM>& y);
117 
118 template <std::size_t DIM>
119 bool operator<(const Monomial<DIM>& x,
120  const Monomial<DIM>& y);
121 
122 template <std::size_t DIM>
123 bool operator>(const Monomial<DIM>& x,
124  const Monomial<DIM>& y);
125 
126 template <std::size_t DIM>
128  const Monomial<DIM>& y);
129 
130 
147 template <std::size_t DIM>
148 struct Monomial
149 {
151 
152  std::string name() const {return "Monomial";}
153  std::size_t dim() const {return DIM;}
154  std::size_t degree() const
155  {
156  return std::accumulate(powers.begin(),powers.end(),std::size_t(0));
157  }
158 
159  bool is_a_constant() const
160  {
161  return (std::size_t(std::count(powers.begin(),powers.end(),(unsigned char)(0))) == DIM);
162  }
163 
164 
165 
177  friend bool operator== <>(const Monomial<DIM>& x,
178  const Monomial<DIM>& y);
179 
186  friend bool operator!= <>(const Monomial<DIM>& x,
187  const Monomial<DIM>& y);
188 
189 
197  friend bool operator< <>(const Monomial<DIM>& x,
198  const Monomial<DIM>& y);
199 
206  friend bool operator> <>(const Monomial<DIM>& x,
207  const Monomial<DIM>& y);
208 
212 private:
214  template<class Archive>
215  void save(Archive & ar, const unsigned int version) const
216  {
217  ar & powers;
218  }
219  template<class Archive>
220  void load(Archive & ar, const unsigned int version)
221  {
222  ar & powers;
223  }
224  BOOST_SERIALIZATION_SPLIT_MEMBER()
225 
226 
227 };
228 
229 }//end slip::
230 
231 
232 namespace slip{
233 
245  template<std::size_t DIM>
246  Monomial<DIM> operator*(const Monomial<DIM>& monomial1,
247  const Monomial<DIM>& monomial2);
250 }
252  /* @{ */
253 namespace slip
254 {
255  template <std::size_t DIM>
256  inline
257  std::ostream& operator<<(std::ostream & out,
258  const Monomial<DIM>& m)
259  {
260  if(m.is_a_constant())
261  {
262  }
263  else
264  {
265  for(std::size_t i = 0; i < (m.powers).size(); ++i)
266  out<<"x"<<(i+1)<<"^"<<(int)m.powers[i]<<" ";
267  }
268  return out;
269  }
270 /* @} */
272  /* @{ */
273  template <std::size_t DIM>
274  inline
275  bool operator==(const Monomial<DIM>& x,
276  const Monomial<DIM>& y)
277  {
278  return (x.powers == y.powers);
279  }
280 
281  template <std::size_t DIM>
282  inline
283  bool operator!=(const Monomial<DIM>& x,
284  const Monomial<DIM>& y)
285  {
286  return !(x == y);
287  }
288 
289 /* @} */
290 
292  /* @{ */
293  template <std::size_t DIM>
294  inline
295  bool operator<(const Monomial<DIM>& x,
296  const Monomial<DIM>& y)
297  {
298  return std::lexicographical_compare((x.powers).rbegin(), (x.powers).rend(),
299  (y.powers).rbegin(), (y.powers).rend());
300  //return x.powers < y.powers;
301  }
302 
303 
304  template <std::size_t DIM>
305  inline
306  bool operator>(const Monomial<DIM>& x,
307  const Monomial<DIM>& y)
308  {
309  return (y < x);
310  }
311 
312 /* @} */
313 
314  template<std::size_t DIM>
315  inline
317  const Monomial<DIM>& monomial2)
318  {
319  Monomial<DIM> tmp;
320  std::transform((monomial1.powers).begin(),
321  (monomial1.powers).end(),
322  (monomial2.powers).begin(),
323  (tmp.powers).begin(),
324  std::plus<unsigned char>());
325  return tmp;
326  }
327 
328 }//end slip::
329 namespace slip
330 {
331 
332 template <typename T, std::size_t DIM>
334 
335 template <typename T, std::size_t DIM>
336 std::ostream& operator<<(std::ostream & out,
338 
356 template <typename T, std::size_t DIM>
357 class MultivariatePolynomial:public std::map<slip::Monomial<DIM>,T>
358 {
359 public :
360 
361  typedef std::map<slip::Monomial<DIM>,T> base;
362  typedef typename std::map<slip::Monomial<DIM>,T>::key_type key_type;
363  typedef typename std::map<slip::Monomial<DIM>,T>::mapped_type mapped_type;
364  typedef typename std::map<slip::Monomial<DIM>,T>::value_type value_type;
365  typedef typename std::map<slip::Monomial<DIM>,T>::key_compare key_compare;
366  typedef typename std::map<slip::Monomial<DIM>,T>::value_compare value_compare;
369 
370  typedef typename std::map<slip::Monomial<DIM>,T>::pointer pointer;
371  typedef const typename std::map<slip::Monomial<DIM>,T>::const_pointer const_pointer;
372  typedef typename std::map<slip::Monomial<DIM>,T>::reference reference;
373  typedef typename std::map<slip::Monomial<DIM>,T>::const_reference const_reference;
374 
375  typedef typename std::map<slip::Monomial<DIM>,T>::difference_type difference_type;
376  typedef typename std::map<slip::Monomial<DIM>,T>::size_type size_type;
377 
378  typedef typename std::map<slip::Monomial<DIM>,T>::iterator iterator;
379  typedef typename std::map<slip::Monomial<DIM>,T>::const_iterator const_iterator;
380 
381  typedef typename std::map<slip::Monomial<DIM>,T>::reverse_iterator reverse_iterator;
382  typedef typename std::map<slip::Monomial<DIM>,T>::const_reverse_iterator const_reverse_iterator;
383 
384 
389 
394  base()
395  {
396  slip::Monomial<DIM> constant;
397  constant.powers.fill((unsigned char)0);
398  this->insert(constant,T());
399  }
400 
413  MultivariatePolynomial(const std::size_t degree):
414  base()
415  {
416 
417  this->create(degree);
418  }
419 
437  template<typename InputIterator>
438  MultivariatePolynomial(const std::size_t degree,
439  InputIterator first,
440  InputIterator last):
441  base()
442  {
443  this->create(degree);
444  assert(int(last-first)== int(this->total_nb_coeff()));
445 
446  for(iterator it = this->begin(); it!=this->end();++it)
447  {
448  (*it).second = *first++;
449  }
450  }
451 
458  template<class InputIterator>
459  MultivariatePolynomial(InputIterator first, InputIterator last):
460  base(first,last)
461  {}
462 
463 
464 
468  MultivariatePolynomial(const self& rhs):
469  base(rhs)
470  {}
471 
476  {}
477 
492  friend std::ostream& operator<< <>(std::ostream & out,
493  const self& v);
510  void insert(const slip::Monomial<DIM>& monomial, const T& coefficient);
517 
523  self& operator+=(const T& val);
524  self& operator-=(const T& val);
525  self& operator*=(const T& val);
526  self& operator/=(const T& val);
527 
528  self operator-() const;
529 
530 
531  self& operator+=(const self& rhs);
532  self& operator-=(const self& rhs);
533  self& operator*=(const self& rhs);
534 
535 
536 
543 
552  self derivative(const std::size_t dim) const;
553 
561  void derivative(const std::size_t dim);
562 
563 
573  self derivative(const std::size_t dim,
574  const std::size_t order) const;
575 
584  void derivative(const std::size_t dim,
585  const std::size_t order);
586 
587 
598  self integral(const std::size_t dim,
599  const T& K = T()) const;
600 
610  void integral(const std::size_t dim,
611  const T& K = T());
612 
624  self integral(const std::size_t dim,
625  const std::size_t order,
626  const T& K = T()) const;
627 
628 
639  void integral(const std::size_t dim,
640  const std::size_t order,
641  const T& K = T());
642 
692  template <typename Vector1, typename Vector2>
693  double fit(Vector1 X,
694  Vector2 Y,
695  const std::size_t order)
696  {
697 
698  //input data
699  //computes the number of coefficients estimate
700  slip::Array<std::size_t> V(DIM+order);
701  slip::iota(V.begin(),V.end(),1,1);
702  std::size_t coeff_size = (std::accumulate(V.begin()+order,V.end(),1,std::multiplies<int>()))/(std::accumulate(V.begin(),V.begin()+DIM,1,std::multiplies<int>()));
703 
704  slip::Array<T> Coeff(coeff_size);
705  //output data
706  double chi_square = 0.0;
709  Y,
710  Coeff,
711  order,
712  power_basis);
713  this->create(order);
714  typename slip::MultivariatePolynomial<T,DIM>::iterator it = this->begin();
715  typename slip::Array<T>::const_iterator ita = Coeff.begin();
716  for(;it != this->end();++it,++ita)
717  {
718  (*it).second = *ita;
719  }
720  return chi_square;
721  }
722 
723 
736  template<typename InputIterator>
737  typename std::iterator_traits<InputIterator>::value_type
738  evaluate(InputIterator first,
739  InputIterator last) const
740  {
741  assert((last-first) == DIM);
742  typedef typename slip::MultivariatePolynomial<T,DIM>::const_iterator const_it;
743 
744  typedef typename std::iterator_traits<InputIterator>::value_type Return;
745  slip::Array2d<Return> values(DIM,this->degree()+1);
746 
747  //pre-computation of the variables' powers
748  for(std::size_t i = 0; i < values.rows(); ++i)
749  {
750  slip::eval_power_basis(*first++,this->degree(),values.row_begin(i),values.row_end(i));
751  }
752 
753 
754  Return result = Return();
755  for(const_it first_m = this->begin();first_m!=this->end();++first_m)
756  {
757  Return tmp = values[0][((*first_m).first).powers[0]];
758  for(std::size_t i = 1; i < DIM; ++i)
759  {
760  tmp*=values[i][((*first_m).first).powers[i]];
761  }
762  result+= ((*first_m).second) * tmp;
763  }
764 
765  return result;
766  }
767 
768 
786  MultivariatePolynomial<T,DIM> partial_evaluate(const std::size_t number,
787  const T& val);
788 
789 
798  self compose(const std::vector<self>& VP);
799 
806 
811  std::string name() const;
812 
813 
817  size_type degree() const;
818 
824  size_type order() const;
825 
829  size_type total_nb_coeff() const;
830 
838  template<typename RandomAccessIterator>
839  void all_coeff(RandomAccessIterator first,
840  RandomAccessIterator last) const
841  {
842  typedef typename std::iterator_traits<RandomAccessIterator>::difference_type _Distance;
843  assert((last - first) == _Distance(this->total_nb_coeff()));
844  assert(DIM > 0);
845 
846  //array of all the powers combinations sort by lexicographical order
847 
848  slip::Array2d<std::size_t> powers_a(slip::power(this->order()+1,DIM),DIM);
849  for(std::size_t d = 0; d < powers_a.dim2(); ++d)
850  {
851  std::size_t step = slip::power((this->order()+1),d);
852  for(std::size_t ord = 0, ord2 = 0; ord <= (powers_a.dim1() - step); ord+=step,++ord2)
853  {
854  std::size_t tmp = ord2%(this->order()+1);
855  for(std::size_t k = 0; k < step; ++k)
856  {
857  powers_a[ord+k][d] = tmp;
858  }
859  }
860  }
861 
862  std::map<slip::Monomial<DIM>,T> tmp_map;
863  slip::Array2d<std::size_t> powers_cut(this->total_nb_coeff(),DIM);
864 
865  for(std::size_t ord = 0; ord < powers_a.dim1(); ++ord)
866  {
867  Monomial<DIM> m;
868  std::copy(powers_a.row_begin(ord),powers_a.row_end(ord),(m.powers).begin());
869  if(m.degree() <= this->order())
870  {
871  tmp_map[m] = T();
872  }
873  }
874 
875 
876  typedef typename slip::MultivariatePolynomial<T,DIM>::const_iterator const_it;
877 
878  for(const_it it = this->begin();it!=this->end();++it)
879  {
880  Monomial<DIM> m = (*it).first;
881  T coefficient = (*it).second;
882  tmp_map[m] += coefficient;
883  }
884 
885  for(const_it it = tmp_map.begin(); it!=tmp_map.end();++it)
886  {
887  *first++ = (*it).second;
888  }
889 
890  }
891 
892 
895 private:
900  void create(const std::size_t degree);
901  friend class boost::serialization::access;
902  template<class Archive>
903  void save(Archive & ar, const unsigned int version) const
904  {
905  ar & boost::serialization::base_object<std::map<slip::Monomial<DIM>,T> >(*this);
906  }
907  template<class Archive>
908  void load(Archive & ar, const unsigned int version)
909  {
910  ar & boost::serialization::base_object<std::map<slip::Monomial<DIM>,T> >(*this);
911  }
912  BOOST_SERIALIZATION_SPLIT_MEMBER()
913 };
914 
919 
927 template<typename T, std::size_t DIM>
928 MultivariatePolynomial<T,DIM> operator+(const MultivariatePolynomial<T,DIM>& P1,
929  const MultivariatePolynomial<T,DIM>& P2);
930 
938 template<typename T, std::size_t DIM>
939 MultivariatePolynomial<T,DIM> operator+(const MultivariatePolynomial<T,DIM>& P,
940  const T& val);
941 
949 template<typename T, std::size_t DIM>
950 MultivariatePolynomial<T,DIM> operator+(const T& val,
951  const MultivariatePolynomial<T,DIM>& P);
952 
953 
961 template<typename T, std::size_t DIM>
962 MultivariatePolynomial<T,DIM> operator-(const MultivariatePolynomial<T,DIM>& P1,
963  const MultivariatePolynomial<T,DIM>& P2);
964 
972  template<typename T, std::size_t DIM>
973  MultivariatePolynomial<T,DIM> operator-(const MultivariatePolynomial<T,DIM>& P,
974  const T& val);
975 
983 template<typename T, std::size_t DIM>
984 MultivariatePolynomial<T,DIM> operator-(const T& val,
985  const MultivariatePolynomial<T,DIM>& P);
986 
994 template<typename T, std::size_t DIM>
995 MultivariatePolynomial<T,DIM> operator*(const MultivariatePolynomial<T,DIM>& P1,
996  const MultivariatePolynomial<T,DIM>& P2);
997 
1005 template<typename T, std::size_t DIM>
1006 MultivariatePolynomial<T,DIM> operator*(const MultivariatePolynomial<T,DIM>& P,
1007  const T& val);
1008 
1016 template<typename T, std::size_t DIM>
1017 MultivariatePolynomial<T,DIM> operator*(const T& val,
1018  const MultivariatePolynomial<T,DIM>& P);
1019 
1020 
1028 template<typename T, std::size_t DIM>
1029 MultivariatePolynomial<T,DIM> operator/(const MultivariatePolynomial<T,DIM>& P,
1030  const T& val);
1033 }//slip::
1034 
1035 
1036 
1037 namespace slip
1038 {
1039 
1040  template<typename T, std::size_t DIM>
1041  inline
1042  void
1044  const T& coefficient)
1045  {
1046  if(monomial.is_a_constant())
1047  {
1048  (*this)[monomial] += coefficient;
1049  }
1050  else
1051  {
1052  if(coefficient != T())
1053  {
1054  (*this)[monomial] += coefficient;
1055  }
1056  }
1057 
1058  }
1059 
1060 
1061  template <typename T, std::size_t DIM>
1062  inline
1063  std::ostream& operator<<(std::ostream & out,
1065  {
1067  out.setf(std::ios_base::scientific);
1068  out.setf(std::ios_base::internal);
1069 
1070 
1071  for(;it!=m.end();++it)
1072  {
1073  Monomial<DIM> m = (*it).first;
1074  T coefficient = (*it).second;
1075  if(m.is_a_constant())
1076  {
1077  out<<coefficient<<" ";
1078  }
1079  else
1080  {
1081  if(coefficient >= T(0))
1082  {
1083  out<<"+ "<<coefficient;
1084  }
1085  else
1086  {
1087  out<<"- "<<std::abs(coefficient);
1088  }
1089  out<<" "<<(*it).first<<" ";
1090  }
1091  }
1092  out<<std::endl;
1093  return out;
1094  }
1095 
1096 
1097 template <std::size_t DIM>
1098  inline
1099  std::ostream& operator<<(std::ostream & out,
1100  const MultivariatePolynomial<std::complex<double>,DIM>& m)
1101  {
1102  typename slip::MultivariatePolynomial<std::complex<double>,DIM>::const_iterator it = m.begin();
1103  out.setf(std::ios_base::scientific);
1104  out.setf(std::ios_base::internal);
1105 
1106 
1107  for(;it!=m.end();++it)
1108  {
1109  Monomial<DIM> m = (*it).first;
1110  std::complex<double> coefficient = (*it).second;
1111  if(m.is_a_constant())
1112  {
1113  out<<coefficient<<" ";
1114  }
1115  else
1116  {
1117 
1118  out<<"+ "<<coefficient;
1119  out<<" "<<(*it).first<<" ";
1120  }
1121  }
1122  out<<std::endl;
1123  return out;
1124  }
1125 
1126 
1127  template <std::size_t DIM>
1128  inline
1129  std::ostream& operator<<(std::ostream & out,
1130  const MultivariatePolynomial<std::complex<float>,DIM>& m)
1131  {
1132  typename slip::MultivariatePolynomial<std::complex<float>,DIM>::const_iterator it = m.begin();
1133  out.setf(std::ios_base::scientific);
1134  out.setf(std::ios_base::internal);
1135 
1136 
1137  for(;it!=m.end();++it)
1138  {
1139  Monomial<DIM> m = (*it).first;
1140  std::complex<float> coefficient = (*it).second;
1141  if(m.is_a_constant())
1142  {
1143  out<<coefficient<<" ";
1144  }
1145  else
1146  {
1147 
1148  out<<"+ "<<coefficient;
1149  out<<" "<<(*it).first<<" ";
1150  }
1151  }
1152  out<<std::endl;
1153  return out;
1154  }
1155 
1156  template <std::size_t DIM>
1157  inline
1158  std::ostream& operator<<(std::ostream & out,
1159  const MultivariatePolynomial<std::complex<long double>,DIM>& m)
1160  {
1161  typename slip::MultivariatePolynomial<std::complex<long double>,DIM>::const_iterator it = m.begin();
1162  out.setf(std::ios_base::scientific);
1163  out.setf(std::ios_base::internal);
1164 
1165 
1166  for(;it!=m.end();++it)
1167  {
1168  Monomial<DIM> m = (*it).first;
1169  std::complex<long double> coefficient = (*it).second;
1170  if(m.is_a_constant())
1171  {
1172  out<<coefficient<<" ";
1173  }
1174  else
1175  {
1176 
1177  out<<"+ "<<coefficient;
1178  out<<" "<<(*it).first<<" ";
1179  }
1180  }
1181  out<<std::endl;
1182  return out;
1183  }
1184 
1185 
1186  // template<typename T, std::size_t DIM>
1187  // inline
1188  // MultivariatePolynomial<T,DIM>& MultivariatePolynomial<T,DIM>::derivative(const std::size_t dim)
1189  // {
1190  // assert(dim > 0);
1191  // assert(dim <= DIM);
1192 
1193  // if(this->degree()!=0)
1194  // {
1195  // slip::MultivariatePolynomial<T,DIM>* tmp = new slip::MultivariatePolynomial<T,DIM>(*this);
1196  // this->clear();
1197  // typename slip::MultivariatePolynomial<T,DIM>::iterator it = tmp->begin();
1198  // for(;it!=tmp->end();++it)
1199  // {
1200  // slip::Monomial<DIM> tmp_m = (*it).first;
1201  // T tmp_coeff = (*it).second * tmp_m.powers[dim-1];
1202  // int p = (int)tmp_m.powers[dim-1] - 1;
1203  // if(p >= 0)
1204  // {
1205  // tmp_m.powers[dim-1]-=1;
1206  // this->insert(tmp_m,tmp_coeff);
1207  // }
1208  // }
1209  // tmp->clear();
1210  // delete tmp;
1211  // }
1212  // else
1213  // {
1214  // slip::Monomial<DIM> constant;
1215  // constant.powers.fill((unsigned char)0);
1216  // this->insert(constant,T());
1217  // }
1218  // return *this;
1219  // }
1220 
1221  // template<typename T, std::size_t DIM>
1222  // inline
1223  // MultivariatePolynomial<T,DIM>& MultivariatePolynomial<T,DIM>::derivative(const std::size_t dim,
1224  // const std::size_t order)
1225  // {
1226  // for(std::size_t i = 0; i < order; ++i)
1227  // {
1228  // this->derivative(dim);
1229  // }
1230  // return *this;
1231  // }
1232 
1233 
1234  template<typename T, std::size_t DIM>
1235  inline
1236  void MultivariatePolynomial<T,DIM>::derivative(const std::size_t dim)
1237  {
1238  assert(dim > 0);
1239  assert(dim <= DIM);
1240 
1241  if(this->degree()!=0)
1242  {
1244  this->clear();
1245  typename slip::MultivariatePolynomial<T,DIM>::iterator it = tmp->begin();
1246  for(;it!=tmp->end();++it)
1247  {
1248  slip::Monomial<DIM> tmp_m = (*it).first;
1249  T tmp_coeff = (*it).second * tmp_m.powers[dim-1];
1250  int p = (int)tmp_m.powers[dim-1] - 1;
1251  if(p >= 0)
1252  {
1253  tmp_m.powers[dim-1]-=1;
1254  this->insert(tmp_m,tmp_coeff);
1255  }
1256  }
1257  tmp->clear();
1258  delete tmp;
1259  }
1260  else
1261  {
1262  slip::Monomial<DIM> constant;
1263  constant.powers.fill((unsigned char)0);
1264  this->insert(constant,T());
1265  }
1266  // return *this;
1267  }
1268 
1269  template<typename T, std::size_t DIM>
1270  inline
1272  {
1273  assert(dim > 0);
1274  assert(dim <= DIM);
1275 
1277  tmp.derivative(dim);
1278  return tmp;
1279  }
1280 
1281 
1282  template<typename T, std::size_t DIM>
1283  inline
1284  void MultivariatePolynomial<T,DIM>::derivative(const std::size_t dim,
1285  const std::size_t order)
1286  {
1287  for(std::size_t i = 0; i < order; ++i)
1288  {
1289  this->derivative(dim);
1290  }
1291  }
1292 
1293  template<typename T, std::size_t DIM>
1294  inline
1296  const std::size_t order) const
1297  {
1299  tmp.derivative(dim,order);
1300  return tmp;
1301  }
1302 
1303 
1304 
1305  // template<typename T, std::size_t DIM>
1306  // inline
1307  // MultivariatePolynomial<T,DIM>& MultivariatePolynomial<T,DIM>::integral(const std::size_t dim,
1308  // const T& K)
1309  // {
1310  // assert(dim > 0);
1311  // assert(dim <= DIM);
1312  // slip::MultivariatePolynomial<T,DIM>* tmp = new slip::MultivariatePolynomial<T,DIM>(*this);
1313  // this->clear();
1314  // typename slip::MultivariatePolynomial<T,DIM>::iterator it = tmp->begin();
1315  // for(;it!=tmp->end();++it)
1316  // {
1317  // slip::Monomial<DIM> tmp_m;
1318  // tmp_m.powers = (it->first).powers;
1319  // T tmp_coeff = it->second / T(tmp_m.powers[dim-1] + 1);
1320  // tmp_m.powers[dim-1]+=1;
1321  // if(tmp_coeff != 0)
1322  // {
1323  // (*this)[tmp_m] = tmp_coeff;
1324  // }
1325  // }
1326 
1327  // slip::Monomial<DIM> constant;
1328  // constant.powers.fill((unsigned char)0);
1329  // this->insert(constant,K);
1330  // tmp->clear();
1331  // delete tmp;
1332  // return *this;
1333  // }
1334 
1335  // template<typename T, std::size_t DIM>
1336  // inline
1337  // MultivariatePolynomial<T,DIM>&
1338  // MultivariatePolynomial<T,DIM>::integral(const std::size_t dim,
1339  // const std::size_t order,
1340  // const T& K)
1341  // {
1342  // for(std::size_t i = 0; i < order; ++i)
1343  // {
1344  // this->integral(dim,K);
1345  // }
1346  // return *this;
1347  // }
1348 
1349 
1350  template<typename T, std::size_t DIM>
1351  inline
1352  void MultivariatePolynomial<T,DIM>::integral(const std::size_t dim,
1353  const T& K)
1354  {
1355  assert(dim > 0);
1356  assert(dim <= DIM);
1358  this->clear();
1359  typename slip::MultivariatePolynomial<T,DIM>::iterator it = tmp->begin();
1360  for(;it!=tmp->end();++it)
1361  {
1362  slip::Monomial<DIM> tmp_m;
1363  tmp_m.powers = (it->first).powers;
1364  T tmp_coeff = it->second / T(tmp_m.powers[dim-1] + 1);
1365  tmp_m.powers[dim-1]+=1;
1366  if(tmp_coeff != 0)
1367  {
1368  (*this)[tmp_m] = tmp_coeff;
1369  }
1370  }
1371 
1372  slip::Monomial<DIM> constant;
1373  constant.powers.fill((unsigned char)0);
1374  this->insert(constant,K);
1375  tmp->clear();
1376  delete tmp;
1377  }
1378 
1379  template<typename T, std::size_t DIM>
1380  inline
1382  const T& K) const
1383  {
1384  MultivariatePolynomial<T,DIM> tmp(*this);
1385  tmp.integral(dim,K);
1386  return tmp;
1387  }
1388 
1389  template<typename T, std::size_t DIM>
1390  inline
1391  void
1393  const std::size_t order,
1394  const T& K)
1395  {
1396  for(std::size_t i = 0; i < order; ++i)
1397  {
1398  this->integral(dim,K);
1399  }
1400  }
1401 
1402  template<typename T, std::size_t DIM>
1403  inline
1406  const std::size_t order,
1407  const T& K) const
1408  {
1409  MultivariatePolynomial<T,DIM> tmp(*this);
1410  tmp.integral(dim,order,K);
1411  return tmp;
1412  }
1413 
1414 
1415 
1416  template<typename T, std::size_t DIM>
1417  inline
1420  const T& val)
1421  {
1422  assert(number <= DIM);
1424  typename slip::MultivariatePolynomial<T,DIM>::const_iterator it = this->begin();
1425 
1426  for(;it!=this->end();++it)
1427  {
1428  Monomial<DIM> m((*it).first);
1429  T coefficient = (*it).second * std::pow(val,((*it).first).powers[number-1]);
1430  m.powers[number-1] = 0;
1431  pol.insert(m,coefficient);
1432  }
1433  return pol;
1434 
1435  }
1436 
1437  template<typename T, std::size_t DIM>
1438  inline
1440  MultivariatePolynomial<T,DIM>::compose(const std::vector<self>& VP)
1441  {
1442  assert(VP.size() == DIM);
1443  //compute Polynomial powers
1444  const std::size_t P_degree = this->degree();
1445  std::vector<std::size_t> V(DIM+P_degree);
1446  slip::iota(V.begin(),V.end(),1,1);
1447  std::size_t result_size = (std::accumulate(V.begin()+P_degree,V.end(),1,std::multiplies<int>()))/(std::accumulate(V.begin(),V.begin()+DIM,1,std::multiplies<int>()));
1448  std::vector<slip::MultivariatePolynomial<T,DIM> > PolyPowers(result_size);
1449  slip::eval_multi_poly_power_nd_basis(VP,P_degree,PolyPowers.begin(),PolyPowers.end());
1450 
1451  std::vector<T> all_coeff(result_size);
1452  this->all_coeff(all_coeff.begin(),all_coeff.end());
1453 
1455  std::inner_product(PolyPowers.begin(),PolyPowers.end(),
1456  all_coeff.begin(),slip::MultivariatePolynomial<T,DIM>());
1457 
1458 
1459 
1460  return Result;
1461  }
1462 
1463  template<typename T, std::size_t DIM>
1464  inline
1465  std::string
1467  {
1468  return "MultivariatePolynomial";
1469  }
1470 
1471  template<typename T, std::size_t DIM>
1472  inline
1474  if(this->size() != 0)
1475  {
1476  typename slip::MultivariatePolynomial<T,DIM>::const_iterator it = this->end();
1477  it--;
1478 
1479  return (it->first).degree();
1480  }
1481  else
1482  return 0;
1483  }
1484 
1485  template<typename T, std::size_t DIM>
1486  inline
1488  {
1489  return this->degree();
1490  }
1491 
1492  template<typename T, std::size_t DIM>
1493  inline
1495  {
1496  std::size_t nb_coeff = 1;
1497  std::size_t fact = 1;
1498  std::size_t degree = this->degree();
1499  for(std::size_t i = 1; i <= DIM;++i)
1500  {
1501  nb_coeff *= degree + i;
1502  fact *= i;
1503  }
1504  nb_coeff/=fact;
1505  return nb_coeff;
1506  }
1507 
1508 
1509 
1510  template<typename T, std::size_t DIM>
1511  inline
1514  {
1515  typename slip::MultivariatePolynomial<T,DIM>::iterator it = this->begin();
1516 
1517  if(((*it).first).is_a_constant())
1518  {
1519  (*it).second += val;
1520  }
1521  else
1522  {
1523  slip::Monomial<DIM> constant;
1524  constant.powers.fill((unsigned char)0);
1525  this->insert(constant,val);
1526  }
1527  return *this;
1528  }
1529 
1530  template<typename T, std::size_t DIM>
1531  inline
1534  {
1535  typename slip::MultivariatePolynomial<T,DIM>::iterator it = this->begin();
1536 
1537  if(((*it).first).is_a_constant())
1538  {
1539  (*it).second -= val;
1540  }
1541  else
1542  {
1543  slip::Monomial<DIM> constant;
1544  constant.powers.fill((unsigned char)0);
1545  this->insert(constant,-val);
1546  }
1547  return *this;
1548  }
1549 
1550  template<typename T, std::size_t DIM>
1551  inline
1554  {
1555  typename slip::MultivariatePolynomial<T,DIM>::iterator it = this->begin();
1556  typename slip::MultivariatePolynomial<T,DIM>::iterator last = this->end();
1557  for(;it!=last;++it)
1558  {
1559  (*it).second *= val;
1560  }
1561  return *this;
1562  }
1563 
1564  template<typename T, std::size_t DIM>
1565  inline
1568  {
1569  typename slip::MultivariatePolynomial<T,DIM>::iterator it = this->begin();
1570  typename slip::MultivariatePolynomial<T,DIM>::iterator last = this->end();
1571  for(;it!=last;++it)
1572  {
1573  (*it).second /= val;
1574  }
1575  return *this;
1576  }
1577 
1578  template<typename T, std::size_t DIM>
1579  inline
1582  {
1583  MultivariatePolynomial<T,DIM> tmp(*this);
1584  typename slip::MultivariatePolynomial<T,DIM>::const_iterator it = this->begin();
1585  typename slip::MultivariatePolynomial<T,DIM>::const_iterator last = this->end();
1586  typename slip::MultivariatePolynomial<T,DIM>::iterator it_tmp = tmp.begin();
1587 
1588  for(;it!=last;++it,++it_tmp)
1589  {
1590  (*it_tmp).second = -(*it).second;
1591  }
1592  return tmp;
1593  }
1594 
1595 
1596  template<typename T, std::size_t DIM>
1597  inline
1599  {
1600  typename slip::MultivariatePolynomial<T,DIM>::const_iterator it_rhs = rhs.begin();
1601  typename slip::MultivariatePolynomial<T,DIM>::const_iterator last_rhs = rhs.end();
1602 
1603  for(;it_rhs!=last_rhs;++it_rhs)
1604  {
1606  this->find((*it_rhs).first);
1607  if(it_tmp!=this->end())
1608  {
1609  (*it_tmp).second += (*it_rhs).second;
1610  if((*it_tmp).second == T(0))
1611  {
1612  this->erase(it_tmp);
1613  }
1614  }
1615  else
1616  {
1617  this->insert((*it_rhs).first,(*it_rhs).second);
1618  }
1619  }
1620  return *this;
1621  }
1622 
1623  template<typename T, std::size_t DIM>
1624  inline
1626  {
1627  typename slip::MultivariatePolynomial<T,DIM>::const_iterator it_rhs = rhs.begin();
1628  typename slip::MultivariatePolynomial<T,DIM>::const_iterator last_rhs = rhs.end();
1629 
1630  for(;it_rhs!=last_rhs;++it_rhs)
1631  {
1633  this->find((*it_rhs).first);
1634  if(it_tmp!=this->end())
1635  {
1636  (*it_tmp).second -= (*it_rhs).second;
1637  if((*it_tmp).second == T(0) && !(*it_tmp).first.is_a_constant())
1638  {
1639  this->erase(it_tmp);
1640  }
1641  }
1642  else
1643  {
1644  this->insert((*it_rhs).first,-(*it_rhs).second);
1645  }
1646  }
1647 
1648  return *this;
1649  }
1650 
1651 
1652 
1653  template<typename T, std::size_t DIM>
1654  inline
1657  {
1659 
1660  for(typename MultivariatePolynomial<T,DIM>::const_iterator const_iter1 =
1661  this->begin();const_iter1 != this->end(); ++const_iter1)
1662  {
1663 
1664  for(typename MultivariatePolynomial<T,DIM>::const_iterator const_iter2 = rhs.begin(); const_iter2 != rhs.end();++const_iter2)
1665  {
1666  tmp[(*const_iter1).first * (*const_iter2).first] +=
1667  (*const_iter1).second * (*const_iter2).second;
1668  if( tmp[(*const_iter1).first * (*const_iter2).first] == T())
1669  {
1670  tmp.erase((*const_iter1).first * (*const_iter2).first);
1671  }
1672  }
1673  }
1674 
1675  //this->clear();
1676  *this = tmp;
1677 
1678  return *this;
1679  }
1680 
1681 
1682  template<typename T, std::size_t DIM>
1683  inline
1684  void MultivariatePolynomial<T,DIM>::create(const std::size_t order)
1685  {
1686  //array of all the powers combinations sort by lexicographical order
1687  slip::Array2d<std::size_t> powers(slip::power(order+1,DIM),DIM);
1688  for(std::size_t d = 0; d < powers.dim2(); ++d)
1689  {
1690  std::size_t step = slip::power((order+1),d);
1691  for(std::size_t ord = 0, ord2 = 0; ord <= (powers.dim1() - step); ord+=step,++ord2)
1692  {
1693  std::size_t tmp = ord2%(order+1);
1694  for(std::size_t k = 0; k < step; ++k)
1695  {
1696  powers[ord+k][d] = tmp;
1697  }
1698  }
1699  }
1700 
1701  for(std::size_t k = 0; k < powers.dim1(); ++k)
1702  {
1704 
1705  std::copy(powers.row_begin(k),powers.row_end(k),(m.powers).begin());
1706  if (m.degree() <= order)
1707  {
1708  this->insert(m,T(1));
1709  }
1710  }
1711  }
1712 
1713 }//slip::
1714 
1716  /* @{ */
1717 namespace slip{
1718 template<typename T,std::size_t DIM>
1719 inline
1722 {
1724  tmp+=P2;
1725  return tmp;
1726 }
1727 
1728 template<typename T,std::size_t DIM>
1729 inline
1731  const T& val)
1732 {
1734  tmp+=val;
1735  return tmp;
1736 }
1737 
1738 template<typename T,std::size_t DIM>
1739 inline
1742 {
1743  return P1+val;
1744 }
1745 
1746 
1747 template<typename T,std::size_t DIM>
1748 inline
1751 {
1753  tmp-=P2;
1754  return tmp;
1755 }
1756 
1757 template<typename T,std::size_t DIM>
1758 inline
1760  const T& val)
1761 {
1763  tmp-=val;
1764  return tmp;
1765 }
1766 
1767 template<typename T,std::size_t DIM>
1768 inline
1771 {
1772  return -(P1-val);
1773 }
1774 
1775 
1776 template<typename T,std::size_t DIM>
1777 inline
1780 {
1782  tmp*=P2;
1783  return tmp;
1784 }
1785 
1786 template<typename T,std::size_t DIM>
1787 inline
1789  const T& val)
1790 {
1792  tmp*=val;
1793  return tmp;
1794 }
1795 
1796 template<typename T,std::size_t DIM>
1797 inline
1800 {
1801  return P1*val;
1802 }
1803 
1804 
1805 template<typename T,std::size_t DIM>
1806 inline
1808  const T& val)
1809 {
1811  tmp/=val;
1812  return tmp;
1813 }
1814 /* @} */
1815 }//slip::
1816 #endif //SLIP_MULTIVARIATEPOLYNOMIAL_HPP
Provides a class to manipulate 2d dynamic and generic arrays.
iterator begin()
Returns a read/write iterator that points to the first element in the block. Iteration is done in ord...
Definition: Block.hpp:189
const std::map< slip::Monomial< DIM >, Type >::const_pointer const_pointer
bool operator!=(const Array< T > &x, const Array< T > &y)
Definition: Array.hpp:1448
std::map< slip::Monomial< DIM >, Type >::pointer pointer
self integral(const std::size_t dim, const T &K=T()) const
Returns the integral of the MultivariatePolynomial. By default, the constant of integrationis K is se...
std::map< slip::Monomial< DIM >, Type >::value_type value_type
std::map< slip::Monomial< DIM >, Type >::mapped_type mapped_type
double fit(Vector1 X, Vector2 Y, const std::size_t order)
Return a polynomial P(X) of degree order that minimizes sum_i (P(x1(i),...,xDIM(i)) - y(i))^2 to best...
std::map< slip::Monomial< DIM >, Type >::key_compare key_compare
T power(T x, Integer N)
function to compute.
Definition: macros.hpp:368
std::map< slip::Monomial< DIM >, Type >::reference reference
MultivariatePolynomial(const std::size_t degree, InputIterator first, InputIterator last)
Constructs a MultivariatePolynomial of degree degree. That is to say the sum of the powers of the gre...
Numerical Monomial structure.
size_type total_nb_coeff() const
Returns the total number of coefficients.
friend class boost::serialization::access
Color< T > operator+(const Color< T > &V1, const Color< T > &V2)
Definition: Color.hpp:602
iterator begin()
Returns a read/write iterator that points to the first element in the Array. Iteration is done in ord...
Definition: Array.hpp:1077
self compose(const std::vector< self > &VP)
Returns the composition of the MultivariatePolynomial with a vector of MultivariatePolynomial.
MultivariatePolynomial< T, DIM > partial_evaluate(const std::size_t number, const T &val)
Returns the evaluation of the MultivariatePolynomial at (x1,x2,...,val,...,xDIM)
std::size_t degree() const
std::map< slip::Monomial< DIM >, Type >::key_type key_type
MultivariatePolynomial(const std::size_t degree)
Constructs a MultivariatePolynomial of degree degree. That is to say the sum of the powers of the gre...
std::map< slip::Monomial< DIM >, T > base
self derivative(const std::size_t dim) const
Returns the derivative the MultivariatePolynomial.
~MultivariatePolynomial()
Destructor of the MultivariatePolynomial.
std::map< slip::Monomial< DIM >, Type >::difference_type difference_type
double svd_least_square_nd(RandomAccessIterator1 x_first, RandomAccessIterator1 x_last, RandomAccessIterator2 y_first, RandomAccessIterator3 s_first, RandomAccessIterator4 p_first, RandomAccessIterator4 p_last, const std::size_t order, slip::EvalBasis< typename std::iterator_traits< RandomAccessIterator1 >::value_type, RandomAccessIterator2 > &basis_fun)
nd Linear Least Square fitting using SVD.
void iota(ForwardIterator first, ForwardIterator last, T value, T step=T(1))
Iota assigns sequential increasing values based on a predefined step to a range. That is...
HyperVolume< T > abs(const HyperVolume< T > &M)
bool operator>(const Array< T > &x, const Array< T > &y)
Definition: Array.hpp:1469
Provides a class to manipulate 1d static and generic arrays.
Provides some polynomial algorithms.
Numerical MultivariatePolynomial class.
void eval_power_basis(const T &x, const std::size_t n, RandomAccessIterator first, RandomAccessIterator last)
Returns the evaluation of the power of x until order n to the range [first,last) using the horner sch...
std::string name() const
size_type degree() const
Returns the degree of the MultivariatePolynomial.
std::map< slip::Monomial< DIM >, Type >::value_compare value_compare
size_type order() const
Returns the degree of the MultivariatePolynomial.
iterator end()
Returns a read/write iterator that points one past the last element in the Array. Iteration is done i...
Definition: Array.hpp:1084
Provides some statistics algorithms.
size_type dim2() const
Returns the number of columns (second dimension size) in the Array2d.
Definition: Array2d.hpp:3145
void copy(_II first, _II last, _OI output_first)
Copy algorithm optimized for slip iterators.
Definition: copy_ext.hpp:177
size_type rows() const
Returns the number of rows (first dimension size) in the Array2d.
Definition: Array2d.hpp:3139
std::string name() const
Returns the name of the class.
iterator end()
Returns a read/write iterator that points one past the last element in the block. Iteration is done i...
Definition: Block.hpp:210
MultivariatePolynomial(InputIterator first, InputIterator last)
Constructs a MultivariatePolynomial with a copy of range.
self & operator+=(const T &val)
Add val to each element of the MultivariatePolynomial.
std::size_t dim() const
MultivariatePolynomial(const self &rhs)
Constructs a copy of the MultivariatePolynomial rhs.
std::map< slip::Monomial< DIM >, Type >::size_type size_type
std::map< slip::Monomial< DIM >, Type >::iterator iterator
std::map< slip::Monomial< DIM >, Type >::const_reference const_reference
row_iterator row_begin(const size_type row)
Returns a read/write iterator that points to the first element of the row row in the Array2d...
std::ostream & operator<<(std::ostream &out, const Array< T > &a)
Definition: Array.hpp:1282
const_pointer const_iterator
Definition: Array.hpp:159
void fill(const T &value)
Fills the container range [begin(),begin()+N) with copies of value.
Definition: Block.hpp:512
std::iterator_traits< RandomAccessIterator1 >::value_type inner_product(RandomAccessIterator1 first1, RandomAccessIterator1 last1, RandomAccessIterator2 first2, typename std::iterator_traits< RandomAccessIterator1 >::value_type init=typename std::iterator_traits< RandomAccessIterator1 >::value_type())
Computes the inner_product of two ranges X and Y: .
void insert(const slip::Monomial< DIM > &monomial, const T &coefficient)
Inserts the monomial monomial associated with the coefficient coefficient into the MultivariatePolyno...
const MultivariatePolynomial< T, DIM > const_self
std::iterator_traits< InputIterator >::value_type evaluate(InputIterator first, InputIterator last) const
Returns the evaluation of the MultivariatePolynomial at (x1,x2,...,xDIM)
slip::block< unsigned char, DIM > powers
std::map< slip::Monomial< DIM >, Type >::const_reverse_iterator const_reverse_iterator
void eval_multi_poly_power_nd_basis(const Vector &x, const std::size_t order, RandomAccessIterator first, RandomAccessIterator last)
Returns the evaluation of the powers of slip::MultivariatePolynomial<T,DIM> such that with the pow...
row_iterator row_end(const size_type row)
Returns a read/write iterator that points one past the end element of the row row in the Array2d...
Provides a class to manipulate monovariate polynomial.
bool operator==(const Array< T > &x, const Array< T > &y)
Definition: Array.hpp:1439
void derivative(SrcIter first, SrcIter last, const std::size_t der_ord, const std::size_t sch_ord, const std::size_t sch_shift, const Container2D &M, ResIter result)
Computes 1d finite differences derivatives of an iterator range.
Provides some linear least square algorithms.
std::map< slip::Monomial< DIM >, Type >::reverse_iterator reverse_iterator
MultivariatePolynomial()
Constructs a MultivariatePolynomial.
Color< T > operator*(const Color< T > &V1, const Color< T > &V2)
Definition: Color.hpp:658
This is a two-dimensional dynamic and generic container. This container statisfies the Bidirectionnal...
Definition: Array2d.hpp:135
Color< T > operator/(const Color< T > &V1, const Color< T > &V2)
Definition: Color.hpp:686
Color< T > operator-(const Color< T > &V1, const Color< T > &V2)
Definition: Color.hpp:630
std::map< slip::Monomial< DIM >, Type >::const_iterator const_iterator
size_type dim1() const
Returns the number of rows (first dimension size) in the Array2d.
Definition: Array2d.hpp:3134
void all_coeff(RandomAccessIterator first, RandomAccessIterator last) const
Returns all the coefficients of the polynomial including zero ones.