75 #ifndef SLIP_MULTIVARIATEPOLYNOMIAL_HPP
76 #define SLIP_MULTIVARIATEPOLYNOMIAL_HPP
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>
103 template <std::
size_t DIM>
106 template <std::
size_t DIM>
110 template <std::
size_t DIM>
114 template <std::
size_t DIM>
118 template <std::
size_t DIM>
119 bool operator<(const Monomial<DIM>& x,
122 template <std::
size_t DIM>
126 template <std::
size_t DIM>
147 template <std::
size_t DIM>
152 std::string
name()
const {
return "Monomial";}
153 std::size_t
dim()
const {
return DIM;}
214 template<
class Archive>
215 void save(Archive & ar,
const unsigned int version)
const
219 template<
class Archive>
220 void load(Archive & ar,
const unsigned int version)
224 BOOST_SERIALIZATION_SPLIT_MEMBER()
245 template<std::
size_t DIM>
246 Monomial<DIM>
operator*(
const Monomial<DIM>& monomial1,
247 const Monomial<DIM>& monomial2);
255 template <std::
size_t DIM>
265 for(std::size_t i = 0; i < (m.
powers).size(); ++i)
266 out<<
"x"<<(i+1)<<
"^"<<(int)m.
powers[i]<<
" ";
273 template <std::
size_t DIM>
281 template <std::
size_t DIM>
293 template <std::
size_t DIM>
295 bool operator<(const Monomial<DIM>& x,
298 return std::lexicographical_compare((x.powers).rbegin(), (x.powers).rend(),
299 (y.powers).rbegin(), (y.powers).rend());
304 template <std::
size_t DIM>
314 template<std::
size_t DIM>
320 std::transform((monomial1.
powers).begin(),
322 (monomial2.
powers).begin(),
324 std::plus<unsigned char>());
332 template <
typename T, std::
size_t DIM>
335 template <
typename T, std::
size_t DIM>
356 template <
typename T, std::
size_t DIM>
361 typedef std::map<slip::Monomial<DIM>,T>
base;
398 this->
insert(constant,T());
417 this->create(degree);
437 template<
typename InputIterator>
443 this->create(degree);
446 for(
iterator it = this->begin(); it!=this->end();++it)
448 (*it).second = *first++;
458 template<
class InputIterator>
492 friend std::ostream& operator<< <>(std::ostream & out,
574 const std::size_t
order)
const;
585 const std::size_t
order);
598 self integral(
const std::size_t dim,
599 const T& K = T())
const;
610 void integral(
const std::size_t dim,
624 self integral(
const std::size_t dim,
625 const std::size_t
order,
626 const T& K = T())
const;
639 void integral(
const std::size_t dim,
640 const std::size_t order,
692 template <
typename Vector1,
typename Vector2>
695 const std::size_t order)
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>()));
706 double chi_square = 0.0;
716 for(;it != this->end();++it,++ita)
736 template<
typename InputIterator>
737 typename std::iterator_traits<InputIterator>::value_type
739 InputIterator last)
const
741 assert((last-first) == DIM);
744 typedef typename std::iterator_traits<InputIterator>::value_type Return;
748 for(std::size_t i = 0; i < values.
rows(); ++i)
754 Return result = Return();
755 for(const_it first_m = this->begin();first_m!=this->end();++first_m)
757 Return tmp = values[0][((*first_m).first).powers[0]];
758 for(std::size_t i = 1; i < DIM; ++i)
760 tmp*=values[i][((*first_m).first).powers[i]];
762 result+= ((*first_m).second) * tmp;
798 self compose(
const std::vector<self>& VP);
811 std::string
name()
const;
838 template<
typename RandomAccessIterator>
840 RandomAccessIterator last)
const
842 typedef typename std::iterator_traits<RandomAccessIterator>::difference_type _Distance;
849 for(std::size_t d = 0; d < powers_a.
dim2(); ++d)
852 for(std::size_t ord = 0, ord2 = 0; ord <= (powers_a.
dim1() - step); ord+=step,++ord2)
854 std::size_t tmp = ord2%(this->
order()+1);
855 for(std::size_t k = 0; k < step; ++k)
857 powers_a[ord+k][d] = tmp;
862 std::map<slip::Monomial<DIM>,T> tmp_map;
865 for(std::size_t ord = 0; ord < powers_a.
dim1(); ++ord)
878 for(const_it it = this->begin();it!=this->end();++it)
881 T coefficient = (*it).second;
882 tmp_map[m] += coefficient;
885 for(const_it it = tmp_map.begin(); it!=tmp_map.end();++it)
887 *first++ = (*it).second;
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
905 ar & boost::serialization::base_object<std::map<slip::Monomial<DIM>,T> >(*this);
907 template<
class Archive>
908 void load(Archive & ar,
const unsigned int version)
910 ar & boost::serialization::base_object<std::map<slip::Monomial<DIM>,T> >(*this);
912 BOOST_SERIALIZATION_SPLIT_MEMBER()
927 template<
typename T, std::
size_t DIM>
928 MultivariatePolynomial<T,DIM>
operator+(
const MultivariatePolynomial<T,DIM>& P1,
929 const MultivariatePolynomial<T,DIM>& P2);
938 template<
typename T, std::
size_t DIM>
939 MultivariatePolynomial<T,DIM>
operator+(
const MultivariatePolynomial<T,DIM>& P,
949 template<
typename T, std::
size_t DIM>
950 MultivariatePolynomial<T,DIM>
operator+(
const T& val,
951 const MultivariatePolynomial<T,DIM>& P);
961 template<
typename T, std::
size_t DIM>
962 MultivariatePolynomial<T,DIM>
operator-(
const MultivariatePolynomial<T,DIM>& P1,
963 const MultivariatePolynomial<T,DIM>& P2);
972 template<
typename T, std::
size_t DIM>
973 MultivariatePolynomial<T,DIM>
operator-(
const MultivariatePolynomial<T,DIM>& P,
983 template<
typename T, std::
size_t DIM>
984 MultivariatePolynomial<T,DIM>
operator-(
const T& val,
985 const MultivariatePolynomial<T,DIM>& P);
994 template<
typename T, std::
size_t DIM>
995 MultivariatePolynomial<T,DIM>
operator*(
const MultivariatePolynomial<T,DIM>& P1,
996 const MultivariatePolynomial<T,DIM>& P2);
1005 template<
typename T, std::
size_t DIM>
1006 MultivariatePolynomial<T,DIM>
operator*(
const MultivariatePolynomial<T,DIM>& P,
1016 template<
typename T, std::
size_t DIM>
1017 MultivariatePolynomial<T,DIM>
operator*(
const T& val,
1018 const MultivariatePolynomial<T,DIM>& P);
1028 template<
typename T, std::
size_t DIM>
1029 MultivariatePolynomial<T,DIM>
operator/(
const MultivariatePolynomial<T,DIM>& P,
1040 template<
typename T, std::
size_t DIM>
1044 const T& coefficient)
1048 (*this)[monomial] += coefficient;
1052 if(coefficient != T())
1054 (*this)[monomial] += coefficient;
1061 template <
typename T, std::
size_t DIM>
1067 out.setf(std::ios_base::scientific);
1068 out.setf(std::ios_base::internal);
1071 for(;it!=m.end();++it)
1074 T coefficient = (*it).second;
1077 out<<coefficient<<
" ";
1081 if(coefficient >= T(0))
1083 out<<
"+ "<<coefficient;
1089 out<<
" "<<(*it).first<<
" ";
1097 template <std::
size_t DIM>
1103 out.setf(std::ios_base::scientific);
1104 out.setf(std::ios_base::internal);
1107 for(;it!=m.end();++it)
1110 std::complex<double> coefficient = (*it).second;
1113 out<<coefficient<<
" ";
1118 out<<
"+ "<<coefficient;
1119 out<<
" "<<(*it).first<<
" ";
1127 template <std::
size_t DIM>
1133 out.setf(std::ios_base::scientific);
1134 out.setf(std::ios_base::internal);
1137 for(;it!=m.end();++it)
1140 std::complex<float> coefficient = (*it).second;
1143 out<<coefficient<<
" ";
1148 out<<
"+ "<<coefficient;
1149 out<<
" "<<(*it).first<<
" ";
1156 template <std::
size_t DIM>
1162 out.setf(std::ios_base::scientific);
1163 out.setf(std::ios_base::internal);
1166 for(;it!=m.end();++it)
1169 std::complex<long double> coefficient = (*it).second;
1172 out<<coefficient<<
" ";
1177 out<<
"+ "<<coefficient;
1178 out<<
" "<<(*it).first<<
" ";
1234 template<
typename T, std::
size_t DIM>
1241 if(this->degree()!=0)
1246 for(;it!=tmp->end();++it)
1249 T tmp_coeff = (*it).second * tmp_m.
powers[dim-1];
1250 int p = (int)tmp_m.
powers[dim-1] - 1;
1254 this->insert(tmp_m,tmp_coeff);
1264 this->insert(constant,T());
1269 template<
typename T, std::
size_t DIM>
1282 template<
typename T, std::
size_t DIM>
1285 const std::size_t order)
1287 for(std::size_t i = 0; i < order; ++i)
1293 template<
typename T, std::
size_t DIM>
1296 const std::size_t order)
const
1350 template<
typename T, std::
size_t DIM>
1360 for(;it!=tmp->end();++it)
1363 tmp_m.
powers = (it->first).powers;
1364 T tmp_coeff = it->second / T(tmp_m.
powers[dim-1] + 1);
1368 (*this)[tmp_m] = tmp_coeff;
1374 this->insert(constant,K);
1379 template<
typename T, std::
size_t DIM>
1389 template<
typename T, std::
size_t DIM>
1393 const std::size_t order,
1396 for(std::size_t i = 0; i < order; ++i)
1398 this->integral(dim,K);
1402 template<
typename T, std::
size_t DIM>
1406 const std::size_t order,
1416 template<
typename T, std::
size_t DIM>
1422 assert(number <= DIM);
1426 for(;it!=this->end();++it)
1429 T coefficient = (*it).second * std::pow(val,((*it).first).powers[number-1]);
1431 pol.
insert(m,coefficient);
1437 template<
typename T, std::
size_t DIM>
1442 assert(VP.size() == DIM);
1444 const std::size_t P_degree = this->degree();
1445 std::vector<std::size_t> V(DIM+P_degree);
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);
1451 std::vector<T> all_coeff(result_size);
1452 this->all_coeff(all_coeff.begin(),all_coeff.end());
1463 template<
typename T, std::
size_t DIM>
1468 return "MultivariatePolynomial";
1471 template<
typename T, std::
size_t DIM>
1474 if(this->size() != 0)
1479 return (it->first).
degree();
1485 template<
typename T, std::
size_t DIM>
1489 return this->degree();
1492 template<
typename T, std::
size_t DIM>
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)
1501 nb_coeff *= degree + i;
1510 template<
typename T, std::
size_t DIM>
1517 if(((*it).first).is_a_constant())
1519 (*it).second += val;
1525 this->insert(constant,val);
1530 template<
typename T, std::
size_t DIM>
1537 if(((*it).first).is_a_constant())
1539 (*it).second -= val;
1545 this->insert(constant,-val);
1550 template<
typename T, std::
size_t DIM>
1559 (*it).second *= val;
1564 template<
typename T, std::
size_t DIM>
1573 (*it).second /= val;
1578 template<
typename T, std::
size_t DIM>
1588 for(;it!=last;++it,++it_tmp)
1590 (*it_tmp).second = -(*it).second;
1596 template<
typename T, std::
size_t DIM>
1603 for(;it_rhs!=last_rhs;++it_rhs)
1606 this->find((*it_rhs).first);
1607 if(it_tmp!=this->end())
1609 (*it_tmp).second += (*it_rhs).second;
1610 if((*it_tmp).second == T(0))
1612 this->erase(it_tmp);
1617 this->insert((*it_rhs).first,(*it_rhs).second);
1623 template<
typename T, std::
size_t DIM>
1630 for(;it_rhs!=last_rhs;++it_rhs)
1633 this->find((*it_rhs).first);
1634 if(it_tmp!=this->end())
1636 (*it_tmp).second -= (*it_rhs).second;
1637 if((*it_tmp).second == T(0) && !(*it_tmp).first.is_a_constant())
1639 this->erase(it_tmp);
1644 this->insert((*it_rhs).first,-(*it_rhs).second);
1653 template<
typename T, std::
size_t DIM>
1661 this->begin();const_iter1 != this->end(); ++const_iter1)
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())
1670 tmp.erase((*const_iter1).first * (*const_iter2).first);
1682 template<
typename T, std::
size_t DIM>
1688 for(std::size_t d = 0; d < powers.dim2(); ++d)
1691 for(std::size_t ord = 0, ord2 = 0; ord <= (powers.dim1() - step); ord+=step,++ord2)
1693 std::size_t tmp = ord2%(order+1);
1694 for(std::size_t k = 0; k < step; ++k)
1696 powers[ord+k][d] = tmp;
1701 for(std::size_t k = 0; k < powers.dim1(); ++k)
1708 this->insert(m,T(1));
1718 template<
typename T,std::
size_t DIM>
1728 template<
typename T,std::
size_t DIM>
1738 template<
typename T,std::
size_t DIM>
1747 template<
typename T,std::
size_t DIM>
1757 template<
typename T,std::
size_t DIM>
1767 template<
typename T,std::
size_t DIM>
1776 template<
typename T,std::
size_t DIM>
1786 template<
typename T,std::
size_t DIM>
1796 template<
typename T,std::
size_t DIM>
1805 template<
typename T,std::
size_t DIM>
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...
const std::map< slip::Monomial< DIM >, Type >::const_pointer const_pointer
bool operator!=(const Array< T > &x, const Array< T > &y)
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.
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)
iterator begin()
Returns a read/write iterator that points to the first element in the Array. Iteration is done in ord...
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
self & operator/=(const T &val)
std::map< slip::Monomial< DIM >, Type >::key_type key_type
self & operator*=(const T &val)
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)
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...
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...
Provides some statistics algorithms.
size_type dim2() const
Returns the number of columns (second dimension size) in the Array2d.
void copy(_II first, _II last, _OI output_first)
Copy algorithm optimized for slip iterators.
size_type rows() const
Returns the number of rows (first dimension size) in the Array2d.
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...
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.
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)
const_pointer const_iterator
void fill(const T &value)
Fills the container range [begin(),begin()+N) with copies of value.
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)
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)
self & operator-=(const T &val)
This is a two-dimensional dynamic and generic container. This container statisfies the Bidirectionnal...
Color< T > operator/(const Color< T > &V1, const Color< T > &V2)
bool is_a_constant() const
Color< T > operator-(const Color< T > &V1, const Color< T > &V2)
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.
void all_coeff(RandomAccessIterator first, RandomAccessIterator last) const
Returns all the coefficients of the polynomial including zero ones.