Linear transformations (operators) over n-dimensional cartesian vector spaces oveer a commutative ring . Members of this domain are morphisms . Products, co-products and composition (grafting) of morphisms is implemented. Operators are represented internally as tensors.
Operator composition and products can be visualized by directed graphs (read from top to bottom) such as:
n = 3 inputs
\ | / \ / / \ |
\ | / \/ / \ / \
\|/ \ / / \ / \
/ \ \/ / \ \ /
/ \ \ / / \ \ /
/ \ \ / / \ |
m = 2 outputs
Lines (edges) in the graph represent vectors, nodes represent operators. Horizontal juxtaposition represents product. Vertical juxtaposition represents composition.
spad
)abbrev domain LIN LinearOperator
LinearOperator(dim:NonNegativeInteger,K:CommutativeRing): Join(Ring,BiModule(K,K)) with
arity: % -> DirectProduct(2,NonNegativeInteger)
elt: (%,%) -> %
id: ()->%
inp: List K -> %
++ incoming vector
inp: List % -> %
out: List K -> %
++ output vector
out: List % -> %
coerce: SquareMatrix(dim,K) -> %
_*: (%,NonNegativeInteger) -> %
== add
import List NonNegativeInteger
T == CartesianTensor(1,dim,K)
Rep == Record(n:NonNegativeInteger, m:NonNegativeInteger, t:T)
rep(x:%):Rep == x pretend Rep
per(x:Rep):% == x pretend %
arity(x:%):DirectProduct(2,NonNegativeInteger) == directProduct [rep(x).n,rep(x).m]
0 == per [0,0,0]
(x:% + y:%):% ==
rep(x).t=0 => per [rep(y).n,rep(y).m,rep(y).t]
rep(y).t=0 => per [rep(x).n,rep(x).m,rep(x).t]
rep(x).n ~= rep(y).n or rep(x).m ~= rep(y).m => error "arity"
per [rep(x).n,rep(x).m,rep(x).t+rep(y).t]
(x:% - y:%):% ==
rep(x).t=0 => per [rep(y).n,rep(y).m,-rep(y).t]
rep(y).t=0 => per [rep(x).n,rep(x).m,rep(x).t]
rep(x).n ~= rep(y).n or rep(x).m ~= rep(y).m => error "arity"
per [rep(x).n,rep(x).m,rep(x).t-rep(y).t]
1 == per [0,0,1]
--
-- f*g : A^n -> A^{m+p} = f:A^n -> A^m * g:A^n -> A^p
--
(x:% * y:%):% ==
output("* rep(x).n",rep(x).n::OutputForm)$OutputPackage
output("* rep(y).n",rep(y).n::OutputForm)$OutputPackage
rep(x).n ~= rep(y).n => error "arity"
r := product(rep(x).t, rep(y).t)
u := 1$DirectProduct(dim,K)::T
ud:= product(u,kroneckerDelta()$T)
for i in 1..rep(x).n repeat
--output("rank",rank(r)::OutputForm)$OutputPackage
--output("n",rep(x).n::OutputForm)$OutputPackage
r := contract(contract(ud,1,r,rep(x).n+1),1,rep(x).n+1)
--output("rank",rank(r)::OutputForm)$OutputPackage
per [rep(x).n,rep(x).m+rep(y).m,r]
-- repeated product
((x:%)^(p:NonNegativeInteger)):% ==
q:=subtractIfCan(p,1)
q case NonNegativeInteger => x^q * x
per [rep(x).n,0,1]
--
-- f+g : A^{n+m} -> A^p = f:A^n -> A^p + g:A^m -> A^p
--
(x:% + y:%):% ==
output("+ rep(x).m",rep(x).m::OutputForm)$OutputPackage
output("+ rep(y).m",rep(y).m::OutputForm)$OutputPackage
rep(x).m ~= rep(y).m => error "arity"
output("+ rep(x).n",rep(x).n::OutputForm)$OutputPackage
output("+ rep(y).n",rep(y).n::OutputForm)$OutputPackage
r := product(rep(x).t, rep(y).t)
u := 1$DirectProduct(dim,K)::T
du:= product(kroneckerDelta()$T,u)
for i in 1..rep(y).m repeat
output("+ rank",rank(r)::OutputForm)$OutputPackage
output("+ rep(y).m",rep(y).m::OutputForm)$OutputPackage
r := contract(contract(du,1,r,rep(y).m+1),1,rep(y).m+2)
--output("rank",rank(r)::OutputForm)$OutputPackage
per [rep(x).n+rep(y).n,rep(y).m,r]
-- repeated sum
(x:% * p:NonNegativeInteger):% ==
q:=subtractIfCan(p,1)
q case NonNegativeInteger => x*q + x
per [0,rep(x).m,1] -- need identity for + !!!
(x:% = y:%):Boolean ==
rep(x).n ~= rep(y).n or rep(x).m ~= rep(y).m => error "arity"
rep(x).t = rep(y).t
(x:K * y:%):% == per [rep(y).n,rep(y).m,x*rep(y).t]
(x:% * y:K):% == per [rep(x).n,rep(x).m,rep(x).t*y]
elt(x:%,y:%):% ==
r:=product(rep(x).t,rep(y).t)
yn:=rep(y).n -- outputs of y
xm:=rep(x).m -- inputs of x
while yn>0 and xm>0 repeat
output("yn",yn::OutputForm)$OutputPackage
output("xm",xm::OutputForm)$OutputPackage
output("rank",rank(r)::OutputForm)$OutputPackage
r:=contract(r,rep(y).n+xm,yn+rep(y).m)
yn:=subtractIfCan(yn,1)::NonNegativeInteger
xm:=subtractIfCan(xm,1)::NonNegativeInteger
per [rep(x).n+xm,yn+rep(y).m,r]
id():% == per [1,1,kroneckerDelta()$T]
inp(x:List K):% == per [1,0,entries(x)::T]
inp(x:List %):% ==
#removeDuplicates([rep(y).n for y in x])~=1 or
#removeDuplicates([rep(y).m for y in x])~=1 => error "arity"
per [rep(first x).n+1,rep(first x).m,[rep(y).t for y in x]::T]$Rep
out(x:List K):% == per [0,1,entries(x)::T]
out(x:List %):% ==
#removeDuplicates([rep(y).n for y in x])~=1 or
#removeDuplicates([rep(y).m for y in x])~=1 => error "arity"
per [rep(first x).n,rep(first x).m+1,[rep(y).t for y in x]::T]$Rep
coerce(x:%):OutputForm == (rep(x).t)::OutputForm
spad
Compiling FriCAS source code from file
/var/zope2/var/LatexWiki/6154772542123042263-25px001.spad using
old system compiler.
LIN abbreviates domain LinearOperator
------------------------------------------------------------------------
initializing NRLIB LIN for LinearOperator
compiling into NRLIB LIN
importing List NonNegativeInteger
compiling local rep : $ -> Record(n: NonNegativeInteger,m: NonNegativeInteger,t: CartesianTensor(One,dim,K))
LIN;rep is replaced by x
Time: 0.09 SEC.
compiling local per : Record(n: NonNegativeInteger,m: NonNegativeInteger,t: CartesianTensor(One,dim,K)) -> $
LIN;per is replaced by x
Time: 0 SEC.
compiling exported arity : $ -> DirectProduct(2,NonNegativeInteger)
Time: 0.20 SEC.
compiling exported Zero : () -> $
Time: 0 SEC.
compiling exported + : ($,$) -> $
Time: 0.02 SEC.
compiling exported - : ($,$) -> $
Time: 0.02 SEC.
compiling exported One : () -> $
Time: 0 SEC.
compiling exported * : ($,$) -> $
Time: 0.03 SEC.
compiling exported ^ : ($,NonNegativeInteger) -> $
Time: 0.01 SEC.
compiling exported + : ($,$) -> $
Time: 0.03 SEC.
compiling exported * : ($,NonNegativeInteger) -> $
Time: 0.01 SEC.
compiling exported = : ($,$) -> Boolean
Time: 0.01 SEC.
compiling exported * : (K,$) -> $
Time: 0.01 SEC.
compiling exported * : ($,K) -> $
Time: 0 SEC.
compiling exported elt : ($,$) -> $
Time: 0.01 SEC.
compiling exported id : () -> $
Time: 0 SEC.
compiling exported inp : List K -> $
Time: 0.08 SEC.
compiling exported inp : List $ -> $
Time: 0.12 SEC.
compiling exported out : List K -> $
Time: 0.01 SEC.
compiling exported out : List $ -> $
Time: 0.02 SEC.
compiling exported coerce : $ -> OutputForm
Time: 0 SEC.
(time taken in buildFunctor: 10)
;;; *** |LinearOperator| REDEFINED
;;; *** |LinearOperator| REDEFINED
Time: 0.02 SEC.
Cumulative Statistics for Constructor LinearOperator
Time: 0.69 seconds
finalizing NRLIB LIN
Processing LinearOperator for Browser database:
--->-->LinearOperator((arity ((DirectProduct 2 (NonNegativeInteger)) %))): Not documented!!!!
--->-->LinearOperator((elt (% % %))): Not documented!!!!
--->-->LinearOperator((id (%))): Not documented!!!!
--------(inp (% (List K)))---------
--->-->LinearOperator((inp (% (List %)))): Not documented!!!!
--------(out (% (List K)))---------
--->-->LinearOperator((out (% (List %)))): Not documented!!!!
--->-->LinearOperator((coerce (% (SquareMatrix dim K)))): Not documented!!!!
--->-->LinearOperator((* (% % (NonNegativeInteger)))): Not documented!!!!
--->-->LinearOperator(constructor): Not documented!!!!
--->-->LinearOperator(): Missing Description
; compiling file "/var/zope2/var/LatexWiki/LIN.NRLIB/LIN.lsp" (written 09 MAR 2011 07:00:54 PM):
; compiling (/VERSIONCHECK 2)
; compiling (PUT (QUOTE |LIN;rep|) ...)
; compiling (DEFUN |LIN;rep| ...)
; compiling (PUT (QUOTE |LIN;per|) ...)
; compiling (DEFUN |LIN;per| ...)
; compiling (DEFUN |LIN;arity;$Dp;3| ...)
; compiling (DEFUN |LIN;Zero;$;4| ...)
; compiling (DEFUN |LIN;+;3$;5| ...)
; compiling (DEFUN |LIN;-;3$;6| ...)
; compiling (DEFUN |LIN;One;$;7| ...)
; compiling (DEFUN |LIN;*;3$;8| ...)
; compiling (DEFUN |LIN;^;$Nni$;9| ...)
; compiling (DEFUN |LIN;+;3$;10| ...)
; compiling (DEFUN |LIN;*;$Nni$;11| ...)
; compiling (DEFUN |LIN;=;2$B;12| ...)
; compiling (DEFUN |LIN;*;K2$;13| ...)
; compiling (DEFUN |LIN;*;$K$;14| ...)
; compiling (DEFUN |LIN;elt;3$;15| ...)
; compiling (DEFUN |LIN;id;$;16| ...)
; compiling (DEFUN |LIN;inp;L$;17| ...)
; compiling (DEFUN |LIN;inp;L$;18| ...)
; compiling (DEFUN |LIN;out;L$;19| ...)
; compiling (DEFUN |LIN;out;L$;20| ...)
; compiling (DEFUN |LIN;coerce;$Of;21| ...)
; compiling (DEFUN |LinearOperator| ...)
; compiling (DEFUN |LinearOperator;| ...)
; compiling (MAKEPROP (QUOTE |LinearOperator|) ...)
; /var/zope2/var/LatexWiki/LIN.NRLIB/LIN.fasl written
; compilation finished in 0:00:00.884
------------------------------------------------------------------------
LinearOperator is now explicitly exposed in frame initial
LinearOperator will be automatically loaded when needed from
/var/zope2/var/LatexWiki/LIN.NRLIB/LIN
Construction operators: input and output
axiom
L:=LIN(2,FRAC POLY INT)
Type: Domain
axiom
A1:L:=inp[script(a,[[1,i]]) for i in 1..2]
Type: LinearOperator
?(2,
Fraction(Polynomial(Integer)))
axiom
arity A1
Type: DirectProduct
?(2,
NonNegativeInteger
?)
axiom
A2:L:=inp[script(a,[[2,i]]) for i in 1..2]
Type: LinearOperator
?(2,
Fraction(Polynomial(Integer)))
axiom
A:L:=inp[A1,A2]
Type: LinearOperator
?(2,
Fraction(Polynomial(Integer)))
axiom
arity A
Type: DirectProduct
?(2,
NonNegativeInteger
?)
axiom
B1:L:=out[script(b,[[],[1,i]]) for i in 1..2]
Type: LinearOperator
?(2,
Fraction(Polynomial(Integer)))
axiom
arity B1
Type: DirectProduct
?(2,
NonNegativeInteger
?)
axiom
B2:L:=out[script(b,[[],[2,i]]) for i in 1..2]
Type: LinearOperator
?(2,
Fraction(Polynomial(Integer)))
axiom
B:L:=out[B1,B2]
Type: LinearOperator
?(2,
Fraction(Polynomial(Integer)))
axiom
arity B
Type: DirectProduct
?(2,
NonNegativeInteger
?)
Products
axiom
A12p := A1 * A2; A12p::OutputForm = A1::OutputForm * A2::OutputForm
* rep(x).n 1
* rep(y).n 1
Type: Equation(OutputForm
?)
axiom
arity(A12p)::OutputForm = arity(A1)::OutputForm * arity(A2)::OutputForm
Type: Equation(OutputForm
?)
axiom
B12p := B1 * B2; B12p::OutputForm = B1::OutputForm * B2::OutputForm
* rep(x).n 0
* rep(y).n 0
Type: Equation(OutputForm
?)
axiom
arity(B12p)::OutputForm = arity(B1)::OutputForm * arity(B2)::OutputForm
Type: Equation(OutputForm
?)
Powers
axiom
A3p:=(A1*A1)*A1
* rep(x).n 1
* rep(y).n 1
* rep(x).n 1
* rep(y).n 1
Type: LinearOperator
?(2,
Fraction(Polynomial(Integer)))
axiom
arity(A3p)
Type: DirectProduct
?(2,
NonNegativeInteger
?)
axiom
test(A3p=A1*(A1*A1))
* rep(x).n 1
* rep(y).n 1
* rep(x).n 1
* rep(y).n 1
Type: Boolean
axiom
test(A3p=A1^3)
* rep(x).n 1
* rep(y).n 1
* rep(x).n 1
* rep(y).n 1
Type: Boolean
axiom
B3p:=(B1*B1)*B1
* rep(x).n 0
* rep(y).n 0
* rep(x).n 0
* rep(y).n 0
Type: LinearOperator
?(2,
Fraction(Polynomial(Integer)))
axiom
arity(B3p)
Type: DirectProduct
?(2,
NonNegativeInteger
?)
axiom
test(B3p=B1*(B1*B1))
* rep(x).n 0
* rep(y).n 0
* rep(x).n 0
* rep(y).n 0
Type: Boolean
axiom
test(B3p=B1^3)
* rep(x).n 0
* rep(y).n 0
* rep(x).n 0
* rep(y).n 0
Type: Boolean
Sums
axiom
A12s := A1 + A2; A12s::OutputForm = A1::OutputForm + A2::OutputForm
+ rep(x).m 0
+ rep(y).m 0
+ rep(x).n 1
+ rep(y).n 1
Type: Equation(OutputForm
?)
axiom
arity(A12s)::OutputForm = arity(A1)::OutputForm + arity(A2)::OutputForm
Type: Equation(OutputForm
?)
axiom
B12s := B1 + B2; B12s::OutputForm = B1::OutputForm + B2::OutputForm
+ rep(x).m 1
+ rep(y).m 1
+ rep(x).n 0
+ rep(y).n 0
+ rank 2
+ rep(y).m 1
Type: Equation(OutputForm
?)
axiom
arity(B12s)::OutputForm = arity(B1)::OutputForm + arity(B2)::OutputForm
Type: Equation(OutputForm
?)
Multiplication
axiom
A3s:=(A1+A1)+A1
+ rep(x).m 0
+ rep(y).m 0
+ rep(x).n 1
+ rep(y).n 1
+ rep(x).m 0
+ rep(y).m 0
+ rep(x).n 2
+ rep(y).n 1
Type: LinearOperator
?(2,
Fraction(Polynomial(Integer)))
axiom
arity(A3s)
Type: DirectProduct
?(2,
NonNegativeInteger
?)
axiom
test(A3s=A1+(A1+A1))
+ rep(x).m 0
+ rep(y).m 0
+ rep(x).n 1
+ rep(y).n 1
+ rep(x).m 0
+ rep(y).m 0
+ rep(x).n 1
+ rep(y).n 2
Type: Boolean
axiom
test(A3s=A1*3)
+ rep(x).m 0
+ rep(y).m 0
+ rep(x).n 0
+ rep(y).n 1
+ rep(x).m 0
+ rep(y).m 0
+ rep(x).n 1
+ rep(y).n 1
+ rep(x).m 0
+ rep(y).m 0
+ rep(x).n 2
+ rep(y).n 1
Type: Boolean
axiom
B3s:=(B1+B1)+B1
+ rep(x).m 1
+ rep(y).m 1
+ rep(x).n 0
+ rep(y).n 0
+ rank 2
+ rep(y).m 1
+ rep(x).m 1
+ rep(y).m 1
+ rep(x).n 0
+ rep(y).n 0
+ rank 2
+ rep(y).m 1
Type: LinearOperator
?(2,
Fraction(Polynomial(Integer)))
axiom
arity(B3s)
Type: DirectProduct
?(2,
NonNegativeInteger
?)
axiom
test(B3s=B1+(B1+B1))
+ rep(x).m 1
+ rep(y).m 1
+ rep(x).n 0
+ rep(y).n 0
+ rank 2
+ rep(y).m 1
+ rep(x).m 1
+ rep(y).m 1
+ rep(x).n 0
+ rep(y).n 0
+ rank 2
+ rep(y).m 1
Type: Boolean
axiom
test(B3s=B1*3)
+ rep(x).m 1
+ rep(y).m 1
+ rep(x).n 0
+ rep(y).n 0
+ rank 1
+ rep(y).m 1
>> Error detected within library code:
Improper index for contraction
Expected error
axiom
B1A1:=B1*A1
* rep(x).n 0
* rep(y).n 1
>> Error detected within library code:
arity
Composition
axiom
AB11:=A1 B1
Type: LinearOperator
?(2,
Fraction(Polynomial(Integer)))
axiom
arity(AB11)
Type: DirectProduct
?(2,
NonNegativeInteger
?)
axiom
BA11:= B1 A1
yn 1
xm 1
rank 2
Type: LinearOperator
?(2,
Fraction(Polynomial(Integer)))
axiom
arity(BA11)
Type: DirectProduct
?(2,
NonNegativeInteger
?)
axiom
AB := A B
Type: LinearOperator
?(2,
Fraction(Polynomial(Integer)))
axiom
arity(AB)
Type: DirectProduct
?(2,
NonNegativeInteger
?)
axiom
BA := B A
yn 2
xm 2
rank 4
yn 1
xm 1
rank 2
>> Error detected within library code:
Improper index for contraction
Multiple inputs and outputs
axiom
W:L:=out[inp[inp([script(w,[[i,j],[k]]) for j in 1..2])$L for i in 1..2] for k in 1..2]
Type: LinearOperator
?(2,
Fraction(Polynomial(Integer)))
axiom
WB1:=W B1
Type: LinearOperator
?(2,
Fraction(Polynomial(Integer)))
axiom
arity(WB1)
Type: DirectProduct
?(2,
NonNegativeInteger
?)
Another kind of diagram:
___ _ _ _ _
___ _) = _\_ _ _\/_
_/ ___ _) _/\_