Functionalities of Univariable & Multivariable Polynomials and Series
As of May 30, 2016 this contains accurate documentation on the functionalities of the univariate and multivariate polynomials/series classes.
Navigation
UExprPoly
is a sparse polynomial representation class. A UExprPoly
object holds:
- A variable (
symbol(std::string)
) - A dictionary (
UExprDict(std::map)
) - The degree (
int
)
UExprDict
is wrapper class of a std::map<int, Expression>
that is typedef as map_int_Expr
, where the key value is of type int
and the mapped value is of type Expression
. Expression
can hold any Basic
mathematical structure. For a univariable polynomial x**2 + 2*x + 1
, UExprDict
would hold {{0, 1}, {1, 2}, {1, 2}}
.
UExprPoly
is inherited from the UPolyBase
base class, which also contains the basic methods needed to perform operations for any kind of univariable polynomials. This is also similar to UIntPoly
.
To use UExprPoly
in a C++ project, include:
#include <symengine/polys/uexprpoly.h>
using SymEngine::UExprPoly;
using SymEngine::UExprDict;
using SymEngine::Symbol;
using SymEngine::symbol;
using SymEngine::Expression;
using SymEngine::map_int_Expr;
Individual functionalities can be chosen separately, or can be used with just using namespace SymEngine;
Compare two polynomials.
Parameter:
-
o
- A
Basic
object, which represent any mathematical expression that can be created in SymEngine
- A
Return:
- 0 if both polynomials are equal.
- -1 if either
- Left polynomial has a lower degree than the right polynomial
- The string value of left polynomial’s variable is lower than the right polynomial’s variable
- The left polynomial’s dictionary is smaller than the right polynomial’s dictionary
- The left polynomial’s nth-term is smaller than the right polynomial’s nth-term
- Otherwise 1
Example:
RCP<const Symbol> x = symbol("x");
RCP<const UExprPoly> P = uexpr_poly(x, {{0, 1}, {1, 2}});
RCP<const UExprPoly> Q = uexpr_poly(x, {{0, 1}, {1, 2}, {2, 1}});
RCP<const UExprPoly> R = uexpr_poly(y, {{0, 1}, {1, 2}, {3, 3}});
std::cout << P->compare(*Q) << std::endl;
std::cout << Q->compare(*Q) << std::endl;
std::cout << R->compare(*Q) << std::endl;
Output:
-1
0
1
Return the coefficient value of the highest degree of the UExprPoly
.
Example:
RCP<const Symbol> x = symbol("x");
RCP<const UExprPoly> a = uexpr_poly(x, {{0, 1}, {1, 2}, {2, 4}});
std::cout << a->max_coef() << std::endl;
Output:
4
Evaluates the UExprPoly
at value x
.
Example:
RCP<const Symbol> x = symbol("x");
RCP<const UExprPoly> a = uexpr_poly(x, {{0, 1}, {1, 2}, {2, symbol("a")}});
std::cout << a->eval(2) << std::endl;
Output:
5 + 4*a
Return true if the polynomial equals 0.
Example:
RCP<const Symbol> x = symbol("x");
RCP<const UExprPoly> z = uexpr_poly(x, {{0, Expression(0)}});
RCP<const UExprPoly> o = uexpr_poly(x, {{0, Expression(1)}});
std::cout << z->is_zero() << std::endl;
std::cout << o->is_zero() << std::endl;
Output:
1
0
Return true if the polynomial equals 1.
Example:
RCP<const Symbol> x = symbol("x");
RCP<const UExprPoly> z = uexpr_poly(x, {{0, Expression(0)}});
RCP<const UExprPoly> o = uexpr_poly(x, {{0, Expression(1)}});
std::cout << z->is_one() << std::endl;
std::cout << o->is_one() << std::endl;
Output:
0
1
Return true if the polynomial equals -1.
Example:
RCP<const Symbol> x = symbol("x");
RCP<const UExprPoly> mo = uexpr_poly(x, {{0, Expression(-1)}});
RCP<const UExprPoly> o = uexpr_poly(x, {{0, Expression(1)}});
std::cout << mo->is_minus_one() << std::endl;
std::cout << o->is_minus_one() << std::endl;
Output:
1
0
Return true if the polynomial is an integer monomial.
Example:
RCP<const Symbol> x = symbol("x");
RCP<const UExprPoly> p = uexpr_poly(x, {{0, Expression(1)}, {1, Expression(2)}});
RCP<const UExprPoly> i = uexpr_poly(x, {{0, Expression(6)}});
std::cout << p->is_integer() << std::endl;
std::cout << i->is_integer() << std::endl;
Output:
0
1
Return true if the polynomial is a monomial with a coefficient of 1 and a degree of 1.
Example:
RCP<const Symbol> x = symbol("x");
RCP<const UExprPoly> i = uexpr_poly(x, {{0, Expression(6)}});
RCP<const UExprPoly> s = uexpr_poly(x, {{1, Expression(1)}});
std::cout << i->is_symbol() << std::endl;
std::cout << s->is_symbol() << std::endl;
Output:
0
1
Return true if the polynomial is a monomial with a coefficient that is not 0 or 1 and a degree of 1 or greater.
Example:
RCP<const Symbol> x = symbol("x");
RCP<const UExprPoly> i = uexpr_poly(x, {{0, Expression(9)}});
RCP<const UExprPoly> m = uexpr_poly(x, {{3, Expression(5)}});
std::cout << i->is_mul() << std::endl;
std::cout << m->is_mul() << std::endl;
Output:
0
1
Return true if the polynomial is a monomial with a coefficient of 1 and a degree greater than 1.
Example:
RCP<const Symbol> x = symbol("x");
RCP<const UExprPoly> m = uexpr_poly(x, {{3, Expression(5)}});
RCP<const UExprPoly> po = uexpr_poly(x, {{5, Expression(1)}});
std::cout << m->is_pow() << std::endl;
std::cout << po->is_pow() << std::endl;
Output:
0
1
Compute the derivative with respect to variable x
.
Example:
RCP<const Symbol> x = symbol("x");
RCP<const UExprPoly> a = uexpr_poly(x, {{0, 1}, {1, 2}, {2, symbol("a")}});
std::cout << a->diff(x)->__str__() << std::endl;
Output:
2*a*x + 2
Expand self
.
Example:
RCP<const Symbol> x = symbol("x");
RCP<const UExprPoly> a = uexpr_poly(x, {{1, 1}, {2, 1}, {3, symbol("a")}});
RCP<const Basic> b = make_rcp<const Pow>(a, integer(3));
std::cout << expand(b)->__str__() << std::endl;
Output:
a**3*x**9 + 3*a**2*x**8 + (2*a + a*(1 + 2*a) + a**2)*x**7 + (1 + 6*a)*x**6 + (3 + 3*a)*x**5 + 3*x**4 + x**3
Return the sum of a
and b
when a
and b
have the same variable, otherwise throw a runtime exception.
Example:
RCP<const Symbol> x = symbol("x");
UExprDict adict_({{0, 1}, {1, 2}, {2, symbol("a")}});
UExprDict bdict_({{0, 2}, {1, 3}, {2, symbol("b")}});
const UExprPoly a(x, std::move(adict_));
const UExprPoly b(x, std::move(bdict_));
std::cout << add_upoly(a, b)->__str__() << std::endl;
Output:
(a + b)*x**2 + 5*x + 3
Return the negation of a
.
Example:
RCP<const Symbol> x = symbol("x");
UExprDict adict_({{0, 1}, {1, symbol("a")}, {2, symbol("c")}});
const UExprPoly a(x, std::move(adict_));
std::cout << neg_upoly(a)->__str__() << std::endl;
Output:
-c*x**2 - a*x - 1
Return the difference of a
and b
when a
and b
have the same variable, otherwise throw a runtime exception.
Example:
RCP<const Symbol> x = symbol("x");
UExprDict adict_({{0, 1}, {1, 2}, {2, 1}});
UExprDict bdict_({{0, 2}, {1, symbol("b")}, {2, symbol("a")}});
const UExprPoly a(x, std::move(adict_));
const UExprPoly b(x, std::move(bdict_));
std::cout << sub_upoly(b, a)->__str__() << std::endl;
Output:
(-1 + a)*x**2 + (-2 + b)*x + 1
Return the product of a
and b
when a
and b
have the same variable and neither a
or b
are monomial constants.
Example:
RCP<const Symbol> x = symbol("x");
RCP<const UExprPoly> a = uexpr_poly(x, {{0, 1}, {1, symbol("b")}, {2, symbol("a")}});
RCP<const UExprPoly> b = uexpr_poly(x, {{0, -1}, {1, -2}, {2, mul(integer(-1), symbol("a"))}});
std::cout << mul_upoly(*a, *b)->__str__() << std::endl;
Output:
-a**2*x**4 + (-2*a - a*b)*x**3 + (-2*a - 2*b)*x**2 + (-2 - b)*x - 1
Construct a UExprPoly
object with variable i
and a dictionary dict
in the form of a UExprDict
.
Example:
RCP<const Symbol> x = symbol("x");
UExprDict dict({{0, 1}, {1, 2}, {2, 1}});
RCP<const UExprPoly> P = uexpr_poly(x, std::move(dict));
std::cout << P->__str__() << std::endl;
Output:
x**2 + 2*x + 1
Construct a UExprPoly
object with variable i
and a dictionary dict
in the form of a map_int_Expr
.
Example:
RCP<const Symbol> x = symbol("x");
map_int_Expr dict = {{0, symbol("d")}, {1, 2}, {2, 3}, {3, symbol("a")}};
RCP<const UExprPoly> P = uexpr_poly(x, std::move(dict));
std::cout << P->__str__() << std::endl;
Output:
a*x**3 + 3*x**2 + 2*x + d
The UnivariateSeries
class is a series expansion module that can perform the Taylor Series expansion of a univariable polynomial. A UnivariateSeries
object holds:
- A variable (
std::string
) - A dictionary (
UExprDict(std::map)
) - The degree (
long
)
To use UnivariateSeries
in a C++ project, include:
#include <symengine/series_generic.h>
using SymEngine::RCP;
using SymEngine::UnivariateSeries;
using SymEngine::UExprDict;
using SymEngine::Symbol;
using SymEngine::symbol;
using SymEngine::Expression;
using SymEngine::map_int_Expr;
Individual functionalities can be chosen separately, or can be used with just include using namespace SymEngine;
Return the coefficient at the degree deg
.
Example:
RCP<const Symbol> x = symbol("x");
auto p = cos(x);
auto ser = UnivariateSeries::series(p, x->get_name(), 3);
// print the 2nd-term coefficient
std::cout << *ser->get_coeff(2) << std::endl;
Output:
-1/2
RCP<const UnivariateSeries> series( const RCP<const Basic> &t, const std::string &x, unsigned int prec )
Compute the series expansion of t
with variable x
with precision prec
.
Example:
RCP<const Symbol> x = symbol("x");
auto p = sin(x);
auto ser = UnivariateSeries::series(p, x->get_name(), 10);
std::cout << *ser << std::endl;
Output:
(1/362880)*x**9 + (-1/5040)*x**7 + (1/120)*x**5 + (-1/6)*x**3 + x + O(x**10)
RCP<const UnivariateSeries> univariate_series( RCP<const Symbol> i, unsigned int prec, const UExprDict &s )
Construct a UnivariateSeries
object with variable i
and a dictionary s
with precision prec
.
Example:
RCP<const Symbol> x = symbol("x");
UExprDict dict({{0, 1}, {1, 2}, {2, 1}});
RCP<const UnivariateSeries> P = univariate_series(x, 2, dict);
std::cout << P->__str__() << std::endl;
Output:
x**2 + 2*x + 1 + O(x**2)
To use the multivariable polynomial module, write #include <symengine/polynomial_multivariate.h>
at the top of your file.
Both MultivariateIntPolynomialExpr
and MultivariatePolynomialExpr
objects and the associated functions exist in the namespace SymEngine
.
Currently in SymEngine there are two multivariable polynomial classes: MultivariateIntPolynomialExpr
and MultivariatePolynomialExpr
. A MultivariateIntPolynomialExpr
can hold a multivariable polynomial with integer_class
coefficients, while a MultivariatePolynomialExpr
can hold a multivariable Laurent polynomial with Expression
coefficients. The creation of a multivariable polynomial should be handled by calling the appropriate create function
MultivariateIntPolynomialExpr p1 = MultivariateIntPolynomialExpr::create({x,y,z}, {{{0,0,0},1_z}
{{0,0,1},2_z}, {{0,1,0},3_z},{{1,0,0},4_z},{{2,0,2},5_z}});
MultivariatePolynomialExpr p2 = MultivariatePolynomialExpr::create({x,y,z}, {{{0,0,0},Expression(symbol(“a”))},
{{0,0,1},Expression(symbol(“b”))}, {{0,1,0},Expression(symbol(“c”))},{{1,0,0},Expression(symbol(“d”)
{{1,2,0},Expression(symbol(“f”))}});
The first argument of the create function is a vec_basic
(std::vector<RCP<const Basic>>
) which contains the generators for the polynomial. The second argument is the dictionary of the polynomial, which is a map from vectors of exponents to coefficients -- so above, p1
is a polynomial representing 1 + 2*z + 3*y + 4*z + 5*x**2 z**2
and p2
represents a + b*z + c*y + d*x + f*x y**2
. In the case of MultivariateIntPolynomialExpr
the dictionary should be an umap_uvec_mpz
(std::unordered_map<vec_uint, integer_class, vec_uint_hash>
) and the dictionary of a MultivariatePolynomialExpr
should be a umap_vec_expr
(std::unordered_map<vec_int, Expression, vec_int_hash>
).
Multivariable Polynomials can also be created from the appropriate univariable polynomials, like so
RCP<const UIntPoly> p1 = uint_poly(x, UExprDict({{1,1_z},{2,2_z},{3,2_z}}));
RCP<const UExprPoly> p2 = uexpr_poly(x, UExprDict({{1,Expression(1)},{2,Expression(2)},{3,Expression(2)}}));
MultivariateIntPolynomialExpr q1 = MultivariateIntPolynomialExpr::convert(*p1);
MultivariatePolynomialExpr q2 = MultivariatePolynomialExpr::convert(*p2);
String printing can be performed by means of the toString()
function
MultivariateIntPolynomialExpr p1 = MultivariateIntPolynomialExpr::create({x,y,z}, {{{0,0,0},1_z}
{{0,0,1},2_z}, {{0,1,0},3_z},{{1,0,0},4_z},{{2,0,2},5_z}});
MultivariatePolynomialExpr p2 = MultivariatePolynomialExpr::create({x,y,z}, {{{0,0,0},Expression(symbol(“a”))},
{{0,0,1},Expression(symbol(“b”))}, {{0,1,0},Expression(symbol(“c”))},{{1,0,0},Expression(symbol(“d”)
{{1,2,0},Expression(symbol(“f”))}});
std::cout << p1.toString() << std::endl;
std::cout << ps.toString() << std::endl;
Arithmetic operations
Addition, subtraction, and multiplication between multivariable polynomials and between multivariable polynomials and the associated univariable polynomial classes can be performed by non-member functions. For example, with MultivariatePolynomialExpr
s and UExprPoly
’s:
MultivariatePolynomialExpr p1 = MultivariatePolynomialExpr::create({x,y,z},{{{0,0,0},Expression(1)}
{{0,0,1},Expression(2)}, {{0,1,0},Expression(3)},{{1,0,0},Expression(4)},{{2,0,2},Expression(5)}});
MultivariatePolynomialExpr p2 = MultivariatePolynomialExpr::create({w,x,y},{{{0,0,0},Expression(6)},
{{0,0,1},Expression(7)}, {{0,1,0},Expression(8)},{{1,0,0},Expression(9)},{{2,0,2},Expression(10)}});
RCP<const UExprPoly> p3 = uexpr_poly(x, UExprDict({{1,Expression(1)},{2,Expression(2)},{3,Expression(2)}}));
RCP<const UExprPoly> p4 = uexpr_poly(y, UExprDict({{1,Expression(1)},{2,Expression(2)},{3,Expression(2)}}));
MultivariatePolynomialExpr q1 = add_mult_poly(p1,p2);
q1 = add_mult_poly(p1,*p3);
q1 = add_mult_poly(*p3,*p4);
q1 = mul_mult_poly(p1,p2);
q1 = mul_mult_poly(p1,*p3);
q1 = mul_mult_poly(*p3,*p4);
q1 = sub_mult_poly(p1,p2);
q1 = sub_mult_poly(p1,*p3);
q1 = sub_mult_poly(*p3,*p4);
The operations with MultivariateIntPolynomialExpr
s are similar. Additionally, operations purely between multivariable polynomials can be performed by member functions.
MultivariatePolynomialExpr p1 = MultivariatePolynomialExpr::create({x,y,z},{{{0,0,0},Expression(1)},
{{0,0,1},Expression(2)}, {{0,1,0},Expression(3)},{{1,0,0},Expression(4)},{{2,0,2},Expression(5)}});
MultivariatePolynomialExpr p2 = MultivariatePolynomialExpr::create({w,x,y},{{{0,0,0},Expression(6)},
{{0,0,1},Expression(7)}, {{0,1,0},Expression(8)},{{1,0,0},Expression(9)},{{2,0,2},Expression(10)}});
MultivariatePolynomialExpr q1 = p1.add(p2);
q1 = p1.sub(p2);
q1 = p1.mul(p2);
q1 = p1.neg();
MultivariateIntPolynomialExpr p3 = MultivariateIntPolynomialExpr::create({x,y,z},{{{0,0,0},1_z},
{{0,0,1},2_z}, {{0,1,0},3_z},{{1,0,0},4_z},{{2,0,2},5_z}});
MultivariateIntPolynomialExpr p4 = MultivariatePolynomialExpr::create({w,x,y},{{{0,0,0},6_z}, {{0,0,1},7_z},
{{0,1,0},8_z},{{1,0,0},9_z},{{2,0,2},10_z}});
MultivariateIntPolynomialExpr q2 = p3.add(p4);
q2 = p3.sub(p4);
q2 = p3.mul(p4);
q2 = p3.neg();
Multivariable polynomials can also be evaluated at n-tuples as follows:
MultivariatePolynomialExpr p1 = MultivariatePolynomialExpr::create({x,y,z},{{{0,0,0},Expression(1)},
{{0,0,1},Expression(2)}, {{0,1,0},Expression(3)},{{1,0,0},Expression(4)},{{2,0,2},Expression(5)}});
MultivariateIntPolynomialExpr p2 = MultivariateIntPolynomialExpr::create({x,y,z},{{{0,0,0},1_z},
{{0,0,1},2_z}, {{0,1,0},3_z},{{1,0,0},4_z},{{2,0,2},5_z}});
std::map<RCP<const Basic>, Expression, RCPBasicKeyLess> m1 = {{x,Expression(1)},{y,Expression(2)},{z,Expression(3)}};
std::map<RCP<const Basic>, integer_class, RCPBasicKeyLess> m2 = {{x,1_z},{y,2_z},{z,3_z}};
Expression n1 = p1->eval(m1);
integer_class n2 = p2->eval(m2);
The map passed to eval
should contain a key-value pair for each variable of the polynomial; partial evaluation is not supported.
Equality can be tested with the function __eq__
MultivariatePolynomialExpr p1 = MultivariatePolynomialExpr::create({x,y,z},{{{0,0,0},Expression(1)},
{{0,0,1},Expression(2)}, {{0,1,0},Expression(3)},{{1,0,0},Expression(4)},{{2,0,2},Expression(5)}});
MultivariatePolynomialExpr p2 = MultivariatePolynomialExpr::create({w,x,y},{{{0,0,0},Expression(6)},
{{0,0,1},Expression(7)}, {{0,1,0},Expression(8)},{{1,0,0},Expression(9)},{{2,0,2},Expression(10)}});
RCP<const UExprPoly> p3 = uexpr_poly(x, UExprDict({{1,Expression(1)},{2,Expression(2)},{3,Expression(2)}}));
RCP<const UExprPoly> p4 = uexpr_poly(y, UExprDict({{1,Expression(1)},{2,Expression(2)},{3,Expression(2)}}));
bool eq1 = p1->__eq__(*p2);
bool eq2 = p3->__eq__(*p4);
The get_args
function returns a vec_basic
containing RCP<const Basic>
s representing each term of the polynomial
MultivariatePolynomialExpr p1 = MultivariatePolynomialExpr::create({x,y,z},{{{0,0,0},Expression(1)},
{{0,0,1},Expression(2)}, {{0,1,0},Expression(3)},{{1,0,0},Expression(4)},{{2,0,2},Expression(5)}});
MultivariateIntPolynomialExpr p2 = MultivariateIntPolynomialExpr::create({x,y,z},{{{0,0,0},1_z},
{{0,0,1},2_z}, {{0,1,0},3_z},{{1,0,0},4_z},{{2,0,2},5_z}});
vec_basic b1 = p1->get_args();
vec_basic b2 = p2->get_args();
The following overloaded operators are provided for MultivariatePolynomialExpr
:
MultivariatePolynomialExpr& operator=( const MultivariatePolynomialExpr& );
MultivariatePolynomialExpr& operator=( const Expression& );
friend MultivariatePolynomialExpr operator+( const MultivariatePolynomialExpr&, const MultivariatePolynomialExpr& );
friend MultivariatePolynomialExpr operator+( const MultivariatePolynomialExpr&, const Expression& );
friend MultivariatePolynomialExpr operator+( const Expression&, const MultivariatePolynomialExpr& );
MultivariatePolynomialExpr& operator+=( const MultivariatePolynomialExpr& );
MultivariatePolynomialExpr& operator+=( const Expression& );
friend MultivariatePolynomialExpr operator-( const MultivariatePolynomialExpr&, const MultivariatePolynomialExpr& );
friend MultivariatePolynomialExpr operator-( const MultivariatePolynomialExpr&, const Expression& );
friend MultivariatePolynomialExpr operator-( const Expression&, const MultivariatePolynomialExpr& );
MultivariateExprPolynomial& operator-=( const MultivariatePolynomialExpr& );
MultivariatePolynomialExpr& operator-=( const Expression& );
MultivariateExprPolynomial operator-( ) const;
friend MultivariatePolynomialExpr operator*( const MultivariatePolynomialExpr&, const MultivariatePolynomialExpr& );
friend MultivariatePolynomialExpr operator*( const MultivariatePolynomialExpr&, const Expression& );
friend MultivariatePolynomialExpr operator*( const Expression&, const MultivariatePolynomialExpr& );
MultivariateExprPolynomial& operator*= (const MultivariatePolynomialExpr& );
MultivariatePolynomialExpr& operator*=( const Expression& );
friend MultivariatePolynomialExpr operator/( const MultivariatePolynomialExpr&, const Expression& )/
MultivariatePolynomialExpr& operator/=( const Expression &b );
bool operator==( const MultivariatePolynomialExpr& );
bool operator==( const Expression );
bool operator!=( const MultivariatePolynomialExpr& );
bool operator!=( const Expression& );
To access the multivariable series module, write #include <symengine/series_generic_multivariate.h>
at the top of your file.
The MultivariateSeries
object and the mult_series
functions all exist in the namespace SymEngine
.
Two MultivariateSeries
constructors are provided. The first is the same constructor provided for all SeriesBase
objects:
MultivariatePolynomialExpr p1 = MultivariatePolynomialExpr::create({x},{{{0},Expression(0)},{{1},Expression(1)},{{2},Expression(3)}}));
RCP<const MultivariateSeries> s = make_rcp<const MultivariateSeries>(p,”x”,10);
If the polynomial passed to this constructor has more than one generator, or the generator of the polynomial does not match the second argument, SYMENGINE_ASSERT
will fail in debug mode.
The second constructor takes a map_basic_uint
(std::map<RCP<const basic>, unsigned int, RCPSymbolCompare>
) in addition to the parameters demanded by the first constructor. The map_basic_uint
defines the precision of the series.
MultivariatePolynomialExpr p1 = MultivariatePolynomialExpr::create({x,y},{{{0},Expression(0)},{{1},Expression(1)},{{2},Expression(3)}}));
map_basic_uint m = {{x,10},{y,10},{z,240}}
RCP<const MultivariateSeries> s = make_rcp<const MultivariateSeries>(p,”x”,10, m);
If the image of a generator in the map_basic_uint
is not greater than the degree of that generator in the polynomial, or if a generator of the polynomial is not represented in the map_basic_uint
, SYMENGINE_ASSERT
will fail in debug mode.
For both constructors, if the polynomial is non-constant and does not have the generator symbol(var)
, SYMENGINE_ASSERT
will fail in debug mode.
A MultivariateSeries can also be created by the create
or multivariate_series
functions, both of which call the first constructor.
MultivariatePolynomialExpr p1 = MultivariatePolynomialExpr::create({x},{{{0},Expression(0)},{{1},Expression(1)},{{2},Expression(3)}});
RCP<const MultivariateSeries> s = MultivariateSeries::create(x,10,p1);
s = multivariate_series(x,10,p1) ;
get_coeff
will return the coefficient of the series associated with a particular degree term. For this function, we treat the series as if it were solely in terms of the generator corresponding to the variable var
, so that if the series s
represents x**2 y + x**2 + x + y + O(|x|**3 + |y|**3)
with var
equal to “x”
, s->get_coeff(2)
should equal y + 1
. This object is returned as an object of type Add
rather than as a polynomial.
MultivariatePolynomialExpr p1 = MultivariatePolynomialExpr::create({x,y},{{{0,0},Expression(0)},{{2,0},Expression(1)},{{0,2},Expression(3)}}));
map_basic_uint m = {{x,10},{y,10},{z,240}}
RCP<const MultivariateSeries> s = make_rcp<const MultivariateSeries>(p,”x”,10, m);
RCP<const Basic> p = s->get_coeff(9);
Series expansion with respect to a single variable can be done in the same manner as any other SeriesBase
object.
RCP<const Basic> f = sin(x);
RCP<const MultivariateSeries> s = MultivariateSeries::series(f,”x”,10);
There are a couple of methods for performing series expansion with respect to multiple variables. The first, mult_series1
, is a reference implementation which calculates the expansion through repeated differentiation.
RCP<const Basic> f = sin(add(x,y));
RCP<const MultivariateSeries> s = mult_series1(f,{{x,5},{y,5}});
The first argument is a RCP<const Basic>
representing the function to be expanded; the second determines the precision in each variable to which the function will be expanded.
The mult_series
is a template which calculates the expansion by calculating the series expansion for each variable in turn. The template parameter Series
determines the series object used in this expansion; it can take any SeriesBase
type object. Regardless of the value of Series
, mult_series
will always return a MultivariableSeries. The arguments are the same as for mult_series1
.
RCP<const Basic> f = sin(add(x,y));
RCP<const MultivariateSeries> s = mult_series<MultivariateSeries>(f,{{x,5},{y,5}});
RCP<const MultivariateSeries> s = mult_series<UnivariateSeries>(f,{{x,5},{y,5}});