NAME

Math::Polynomial - Perl class representing polynomials in one variable

VERSION

This documentation refers to version 1.000 of Math::Polynomial.

SYNOPSIS

  use Math::Polynomial 1.000;

  # simple constructors:
  $p  = Math::Polynomial->new(0, -3, 0, 2);    # (2*x**3 - 3*x)
  $zp = Math::Polynomial->new();               # the zero polynomial
  $zp = Math::Polynomial->new(0);              # the zero polynomial
  $q  = Math::Polynomial->monomial(3);         # (x**3)
  $r  = Math::Polynomial->monomial(3, 2);      # (2*x**3)

  # Lagrange interpolation:
  $s = Math::Polynomial->interpolate([0..3], [0, -1, 10, 45]);

  # constructors as object methods:
  $t = $p->new(0, -3, 0, 2);                   # (2*x**3 - 3*x)
  $u = $p->monomial(3, 2);                     # (2*x**3)
  $v = $p->interpolate([0..3], [0, -1, 10, 45]); # (2*x**3 - 3*x)

  # properties
  $coeff = $p->coeff(0);                       #     0
  $coeff = $p->coeff(1);                       #        -3
  $coeff = $p->coeff(2);                       #            0
  $coeff = $p->coeff(3);                       #               2
  $coeff = $p->coeff(4);                       # 0
  $const = $p->coeff_zero;                     # 0
  $const = $p->coeff_one;                      # 1
  @coeff = $p->coeff;                          #    (0, -3, 0, 2)
  @coeff = $zp->coeff;                         #    ()
  @coeff = $p->coefficients;                   #    (0, -3, 0, 2)
  @coeff = $zp->coefficients;                  #    (0)
  $n = $p->degree;                             # 3
  $n = $zp->degree;                            # -1
  $n = $p->proper_degree;                      # 3
  $n = $zp->proper_degree;                     # undef

  # evaluation
  $y = $p->evaluate(4);                        # 116

  # comparison
  $bool = !$p;         $bool = $p->is_zero;    # p(x) == 0 everywhere
  $bool = $p == $q;    $bool = $p->is_equal($q);      # equality
  $bool = $p != $q;    $bool = $p->is_unequal($q);    # inequality

  # arithmetic
  $q = -$p;            $q = $p->neg;           # q(x) == -p(x)
  $q = $p1 + $p2;      $q = $p1->add($p2);     # q(x) == p1(x) + p2(x)
  $q = $p1 - $p2;      $q = $p1->sub_($p2);    # q(x) == p1(x) - p2(x)
  $q = $p1 * $p2;      $q = $p1->mul($p2);     # q(x) == p1(x) * p2(x)
  $q = $p1 / $p2;      $q = $p1->div($p2);     # p1 == q * p2 + r,
                                               #   deg r < deg p2
  $r = $p1 % $p2;      $r = $p1->mod($p2);     # p1 == q * p2 + r,
                                               #   deg r < deg p2
  $q = $p + 3;         $q = $p->add_const(3);  # q(x) == p(x) + 3
  $q = $p - 3;         $q = $p->sub_const(3);  # q(x) == p(x) - 3
  $q = $p * 3;         $q = $p->mul_const(3);  # q(x) == p(x) * 3
  $q = $p / 3;         $q = $p->div_const(3);  # q(x) == p(x) / 3

  $q = $p ** 3;        $q = $p->pow(3);        # q(x) == p(x) ** 3
  $q = $p << 3;        $q = $p->shift_up(3);   # q(x) == p(x) * x**3
  $q = $p >> 3;        $q = $p->shift_down(3); # p == q * x**3 + r,
                                               #   deg r < 3

  $r = $p->slice(0, 3);              # p ==  q * x**3 + r, deg r < 3
  $r = $p->slice(2, 3);              # p == (q * x**3 + r) * x**2 + s,
                                     #   deg r < 3, deg s < 2

  ($q, $r) = $p1->divmod($p2);                 # p1 == q * p2 + r,
                                               #   deg r < deg p2
  $r = $p1->pow_mod(3, $p2);                   # p1**3 == q * p2 + r,
                                               #   deg r < deg p2
  $r = $p1->mmod($p2);                         # c * p1 == q * p2 + r,
                                               #   deg r < deg p2,
					       #   c is some constant

  $q = $p1->nest($p2);                         # q(x) == p1(p2(x))
  $q = $p->monize;                             # p(x) == q(x) * c,
                                               #   q is monic

  # greatest common divisor
  $d = $p1->gcd($p2);                          # p1 == q1 * d,
                                               # p2 == q2 * d,
                                               # deg d is maximal

  $d = $p1->gcd($p2, 'mmod');                  # like gcd, but with
  					       # alternate modulus op

  # extended Euclidean algorithm
  ($d, $d1, $d2, $m1, $m2) = $p1->xgcd($p2);   # p1 == q1 * d,
                                               # p2 == q2 * d,
                                               # deg d is maximal,
                                               # d == p1*d1 + p2*d2,
                                               # 0 == p1*m1 + p2*m2

  # calculus
  $q = $p->differentiate;             # q(x) == d/dx p(x)
  $q = $p->integrate;                 # d/dx q(x) == p(x), q(0) == 0
  $q = $p->integrate(10);             # d/dx q(x) == p(x), q(0) == 10
  $a = $p->definite_integral(1, 2);   # Integral from 1 to 2, p(x) dx

  # configurable string representation
  $config = {
    ascending     => 0,
    with_variable => 1,
    fold_sign     => 0,
    fold_zero     => 1,
    fold_one      => 1,
    fold_exp_zero => 1,
    fold_exp_one  => 1,
    convert_coeff => sub { "$_[0]" },
    plus          => q{ + },
    minus         => q{ - },
    leading_plus  => q{},
    leading_minus => q{- },
    times         => q{ },
    power         => q{^},
    variable      => q{x},
    prefix        => q{(},
    suffix        => q{)},
  };
  $str = "$p";                                 # '(2 x^3 + -3 x)'
  $str = $p->as_string();                      # '(2 x^3 + -3 x)'
  $str = $p->as_string($config);               # '(2 x^3 + -3 x)'

  $str = $p->as_string({fold_sign => 1});      # '(2 x^3 - 3 x)'

  $p->string_config({fold_sign => 1});
  $str = "$p";                                 # '(2 x^3 - 3 x)'
  $str = $p->as_string;                        # '(2 x^3 - 3 x)'

  $p->string_config(undef);
  $str = "$p";                                 # '(2 x^3 + -3 x)'

  Math::Polynomial->string_config({fold_sign => 1});
  $str = "$p";                                 # '(2 x^3 - 3 x)'

  $config = $p->string_config;                 # undef
  $config = Math::Polynomial->string_config;   # {fold_sign => 1}

  $config = {
    with_variable => 0,
    ascending     => 1,
    plus          => q{, },
  };
  $str = $p->as_string($config);               # '(0, -3, 0, 2)'

  # examples of other coefficient spaces
  $c0 = Math::Complex->make(0, 3);
  $c1 = Math::Complex->make(2, 1);
  $p = Math::Polynomial->new($c0, $c1);        # p(x) == (2+i)*x + 3i

  $c0 = Math::BigRat->new('-1/2');
  $c1 = Math::BigRat->new('0');
  $c2 = Math::BigRat->new('3/2');
  $p = Math::Polynomial->new($c0, $c1, $c2);  # p(x) == 3/2*x**2 - 1/2

DESCRIPTION

Math::Polynomial objects represent polynomials in one variable, i.e. expressions built with finitely many additions, subtractions and multiplications of the variable and some constants. A standard way of writing down a polynomial in one variable is as a sum of products of some constant and a power of x, ordered by powers of x. The constants in those terms are called coefficients.

The polynomial p(x) = 0 is called the zero polynomial. For polynomials other than the zero polynomial, the exponent of the highest power of x with a nonzero coefficient is called the degree of the polynomial.

Math::Polynomial objects are immutable. New objects can be created using a variety of constructors or as expressions composed from existing objects.

The module works with various types of coefficients, like ordinary floating point numbers, complex numbers, arbitrary precision rationals, matrices, elements of finite fields, and lots of others. All that is required is that the coefficients are either Perl numbers or objects with suitably overloaded arithmetic operators. Operations on polynomials are carried out by reducing them to basic operations in the domain of their coefficients.

Math::Polynomial objects are implicitly bound to their coefficient space, which will be inherited when new polynomials are derived from existing ones, or determined from actual coefficients when polynomials are created from scratch. It is the responsibility of the user not to mix coefficients that cannot be added to or multiplied by each other.

Note that ordinary Perl numbers are of only limited use as coefficients, since floating point arithmetic, unlike arithmetic in algebraic fields, suffers from rounding errors.

CLASS VARIABLES

$VERSION

$VERSION contains the current version number of the module. Its most typical use is the statement:

use Math::Polynomial 1.000;

This will make sure the module version used is at least 1.000, which is recommended because previous versions had a different API.

$max_degree

$max_degree limits the arguments for the pow and shift_up operators and the monomial constructors, see "pow". Its default value is one million.

CLASS METHODS

Constructors

new($coeff0, $coeff1, $coeff2, ...)

Math::Polynomial->new(@coeff) creates a new polynomial with the given coefficients for x to the power of zero, one, two, etc. For example, new(7, 1) creates an object representing p(x) = 7+x.

Note that coefficients are specified in ascending order of powers of x. The degree of the polynomial will be at most n-1 if n coefficients are given, less if one or more of the highest-order coefficients are zero.

Specifying at least one coefficient (which may be zero) ensures that the created polynomials use the desired coefficient space. Without any parameters, new creates a zero polynomial on Perl numeric values.

monomial($degree)
monomial($degree, $coeff)

Math::Polynomial->monomial($degree, $coeff) creates a polynomial with $coeff as the coefficient for x to the power of $degree, and all other coefficients zero. The degree must be a non-negative integer number. If $coeff is omitted, it defaults to the Perl scalar 1.

To prevent accidential excessive memory consumption, $degree must be at most $Math::Polynomial::max_degree.

interpolate([$x1, $x2, ...], [$y1, $y2, ...])

Math::Polynomial->interpolate(\@x_values, \@y_values) creates a Lagrange interpolation polynomial passing through support points with the given x- and y-coordinates. The x-values must be mutually distinct. The number of y-values must be equal to the number of x-values. For n support points this takes O(n**3) multiplications, O(n**3) additions, O(n) divisions and O(n**2) comparisons in the coefficient space. The result will be a polynomial of degree n-1.

Note that with increasing numbers of support points, Lagrange interpolation tends to get numerically unstable, meaning drastically inaccurate if carried out with limited precision. Furthermore, high-degree interpolation polynomials can oscillate wildly in the neighbourhood of the support points, let alone elswhere. This is not a fault of the module but fundamental to the nature of these functions.

OBJECT METHODS

Constructors

Each class-level constructor can be used as an object method, too, i.e. be invoked from an object rather than a class name. This way, coefficient space properties are passed on from the invocant object to the new object, saving some initial coefficient analysis. Other properties like per-object stringification settings (explained below) are inherited likewise.

new($coeff0, $coeff1, $coeff2, ...)

If $p refers to a Math::Polynomial object, the object method $p->new(@coeff) creates and returns a new polynomial sharing the coefficient space with $p, but with its own list of coefficients as specified in @coeff.

monomial($degree)
monomial($degree, $coeff)

$p->monomial($degree, $coeff) creates a monomial like Math::Polynomial->monomial($degree, $coeff), but sharing inheritable properties with $p. If $coeff is omitted it defaults to the multiplicative unit element of the coefficient space of $p.

To prevent accidential excessive memory consumption, $degree must be at most $Math::Polynomial::max_degree.

interpolate([$x1, $x2, ...], [$y1, $y2, ...])

$p->interpolate(\@x_values, \@y_values) is the object method variant of the Lagrange interpolation polynomial constructor. It creates a polynomial passing through support points with the given x- and y-coordinates. The x-values must be mutually distinct. The number of y-values must be equal to the number of x-values. All values must belong to the coefficient space of $p.

Property Accessors

coefficients

$p->coefficients returns the coefficients of $p in ascending order of exponents, including zeroes, up to the highest-order non-zero coefficient. The result will be a list of n+1 coefficients for polynomials of degree n, or a single zero coefficient for zero polynomials.

coeff

$p->coeff returns the coefficients of $p much like $p->coefficients, but for zero polynomials the result will be an empty list.

(Mnemonic for coeff versus coefficients: Shorter name, shorter list.)

coeff($degree)

$p->coeff($exp) returns the coefficient of degree $exp of $p. If $exp is less than zero or larger than the degree of $p, the zero element of the coefficient space is returned.

coeff_zero

$p->coeff_zero returns the zero element of the coefficient space of $p, i.e. the neutral element with respect to addition.

coeff_one

$p->coeff_one returns the multiplicative unit element of the coefficient space of $p, i.e. the neutral element with respect to multiplication.

degree

$p->degree returns -1 if $p is a zero polynomial, otherwise the degree of $p.

proper_degree

$p->proper_degree returns undef if $p is a zero polynomial, otherwise the degree of $p. This can be useful for catching incorrect numerical uses of degrees where zero polynomials might be involved.

Evaluation

evaluate

$p->evaluate($x) computes the value of the polynomial function given by $p at the position $x. For polynomials of degree n, this takes n multiplications and n additions in the coefficient space.

Comparison Operators

All comparison operators return boolean results.

!
is_zero

$p->is_zero or short !$p checks whether $p is a zero polynomial.

==
is_equal

$p->is_equal($q) or short $p == $q checks whether $p is equivalent to $q. The result is true if both polynomials have the same degree and all pairs of coefficients of same degree are equal. For polynomials of equal degree n, this takes at most n+1 equality checks in the coefficient space.

!=
is_unequal

$p->is_unequal($q) or short $p != $q checks whether $p is not equivalent to $q. The result is true if the polynomials have different degree or at least one pair of coefficients of same degree is different. For polynomials of equal degree n, this takes at most n+1 equality checks in the coefficient space.

Note that there are no ordering comparisons (<, <=, >, <=>, ...) as neither polynomial nor coefficient spaces in general need to be ordered spaces.

Arithmetic Operators

unary -
neg

$p->neg or short -$p calculates the negative of a polynomial. For a polynomial of degree n, this takes n+1 negations in the coefficient space.

+
add

$p->add($q) or short $p + $q calculates the sum of two polynomials. For polynomials of degree m and n, this takes 1+min(m, n) additions in the coefficient space.

-
sub_

$p->sub_($q) or short $p - $q calculates the difference of two polynomials. For polynomials of degree m and n, this takes 1+min(m, n) subtractions in the coefficient space, plus n-m negations if n is greater than m.

The trailing underscore in the method name may look a bit odd but will prevent primitive syntax-aware tools from stumbling over "misplaced" sub keywords.

*
mul

$p->mul($q) or short $p * $q calculates the product of two polynomials. For polynomials of degree m and n, this takes (m+1)*(n+1) multiplications and m*n additions in the coefficient space.

divmod

($q, $r) = $p1->divmod($p2) divides a polynomial by another polynomial and returns the polynomial part of the quotient, and the remainder. The second polynomial must not be a zero polynomial. The remainder is a polynomial of lesser degree than the second polynomial and satisfies the equation $p1 == $p2*$q + $r. For polynomials of degree m and n, m>=n, this takes m+1-n divisions, (m+1-n)*n multiplications and (m+1-n)*n subtractions in the coefficient space.

/
div

$p->div($q) or short $p / $q calculates the polynomial part of the quotient of two polynomials. This takes the same operations in the coefficient space as divmod.

%
mod

$p->mod($q) or short $p % $q calculates the remainder from dividing one polynomial by another. This takes the same operations in the coefficient space as divmod.

mmod

$p->mmod($q) (modified mod) calculates the remainder from dividing one polynomial by another, multiplied by some constant. The constant is a**d where a is the highest coefficient of q and d = degree(p) - degree(q) + 1, if degree(p) > degree(q), otherwise 1. This operation is suitable to substitute mod in the Euclidean algorithm and can be calculated without division in the coefficient space. For polynomials of degree m and n, m>=n, this takes (m+1-n)*(m+3*n)/2 multiplications and (m+1-n)*n subtractions in the coefficient space.

**
pow

$p->pow($n) or short $p ** $n calculates a power of a polynomial. The exponent $n must be a non-negative integer. To prevent accidential excessive time and memory consumption, the degree of the result must be at most $Math::Polynomial::max_degree, which is one million by default. Calculating the n-th power of a polynomial of degree m takes O(m*m*n*n) multiplications and additions in the coefficient space.

pow_mod

$p1->pow_mod($n, $p2) is equivalent to ($p1 ** $n) % $p2, except that the modulus operation is repeatedly applied to intermediate results in order to keep their degrees small. The exponent $n must be a non-negative integer.

add_const
sub_const
mul_const
div_const

The arithmetic operations add_const, sub_const, mul_const and div_const can be used to efficiently add a constant to or subtract a constant from a polynomial, or multiply or divide a polynomial by a constant, respectively.

Overloaded arithmetic operators (+, -, *, ...) work with constants in place of polynomial operands, too, by converting non-polynomial arguments into constant polynomials first. However, this usage is both less efficient and less obvious, and therefore not recommended.

Note that there is no use for a mod_const method, as polynomial division by a constant always yields a zero remainder.

<<
shift_up

$p->shift_up($n) or short $p << $n calculates the product of a polynomial and a power of x. The exponent $n must be a non-negative integer. To prevent accidential excessive memory consumption, the degree of the result must be at most $Math::Polynomial::max_degree.

>>
shift_down

$p->shift_down($n) or short $p >> $n divides a polynomial by a power of x and returns the polynomial part of the result, i.e. discarding negative powers of x. The exponent $n must be a non-negative integer.

Shifting up or down is more efficient than multiplication or division as it does not take any operations in the coefficient space.

slice

$p->slice($m, $n) is equivalent to:

$xm = $p->make_monomial($m);
$xn = $p->make_monomial($n);
($p / $xm) % $xn

I.e., it returns a polynomial built from a slice of the coefficients of the original polynomial starting with degree $m, and at most $n coefficients. However, it is more efficient than division and modulo as it does not perform any operations in the coefficient space. The indexes $m and $n must be non-negative integers.

monize

$p->monize converts an arbitrary nonzero polynomial to a monic polynomial via division by its highest-order coefficient. The result will be monic, i.e. with a highest-order coefficient of one, if the invocant was not the zero polynomial, otherwise the zero polynomial. Monization of a nonzero polynomial of degree n takes n divisions in the coefficient space.

Miscellaneous Operators

nest

$p1->nest($p2) calculates the nested polynomial p1(p2(x)) from two polynomials p1(x) and p2(x). For polynomials of degree m and n this takes O(m*m*n*n) multiplications and additions in the coefficient space. The result will be a polynomial of degree m*n if neither of the polynomials is a zero polynomial, otherwise a constant or zero polynomial.

gcd

$p1->gcd($p2, $mod) calculates a greatest common divisor of two polynomials, using the Euclidean algorithm and the modulus operator as specified by name. The $mod parameter is optional and defaults to 'mod'. With polynomials of degree m and n, m>=n, and the default modulus operator mod, this takes at most n polynomial divisions of decreasing degrees or O(m+n) divisions and O(m*n) multiplications and subtractions in the coefficient space. With the mmod operator, this takes O(m*n) multiplications and subtractions in the coefficient space.

mmod can have advantages over mod in situations where division in the coefficient space is much more expensive than multiplication.

xgcd

($d, $d1, $d2, $m1, $m2) = $p1->xgcd($p2) calculates a greatest common divisor d and four polynomials d1, d2, m1, m2, such that d = p1*d1 + p2*d2, 0 = p1*m1 + p2*m2, degree(m1*d) = degree(p2), degree(m2*d) = degree(p1), using the extended Euclidean algorithm. With polynomials of degree m and n, m>=n, this takes at most n polynomial divisions and 2*n polynomial multiplications and subtractions of decreasing degrees, or, in the coefficient space: O(m+n) divisions and O(m*n) multiplications and subtractions.

Calculus Operators

Calculus operators as presented here are meaningful mostly on the coefficient space of real numbers. In particular, they require that coefficients can be multiplied and divided by integer numbers.

differentiate

If the coefficient space allows multiplication by Perl integers, $p->differentiate calculates the first derivative of a polynomial. For a polynomial of degree n, this takes n multiplications in the coefficient space.

integrate

If the coefficient space allows division by Perl integers, $p->integrate calculates an antiderivative of a polynomial. The coefficient of degree zero of the result will be zero. $p->integrate($c) does the same but adds the constant $c. For a polynomial of degree n, both forms of integration take n+1 divisions in the coefficient space.

definite_integral

If the coefficient space allows division by Perl integers, $p->definite_integral($x1, $x2) calculates the value of the definite integral from $x1 to $x2 over the polynomial function given by $p. For real numbers x1 < x2, this can be interpreted as the signed area bound by the lines x=x1, y=0, x=x2 and the graph of p(x), where parts below the x-axis are regarded as negative.

For a polynomial of degree n, this takes n+1 divisions, 2*n multiplications, 2*n additions and 1 subtraction in the coefficient space. If you need to calculate more than one definite integral over the same polynomial function, it is more efficient to store an antiderivative once (see "integrate") and evaluate it at the different interval limits. The statement...

$a = $p->definite_integral($x1, $x2);

... is essentially equivalent to:

$p_int = $p->integrate;
$a     = $p_int->evaluate($x2) - $p_int->evaluate($x1);

String Representation

""
as_string

In string context, Math::Polynomial objects will automatically be converted to a character string, which is the same as the result of the as_string() method when called without parameter.

An optional configuration hashref controls many layout aspects of the string representation. In the absence of an explicit configuration, a per-object default configuration is used, and in the absence of that, a global default configuration (see string_config).

Each individual configuration setting has a default value as defined in the next section.

string_config

$p->string_config($hashref) sets the per-object default stringification configuration to $hashref. $hashref may be undef to remove a previously set configuration.

$p->string_config returns the per-object default stringification configuration as a reference to a hash, if present, otherwise undef.

Math::Polynomial->string_config($hashref) sets the global default stringification configuration to $hashref. Math::Polynomial->string_config returns that configuration. It should always refer to an existing hash, which may of course be empty.

A per-object configuration will be propagated to any new objects created from an object. Thus it is easy to use consistent settings without having to touch global parameters.

Stringification Configuration Options

ascending

True value: order coefficients from lowest to highest degree; False value (default): from highest to lowest.

with_variable

True value (default): display coefficients together with powers of the variable; false value: display coefficients alone. False implies that fold_zero, times, power and variable will have no effect.

fold_sign

True value: contract the addition symbol and the sign of a negative value to a single subtraction symbol; false value (default): do not carry out this kind of replacement. True is only allowed if the coefficient space defines a "less than" operator.

fold_zero

True value (default): suppress terms with coefficients equal to zero; false value: do not suppress any terms. Zero polynomials are represented with a zero constant term in any case.

fold_one

True value (default): suppress coefficients equal to one when multiplied by a variable power; false value: do not suppress factors of one. Note that coefficients very close but not quite equal to one might be stringified to one without being caught by this rule.

fold_exp_zero

True value (default): suppress the variable and the zero exponent in the constant term; false value: display even the constant term with a variable power.

fold_exp_one

True value (default): suppress the exponent in the term of the variable to the power of one; false value: display even the linear term with an exponent.

convert_coeff

Code reference specifying a function that takes a coefficient value and returns a string representing that value. Default is ordinary stringification.

plus

Addition symbol to put between terms. Default is a plus character surrounded by blanks.

minus

Subtraction symbol replacing a plus symbol and a negative sign, if applicable (see fold_sign). Default is a minus character surrounded by blanks.

leading_plus

Sign symbol to put before the first term unless fold_sign is true and the term is negative. Default is an empty string.

leading_minus

Sign symbol replacing a negative sign at the first term, if fold_sign is true. Default is a minus followed by a blank.

times

Multiplication symbol to put between the coefficient and the variable in each term. Default is a blank.

power

Exponentiation symbol to put between the variable and the exponent in each term. Default is a caret (^).

variable

Symbol representing the variable. Default is a lower case x.

prefix

Prefix to prepend to the entire polynomial. Default is a left parenthesis.

suffix

Suffix to append to the entire polynomial. Default is a right parenthesis.

EXTENSION REQUIREMENTS

Math::Polynomial can be extended in different ways. Subclasses may restrict coefficient spaces to facilitate certain algorithms such as numerical root ex TODO

Special polynomials (such as Legendre, Hermite, Laguerre polynomials etc.) may be provided by packages offering just some constructors for them but no separate classes. TODO Special algorithms dealing with or employing polynomials, such as for finding roots, finding polynomial approximations for other functions etc. may be provided by packages TODO

DIAGNOSTICS

Currently, Math::Polynomial does not thoroughly check coefficient values for sanity. Incompatible coefficients might trigger warnings or error messages from the coefficient class implementation, blaming Math::Polynomial to operate on incompatible operands. Unwisely chosen coefficient objects, lacking overrides for arithmetic operations, might even silently be used with their memory address acting as an integer value.

Some types of wrong usage, however, are diagnosed and will trigger one of the error messages listed below. All of them terminate program execution unless they are trapped in an eval block.

array context required

A method designed to return more than one value, like divmod or xgcd, was not called in array context. The results of these methods have to be assigned to a list of values rather than a single value.

array context required if called without argument

The coeff method was called without arguments, so as to return a list of coefficients, but not in array context. The list of coefficients should be assigned to an array. To retrieve a single coefficient, coeff should be called with a degree argument.

bad modulus operator

A modulus operator was passed to gcd which turned out to violate rules required by such an operator, like constraints on the degree of returned polynomials.

division by zero

The div_const method was called with a zero argument. Coefficient spaces are supposed to not allow division by zero, therefore Math::Polynomial tries to safeguard against it.

division by zero polynomial

Some kind of polynomial division, like div, mod, divmod or an expression with / or % was attempted with a zero polynomial acting as denominator. Division by a zero polynomial is not defined.

exponent too large

One of the methods pow, shift_up, make_monomial or new_monomial was called with arguments that would lead to a result with an excessively high degree. You can tweak the class variable $max_degree to change the actual limit. Calculations involving large polynomials can consume a lot of memory and CPU time. Exponent sanity checks help to avoid that from happening by accident.

no such method: %s

A modulus operator name was passed to gcd which is not actually the name of a method.

non-negative integer argument expected

One of the methods expecting non-negative integer arguments, like pow, shift_up, shift_down, slice, make_monomial or new_monomial, got something else instead.

object method invoked on a non-reference

An object method, like make, make_monomial or interpolate, was called as if it was a class method. These methods should be invoked using the instance_variable->method_name syntax. Class methods with similar functionality are available in most cases, as documented in the section on class methods.

usage: %s

A method designed to be called in a certain manner with certain types of arguments got not what it expected.

For example, interpolate takes two references of arrays of equal length.

Usage messages give an example of the expected calling syntax.

wrong operand type

An arithmetic expression used an operation not defined for polynomials, such as a power with a polynomial exponent.

x values not disjoint

One of the Lagrange interpolation methods (interpolated or interpolate) was called with at least two equal x-values. Support points for this kind of interpolation must have distinct x-values.

SEE ALSO

Part of this distribution
Math::Polynomial::Generic
Planned for release
Math::Polynomial::Legendre
Math::Polynomial::Chebyshev
Math::Polynomial::Gegenbauer
Math::Polynomial::Jacobi
Math::Polynomial::Hermite
Math::Polynomial::Laguerre
Math::Polynomial::Roots::DurandKerner

AUTHOR

Martin Becker, <becker-cpan-mp@cozap.com>

ACKNOWLEDGEMENTS

Mats Kindahl, <mats@kindahl.net>, wrote an earlier version of this module and maintained it 1997-2007.

LICENSE AND COPYRIGHT

Copyright (c) 2007-2009 by Martin Becker. All rights reserved.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.6 or, at your option, any later version of Perl 5 you may have available.

DISCLAIMER OF WARRANTY

This module is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.