http://en.wikipedia.org/wiki/Tensor_product
A tensor product is "the most general bilinear operation" available in
a specified domain of computation, satisfying:
We can use the domain constructor Sum
[SandBoxSum]?
axiom
)lib SUM
Sum is now explicitly exposed in frame initial
Sum will be automatically loaded when needed from
/var/zope2/var/LatexWiki/SUM.NRLIB/code.o
First we can define some recursive operations on the polynomials
axiom
scanPoly(p,n) == _
(p=0 => 0; mapMonomial(leadingMonomial(p),n)+scanPoly(reductum p,n))
Type: Void
axiom
mapMonomial(p,n) == _
monomial(coefficient(p,degree p),scanIndex(degree(p),n))$SMP(Integer,Sum(Symbol,Symbol))
Type: Void
axiom
scanIndex(p,n) == _
(zero? p => 0$IndexedExponents(Sum(Symbol,Symbol)); _
monomial(leadingCoefficient(p), _
if n=1 then in1(leadingSupport(p))$Sum(Symbol,Symbol) _
else in2(leadingSupport(p))$Sum(Symbol,Symbol) _
)$IndexedExponents(Sum(Symbol,Symbol))+ _
scanIndex(reductum(p),n))
Type: Void
For example:
axiom
-- functions are first compiled here
--
scanPoly(x,1)
axiom
Compiling function scanIndex with type (IndexedExponents Symbol,
Integer) -> IndexedExponents Sum(Symbol,Symbol)
; (DEFUN |*2;scanIndex;1;initial| ...) is being compiled.
;; The variable |*2;scanIndex;1;initial;MV| is undefined.
;; The compiler will assume this variable is a global.
axiom
Compiling function mapMonomial with type (Polynomial Integer,Integer
) -> SparseMultivariatePolynomial(Integer,Sum(Symbol,Symbol))
; (DEFUN |*2;mapMonomial;1;initial| ...) is being compiled.
;; The variable |*2;mapMonomial;1;initial;MV| is undefined.
;; The compiler will assume this variable is a global.
axiom
Compiling function scanPoly with type (Polynomial Integer,Integer)
-> SparseMultivariatePolynomial(Integer,Sum(Symbol,Symbol))
; (DEFUN |*2;scanPoly;3;initial| ...) is being compiled.
;; The variable |*2;scanPoly;3;initial;MV| is undefined.
;; The compiler will assume this variable is a global.
axiom
Compiling function scanPoly with type (Polynomial Integer,Integer)
-> SparseMultivariatePolynomial(Integer,Sum(Symbol,Symbol))
;;; *** |*2;scanPoly;3;initial| REDEFINED
; (DEFUN |*2;scanPoly;3;initial| ...) is being compiled.
;; The variable |*2;scanPoly;3;initial;MV| is undefined.
;; The compiler will assume this variable is a global.
axiom
Compiling function scanPoly with type (Variable x,Integer) ->
SparseMultivariatePolynomial(Integer,Sum(Symbol,Symbol))
; (DEFUN |*2;scanPoly;1;initial| ...) is being compiled.
;; The variable |*2;scanPoly;1;initial;MV| is undefined.
;; The compiler will assume this variable is a global.
Type: SparseMultivariatePolynomial
?(Integer,Sum(Symbol,Symbol))
injects the polynomial x
in to the tensor product. So
now the full tensor product is just:
axiom
tensorPoly(p,q) == _
scanPoly(p,1)*scanPoly(q,2)
Type: Void
For example:
axiom
p:=2*x^2+3
Type: Polynomial Integer
axiom
q:=5*x*y+7*y+11
Type: Polynomial Integer
axiom
r:=tensorPoly(p,q)
axiom
Compiling function tensorPoly with type (Polynomial Integer,
Polynomial Integer) -> SparseMultivariatePolynomial(Integer,Sum(
Symbol,Symbol))
; (DEFUN |*2;tensorPoly;1;initial| ...) is being compiled.
;; The variable |*2;tensorPoly;1;initial;MV| is undefined.
;; The compiler will assume this variable is a global.
Type: SparseMultivariatePolynomial
?(Integer,Sum(Symbol,Symbol))
axiom
monomials(r)
Type: List SparseMultivariatePolynomial
?(Integer,Sum(Symbol,Symbol))
Demonstrating the axioms (1) (2) and (3) of the tensor product:
axiom
w:= 13*y^2+17*y+19
Type: Polynomial Integer
axiom
test( tensorPoly(p+q,w) = (tensorPoly(p,w) + tensorPoly(q,w)) )
Type: Boolean
axiom
test( tensorPoly(p,q+w) = (tensorPoly(p,q) + tensorPoly(p,w)) )
Type: Boolean
axiom
test( tensorPoly(p,23*w) = 23*tensorPoly(p,w) )
Type: Boolean
axiom
test( tensorPoly(23*p,w) = 23*tensorPoly(p,w) )
Type: Boolean
I suppose that we could give an inductive proof that this
implementation of the tensor product of polynomials is
correct ... but for now lets take this demonstration as
reassurance.