====================================================================
Polynomial examples
====================================================================

The domain constructor Polynomial (abbreviation: POLY) provides
polynomials with an arbitrary number of unspecified variables.

It is used to create the default polynomial domains in FriCAS.  Here
the coefficients are integers.

  x + 1
    x + 1
                          Type: Polynomial Integer

Here the coefficients have type Float.

  z - 2.3
    z - 2.3
                           Type: Polynomial Float

And here we have a polynomial in two variables with coefficients which
have type Fraction Integer.

  y**2 - z + 3/4
           2   3
    - z + y  + -
               4
                           Type: Polynomial Fraction Integer

The representation of objects of domains created by Polynomial is that
of recursive univariate polynomials. The term univariate means "one
variable". The term multivariate means "possibly more than one variable".

This recursive structure is sometimes obvious from the display of a polynomial.

  y **2 + x*y + y
     2
    y  + (x + 1)y
                           Type: Polynomial Integer

In this example, you see that the polynomial is stored as a polynomial
in y with coefficients that are polynomials in x with integer coefficients.  
In fact, you really don't need to worry about the representation unless you 
are working on an advanced application where it is critical. The polynomial 
types created from DistributedMultivariatePolynomial and
NewDistributedMultivariatePolynomial are stored and displayed in a
non-recursive manner.

You see a "flat" display of the above polynomial by converting to
one of those types.

  % :: DMP([y,x],INT)
     2
    y  + y x + y
                   Type: DistributedMultivariatePolynomial([y,x],Integer)

We will demonstrate many of the polynomial facilities by using two
polynomials with integer coefficients.

By default, the interpreter expands polynomial expressions, even if they
are written in a factored format.

  p := (y-1)**2 * x * z
        2
    (x y  - 2x y + x)z
                   Type: Polynomial Integer

See Factored to see how to create objects in factored form directly.

  q := (y-1) * x * (z+5)
    (x y - x)z + 5x y - 5x
                   Type: Polynomial Integer

The fully factored form can be recovered by using factor.

  factor(q)
    x(y - 1)(z + 5)
                   Type: Factored Polynomial Integer

This is the same name used for the operation to factor integers.  Such
reuse of names is called overloading and makes it much easier to think
of solving problems in general ways.  FriCAS facilities for factoring
polynomials created with Polynomial are currently restricted to the
integer and rational number coefficient cases.

The standard arithmetic operations are available for polynomials.

  p - q**2
         2 2     2     2  2          2      2       2             2
     (- x y  + 2x y - x )z  + ((- 10x  + x)y  + (20x  - 2x)y - 10x  + x)z
   + 
          2 2      2       2
     - 25x y  + 50x y - 25x
                   Type: Polynomial Integer

The operation gcd is used to compute the greatest common divisor of
two polynomials.

  gcd(p,q)
    x y - x
                   Type: Polynomial Integer

In the case of p and q, the gcd is obvious from their definitions.  We
factor the gcd to show this relationship better.

  factor %
    x(y - 1)
                   Type: Factored Polynomial Integer

The least common multiple is computed by using lcm.

  lcm(p,q)
        2             2        2
    (x y  - 2x y + x)z  + (5x y  - 10x y + 5x)z
                   Type: Polynomial Integer

Use content to compute the greatest common divisor of the coefficients
of the polynomial.

  content p
    1
                   Type: PositiveInteger

Many of the operations on polynomials require you to specify a variable.  
For example, resultant requires you to give the variable in which the 
polynomials should be expressed.

This computes the resultant of the values of p and q, considering them 
as polynomials in the variable z.  They do not share a root when thought 
of as polynomials in z.

  resultant(p,q,z)
       2 3      2 2      2      2
     5x y  - 15x y  + 15x y - 5x
                   Type: Polynomial Integer

This value is 0 because as polynomials in x the polynomials have a
common root.

  resultant(p,q,x)
    0
                   Type: Polynomial Integer

The data type used for the variables created by Polynomial is Symbol.
As mentioned above, the representation used by Polynomial is recursive
and so there is a main variable for nonconstant polynomials.

The operation mainVariable returns this variable.  The return type is 
actually a union of Symbol and "failed".

  mainVariable p
    z
                   Type: Union(Symbol,...)

The latter branch of the union is be used if the polynomial has no
variables, that is, is a constant.

  mainVariable(1 :: POLY INT)
    "failed"
                   Type: Union("failed",...)

You can also use the predicate ground? to test whether a polynomial is
in fact a member of its ground ring.

  ground? p
    false
                   Type: Boolean

  ground?(1 :: POLY INT)
    true
                   Type: Boolean

The complete list of variables actually used in a particular polynomial 
is returned by variables.  For constant polynomials, this list is empty.

  variables p
    [z,y,x]
                   Type: List Symbol

The degree operation returns the degree of a polynomial in a specific variable.

  degree(p,x)
    1
                   Type: PositiveInteger

  degree(p,y)
    2
                   Type: PositiveInteger

  degree(p,z)
    1
                   Type: PositiveInteger

If you give a list of variables for the second argument, a list of the
degrees in those variables is returned.

  degree(p,[x,y,z])
    [1,2,1]
                   Type: List NonNegativeInteger

The minimum degree of a variable in a polynomial is computed using 
minimumDegree.

  minimumDegree(p,z)
    1
                   Type: PositiveInteger

The total degree of a polynomial is returned by totalDegree.

  totalDegree p
    4
                   Type: PositiveInteger

It is often convenient to think of a polynomial as a leading monomial plus
the remaining terms.

  leadingMonomial p
        2
     x y z
                   Type: Polynomial Integer

The reductum operation returns a polynomial consisting of the sum of
the monomials after the first.

  reductum p
    (- 2x y + x)z
                   Type: Polynomial Integer

These have the obvious relationship that the original polynomial is
equal to the leading monomial plus the reductum.

  p - leadingMonomial p - reductum p
    0
                   Type: Polynomial Integer

The value returned by leadingMonomial includes the coefficient of that term.  
This is extracted by using leadingCoefficient on the original polynomial.

  leadingCoefficient p
    1
                   Type: PositiveInteger

The operation eval is used to substitute a value for a variable in a 
polynomial.

  p
        2
    (x y  - 2x y + x)z
                   Type: Polynomial Integer

This value may be another variable, a constant or a polynomial.

  eval(p,x,w)
        2
    (w y  - 2w y + w)z
                   Type: Polynomial Integer

  eval(p,x,1)
      2
    (y  - 2y + 1)z
                   Type: Polynomial Integer

Actually, all the things being substituted are just polynomials,
some more trivial than others.

  eval(p,x,y^2 - 1)
      4     3
    (y  - 2y  + 2y - 1)z
                   Type: Polynomial Integer

Derivatives are computed using the D operation.

  D(p,x)
      2
    (y  - 2y + 1)z
                   Type: Polynomial Integer

The first argument is the polynomial and the second is the variable.

  D(p,y)
    (2x y - 2x)z
                   Type: Polynomial Integer

Even if the polynomial has only one variable, you must specify it.

  D(p,z)
       2
    x y  - 2x y + x
                   Type: Polynomial Integer

Integration of polynomials is similar and the integrate operation is used.

Integration requires that the coefficients support division. FriCAS
converts polynomials over the integers to polynomials over the rational 
numbers before integrating them.

  integrate(p,y)
     1    3      2
    (- x y  - x y  + x y)z
     3
                  Type: Polynomial Fraction Integer

It is not possible, in general, to divide two polynomials.  In our
example using polynomials over the integers, the operation monicDivide
divides a polynomial by a monic polynomial (that is, a polynomial with
leading coefficient equal to 1).  The result is a record of the
quotient and remainder of the division.

You must specify the variable in which to express the polynomial.

  qr := monicDivide(p,x+1,x)
                 2                           2
    [quotient= (y  - 2y + 1)z,remainder= (- y  + 2y - 1)z]
     Type: Record(quotient: Polynomial Integer,remainder: Polynomial Integer)

The selectors of the components of the record are quotient and remainder.  
Issue this to extract the remainder.

  qr.remainder
        2
    (- y  + 2y - 1)z
                       Type: Polynomial Integer

Now that we can extract the components, we can demonstrate the
relationship among them and the arguments to our original expression
qr := monicDivide(p,x+1,x).

  p - ((x+1) * qr.quotient + qr.remainder)
    0
                       Type: Polynomial Integer

If the / operator is used with polynomials, a fraction object is
created.  In this example, the result is an object of type 
Fraction Polynomial Integer.

  p/q
    (y - 1)z
    --------
      z + 5
                       Type: Fraction Polynomial Integer

If you use rational numbers as polynomial coefficients, the
resulting object is of type Polynomial Fraction Integer.

  (2/3) * x**2 - y + 4/5 
          2  2   4
    - y + - x  + -
          3      5
                       Type: Polynomial Fraction Integer

This can be converted to a fraction of polynomials and back again, if
required.

  % :: FRAC POLY INT
               2
    - 15y + 10x  + 12
    -----------------
            15
                       Type: Fraction Polynomial Integer

  % :: POLY FRAC INT
          2  2   4
    - y + - x  + -
          3      5
                       Type: Polynomial Fraction Integer

To convert the coefficients to floating point, map the numeric
operation on the coefficients of the polynomial.

  map(numeric,%)
    - 1.0 y + 0.6666666666 6666666667 x  + 0.8
                       Type: Polynomial Float

See Also:
o )help Factored
o )help UnivariatePolynomial
o )help MultivariatePolynomial
o )help DistributedMultivariatePolynomial
o )help NewDistributedMultivariatePolynomial
o )show Polynomial

