NAME
Sidef::Types::Number::Polynomial - Univariate polynomial arithmetic and operations
DESCRIPTION
This class implements univariate polynomials with arbitrary-precision coefficients. Polynomials are represented as mathematical expressions in a single variable (x), supporting arithmetic, evaluation, differentiation, root-finding, and algebraic manipulation.
Internally, polynomials are stored as a sparse hash mapping integer exponents to their coefficients (Sidef::Types::Number::Number objects). Terms with a zero coefficient are never stored, making the representation efficient for sparse polynomials with many zero terms.
SYNOPSIS
# Constructors
var a = Polynomial(5) # monomial x^5
var b = Polynomial([1, 2, 3, 4]) # x^3 + 2*x^2 + 3*x + 4
var c = Polynomial(5 => 3, 2 => 10) # 3*x^5 + 10*x^2
var d = Polynomial("x^3 - 2*x + 1") # parsed from string
# Arithmetic
var sum = b + c # polynomial addition
var prod = b * c # polynomial multiplication
var quot = b / c # polynomial division
# Evaluation
say(b.eval(2)) # evaluate at x=2: 26
# Algebraic operations
say(b.derivative) # 3*x^2 + 4*x + 3
say(b.roots) # numerical roots
say(b.gcd(c)) # greatest common divisor
COEFFICIENT ORDER IN ARRAY CONSTRUCTORS
When building a polynomial from an array, coefficients are supplied in descending degree order (highest-degree first):
Polynomial([a_n, a_{n-1}, ..., a_1, a_0])
# represents: a_n*x^n + a_{n-1}*x^{n-1} + ... + a_1*x + a_0
Examples:
Polynomial([1, 2, 3]) # x^2 + 2*x + 3 (NOT 3*x^2 + 2*x + 1)
Polynomial([1, 0, -1]) # x^2 - 1
Polynomial([1, 0, 0, 1]) # x^3 + 1
Individual array elements may also be [exponent, coefficient] pairs to set a coefficient at an explicit degree:
Polynomial([[3, 2], [1, 5]]) # 2*x^3 + 5*x
INHERITS
Inherits methods from:
Sidef::Types::Number::Number
METHODS
new
Polynomial(n)
Polynomial([c_n, ..., c_1, c_0])
Polynomial("expression")
Polynomial(exp1 => coeff1, exp2 => coeff2, ...)
self.new(value)
Constructs a new Polynomial object. The following calling forms are supported:
- Monomial — a single
Numberargumentn: creates the monomialx^n. -
Polynomial(5) # x^5 Polynomial(0) # x^0 = 1 - Array — a single array-ref argument: coefficients in descending degree order.
-
Polynomial([1, 2, 3]) # x^2 + 2*x + 3Array elements may themselves be
[exponent, coeff]pairs for explicit placement:Polynomial([[2, 1], [0, 3]]) # x^2 + 3 - String — a single string argument: parses an algebraic expression. Supports terms of the form
[±][coefficient[/denominator]*]x[^exponent], as well as fraction syntax(numerator)/(denominator). -
Polynomial("3*x^2 + 2*x + 1") # 3*x^2 + 2*x + 1 Polynomial("x^3 - 5") # x^3 - 5 Polynomial("1/2*x^2 + 3/4") # (1/2)*x^2 + 3/4 - Sparse key-value pairs — alternating exponent/coefficient arguments:
-
Polynomial(5 => 3, 2 => 10) # 3*x^5 + 10*x^2 Polynomial(0 => 7) # constant 7Zero coefficients are silently dropped.
- Instance call with one argument — when called as a method on an existing polynomial, evaluates that polynomial at the given value (equivalent to "eval"):
-
var p = Polynomial([1, 0, -1]) # x^2 - 1 say(p.new(3)) # 3^2 - 1 = 8
Aliases: call
+
a + b
Returns the sum of a and b. When both arguments are polynomials, corresponding coefficients are added. When b is a scalar, it is added to the constant term (x^0 coefficient), inserting it if absent.
say(Polynomial([1, 2]) + Polynomial([3, 4])) # 4*x + 6
Aliases: add
++
a++
Adds 1 to the constant term of a. Returns a new polynomial with the x^0 coefficient incremented by one.
var p = Polynomial([1, 2, 3])
p++
say(p) # x^2 + 2*x + 4
Aliases: inc
-
a - b
Returns the difference a - b. When both arguments are polynomials, corresponding coefficients are subtracted. When b is a scalar, it is subtracted from the constant term, inserting a negated term if absent.
say(Polynomial([1, 2, 3]) - Polynomial([0, 1])) # x^2 + x + 3
Aliases: sub
--
a--
Subtracts 1 from the constant term of a. Returns a new polynomial with the x^0 coefficient decremented by one.
var p = Polynomial([1, 2, 3])
p--
say(p) # x^2 + 2*x + 2
Aliases: dec
*
a * b
Returns the product of a and b. When both are polynomials, performs full polynomial multiplication (convolution of coefficients): the degree of the result equals deg(a) + deg(b). When b is a scalar, each coefficient is multiplied by b.
say(Polynomial([1, 2, 3]) * Polynomial([4, 5]))
# (x^2 + 2*x + 3) * (4*x + 5) = 4*x^3 + 13*x^2 + 22*x + 15
Aliases: mul
sqr
x.sqr
Returns the square of x. Equivalent to x * x.
say(Polynomial([1, 1]).sqr) # (x+1)^2 = x^2 + 2*x + 1
**
a ** n
Returns a raised to the power n using binary (square-and-multiply) exponentiation.
If
nis a non-negative integer, returns the polynomial product.If
nis a negative integer, returnsFraction(1, a^|n|)— a rational function.If
nis not an integer, falls back toa.to_n.pow(n), converting the polynomial to a scalar first (only valid for constant polynomials).
say(Polynomial([1, 1]) ** 3)
# (x+1)^3 = x^3 + 3*x^2 + 3*x + 1
Aliases: pow
/
a / b
Divides a by b.
If
bis a polynomial and division is exact (zero remainder), returns the quotient polynomial.If the division is inexact, returns a
Sidef::Types::Number::Fractionrepresenting the rational function(q*b + r) / bwhereq,rare the quotient and remainder.If
bis zero, returns a polynomial with an infinite coefficient.If
bis a scalar, divides each coefficient byb.
say(Polynomial([1, 0, -1]) / Polynomial([1, -1]))
# (x^2 - 1) / (x - 1) = x + 1 (exact)
Aliases: ÷, div
//
a // b
Returns only the quotient polynomial from Euclidean division, discarding the remainder. Equivalent to the first element of "divmod".
Note: The rounding-mode variants (idiv_ceil, idiv_floor, idiv_round, idiv_trunc) are all currently aliased to the same floor-division behaviour.
Aliases: idiv, idiv_ceil, idiv_floor, idiv_round, idiv_trunc
%
a % b
Returns the remainder polynomial from Euclidean division of a by b, i.e. the polynomial r of degree less than deg(b) satisfying a = q*b + r. When b is a scalar, each coefficient is reduced modulo b by wrapping it in a Sidef::Types::Number::Mod object.
say(Polynomial([1, 0, 0, 0]) % Polynomial([1, 0, 1]))
# x^3 mod (x^2+1) = -x (since x^3 = x*(x^2+1) - x)
Aliases: mod
divmod
x.divmod(y)
Performs Euclidean polynomial long division and returns a two-element list (quotient, remainder) satisfying:
x == (quotient * y) + remainder
deg(remainder) < deg(y)
Returns (NaN, zero) if the leading coefficient of y is zero or NaN.
var (q, r) = Polynomial([1, 0, 0]) .divmod( Polynomial([1, 1]) )
# x^2 ÷ (x+1) => q = x-1, r = 1
neg
x.neg
Returns the additive inverse of x: all coefficients are negated. Adding x and x.neg gives the zero polynomial.
say(Polynomial([1, 2, 3]).neg) # -x^2 - 2*x - 3
abs
x.abs
Returns x * x.sgn, i.e. the polynomial multiplied by the sign of its leading coefficient. This ensures the leading coefficient is positive. For the zero polynomial, returns zero.
say(Polynomial([-1, 2, -3]).abs)
# -x^2 + 2*x - 3 has leading coeff -1, so abs = x^2 - 2*x + 3
sgn
x.sgn
Returns the sign of the leading coefficient of x: -1, 0, or 1 as a Sidef::Types::Number::Number. Returns 0 for the zero polynomial.
inv
x.inv
Returns a Sidef::Types::Number::Fraction representing 1/x. This creates the rational function 1 / x(t). Meaningful as an exact inverse only when x is a constant polynomial; for non-constant polynomials in a quotient ring, see Sidef::Types::Number::PolynomialMod.
invmod
x.invmod(m)
Computes x.mod(m).inv: reduces x modulo the polynomial m and then returns its multiplicative inverse. Equivalent to creating PolynomialMod(x, m).inv.
powmod
x.powmod(n, m)
Computes x^n mod m using binary (square-and-multiply) exponentiation, reducing modulo polynomial m after each multiplication step. More efficient than computing x**n and then taking % m separately for large n.
say(Polynomial([1, 1]).powmod(100, Polynomial([1, 0, 1])))
# (x+1)^100 mod (x^2+1)
gcd
x.gcd(y)
Returns the greatest common divisor of polynomials x and y using the polynomial Euclidean algorithm. Handles zero polynomials explicitly: gcd(x, 0) = x and gcd(0, y) = y. The result is normalized to monic (leading coefficient equal to 1) before being returned.
var p = Polynomial([1, 0, -1]) # x^2 - 1
var q = Polynomial([1, -1]) # x - 1
say(p.gcd(q)) # x - 1 (monic)
Reference: https://en.wikipedia.org/wiki/Polynomial_greatest_common_divisor#Euclid's_algorithm
gcdext
x.gcdext(y)
Extended Euclidean algorithm for polynomials. Returns a list of five values:
(g, u, v, a1, b1)
where g = gcd(x, y) and u, v are Bézout coefficient polynomials satisfying:
(u * x) + (v * y) == g
The additional values a1 and b1 are the final-step remainder polynomials scaled by a sign factor (-1)^i; they are the cofactors of the last non-trivial step and satisfy x/g = ±a1, y/g = ±b1 in the monic-normalised sense.
Note: The return list has five elements. If you only need the GCD and Bézout pair, capture just the first three:
var (g, u, v) = x.gcdext(y)
say(((u * x) + (v * y)) == g) # true
lcm
x.lcm(y)
Returns the least common multiple of polynomials x and y, computed as:
lcm(x, y) = abs(x * y) / gcd(x, y)
The abs ensures the leading coefficient of the result is positive.
normalize_to_monic
x.normalize_to_monic
Returns a monic version of x by dividing all coefficients by the leading coefficient. If the leading coefficient is already 1, returns x unchanged. If the leading coefficient is zero or the polynomial is empty, returns x unchanged.
say(Polynomial([3, 6, 9]).normalize_to_monic) # x^2 + 2*x + 3
is_squarefree
x.is_squarefree
Returns true if x has no repeated irreducible factors, i.e. if gcd(x, x.derivative) equals 1 (the constant polynomial 1, monic of degree 0). Equivalently, x is square-free if and only if it shares no root with its own derivative.
say(Polynomial([1, 0, -1]).is_squarefree) # true (x^2-1 = (x-1)(x+1))
say(Polynomial([1, -2, 1]).is_squarefree) # false (x^2-2x+1 = (x-1)^2)
squarefree_part
x.squarefree_part
Returns the square-free part of x: the result of dividing x by gcd(x, x.derivative). The square-free part has the same roots as x but each root occurs with multiplicity at most 1.
say(Polynomial([1, -2, 1]).squarefree_part)
# (x-1)^2 → squarefree part is (x-1)
say(Polynomial([1, 0, 0, 0]).squarefree_part)
# x^3 → squarefree part is x
derivative
x.derivative
Returns the formal derivative of x using the power rule: each term c_k * x^k maps to k * c_k * x^{k-1}. The constant term (k=0) is dropped. Works with any coefficient type, including complex or rational coefficients.
var p = Polynomial([1, 0, -3, 2]) # x^3 - 3*x + 2
say(p.derivative) # 3*x^2 - 3
eval
x.eval(value)
Evaluates the polynomial at value by computing the sum:
sum of: coeff_k * value^k for each nonzero term k
Each coefficient is itself evaluated at value via its own .eval method, allowing polynomials with polynomial coefficients (multivariate use). Returns 0 for the zero polynomial.
Operator-precedence note: when chaining say with eval, wrap in parentheses:
var p = Polynomial([1, 2, 3]) # x^2 + 2*x + 3
say(p.eval(5)) # 25 + 10 + 3 = 38
newton_method
f.newton_method
f.newton_method(x0)
f.newton_method(x0, df)
Applies Newton's method to find a root of f, starting from initial guess x0. Both x0 and df (the derivative polynomial) are optional:
x0defaults toNumber::i(the complex uniti = sqrt(-1)).dfdefaults tof.derivative.
The iteration x_{n+1} = x_n - f(x_n) / f'(x_n) runs for up to PREC steps (the current working precision). Returns the last refined approximation, which equals an actual root when convergence is detected (f(x) rounds to zero within precision).
var f = Polynomial([1, 0, -2]) # x^2 - 2
var df = f.derivative
say(f.newton_method(1.5, df)) # ≈ 1.41421356... (√2)
roots
f.roots
Attempts to find all roots of f numerically. Returns an Sidef::Types::Array::Array of root values (which may be complex numbers).
The algorithm:
- 1. Uses
deg(f)evenly-spaced roots of unity as initial guesses. - 2. Applies Newton's method from each starting point.
- 3. If fewer than
deg(f)distinct roots are found, retries with transformed starting points (e.g. multiplied byi,exp, etc.).
Only distinct roots are returned (duplicates within working precision are collapsed). For polynomials with repeated roots, some roots may be missed.
say(Polynomial([1, 0, -1]).roots) # [-1, 1] (roots of x^2 - 1)
say(Polynomial([1, 0, 0, -1]).roots) # roots of x^3 - 1
binomial
n.binomial(k)
Computes the generalised binomial coefficient C(n, k) where n is a Polynomial and k is a non-negative integer, using the falling-factorial definition:
C(n, k) = (n * (n-1) * (n-2) * ... * (n-k+1)) / k!
The numerator product is computed via binary splitting for efficiency. Returns the constant polynomial 1 when k = 0.
var x = Polynomial(1) # x (monomial x^1)
say(x.binomial(2)) # x*(x-1)/2
degree
x.degree
Returns the degree of the polynomial: the highest exponent with a non-zero coefficient, as a Sidef::Types::Number::Number. Returns 0 for the zero polynomial (the empty polynomial has no keys, so the fallback value is 0).
say(Polynomial([1, 2, 3]).degree) # 2
say(Polynomial([]).degree) # 0 (zero polynomial)
Aliases: deg
coeff
x.coeff(k)
Returns the coefficient of the term with exponent k. Returns 0 if no such term exists.
var p = Polynomial([3, 2, 1]) # 3*x^2 + 2*x + 1
say(p.coeff(0)) # 1 (constant term)
say(p.coeff(1)) # 2 (coefficient of x)
say(p.coeff(2)) # 3 (coefficient of x^2)
say(p.coeff(5)) # 0 (absent term)
coeffs
x.coeffs
Returns an Array of [exponent, coefficient] pairs for all nonzero terms, sorted in ascending order by exponent (lowest degree first).
var p = Polynomial([1, 2, 3]) # x^2 + 2*x + 3
say(p.coeffs)
# [[0, 3], [1, 2], [2, 1]]
# (constant term first, highest-degree term last)
exponents
x.exponents
Returns an Array of all exponents that have nonzero coefficients, sorted in ascending order.
say(Polynomial(5 => 3, 2 => 1).exponents) # [2, 5]
content
x.content
Returns the content of the polynomial: the GCD of all its coefficients. Useful for extracting the largest scalar factor.
say(Polynomial([6, 9, 12]).content) # 3 (gcd(6,9,12))
Aliases: cont
primitive_part
x.primitive_part
Returns the primitive part of x: the polynomial divided by its content. The result has integer coefficients whose GCD is 1.
say(Polynomial([6, 9, 12]).primitive_part)
# (6*x^2 + 9*x + 12) / 3 = 2*x^2 + 3*x + 4
Aliases: prim_part, primpart
leading_coefficient
x.leading_coefficient
Returns the coefficient of the highest-degree term. Returns 0 for the zero polynomial.
say(Polynomial([3, 2, 1]).leading_coefficient) # 3
Aliases: leading_coeff
leading_term
x.leading_term
Returns the leading term of x as a Polynomial consisting of only the highest-degree term (with its coefficient intact).
say(Polynomial([3, 2, 1]).leading_term) # 3*x^2
leading_monomial
x.leading_monomial
Returns the leading monomial of x: the highest-degree term with its coefficient replaced by 1.
say(Polynomial([3, 2, 1]).leading_monomial) # x^2
height
x.height
Returns the maximum absolute value among all coefficients of x. Also called the infinity norm or Chebyshev norm of the coefficient vector.
say(Polynomial([3, -5, 2]).height) # 5
re
x.re
Returns the constant term (coefficient of x^0) of the polynomial, as a Sidef::Types::Number::Number. Returns 0 if no constant term is present. This reflects the embedding of scalars into the polynomial ring.
say(Polynomial([1, 2, 3]).re) # 3 (a Number, not a Polynomial)
Aliases: real
is_real
x.is_real
Returns true if and only if x is effectively a real scalar constant: either the zero polynomial, or a polynomial with a single term at degree 0 whose coefficient satisfies .is_real. Returns false for any polynomial with a non-zero higher-degree term.
say(Polynomial([5]).is_real) # true (constant real)
say(Polynomial([1, 0]).is_real) # false (non-constant)
is_zero
x.is_zero
Returns true if x is the zero polynomial (no nonzero terms).
say(Polynomial([]).is_zero) # true (empty polynomial)
say(Polynomial([0, 1]).is_zero) # false (x is not zero)
is_one
x.is_one
Returns true if x equals the constant polynomial 1 (the multiplicative identity).
say(Polynomial([1]).is_one) # true
say(Polynomial([1, 0]).is_one) # false (this is x, not 1)
is_mone
x.is_mone
Returns true if x equals the constant polynomial -1.
is_nan
x.is_nan
Returns true if any coefficient of the polynomial is NaN. A NaN coefficient can appear as a result of invalid operations such as division by zero or failed modular inversion.
is_inf
x.is_inf
Returns true if any coefficient of the polynomial is positive infinity.
is_ninf
x.is_ninf
Returns true if any coefficient of the polynomial is negative infinity.
norm
x.norm
Returns the norm of the constant term: x.real.norm. This is the norm of the x^0 coefficient as a number, not the Euclidean norm of the coefficient vector.
to_n
x.to_n
Converts the polynomial to a scalar Sidef::Types::Number::Number:
Zero polynomial (no terms): returns
0.Constant polynomial (only a
x^0term, all others zero or absent): returns the constant coefficient.Non-constant polynomial: returns
NaN.
to_poly
x.to_poly
Returns the polynomial itself. Provides a uniform interface for type conversion (e.g. PolynomialMod overrides this to return the underlying residue polynomial).
lift
x.lift
Returns a new Polynomial with each coefficient replaced by its .lift value. For plain Number coefficients this is a no-op (returns an equivalent copy). For polynomials with Mod-valued coefficients (e.g. after calling .mod(n) on a polynomial over a modular ring), lift unwraps each coefficient from its modular context.
float
x.float
Returns a new Polynomial with each coefficient converted to a floating-point approximation.
rat
x.rat
Returns a new Polynomial with each coefficient converted to an exact rational number (Math::GMPq).
rat_approx
x.rat_approx
Returns a new Polynomial with each floating-point coefficient replaced by a nearby rational approximation.
floor
x.floor
Returns a new Polynomial with floor() applied to each coefficient, rounding each one down to the nearest integer.
say(Polynomial([1.8, 2.3]).floor) # x + 2
ceil
x.ceil
Returns a new Polynomial with ceil() applied to each coefficient, rounding each one up to the nearest integer.
say(Polynomial([1.5, 2.3]).ceil) # 2*x + 3
round
x.round(r)
Returns a new Polynomial with each coefficient rounded to r decimal places (or to the nearest integer when r is zero).
say(Polynomial([1.456, 2.789]).round(1)) # 1.5*x + 2.8
!=
a != b
Returns true if a and b are not equal. Implemented as the logical negation of "==". See "==" for equality semantics.
Aliases: ne
==
a == b
Returns true if a equals b.
Polynomial vs Polynomial: true if every coefficient of
aequals the corresponding coefficient ofb(missing coefficients are treated as zero). Comparison is symmetric.Polynomial vs scalar: true if
ais a constant polynomial whosex^0coefficient equals the scalar, and all other coefficients are zero.
Aliases: eq
<=>
a <=> b
Three-way comparison. Returns -1, 0, or 1.
Polynomial vs Polynomial:
Polynomial vs scalar: only defined for constant polynomials (all non-constant coefficients zero). Returns
undeffor non-constant polynomials when compared against a scalar.
Aliases: cmp
<
a < b
Returns true if a is strictly less than b under the ordering defined by "<=">.
Aliases: lt
>
a > b
Returns true if a is strictly greater than b.
Aliases: gt
≤
a ≤ b
Returns true if a is less than or equal to b.
Aliases: <=, le
≥
a ≥ b
Returns true if a is greater than or equal to b.
Aliases: >=, ge
to_s
x.to_s
Returns a Sidef::Types::String::String representation of the polynomial in standard mathematical notation, with terms ordered from highest to lowest degree:
say(Polynomial([1, 2, 3]).to_s) # "x^2 + 2*x + 3"
say(Polynomial([1, 0, -1]).to_s) # "x^2 - 1"
say(Polynomial([]).to_s) # "0"
Coefficient 1 is suppressed (x not 1*x); negative signs replace leading +. Parentheses are added around complex coefficients.
Aliases: stringify
pretty
x.pretty
Like "to_s" but calls the .pretty method on each coefficient rather than .to_s. This may produce Unicode formatting (e.g. Unicode fractions or superscripts) depending on the coefficient type.
dump
x.dump
Returns a Sidef::Types::String::String showing the polynomial's internal sparse representation, suitable for debugging and round-tripping:
say(Polynomial([1, 2, 3]).dump)
# Polynomial(0 => 3, 1 => 2, 2 => 1)
Terms are listed in ascending exponent order with each coefficient shown via its own .dump.
BOOLEAN CONTEXT
In boolean context (if, while, etc.), a Polynomial is truthy if its constant term (x^0 coefficient) is truthy, and falsy if zero or absent.
if (Polynomial([1, 0])) { ... } # falsy: no constant term
if (Polynomial([1, 3])) { ... } # truthy: constant term is 3
EXAMPLES
Basic arithmetic
var p = Polynomial([1, -2, 1]) # x^2 - 2*x + 1 = (x-1)^2
var q = Polynomial([1, -1]) # x - 1
var sum = (p + q)
say(sum) # x^2 - x
var prod = (p * q)
say(prod) # x^3 - 3*x^2 + 3*x - 1
var (quot, rem) = p.divmod(q)
say(quot) # x - 1
say(rem) # 0
say(p.eval(3)) # 9 - 6 + 1 = 4
say(p.eval(1)) # 0 (1 is a double root)
Differentiation
var p = Polynomial([1, 0, -3, 2]) # x^3 - 3*x + 2
var dp = p.derivative
say(dp) # 3*x^2 - 3
say(dp.derivative) # 6*x
Root finding
say(Polynomial([1, 0, -1]).roots) # roots of x^2-1: [-1, 1]
say(Polynomial([1, 0, 1]).roots) # roots of x^2+1: [-i, i]
GCD, extended GCD, and Bézout identity
var p = Polynomial([1, 0, -1]) # x^2 - 1
var q = Polynomial([1, -1]) # x - 1
say(p.gcd(q)) # x - 1
var (g, u, v) = p.gcdext(q)
say(g) # x - 1
say(((u * p) + (v * q)) == g) # true
Content and primitive part
var r = Polynomial([6, 9, 12]) # 6*x^2 + 9*x + 12
say(r.content) # 3
say(r.primitive_part) # 2*x^2 + 3*x + 4
Square-free decomposition
var p = Polynomial([1, -2, 1]) # (x-1)^2
say(p.is_squarefree) # false
say(p.squarefree_part) # x - 1
Modular polynomial exponentiation
var base = Polynomial([1, 1]) # x + 1
var mod = Polynomial([1, 0, 1]) # x^2 + 1
say(base.powmod(10, mod))
# (x+1)^10 mod (x^2+1)
Sparse construction and inspection
var p = Polynomial(7 => 1, 3 => 5, 0 => 2) # x^7 + 5*x^3 + 2
say(p.degree) # 7
say(p.exponents) # [0, 3, 7]
say(p.coeff(3)) # 5
say(p.height) # 5
String constructor
var p = Polynomial("3*x^2 - 2*x + 1")
say(p.eval(0)) # 1
say(p.eval(1)) # 2
Newton's method
var f = Polynomial([1, 0, -2]) # x^2 - 2
var df = f.derivative # 2*x
say(f.newton_method(1.5, df)) # ≈ 1.41421356... (√2)
NOTES
Zero polynomial: The zero polynomial is represented as an empty hash (no keys). Its degree is 0, not -1 or -∞. Use
.is_zeroto test for it explicitly.Coefficient ring: Coefficients are arbitrary
Sidef::Types::Number::Numberobjects — integers, rationals, floats, or even complex numbers. There is no restriction to any particular coefficient ring.No operator precedence: See the "IMPORTANT: OPERATOR PRECEDENCE" section at the top of this document. All operators share equal precedence and associate left-to-right. When in doubt, add parentheses.
Division: The
/operator returns aSidef::Types::Number::Fractionwhen division is inexact. Use//(idiv) to always get just the quotient polynomial, ordivmodto get both quotient and remainder.Comparison vs scalar: The
<=>operator returnsundef(not a defined value) when comparing a non-constant polynomial against a scalar. Guard with a defined-check when this is possible.
SEE ALSO
Sidef::Types::Number::Number, Sidef::Types::Number::PolynomialMod, Sidef::Types::Number::Fraction, Sidef::Types::Number::Mod
AUTHOR
Daniel Șuteu