====================================================================
Operator examples
====================================================================

Given any ring R, the ring of the Integer-linear operators over R is
called Operator(R).  To create an operator over R, first create a
basic operator using the operation operator, and then convert it to
Operator(R) for the R you want.

We choose R to be the two by two matrices over the integers.

  R := SQMATRIX(2, INT)
    SquareMatrix(2,Integer)
                            Type: Domain

Create the operator tilde on R.

  t := operator("tilde") :: OP(R)
    tilde
                            Type: Operator SquareMatrix(2,Integer)

Since Operator is unexposed we must either package-call operations
from it, or expose it explicitly.  For convenience we will do the latter.

Expose Operator.

  )set expose add constructor Operator

To attach an evaluation function (from R to R) to an operator over R,
use evaluate(op, f) where op is an operator over R and f is a function
R -> R.  This needs to be done only once when the operator is defined.
Note that f must be Integer-linear (that is, f(ax+y) = a f(x) + f(y)
for any integer a, and any x and y in R).

We now attach the transpose map to the above operator t.

  evaluate(t, m +-> transpose m)
    tilde
                       Type: Operator SquareMatrix(2,Integer)

Operators can be manipulated formally as in any ring: + is the
pointwise addition and * is composition.  Any element x of R can be
converted to an operator op(x) over R, and the evaluation function of
op(x) is left-multiplication by x.

Multiplying on the left by this matrix swaps the two rows.

  s : R := matrix [ [0, 1], [1, 0] ]
        +0  1+
        |    |
        +1  0+
                       Type: SquareMatrix(2,Integer)

Can you guess what is the action of the following operator?

  rho := t * s
             +0  1+
        tilde|    |
             +1  0+
                       Type: Operator SquareMatrix(2,Integer)

Hint: applying rho four times gives the identity, so rho^4-1 should
return 0 when applied to any two by two matrix.

  z := rho**4 - 1
                   +0  1+     +0  1+     +0  1+     +0  1+
        - 1 + tilde|    |tilde|    |tilde|    |tilde|    |
                   +1  0+     +1  0+     +1  0+     +1  0+
                       Type: Operator SquareMatrix(2,Integer)

Now check with this matrix.

  m:R := matrix [ [1, 2], [3, 4] ]
        +1  2+
        |    |
        +3  4+
                       Type: SquareMatrix(2,Integer)

  z m
        +0  0+
        |    |
        +0  0+
                       Type: SquareMatrix(2,Integer)

As you have probably guessed by now, rho acts on matrices by rotating
the elements clockwise.

  rho m
        +3  1+
        |    |
        +4  2+
                       Type: SquareMatrix(2,Integer)

  rho rho m
         +4  3+
         |    |
         +2  1+
                       Type: SquareMatrix(2,Integer)

  (rho^3) m
         +2  4+
         |    |
         +1  3+
                       Type: SquareMatrix(2,Integer)

Do the swapping of rows and transposition commute?  We can check by
computing their bracket.

  b := t * s - s * t
           +0  1+             +0  1+
         - |    |tilde + tilde|    |
           +1  0+             +1  0+
                       Type: Operator SquareMatrix(2,Integer)

Now apply it to m.

  b m
         +1  - 3+
         |      |
         +3  - 1+
                       Type: SquareMatrix(2,Integer)
 
Next we demonstrate how to define a differential operator on a polynomial ring.

This is the recursive definition of the n-th Legendre polynomial.

  L n ==
    n = 0 => 1
    n = 1 => x
    (2*n-1)/n * x * L(n-1) - (n-1)/n * L(n-2)
                        Type: Void

Create the differential operator d/dx on polynomials in x over the
rational numbers.

  dx := operator("D") :: OP(POLY FRAC INT)
     D
                        Type: Operator Polynomial Fraction Integer

Now attach the map to it.

  evaluate(dx, p +-> D(p, 'x))
    D
                        Type: Operator Polynomial Fraction Integer

This is the differential equation satisfied by the n-th Legendre polynomial.

  E n == (1 - x**2) * dx**2 - 2 * x * dx + n*(n+1)
                        Type: Void

Now we verify this for n = 15.  Here is the polynomial.

  L 15
     9694845  15   35102025  13   50702925  11   37182145  9   14549535  7
     ------- x   - -------- x   + -------- x   - -------- x  + -------- x
       2048          2048           2048           2048          2048
   + 
       2909907  5   255255  3   6435
     - ------- x  + ------ x  - ---- x
         2048        2048       2048
                        Type: Polynomial Fraction Integer

Here is the operator.

  E 15
    240 - 2x D - (x  - 1)D
                        Type: Operator Polynomial Fraction Integer

Here is the evaluation.

  (E 15)(L 15)
    0
                        Type: Polynomial Fraction Integer

See Also:
o )show Operator

