fricas
(1) -> )lib CARTEN MONAL PROP
CartesianTensor is now explicitly exposed in frame initial
CartesianTensor will be automatically loaded when needed from
/var/aw/var/LatexWiki/CARTEN.NRLIB/CARTEN
Monoidal is now explicitly exposed in frame initial
Monoidal will be automatically loaded when needed from
/var/aw/var/LatexWiki/MONAL.NRLIB/MONAL
Prop is now explicitly exposed in frame initial
Prop will be automatically loaded when needed from
/var/aw/var/LatexWiki/PROP.NRLIB/PROP
spad
)abbrev domain LOP LinearOperator
LinearOperator(gener:OrderedFinite,K:Field): Exports == Implementation where
NNI ==> NonNegativeInteger
NAT ==> PositiveInteger
T ==> CartesianTensor(1,dim,K)
Exports ==> Join(Ring, FramedModule K, Monoidal NNI, RetractableTo K) with
dimension: () -> CardinalNumber
arity: % -> Prop %
basisOut: () -> List %
basisIn: () -> List %
tensor: % -> T
I : () -> %
map: (K->K,%) -> %
if K has Evalable(K) then Evalable(K)
eval: % -> %
ravel: % -> List K
unravel: (Prop %,List K) -> %
coerce:(x:List NAT) -> %
++ identity for composition and permutations of its products
coerce:(x:List None) -> %
++ [] = 1
elt: (%,%) -> %
elt: (%,NAT) -> %
elt: (%,NAT,NAT) -> %
elt: (%,NAT,NAT,NAT) -> %
_/: (Tuple %,Tuple %) -> %
_/: (Tuple %,%) -> %
_/: (%,Tuple %) -> %
++ yet another syntax for product
ev: NAT -> %
++ (2,0)-tensor for evaluation
co: NAT -> %
++ (0,2)-tensor for co-evaluation
Implementation ==> add
import List NNI
import NAT
L ==> Record(domain:NNI, codomain:NNI, data:T)
-- FreeMonoid provides unevaluated products
Rep ==> FreeMonoid L
RR ==> Record(gen:L,exp:NNI)
rep(x:%):Rep == x pretend Rep
per(x:Rep):% == x pretend %
dim:NNI := size()$gener
dimension():CardinalNumber == coerce dim
-- Prop (arity)
dom(f:%):NNI ==
r:NNI := 0
for y in factors(rep f) repeat
r:=r+(y.gen.domain)*(y.exp)
return r
cod(f:%):NNI ==
r:NNI := 0
for y in factors(rep f) repeat
r:=r+(y.gen.codomain)*(y.exp)
return r
prod(f:L,g:L):L ==
r:T := product(f.data,g.data)
-- dom(f) + cod(f) + dom(g) + cod(g)
p:List Integer := concat _
[[i for i in 1..(f.domain)], _
[(f.domain)+(f.codomain)+i for i in 1..(g.domain)], _
[(f.domain)+i for i in 1..(f.codomain)], _
[(f.domain)+(g.domain)+(f.codomain)+i for i in 1..(g.codomain)]]
-- dom(f) + dom(g) + cod(f) + cod(g)
--output("prod p = ",p::OutputForm)$OutputPackage
[(f.domain)+(g.domain),(f.codomain)+(g.codomain),reindex(r,p)]
dats(fs:List RR):L ==
r:L := [0,0,1$T]
for y in fs repeat
t:L:=y.gen
for n in 1..y.exp repeat
r:=prod(r,t)
return r
dat(f:%):L == dats factors rep f
arity(f:%):Prop % == f::Prop %
eval(f:%):% == per coerce dat(f)
retractIfCan(f:%):Union(K,"failed") ==
dom(f)=0 and cod(f)=0 => retract(dat(f).data)$T
return "failed"
retract(f:%):K ==
dom(f)=0 and cod(f)=0 => retract(dat(f).data)$T
error "failed"
-- basis
basisOut():List % == [per coerce [0,1,entries(row(1,i)$SquareMatrix(dim,K))::T] for i in 1..dim]
basisIn():List % == [per coerce [1,0,entries(row(1,i)$SquareMatrix(dim,K))::T] for i in 1..dim]
ev(n:NAT):% == reduce(_+,[ dx^n * dx^n for dx in basisIn()])$List(%)
-- dx:= basisIn()
-- reduce(_+,[ (dx.i)^n * (dx.i)^n for i in 1..dim])
co(n:NAT):% == reduce(_+,[ Dx^n * Dx^n for Dx in basisOut()])$List(%)
-- Dx:= basisOut()
-- reduce(_+,[ (Dx.i)^n * (Dx.i)^n for i in 1..dim])
-- manipulation
map(f:K->K, g:%):% == per coerce [dom g,cod g,unravel(map(f,ravel dat(g).data))$T]
if K has Evalable(K) then
eval(g:%,f:List Equation K):% == map((x:K):K+->eval(x,f),g)
ravel(g:%):List K == ravel dat(g).data
unravel(p:Prop %,r:List K):% ==
dim^(dom(p)+cod(p)) ~= #r => error "failed"
per coerce [dom(p),cod(p),unravel(r)$T]
tensor(x:%):T == dat(x).data
-- sum
(f:% + g:%):% ==
dat(f).data=0 => g
dat(g).data=0 => f
dom(f) ~= dom(g) or cod(f) ~= cod(g) => error "arity"
per coerce [dom f,cod f,dat(f).data+dat(g).data]
(f:% - g:%):% ==
dat(f).data=0 => g
dat(g).data=0 => f
dom(f) ~= dom(f) or cod(g) ~= cod(g) => error "arity"
per coerce [dom f, cod f,dat(f).data-dat(g).data]
_-(f:%):% == per coerce [dom f, cod f,-dat(f).data]
-- identity for sum (trivial zero map)
0 == per coerce [0,0,0]
zero?(f:%):Boolean == dat(f).data = 0 * dat(f).data
-- identity for product
1:% == per 1
one?(f:%):Boolean == one? rep f
-- identity for composition
I == per coerce [1,1,kroneckerDelta()$T]
(x:% = y:%):Boolean == rep eval x = rep eval y
-- permutations and identities
coerce(p:List NAT):% ==
r:=I^#p
#p = 1 and p.1 = 1 => return r
p1:List Integer:=[i for i in 1..#p]
p2:List Integer:=[#p+i for i in p]
p3:=concat(p1,p2)
--output("coerce p3 = ",p3::OutputForm)$OutputPackage
per coerce [#p,#p,reindex(dat(r).data,p3)]
coerce(p:List None):% == per coerce [0,0,1]
coerce(x:K):% == x*1
-- tensor product
elt(f:%,g:%):% == f * g
elt(f:%,g:NAT):% == f * I^g
elt(f:%,g1:NAT,g2:NAT):% == f * [g1 @ NAT,g2 @ NAT]::List NAT::%
elt(f:%,g1:NAT,g2:NAT,g3:NAT):% == f * [g1 @ NAT,g2 @ NAT,g3 @ NAT]::List NAT::%
apply(f:%,g:%):% == f * g
(f:% * g:%):% == per (rep f * rep g)
leadI(x:Rep):NNI ==
r:=hclf(x,rep(I)^size(x))
size(r)=0 => 0
nthExpon(r,1)
trailI(x:Rep):NNI ==
r:=hcrf(x,rep(I)^size(x))
size(r)=0 => 0
nthExpon(r,1)
-- composition:
-- f/g : A^n -> A^p = f:A^n -> A^m / g:A^m -> A^p
(ff:% / gg:%):% ==
g:=gg; f:=ff
-- partial application from the left
nn:=subtractIfCan(cod ff,dom gg)
if nn case NNI and nn>0 then
-- apply g on f from the left, pass extra f outputs on the right
print(hconcat([message("arity warning: "), _
over(arity(ff)::OutputForm, _
arity(gg)::OutputForm*(arity(I)::OutputForm)^nn::OutputForm) ]))$OutputForm
g:=gg*I^nn
mm:=subtractIfCan(dom gg, cod ff)
-- apply g on f from the left, add extra g inputs on the left
if mm case NNI and mm>0 then
print(hconcat([message("arity warning: "), _
over((arity(I)::OutputForm)^mm::OutputForm*arity(ff)::OutputForm, _
arity(gg)::OutputForm)]))$OutputForm
f:=I^mm*ff
-- parallelize composition f/g = (f1/g1)*(f2/g2)
if cod(f)>0 then
i:Integer:=1
j:Integer:=1
n:NNI:=1
m:NNI:=1
f1 := per coerce nthFactor(rep f,1)
g1 := per coerce nthFactor(rep g,1)
while cod(f1)~=dom(g1) repeat
if cod(f1) < dom(g1) then
if n < nthExpon(rep f,i) then
n:=n+1
else
n:=1
i:=i+1
f1 := f1 * per coerce nthFactor(rep f,i)
else if cod(f1) > dom(g1) then
if m < nthExpon(rep g,j) then
m:=m+1
else
n:=1
j:=j+1
g1 := g1 * per coerce nthFactor(rep g,j)
f2 := per overlap(rep f1, rep f).rm
g2 := per overlap(rep g1,rep g).rm
f := f1
g := g1
else
f2 := per 1
g2 := per 1
-- factor parallel identites
nl := leadI hclf(rep f,rep g)
nI := rep(I)^nl
f := per overlap(nI,rep f).rm
g := per overlap(nI,rep g).rm
ln := trailI hcrf(rep f,rep g)
In := rep(I)^ln
f := per overlap(rep f,In).lm
g := per overlap(rep g,In).lm
-- remove leading and trailing identities
nf := leadI rep f
f := per overlap(rep(I)^nf,rep f).rm
ng := leadI rep g
g := per overlap(rep(I)^ng,rep g).rm
fn := trailI rep f
f := per overlap(rep f,rep(I)^fn).lm
gn := trailI rep g
g := per overlap(rep g,rep(I)^gn).lm
-- Factoring out parallel identities guarantees that:
if nf>0 and ng>0 then error "either nf or ng or both must be 0"
if fn>0 and gn>0 then error "either fn or gn or both must be 0"
-- Exercise for Reader:
-- Prove the following contraction and permutation is correct by
-- considering all 9 cases for (nf=0 or ng=0) and (fn=0 or gn=0).
-- output("leading [nl,nf,ng] = ",[nl,nf,ng]::OutputForm)$OutputPackage
-- output("trailing [ln,fn,gn] = ",[ln,fn,gn]::OutputForm)$OutputPackage
r:T := contract(cod(f)-ng-gn, dat(f).data,dom(f)+ng+1, dat(g).data,nf+1)
p:List Integer:=concat [ _
[dom(f)+gn+i for i in 1..nf], _
[i for i in 1..dom(f)], _
[dom(f)+nf+ng+i for i in 1..fn], _
[dom(f)+i for i in 1..ng], _
[dom(f)+nf+ng+fn+gn+i for i in 1..cod(g)], _
[dom(f)+ng+i for i in 1..gn] ]
--print(p::OutputForm)$OutputForm
r:=reindex(r,p)
if f2=1 and g2=1 then
return per nI * per coerce [nf+dom(f)+fn,ng+cod(g)+gn,r] * per In
if f2=1 then error "g2 should be 1"
if g2=1 then error "f2 should be 1"
return per nI * per coerce [nf+dom(f)+fn,ng+cod(g)+gn,r] * per In * (f2/g2)
-- another notation for composition of products
(t:Tuple % / x:%):% == t / construct([x])$PrimitiveArray(%)::Tuple(%)
(x:% / t:Tuple %):% == construct([x])$PrimitiveArray(%)::Tuple(%) / t
(f:Tuple % / g:Tuple %):% ==
fs:List % := [select(f,i) for i in 0..#(f)-1]
gs:List % := [select(g,i) for i in 0..#(g)-1]
fr:=reduce(elt@(%,%)->%,fs,1)
gr:=reduce(elt@(%,%)->%,gs,1)
fr / gr
(x:K * y:%):% == per coerce [dom y, cod y,x*dat(y).data]
--(x:% * y:K):% == per coerce [dom x,cod x,dat(x).data*y]
(x:Integer * y:%):% == per coerce [dom y,cod y,x*dat(y).data]
-- display operators using basis
show(x:%):OutputForm ==
dom(x)=0 and cod(x)=0 => return (dat(x).data)::OutputForm
if size()$gener > 0 then
gens:List OutputForm:=[index(i::PositiveInteger)$gener::OutputForm for i in 1..dim]
else
-- default to numeric indices
gens:List OutputForm:=[i::OutputForm for i in 1..dim]
-- input basis
inps:List OutputForm := []
for i in 1..dom(x) repeat
empty? inps => inps:=gens
inps:=concat [[(inps.k * gens.j) for j in 1..dim] for k in 1..#inps]
-- output basis
outs:List OutputForm := []
for i in 1..cod(x) repeat
empty? outs => outs:=gens
outs:=concat [[(outs.k * gens.j) for j in 1..dim] for k in 1..#outs]
-- combine input (superscripts) and/or output(subscripts) to form basis symbols
bases:List OutputForm
if #inps > 0 and #outs > 0 then
bases:=concat([[ scripts(message("|"),[i,j]) for i in outs] for j in inps])
else if #inps > 0 then
bases:=[super(message("|"),i) for i in inps]
else if #outs > 0 then
bases:=[sub(message("|"),j) for j in outs]
else
bases:List OutputForm:= []
-- merge bases with data to form term list
terms:=[(k=1 => base;k::OutputForm*base)
for base in bases for k in ravel dat(x).data | k~=0]
empty? terms => return 0::OutputForm
-- combine the terms
return reduce(_+,terms)
coerce(x:%):OutputForm ==
r:OutputForm := empty()
for y in factors(rep x) repeat
if y.exp = 1 then
if size rep x = 1 then
r := show per coerce y.gen
else
r:=r*paren(list show per coerce y.gen)
else
r:=r*paren(list show per coerce y.gen)^(y.exp::OutputForm)
return r
spad
Compiling FriCAS source code from file
/var/lib/zope2.10/instance/axiom-wiki/var/LatexWiki/5221482899668613588-25px002.spad
using old system compiler.
LOP abbreviates domain LinearOperator
------------------------------------------------------------------------
initializing NRLIB LOP for LinearOperator
compiling into NRLIB LOP
importing List NonNegativeInteger
importing PositiveInteger
processing macro definition L ==> Record(domain: NonNegativeInteger,codomain: NonNegativeInteger,data: CartesianTensor(One,dim,K))
processing macro definition Rep ==> FreeMonoid Record(domain: NonNegativeInteger,codomain: NonNegativeInteger,data: CartesianTensor(One,dim,K))
processing macro definition RR ==> Record(gen: Record(domain: NonNegativeInteger,codomain: NonNegativeInteger,data: CartesianTensor(One,dim,K)),exp: NonNegativeInteger)
compiling local rep : % -> FreeMonoid Record(domain: NonNegativeInteger,codomain: NonNegativeInteger,data: CartesianTensor(One,dim,K))
LOP;rep is replaced by x
Time: 0.02 SEC.
compiling local per : FreeMonoid Record(domain: NonNegativeInteger,codomain: NonNegativeInteger,data: CartesianTensor(One,dim,K)) -> %
LOP;per is replaced by x
Time: 0 SEC.
compiling exported dimension : () -> CardinalNumber
Time: 0 SEC.
compiling exported dom : % -> NonNegativeInteger
Time: 0 SEC.
compiling exported cod : % -> NonNegativeInteger
Time: 0 SEC.
compiling local prod : (Record(domain: NonNegativeInteger,codomain: NonNegativeInteger,data: CartesianTensor(One,dim,K)),Record(domain: NonNegativeInteger,codomain: NonNegativeInteger,data: CartesianTensor(One,dim,K))) -> Record(domain: NonNegativeInteger,codomain: NonNegativeInteger,data: CartesianTensor(One,dim,K))
Time: 0 SEC.
compiling local dats : List Record(gen: Record(domain: NonNegativeInteger,codomain: NonNegativeInteger,data: CartesianTensor(One,dim,K)),exp: NonNegativeInteger) -> Record(domain: NonNegativeInteger,codomain: NonNegativeInteger,data: CartesianTensor(One,dim,K))
Time: 0 SEC.
compiling local dat : % -> Record(domain: NonNegativeInteger,codomain: NonNegativeInteger,data: CartesianTensor(One,dim,K))
Time: 0 SEC.
compiling exported arity : % -> Prop %
Time: 0 SEC.
compiling exported eval : % -> %
Time: 0 SEC.
compiling exported retractIfCan : % -> Union(K,failed)
Time: 0 SEC.
compiling exported retract : % -> K
Time: 0 SEC.
compiling exported basisOut : () -> List %
Time: 0 SEC.
compiling exported basisIn : () -> List %
Time: 0 SEC.
compiling exported ev : PositiveInteger -> %
Time: 0.01 SEC.
compiling exported co : PositiveInteger -> %
Time: 0 SEC.
compiling exported map : (K -> K,%) -> %
Time: 0 SEC.
****** Domain: K already in scope
augmenting K: (Evalable K)
compiling exported eval : (%,List Equation K) -> %
Time: 0 SEC.
compiling exported ravel : % -> List K
Time: 0 SEC.
compiling exported unravel : (Prop %,List K) -> %
Time: 0 SEC.
compiling exported tensor : % -> CartesianTensor(One,dim,K)
Time: 0 SEC.
compiling exported + : (%,%) -> %
Time: 0 SEC.
compiling exported - : (%,%) -> %
Time: 0 SEC.
compiling exported - : % -> %
Time: 0 SEC.
compiling exported Zero : () -> %
Time: 0 SEC.
compiling exported zero? : % -> Boolean
Time: 0 SEC.
compiling exported One : () -> %
Time: 0 SEC.
compiling exported one? : % -> Boolean
Time: 0 SEC.
compiling exported I : () -> %
Time: 0 SEC.
compiling exported = : (%,%) -> Boolean
Time: 0 SEC.
compiling exported coerce : List PositiveInteger -> %
Time: 0.01 SEC.
compiling exported coerce : List None -> %
Time: 0 SEC.
compiling exported coerce : K -> %
Time: 0 SEC.
compiling exported elt : (%,%) -> %
Time: 0 SEC.
compiling exported elt : (%,PositiveInteger) -> %
Time: 0 SEC.
compiling exported elt : (%,PositiveInteger,PositiveInteger) -> %
Time: 0 SEC.
compiling exported elt : (%,PositiveInteger,PositiveInteger,PositiveInteger) -> %
Time: 0 SEC.
compiling exported apply : (%,%) -> %
Time: 0 SEC.
compiling exported * : (%,%) -> %
Time: 0 SEC.
compiling local leadI : FreeMonoid Record(domain: NonNegativeInteger,codomain: NonNegativeInteger,data: CartesianTensor(One,dim,K)) -> NonNegativeInteger
Time: 0 SEC.
compiling local trailI : FreeMonoid Record(domain: NonNegativeInteger,codomain: NonNegativeInteger,data: CartesianTensor(One,dim,K)) -> NonNegativeInteger
Time: 0 SEC.
compiling exported / : (%,%) -> %
Time: 0.06 SEC.
compiling exported / : (Tuple %,%) -> %
Time: 0 SEC.
compiling exported / : (%,Tuple %) -> %
Time: 0 SEC.
compiling exported / : (Tuple %,Tuple %) -> %
Time: 0 SEC.
compiling exported * : (K,%) -> %
Time: 0 SEC.
compiling exported * : (Integer,%) -> %
Time: 0 SEC.
compiling local show : % -> OutputForm
Time: 0.01 SEC.
compiling exported coerce : % -> OutputForm
Time: 0.02 SEC.
****** Domain: K already in scope
augmenting K: (Evalable K)
****** Domain: K already in scope
augmenting K: (Finite)
****** Domain: K already in scope
augmenting K: (Hashable)
(time taken in buildFunctor: 3062)
;;; *** |LinearOperator| REDEFINED
;;; *** |LinearOperator| REDEFINED
Time: 0 SEC.
Warnings:
[1] dom: gen has no value
[2] dom: domain has no value
[3] dom: exp has no value
[4] cod: gen has no value
[5] cod: codomain has no value
[6] cod: exp has no value
[7] prod: data has no value
[8] prod: domain has no value
[9] prod: codomain has no value
[10] dats: gen has no value
[11] dats: exp has no value
[12] retractIfCan: data has no value
[13] retract: data has no value
[14] map: data has no value
[15] ravel: data has no value
[16] tensor: data has no value
[17] +: data has no value
[18] -: data has no value
[19] zero?: data has no value
[20] coerce: data has no value
[21] /: i has no value
[22] /: j has no value
[23] /: data has no value
[24] *: data has no value
[25] show: data has no value
[26] coerce: exp has no value
[27] coerce: gen has no value
Cumulative Statistics for Constructor LinearOperator
Time: 0.22 seconds
finalizing NRLIB LOP
Processing LinearOperator for Browser database:
--->-->LinearOperator(constructor): Not documented!!!!
--->-->LinearOperator((dimension ((CardinalNumber)))): Not documented!!!!
--->-->LinearOperator((arity ((Prop %) %))): Not documented!!!!
--->-->LinearOperator((basisOut ((List %)))): Not documented!!!!
--->-->LinearOperator((basisIn ((List %)))): Not documented!!!!
--->-->LinearOperator((tensor ((CartesianTensor (One) dim K) %))): Not documented!!!!
--->-->LinearOperator((I (%))): Not documented!!!!
--->-->LinearOperator((map (% (Mapping K K) %))): Not documented!!!!
--->-->LinearOperator((eval (% %))): Not documented!!!!
--->-->LinearOperator((ravel ((List K) %))): Not documented!!!!
--->-->LinearOperator((unravel (% (Prop %) (List K)))): Not documented!!!!
--------(coerce (% (List (PositiveInteger))))---------
--->-->LinearOperator((coerce (% (List (PositiveInteger))))): Improper first word in comments: identity
"identity for composition and permutations of its products"
--------(coerce (% (List (None))))---------
--->-->LinearOperator((coerce (% (List (None))))): Improper first word in comments: []
"[] = 1"
--->-->LinearOperator((elt (% % %))): Not documented!!!!
--->-->LinearOperator((elt (% % (PositiveInteger)))): Not documented!!!!
--->-->LinearOperator((elt (% % (PositiveInteger) (PositiveInteger)))): Not documented!!!!
--->-->LinearOperator((elt (% % (PositiveInteger) (PositiveInteger) (PositiveInteger)))): Not documented!!!!
--->-->LinearOperator((/ (% (Tuple %) (Tuple %)))): Not documented!!!!
--->-->LinearOperator((/ (% (Tuple %) %))): Not documented!!!!
--------(/ (% % (Tuple %)))---------
--->-->LinearOperator((/ (% % (Tuple %)))): Improper first word in comments: yet
"yet another syntax for product"
--------(ev (% (PositiveInteger)))---------
--->-->LinearOperator((ev (% (PositiveInteger)))): Improper first word in comments:
"(2,{}0)-tensor for evaluation"
--------(co (% (PositiveInteger)))---------
--->-->LinearOperator((co (% (PositiveInteger)))): Improper first word in comments:
"(0,{}2)-tensor for co-evaluation"
--->-->LinearOperator(): Missing Description
; compiling file "/var/aw/var/LatexWiki/LOP.NRLIB/LOP.lsp" (written 07 MAY 2024 04:03:58 PM):
; wrote /var/aw/var/LatexWiki/LOP.NRLIB/LOP.fasl
; compilation finished in 0:00:00.560
------------------------------------------------------------------------
LinearOperator is now explicitly exposed in frame initial
LinearOperator will be automatically loaded when needed from
/var/aw/var/LatexWiki/LOP.NRLIB/LOP
Tests
fricas
L := LOP(OVAR ['1,'2],EXPR INT)
Type: Type
fricas
dimension()$L
fricas
macro Σ(f,i,b) == reduce(+,[f*b.i for i in 1..#b])
Type: Void
fricas
A:L := Σ( Σ( script(a,[[j],[i]]), i,basisIn()$L), j,basisOut()$L)
fricas
3*A
fricas
A/3
1
-
1
arity warning: ------
0 1 1
- (-)
0 1
fricas
I:L := [1]
fricas
test( I*I = [1,2] )
Type: Boolean
fricas
X:L := [2,1]
fricas
-- printing
I*X*X*I
fricas
-- braid
B3:=(I*X)/(X*I)
fricas
test(B3/B3/B3 = I*I*I)
Type: Boolean
fricas
-- parallel
(X*X)/(X*X)
fricas
-- trace
U:L:=ev(1)
fricas
Ω:L:=co(1)
fricas
Ω/U
Various special cases of composition
fricas
-- case 1
test( X/X = [1,2] )
Type: Boolean
fricas
test( (I*X)/(I*X) = [1,2,3] )
Type: Boolean
fricas
test( (I*X*I)/(I*X*I) = [1,2,3,4] )
Type: Boolean
fricas
-- case 2
test( (X*I*I)/(X*X) = [1,2,4,3] )
Type: Boolean
fricas
-- case 3
test( (X*X)/(X*I*I) = [1,2,4,3] )
Type: Boolean
fricas
-- case 4
test ( (I*I*X)/(X*X) = [2,1,3,4] )
Type: Boolean
fricas
-- case 5
test( (I*X*I)/(X*X) = [3,1,4,2] )
Type: Boolean
fricas
-- case 6
test( (I*I*X)/(X*I*I)=[2,1,4,3] )
Type: Boolean
fricas
test( (I*X)/(X*I) = [3,1,2] )
Type: Boolean
fricas
test( (I*X*I)/(X*I*I)=[3,1,2,4] )
Type: Boolean
fricas
-- case 7
test( (X*X)/(I*I*X) = [2,1,3,4] )
Type: Boolean
fricas
-- case 8
test( (X*I)/(I*X) = [2,3,1] )
Type: Boolean
fricas
-- case 9
test( (X*X)/(I*X*I) = [2,4,1,3] )
Type: Boolean