
% Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are
% met:
%
%     - Redistributions of source code must retain the above copyright
%       notice, this list of conditions and the following disclaimer.
%
%     - Redistributions in binary form must reproduce the above copyright
%       notice, this list of conditions and the following disclaimer in
%       the documentation and/or other materials provided with the
%       distribution.
%
%     - Neither the name of The Numerical ALgorithms Group Ltd. nor the
%       names of its contributors may be used to endorse or promote products
%       derived from this software without specific prior written permission.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
% IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
% TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
% PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
% OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES-- LOSS OF USE, DATA, OR
% PROFITS-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
% LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


Given any ring \spad{R}, the ring of the \spadtype{Integer}-linear operators
over \spad{R} is called \spadtype{Operator(R)}.
\index{operator}
To create an operator over \spad{R}, first create a basic operator using the
operation \spadfun{operator}, and then convert it to \spadtype{Operator(R)}
for the \spad{R} you want.
%
\xtc{
We choose \spad{R} to be the two by two matrices over the integers.
}{
\spadcommand{R := SQMATRIX(2, INT)\bound{r}}
}
\xtc{
Create the operator \spad{tilde} on \spad{R}.
}{
\spadcommand{t := operator("tilde") :: OP(R) \free{r}\bound{t}}
}
%
Since \spadtype{Operator} is unexposed we must either package-call operations
from it, or expose it explicitly.  For convenience we will do the latter.
%
\noOutputXtc{
Expose \spad{Operator}.
}{
\spadcommand{)set expose add constructor Operator \free{t}\bound{expose}}
}
%
To attach an evaluation function (from \spad{R} to \spad{R}) to an
operator over \spad{R}, use \spad{evaluate(op, f)} where \spad{op}
is an operator over \spad{R} and \spad{f} is a function \spad{R ->
R}.
This needs to be done only once when the operator is defined.
Note that \spad{f} must be \spadtype{Integer}-linear (that is,
\spad{f(ax+y) = a f(x) + f(y)} for any integer \spad{a}, and any
\spad{x} and \spad{y} in \spad{R}).
%
\xtc{
We now attach the transpose map to the above operator \spad{t}.
}{
\spadcommand{evaluate(t, m +-> transpose m)\free{expose}\free{t}\bound{evt}}
}
%
Operators can be manipulated formally as in any ring: \spadop{+} is the
pointwise addition and \spadop{*} is composition.
Any element \spad{x} of \spad{R} can be converted to an operator
\subscriptText{\tt op}{\tt x}
over \spad{R}, and the evaluation function of
\subscriptText{\tt op}{\tt x}
is left-multiplication by \spad{x}.
%
\xtc{
Multiplying on the
left by this matrix swaps the two rows.
}{
\spadcommand{s : R := matrix [[0, 1], [1, 0]]\bound{s}}
}
%
\xtc{
Can you guess what is the action of the following operator?
}{
\spadcommand{rho := t * s\free{evt s}\bound{rho}}
}
%
%
\xtc{
Hint: applying \spad{rho} four times gives the identity, so
\spad{rho^4-1} should return 0 when applied to any two by two matrix.
}{
\spadcommand{z := rho^4 - 1\free{rho}\bound{z}}
}
%
%
\xtc{
Now check with this matrix.
}{
\spadcommand{m:R := matrix [[1, 2], [3, 4]]\bound{m}}
}
\xtc{
}{
\spadcommand{z m\free{z m}}
}
%
%
\xtc{
As you have probably guessed by now, \spad{rho} acts on matrices
by rotating the elements clockwise.
}{
\spadcommand{rho m\free{rho m}}
}
\xtc{
}{
\spadcommand{rho rho m\free{rho m}}
}
\xtc{
}{
\spadcommand{(rho^3) m\free{rho m}}
}
%
%
\xtc{
Do the swapping of rows and transposition commute?
We can check by computing their bracket.
}{
\spadcommand{b := t * s - s * t\free{s evt}\bound{b}}
}
%
%
\xtc{
Now apply it to \spad{m}.
}{
\spadcommand{b m \free{b m}}
}
%

Next we demonstrate how to define a differential operator
on a polynomial ring.
\xtc{
This is the recursive definition of the \spad{n}-th Legendre polynomial.
\index{polynomial!Legendre}
}{
\begin{spadsrc}[\bound{l}]
L n ==
  n = 0 => 1
  n = 1 => x
  (2*n-1)/n * x * L(n-1) - (n-1)/n * L(n-2)
\end{spadsrc}
}
\xtc{
Create the differential operator \texht{$d \over {dx}$}{\spad{d/dx}} on
polynomials in \spad{x} over the rational numbers.
}{
\spadcommand{dx := operator("D") :: OP(POLY FRAC INT) \bound{dx}}
}
\xtc{
Now attach the map to it.
}{
\spadcommand{evaluate(dx, p +-> D(p, 'x)) \free{dx}\bound{edx}}
}
\xtc{
This is the differential equation satisfied by the \spad{n}-th
Legendre polynomial.
}{
\spadcommand{E n == (1 - x^2) * dx^2 - 2 * x * dx + n*(n+1) \free{edx}\bound{E}}
}
\xtc{
Now we verify this for \spad{n = 15}.
Here is the polynomial.
}{
\spadcommand{L 15 \free{L}}
}
\xtc{
Here is the operator.
}{
\spadcommand{E 15 \free{E}}
}
\xtc{
Here is the evaluation.
}{
\spadcommand{(E 15)(L 15) \free{L E}}
}
