Clifford Algebra examples:

36 views
Skip to first unread message

Bertfried Fauser

unread,
Nov 26, 2009, 9:57:50 AM11/26/09
to fricas...@googlegroups.com, axiom-devel, Martin Baker, root, Ablamowicz
Hi,

attached to this mail is a pdf which contains Clifford algebra test
cases (mainly dim V=2).
I was not able to scale the maple output to a smaler font face, so the
larger examples seem
hard to be recognised, sorry for that.

I hope that this mail will get through to fricas-devel but in case it
does not, I sent it to a few
interested people directly.

Kind regards
BF.

--
% PD Dr Bertfried Fauser
% Research Fellow, School of Computer Science, Univ. of Birmingham
% Honorary Associate, University of Tasmania
% Privat Docent: University of Konstanz, Physics Dept
<http://www.uni-konstanz.de>
% contact |-> URL : http://www.cs.bham.ac.uk/~fauserb/
% Phone : +44-121-41-42795 and +49 1520 9874517
CliffordTestcases.pdf

Bertfried Fauser

unread,
Nov 26, 2009, 1:29:16 PM11/26/09
to Martin Baker, axiom-devel, fricas...@googlegroups.com, Ablamowicz
Dear Martin,

> Can I ask about the definitions of the involutions:
Yes, please ask, I'll answer if I know and time permits.

> gradeInvolution == reversion? sign=(-1)^(d(d-1)/2) symbol= ~
> Cliplus clirev == ? symbol=multiply by pseudoscalar? symbol=
> Clifford conjugation: scalar part minus non-scalar part? symbol=

The involutions you give are again assuming a diagonal (orthonormal)
basis for the quadratic (bilinear) form. Since this is bad for applications,
it has to be avoided. Of course if you know you are in a diagonal basis
you can use faster algorithms (like defining a cmulDiag)

Grade involution:
Any (Grassmann-) Clifford algebra is built up from a base space V (of dimension
dim V = n) You have two natural transformations on V which generalize
to the whole space W=/\V of dim W = 2^n.
a) The identity map (does nothing on W)
b) The map sending every vector v \in V to its additiove inverse (negative)
barV : V -> V :: v |--> -v
This will send any basis vector to its negative (regardless of the bilinear
form). So iff your basis is like the grBasis :=[Id, e1, e2, e1we2, e3,...]
barW will send all elements eiw..wej to (-)^number of basis
elements eiw..wej
c) Iff the basis is more general (like in the case with an antisymmetric part in
the bilinear form, you always fing a new basis (inhomgeous in the old
generators) such that the involution does the trick for the new
basis elements.
Eg: B:= matrix [[1,q],[-q ,1]] you would liek tto define a new
Grassmann basis
grBasWf = [Id, f1(=e1),f2(=e2), f1wf2 ( f1wf2-q*Id), f3 (=e3),...] etc
In this case you will see that the new basis is graded (only even or odd
elements appear) so the involution still works as expected.

Whta you technically do is the following:
* Take a vector space V
* build the free algebra over it, that is the tensor algebra TV, its product is
concatenation it is noncommutative
* You are only intersted in antisymmetric tensors, hence factor out
all symmetric
ones. That is you identify all terms of the form
(v1 (x)... (x) vi (x) vi (x) ... (x) vd) = 0
[One can check that this is a graded ideal I_gr and one can therefor factor
the tensor algebra TV/I_gr = /\V
(for the generators this means you impose ei^2=0. From that you conclude that
0=(ei+ej)^(x)2 = ei^2+ei (x) ej + ej (x) ei + ej^2
= ei (x) ej + ej (x) ej
calling the projectet tensor /\ you get
ei /\ ej = - ej /\ ei )

Reversion:
This is quite different. The reversion needs to know about the Clifford
multiplication, so its actually defined in the Clifford basis
cliBas:= [Id, e(1), e(2), e(12):=e(1)*e(2), e(3),... ]
and it reverses the order of the Clifford multiplication (which depends on
the quadratic (bilinear) form. Hence you have (eij) Grassmann ,
e(ij) Clifford
basis elements)
reversion e12 = reversion (e(12)-B(e1,e2)*Id) = e(21)-B(e1,e2)*Id
= e2/\e1 +(B(e2,e1)-B(e1,e2))*Id
= -e12 - 2F(e1,e2)
where F(e1,e2) is the antisymmetric part of B, hence this difficulty will
_only_ appear when there is an antisymmetric part. Since not many people
have looked at that, its rarely described in literature, but see my
joint papers
with Rafal Ablamowicz:
#
Mathematics of CLIFFORD - A Maple package for Clifford and Grassmann algebras
Rafal Ablamowicz, B. Fauser: Adv. in Appl. Clifford Alg. 15 No. 2, 2005:157-181

#
arXiv:math-ph/0212032
Clifford and Grassmann Hopf algebras via the BIGEBRA package for Maple
Rafal Ablamowicz, B. Fauser: Comp. Physics Comm. 170, 2005:115--130
available from the arXiv (or I can send you pdf's).

Technically the reversion comes from the dualising the vector space V -> V*
and building the tensor algebra over the dualised vector space V* and
identifying
V* ~= V canonically. The project onto antisymmetric tensors. You see
that the symmetric group acts on tensors by permuting the 'list' ov
vectors a tensor is forms of. The reverison is the unique larget
permutation (usually called w)
with the most inversions (in reduced notation). So reversion is not
just adding a sign, its really reversing the list of all vectors
(generators) and then reorder them using the antisymmetry and collect
the minus signs.

conjugation is just the composition of recerion and grade involution:

conjugation x == reversion gradeinvolution x
(== gradeinvolution reversion x) -- oder does not matter

So first thing is to implement:

Grassmann wedge
Grassmann meet (note that the meet is a sort of wedge but with the roles
of the grades inverted)
Clifford product for a bilinear form (this is not hard, its the same routine
which calculates the Clifford product for a symmetric bilinear form or an
arbitrary bilinear form)

> I expect I had better ignore the Spinors for now although I am curious about
> how they should be added on later.

Indeed, forget about them for now. I just added the spinor things to
make sure there are matrix analogs which show that the algebra
computes correctly. It is
just a way to convince yourself that everything works right. It was not meant
(yet) as a feature request. (Spinors come in handy when describing
linear complexes in projective space)

> Upto now I have thought of spinors as an even subalgebra of Clifford
> algebras?

There are many ways to look at spinors. Every way has its own benefit.
Indeed the weakest is to go for matrix representations and confuse
those with the abstract algebra. In the examples you see that all
three Clifford algebras Cl(2,0), CL(1,1)
and CL(0,2) finally can be modelled by 2x2 matrices, but how to
identify them if only the matrices are given?
The spinors in the examples are (left) idela spinors, that is they
are elements of a minimal left ideal of the Clifford algebra and
therefore them self representable as Clifford numbers (as clearly can
be seen by inspecting the lists calld spinorSpace). If represented in
the (same) spinor basis, these elements make up a matrix with a single
non-zero column, forgetting about the zero columns gives what you see
usually (but it gets more complicated if the ring is no longer the
reals, even complex conjugation is then a differently presented
operation).
Some of the matrix concepts are difficult to translate back into the
algebra, eg transposition if the bilinear form is not
diagonal/symmetric... this is a reseach
subject (and I hope there will be soon a paper comming out clarifying
this partly).

> (rotation by 2*pi multiplies by -1) but
> this does not seem to be the case here? Would spinors require a new type of
> multiplication or a new domain?

If a spinor is represented _inside_ of the Clifford algebra, no new
multiplications are needed. That's the nice feature of unifying these
things. Interpreting spinors as rotations can be done by constructing
so called operator spinors, well described eg in Perrti Lounesto's
boon Clifford algebras and spinors. Also this is not yet important.
(And will not need new algebra).

What you need to implement at the moment is:

a) A Grassmann basis (module over some (commutative) ring, field)
[Clifford has some undocumented features which allow a q-deformation here
but I guess you should ignore that too]

b) the wedge and meet products, and some helper functions, like
extraction of the coefficient of the identiy, the volume elemenet etc
gradeinvolution, Grassmann reversion (that is the above reversion where
all terms comming from the bilinear form are absent), so this is
just the sign
factor (or better (-1)^{number of involutions of the permutatiosn which
reorders the rerm} this would allow to replace -1 by generic q).

a) and b) make up a GrassmannAlgebra (and with very little effort could be
turned into a Grassmann Hopf algebra by adding a wedge corproduct, and
an antipode)

c) The Clifford product, based on a correctly implemented
leftContraction and rightContraction. This is done easily by a
recursion, as I tried to explain in a previous mail.

With x,y in V u,v,w in W=/\V you have

i) x * y = lc(x,y) + x/\y and 1*1=1
ii) x * (u /\ v) = x /\ u /\ v + lc(x, u/\v)
= x/\u/\v + lc(x,u)/\v + gradeinvolution(u) /\ lc(x, v)
(same for (u/\v) * y using right contraction)
iii) Since every term u can be recursively be decomposed as a Clifford product
you can finally evaluate u * v by
u = w*x (where the grade of w is strictly less than that of u
u * v = (w*x)*v = w*(x*v) and use the above recursion with 1*1=1

I am sorry to have to less time currently to sit down and just provide the code,
I have some other things on my table which are urgent.

Hope this helps, otherwise feel free to ask.
Ciao

Martin Baker

unread,
Dec 9, 2009, 6:25:16 AM12/9/09
to FriCAS - computer algebra system
Bertfried (and anyone else interested in Clifford algebra),

I have put a new version of the Spad code here:
http://www.euclideanspace.com/maths/standards/program/clifford/

This code implements the rules that you listed in your previous
messages. The contraction and Clifford products agree with your test
cases as you can see here:

http://www.euclideanspace.com/maths/standards/program/clifford/test/

I am still working on the regression product.

As far as I know the contraction should work with any dimensional
algebra, by recursively decomposing, but since the tests are based on
2D vectors I can't be completely sure all paths are tested out?

The Clifford multiplication should also work this way, but in one
practice I had to cheat, I would like to implement this rule:

> iii) Since every term u can be recursively be decomposed as a Clifford product
> you can finally evaluate u * v by
> u = w*x (where the grade of w is strictly less than that of u
> u * v = (w*x)*v = w*(x*v) and use the above recursion with 1*1=1

but I could not work out how to implement this so I temporarily used
this code:

-- if none of the above is true then apply:
-- u*v = u/\v + \/(u,v)
-- so,
-- u/\v = u*v - \/(u,v)
-- (u/\v)*w = v*v*w - bilinear(u,v)*w
uType:SINT := leftMostBase(op1type) -- highest ^factor
vType:SINT := xor(op1type,uType) -- remaining ^factors
ut:% := New; ut.uType := 1$K
wt:% := New; wt.op2type := 1$K
resul := ut * cliffordProdTerm(1$K,vType,1$K,op2type)
resul := resul - bilinear(uType,vType)*wt
resul := (op1mult*op2mult)*resul -- apply 'scalar'
multipliers
resul

which would only work up to bivectors?

I would appreciate any hints about how to implement this properly.

There are a few other areas where I am not completely sure that I have
got it right, such as gradeInvolution, so I think the code will
eventually need checking by an expert eye or testing with a higher
dimensional algebra.

Amongst the other changes that I made are:

* Changed constructor which previously required a QuadraticForm as a
parameter. It now takes a SquareMatrix as input to represent a more
general bilinear form. In other words there is no longer a requirement
for the bilinear form to be symmetrical about the diagonal.
* Removed inheritance from VectorSpace, This domain still inherits
from module but it does not yet support non-commutative elements.

Martin

Bertfried Fauser

unread,
Dec 9, 2009, 6:31:33 AM12/9/09
to fricas...@googlegroups.com
Hi Martin,

I am of for Oxford for the rest of the week in a couple of minutes. I will
download the code and tests and will see if I have time to look at it.
Otherwise I will do so over the week end.

Bertfried Fauser

unread,
Dec 14, 2009, 6:06:46 AM12/14/09
to fricas...@googlegroups.com, Martin Baker, root
Dear Martin,

I have tested a bit the clifford product you have provided, as also the left and
right constructions. So fare it seems OK, however I have had some problems to
convince myself about that due to the following problem (see also commenst in
the attached file, marked '## BF'

We deal with several products and we should be able to define a
precedence. FriCAS allows me to type in an expression like

A/\B*C/\D

and its not clear what happens, since these structures do not
associate over another

(A/\B)*(C/\D) -- is what I expected
((A/\B)*C)/\D -- is what I got

hence the infix form of the wedge product is _bad_ since these elements actually
provide the basis (and geometric building blocks) of the Clifford algebra, one
would hence not like to 'split' these things up.

A minor point is the output, which could be condensed and made be more
intuitive by grouping the Grassmann wedge indices into a single
subset, like e(1,2,3,4)

I had no time to look into the code, and I will possibly have no time to do so
in the next days, sorry about that.

Kind regards
GrassmannTest.txt

Martin Baker

unread,
Dec 14, 2009, 11:51:30 AM12/14/09
to fricas...@googlegroups.com, Bertfried Fauser, root
Bertfried,

Thanks very much for testing this,

> We deal with several products and we should be able to define a
> precedence. FriCAS allows me to type in an expression like
>
> A/\B*C/\D
>
> and its not clear what happens, since these structures do not
> associate over another
>
> (A/\B)*(C/\D) -- is what I expected
> ((A/\B)*C)/\D -- is what I got

I can only guess that the precedence of the infix operators /\ and * (in the
interpreter) is the same and therefore they are evaluated in the order given?

I did ask about infix precedence here:
http://groups.google.com/group/fricas-
devel/browse_thread/thread/6fdbe45592659961?hl=en#

To summarise:
* precedence for a given operator, such as /\, is global, so if we fix this it
may break logical operators which also use /\.
* compiler and interpreter work differently.
* precedence cant be changed from SPAD so changes would require a lisp file.

To summarise the summery:
* Its all very messy and I don't know what to do - help anyone!

> A minor point is the output, which could be condensed and made be more
> intuitive by grouping the Grassmann wedge indices into a single
> subset, like e(1,2,3,4)

It would be very easy to _input_ in this form, for instance:

(2) -> a:B1 := e(1,2,3)

(2) e e e
1 2 3
Type: GrassmannAlgebra(3,Fraction(Integer),[[1,0,0],[0,1,0],[0,0,1]])

The only issue is that I can only work out how to do this by having a separate
definition and implementation for each grade:

e: (PI,PI) -> %
e: (PI,PI,PI) -> %
...
e(i,j) == _/_\(e(i),e(j))
e(i,j,k) == _/_\(e(i,j),e(k))
...

Does anyone know if these can be combined by defining them recursively in some
way?
I guess it does not matter as there must be a limited number of parameters to
a function anyway?

I could probably change the _output_ to use this notation, although I would
need to read up on OutputForm first, but would you really want this in
preference to the suffix notation?

Would you prefer:

e(1,2,3)

e e e
1 2 3

e
1 2 3

The first form would have advantages in not requiring a monospaced font
although I find it less readable, the last option is better but might be
confusing for indicies over 9?

> I had no time to look into the code, and I will possibly have no time to do
> so in the next days, sorry about that.

No hurry, I realise you are very busy at the moment, but if you do manage to
find any time I would appreciate any hints on implementing this rule you gave
me:

> iii) Since every term u can be recursively be decomposed as a Clifford
product
> you can finally evaluate u * v by
> u = w*x (where the grade of w is strictly less than that of u
> u * v = (w*x)*v = w*(x*v) and use the above recursion with 1*1=1

I have implemented this as follows but I know this won't work for higher
grades (its not recursive as is required):

-- if none of the above is true then apply:
-- u*v = u/\v + \/(u,v)
-- so,
-- u/\v = u*v - \/(u,v)
-- (u/\v)*w = v*v*w - bilinear(u,v)*w
uType:SINT := leftMostBase(op1type) -- highest ^factor
vType:SINT := xor(op1type,uType) -- remaining ^factors
ut:% := New; ut.uType := 1$K
wt:% := New; wt.op2type := 1$K
resul := ut * cliffordProdTerm(1$K,vType,1$K,op2type)
resul := resul - bilinear(uType,vType)*wt
resul := (op1mult*op2mult)*resul -- apply 'scalar'
multipliers
resul

Also any thoughts you might have on implementing inverse well enough to be
able to do transforms. I suspect that the current recip(x: %) function would
not work with non-diagonal forms.

As I say, no hurry, but when you find the time a few small hints would be
appreciated.

Thanks,

Martin

Martin Rubey

unread,
Dec 14, 2009, 12:03:31 PM12/14/09
to fricas...@googlegroups.com, Bertfried Fauser, root
Martin Baker <ax8...@martinb.com> writes:

> It would be very easy to _input_ in this form, for instance:
>
> (2) -> a:B1 := e(1,2,3)
>
> (2) e e e
> 1 2 3
> Type: GrassmannAlgebra(3,Fraction(Integer),[[1,0,0],[0,1,0],[0,0,1]])
>
> The only issue is that I can only work out how to do this by having a separate
> definition and implementation for each grade:
>
> e: (PI,PI) -> %
> e: (PI,PI,PI) -> %
> ...
> e(i,j) == _/_\(e(i),e(j))
> e(i,j,k) == _/_\(e(i,j),e(k))
> ...
>
> Does anyone know if these can be combined by defining them recursively in some
> way?

You have to make e take a list. Then something like

e: List PI -> %
e(l) == reduce(_/_\, [e i for i in l], 0)

should work.

Martin

Ralf Hemmecke

unread,
Dec 14, 2009, 1:38:52 PM12/14/09
to fricas...@googlegroups.com, Bertfried Fauser, root
> I can only guess that the precedence of the infix operators /\ and * (in the
> interpreter) is the same and therefore they are evaluated in the order given?

See, everyone would have to guess. I think it's just good practise to
make you intentions clear by adding explicit parentheses.

Suppose I define a binary operator

=: (%, %) -> %

(which I could do in SPAD). I just use "=" as a fancy name for a binary
infix operator (has nothing to do with equality).

If I then write something like

a=b*c=d

what would you guess what the precedence is? Where would you look up?
(Try to do this without starting fricas.)



The following seems to show a bug in fricas?

Waldek, I really tried to write a new domain with = of the above type.

---rhxBEGIN newop.spad
)abbrev domain MYINT MyInt
MyInt(): Join(IntegerNumberSystem, ConvertibleTo String, OpenMath,_
Canonical, canonicalsClosed) with
_=: (%, %) -> %
== Integer add
((x:%) = (y:%)):% == x - y
---rhxEND newop.spad

seems to compile fine.

But how can I call this function in infix form?

Ralf

(1) -> )co newop
Compiling FriCAS source code from file
/home/hemmecke/scratch/newop.spad using old system compiler.
MYINT abbreviates domain MyInt
------------------------------------------------------------------------
initializing NRLIB MYINT for MyInt
compiling into NRLIB MYINT
compiling exported = : ($,$) -> $
Time: 0.06 SEC.

(time taken in buildFunctor: 0)

;;; *** |MyInt| REDEFINED

;;; *** |MyInt| REDEFINED
Time: 0.01 SEC.


Cumulative Statistics for Constructor MyInt
Time: 0.08 seconds


(|RealConstant|) extends
(|ConvertibleTo| (|DoubleFloat|)) but not
(|ConvertibleTo| (|String|)) finalizing NRLIB MYINT
Processing MyInt for Browser database:
--->-->MyInt((= (% % %))): Not documented!!!!
--->-->MyInt(constructor): Not documented!!!!
--->-->MyInt(): Missing Description
; compiling file "/home/hemmecke/scratch/MYINT.NRLIB/MYINT.lsp" (written
14 DEC 2009 07:36:29 PM):
; compiling (/VERSIONCHECK 2)
; compiling (DEFUN |MYINT;=;3$;1| ...)
; compiling (DEFUN |MyInt| ...)
; compiling (DEFUN |MyInt;| ...)
; compiling (MAKEPROP (QUOTE |MyInt|) ...)
; compiling (MAKEPROP (QUOTE |MyInt|) ...)
; file: /home/hemmecke/scratch/MYINT.NRLIB/MYINT.lsp
; in: DEFUN |MyInt;|
; (BOOT::|haddProp| BOOT::|$ConstructorCache| 'BOOT::|MyInt| NIL
; (CONS 1 BOOT::$))
;
; caught WARNING:
; undefined variable: |$ConstructorCache|

; in: DEFUN |MyInt|
; (VMLISP:HGET BOOT::|$ConstructorCache| 'BOOT::|MyInt|)
; --> GETHASH
; ==>
; (SB-IMPL::GETHASH3 'BOOT::|MyInt| BOOT::|$ConstructorCache| NIL)
;
; caught WARNING:
; undefined variable: |$ConstructorCache|

;
; caught WARNING:
; This variable is undefined:
; |$ConstructorCache|
;
; compilation unit finished
; caught 3 WARNING conditions


; /home/hemmecke/scratch/MYINT.NRLIB/MYINT.fasl written
; compilation finished in 0:00:00
------------------------------------------------------------------------
MyInt is now explicitly exposed in frame frame1
MyInt will be automatically loaded when needed from
/home/hemmecke/scratch/MYINT.NRLIB/MYINT

(1) -> a: MyInt := 1

(1) 1
Type:
MyInt
(2) -> b: MyInt := 13*a

(2) 13
Type:
MyInt
(3) -> c: MyInt := (a=b)@MyInt
There are 3 exposed and 0 unexposed library operations named
equation having 2 argument(s) but none was determined to be
applicable. Use HyperDoc Browse, or issue
)display op equation
to learn more about the available operations. Perhaps
package-calling the operation or using coercions on the arguments
will allow you to apply the operation.

Cannot find a definition or applicable library operation named
equation with argument type(s)
MyInt
MyInt

Perhaps you should use "@" to indicate the required return type,
or "$" to specify which version of the function you need.
(3) -> )disp op =

There are 3 exposed functions called = :
[1] (MyInt,MyInt) -> MyInt from MyInt
[2] (D,D) -> Boolean from D if D has BASTYPE
[3] (D1,D1) -> Equation(D1) from Equation(D1) if D1 has TYPE

There are 3 unexposed functions called = :
[1] (FortranScalarType,FortranScalarType) -> Boolean from
FortranScalarType
[2] (OutputForm,OutputForm) -> OutputForm from OutputForm
[3] (Reference(D2),Reference(D2)) -> Boolean from Reference(D2)
if D2 has TYPE

Ralf Hemmecke

unread,
Dec 14, 2009, 2:16:02 PM12/14/09
to fricas...@googlegroups.com, Bertfried Fauser, root
Maybe you should combine Martin's function with

ee(t: Tuple Integer): List Integer == entries t;

What I can do is...

(5) -> p: Tuple(Integer) := (1,4,5)

(5) [1,4,5]
Type:
Tuple(Integer)
(6) -> ee p
Compiling function ee with type Tuple(Integer) -> List(Integer)

(6) [1,4,5]

Unfortunately, it's only possible to call

(7) -> ee((3,4,2)@Tuple(Integer))

(7) [3,4,2]

(9) -> ee(2,1)
There are no library operations named ee
Use HyperDoc Browse or issue
)what op ee
to learn if there is any operation containing " ee " in its name.

Cannot find a definition or applicable library operation named ee
with argument type(s)
PositiveInteger
PositiveInteger

Perhaps you should use "@" to indicate the required return type,
or "$" to specify which version of the function you need.

It's a tragedy that Aldor is dead. :-(

Ralf

Bill Page

unread,
Dec 14, 2009, 7:43:43 PM12/14/09
to fricas...@googlegroups.com, Bertfried Fauser, root
On Mon, Dec 14, 2009 at 1:38 PM, Ralf Hemmecke wrote:
>
> Suppose I define a binary operator
>
>   =: (%, %) -> %
>
> (which I could do in SPAD). I just use "=" as a fancy name for a binary
> infix operator (has nothing to do with equality).
>
> If I then write something like
>
>   a=b*c=d
>
> what would you guess what the precedence is? Where would you look up?
> (Try to do this without starting fricas.)
>
> The following seems to show a bug in fricas?
>
> Waldek, I really tried to write a new domain with = of the above type.
>
> ---rhxBEGIN newop.spad
> )abbrev domain MYINT MyInt
> MyInt(): Join(IntegerNumberSystem, ConvertibleTo String, OpenMath,_
>     Canonical, canonicalsClosed) with
>   _=: (%, %) -> %
>  == Integer add
>   ((x:%) = (y:%)):% == x - y
> ---rhxEND newop.spad
>
> seems to compile fine.
>
> But how can I call this function in infix form?
>

Ralf,

The interpreter internally translates 'x=y' to 'equation(x,y)' so try this:

Try this:

---rhxBEGIN newop.spad
)abbrev domain MYINT MyInt
MyInt(): Join(IntegerNumberSystem, ConvertibleTo String, OpenMath,_
Canonical, canonicalsClosed) with
equation: (%, %) -> %
== Integer add
equation((x:%) , (y:%)):% == x - y
---rhxEND newop.spad

(1) -> )co newop
Compiling FriCAS source code from file /home/wspage/newop.spad using
old system compiler.
MYINT abbreviates domain MyInt
------------------------------------------------------------------------
initializing NRLIB MYINT for MyInt
compiling into NRLIB MYINT
compiling exported equation : ($,$) -> $

;;; *** |MYINT;equation;3$;1| REDEFINED
Time: 0 SEC.

(time taken in buildFunctor: 4)

;;; *** |MyInt| REDEFINED

;;; *** |MyInt| REDEFINED
Time: 0.004 SEC.


Cumulative Statistics for Constructor MyInt
Time: 0.004 seconds


(|RealConstant|) extends
(|ConvertibleTo| (|DoubleFloat|)) but not
(|ConvertibleTo| (|String|)) finalizing NRLIB MYINT
Processing MyInt for Browser database:
--->/home/wspage/newop.spad-->MyInt((equation (% % %))): Not documented!!!!
--->/home/wspage/newop.spad-->MyInt(constructor): Not documented!!!!
--->/home/wspage/newop.spad-->MyInt(): Missing Description
; compiling file "/home/wspage/MYINT.NRLIB/MYINT.lsp" (written 14 DEC
2009 07:36:24 PM):

; file: /home/wspage/MYINT.NRLIB/MYINT.lsp
; in: DEFUN |MyInt;|
; (BOOT::|haddProp| BOOT::|$ConstructorCache| 'BOOT::|MyInt| NIL
; (CONS 1 BOOT::$))
;
; caught WARNING:
; undefined variable: |$ConstructorCache|

; in: DEFUN |MyInt|
; (VMLISP:HGET BOOT::|$ConstructorCache| 'BOOT::|MyInt|)
; --> GETHASH
; ==>
; (SB-IMPL::GETHASH3 'BOOT::|MyInt| BOOT::|$ConstructorCache| NIL)
;
; caught WARNING:
; undefined variable: |$ConstructorCache|
;
; compilation unit finished
; Undefined variable:
; |$ConstructorCache|
; caught 2 WARNING conditions

; /home/wspage/MYINT.NRLIB/MYINT.fasl written
; compilation finished in 0:00:00.008
------------------------------------------------------------------------
MyInt is already explicitly exposed in frame frame1
MyInt will be automatically loaded when needed from
/home/wspage/MYINT.NRLIB/MYINT

(1) -> (2=1)@MyInt

Ralf Hemmecke

unread,
Dec 15, 2009, 2:33:21 AM12/15/09
to fricas-devel
>> ---rhxBEGIN newop.spad
>> )abbrev domain MYINT MyInt
>> MyInt(): Join(IntegerNumberSystem, ConvertibleTo String, OpenMath,_
>> Canonical, canonicalsClosed) with
>> _=: (%, %) -> %
>> == Integer add
>> ((x:%) = (y:%)):% == x - y
>> ---rhxEND newop.spad
>>
>> seems to compile fine.
>>
>> But how can I call this function in infix form?

> The interpreter internally translates 'x=y' to 'equation(x,y)' so try this:
>
> Try this:
>
> ---rhxBEGIN newop.spad
> )abbrev domain MYINT MyInt
> MyInt(): Join(IntegerNumberSystem, ConvertibleTo String, OpenMath,_
> Canonical, canonicalsClosed) with
> equation: (%, %) -> %
> == Integer add
> equation((x:%) , (y:%)):% == x - y
> ---rhxEND newop.spad

OK, that might be a workaround for now, but you probably agree that this
is an interpreter bug. In my case there is a function "=: (%, %) -> %"
around so the interpreter should rather pick this instead of translating
= to equation in the first place. No?

Or is "=" in FriCAS just to be considered as syntactic sugar for
"equation"? Cannot be try, since there is also =:(%,%)->Boolean.

Maybe only people like me add signatures like "=: (%, %) -> %", so it is
not too important, but I would count that behaviour as a bug.

Ralf

Bill Page

unread,
Dec 15, 2009, 9:48:54 AM12/15/09
to fricas...@googlegroups.com
On Tue, Dec 15, 2009 at 2:33 AM, Ralf Hemmecke wrote:
>
>> The interpreter internally translates 'x=y' to 'equation(x,y)' so try this:
>>
>> Try this:
>>
>> ---rhxBEGIN newop.spad
>> )abbrev domain MYINT MyInt
>> MyInt(): Join(IntegerNumberSystem, ConvertibleTo String, OpenMath,_
>>     Canonical, canonicalsClosed) with
>>   equation: (%, %) -> %
>>  == Integer add
>>   equation((x:%) , (y:%)):% == x - y
>> ---rhxEND newop.spad
>
> OK, that might be a workaround for now, but you probably agree that this
> is an interpreter bug. In my case there is a function "=: (%, %) -> %"
> around so the interpreter should rather pick this instead of translating
> = to equation in the first place. No?
>

I am not sure. i think the problem is that there is no good design in
Axiom/FriCAS for the use boolean operators versus symbolic boolean
expressions/relations such as equations and inequalities. The
interpreter wants = to be symbolic but it is not consistent since
other operators such as < and > or even ~= are not treated this way.
The Equation domain exports a coercion

coerce : % -> Boolean if S has SETCAT

(really should be 'eval' !) which evaluates the relation using = from
SetCategory. In the library = is (almost) always treated in the same
way as > and <, i.e. as functions that return a boolean value. So I
guess one could say that this is a typical kind of interpreter hack.

> Or is "=" in FriCAS just to be considered as syntactic sugar for
> "equation"? Cannot be try, since there is also =:(%,%)->Boolean.
>

See above.

> Maybe only people like me add signatures like "=: (%, %) -> %", so it is
> not too important, but I would count that behaviour as a bug.
>

As I said, I think it is more of a design bug. I know Gaby has
started to do some work in OpenAxiom to straighten this out but I
think it would be worthwhile to discuss it further. I did spend some
time thinking about inequalities a few months ago:

http://axiom-wiki.newsynthesis.org/SandBoxInequation
http://axiom-wiki.newsynthesis.org/SandBoxEquation

Comments?

Regards,
Bill Page.

Martin Baker

unread,
Dec 15, 2009, 12:06:36 PM12/15/09
to FriCAS - computer algebra system
Martin,

> You have to make e take a list. Then something like
> e: List PI -> %
> e(l) == reduce(_/_\, [e i for i in l], 0)
> should work.

I have been trying to compile this without success. It seems to work
OK with the interpreter but when I compile it I first got a name
conflict with the original e(PI) (although they have different
signatures: e: PI -> % and e: List PI -> %) and when I change the name
to avoid this name conflict I get an unhelpful error message.

Martin
------------------------------------------------
First check that it works in the interpreter (Which it does):

(1) -> B1 := GrassmannAlgebra(2,Fraction(Integer),[[1,0],[0,1]])

(2) GrassmannAlgebra(2,Fraction(Integer),[[1,0],[0,1]])
Type:
Domain

(2) -> a := reduce(/\,[e(i)$B1 for i in [1,2]],1)

(6) e e
1 2
Type: GrassmannAlgebra(2,Fraction(Integer),[[1,0],
[0,1]])
(3) ->

Then I tried compiling it with this implementation:

e(l) == reduce(_/_\, [e i for i in l], 1)

When I compile this I get:

compiling exported e : List PositiveInteger -> $
****** comp fails at level 3 with expression: ******
error in function e

(IF (< |n| | << | (|::| |b| (|NonNegativeInteger|)) | >> |)
(|error| "No such basis element")
(SEQ
(LET |iz|
(^ 2 (|::| (- |b| 1) (|NonNegativeInteger|))))
(LET |z|
((|elt| |Rep| |new|) |dim| (|elt| K 0)))
(LET (|z| |iz|)
1)
(|exit| 1 |z|)))
****** level 3 ******
$x:= (:: b (NonNegativeInteger))
$m:= $EmptyMode
$f:=
((((|last| #) (|rest| #) (|first| # #) (|value| #) ...)))

>> Apparent user error:
Cannot coerce b
of mode (List (PositiveInteger))
to mode (NonNegativeInteger)

(9) ->

So I renamed the existing e: PI -> % function to es: PI -> % to avoid
a name conflict but I am still getting an error which has so far
defeated me:

e(l) == reduce(_/_\, [es i for i in l], 1)

When I compile this I get:

compiling exported e : List PositiveInteger -> $
****** comp fails at level 2 with expression: ******
error in function e

(|reduce| | << /\\ >> | (COLLECT (IN |i| |l|) (|es| |i|)) 1)
****** level 2 ******
$x:= /\
$m:= $EmptyMode
$f:=
((((|last| #) (|rest| #) (|first| # #) (|value| #) ...)))

>> Apparent user error:
cannot compile (reduce /\ (COLLECT (IN i l) (es i)) (One))

Martin Rubey

unread,
Dec 15, 2009, 12:21:54 PM12/15/09
to fricas...@googlegroups.com
could you please send the source code?

Martin

Bertfried Fauser

unread,
Dec 15, 2009, 12:49:07 PM12/15/09
to fricas...@googlegroups.com
Hi Martin,

reduce over something complicated cause many problems in the
symmetric function code (which I should work on more), the solution
was often first to generate the list and then reduce

lst List Integer := [e(i) for i in 1..4]
reduce(_/_\, lst)

when the ``[ blah for i in range]'' was inside of the reduce it just didn't
got through the spad compiler. Perhaps worth a try?

Have to run,
Ciao

Waldek Hebisch

unread,
Dec 15, 2009, 12:56:17 PM12/15/09
to fricas...@googlegroups.com
I would say that '=' is very special: assigning it any meaning
different from building an equation or equality would be quite
confusing. Note that building equation is essentially symbolic
form of equality, so meaning is reasonably consistent.

ATM I am not sure if this mapping from '=' to equation makes
somehing easier -- I certainly would prefer uniform treatment.
But IMHO if this hack makes thing easier for interpreter (AFAICS
it is not done for Spad), then it is justified.
--
Waldek Hebisch
heb...@math.uni.wroc.pl

Martin Baker

unread,
Dec 15, 2009, 1:11:00 PM12/15/09
to fricas...@googlegroups.com
On Tuesday 15 December 2009 17:49:07 Bertfried Fauser wrote:
> Hi Martin,
>
> reduce over something complicated cause many problems in the
> symmetric function code (which I should work on more), the solution
> was often first to generate the list and then reduce
>
> lst List Integer := [e(i) for i in 1..4]
> reduce(_/_\, lst)
>
> when the ``[ blah for i in range]'' was inside of the reduce it just didn't
> got through the spad compiler. Perhaps worth a try?
>
Bertfried,

Thanks, you are correct, I changed it to the following and it worked:

-- to allow entries like e([1,2])
e(l) ==
lst:List % := [es i for i in l]
reduce(_/_\, lst , 1)

So I can now get input in this form e([1,2])

(1) -> B1 := GrassmannAlgebra(2,Fraction(Integer),[[1,0],[0,1]])

(1) GrassmannAlgebra(2,Fraction(Integer),[[1,0],[0,1]])
Type: Domain
(2) -> a:b1 := e([1,2])

(2) e
1,2
Type: Symbol
(3) ->

I'll see if I can combine it with the idea from Ralf to remove the need for
the square brackets?

Martin B

Martin Baker

unread,
Dec 31, 2009, 4:25:03 AM12/31/09
to FriCAS - computer algebra system
Bertfried (and anyone else interested in Clifford algebra),

I have put a new version of the Clifford product code here:
http://www.euclideanspace.com/maths/standards/program/clifford/

I was having problems making the Clifford product completely general
and able to work for every dimension and grade but I think it should
now work correctly?

Until now I could not work out a general way to solve:
(u /\ x) * v
where: x in vector, u,v in multivector

But I found:
(ea /\ … /\ eb /\ ec) * (ef /\ … /\ eg ) =
(ea /\ … /\ eb) * (ec _| (ef /\ … /\ eg) + ec /\ ef /\ … /\ eg ) -
(ea /\ … /\ eb |_ ec) * (ef /\ … /\ eg)

from your document arXiv:math-ph/0212031v1 10 Dec 2002 by Rafal
Ablamowicz, B. Fauser.

Which I think is:

(u /\ x) * v = u * (x _| v + x /\v) - (u |_ x) * v

So I have incorporated this into the code.

Now all I need to do is work out an inverse function that is suitable
for applying geometric transforms and I think this will be very
useful.

Martin

Reply all
Reply to author
Forward
0 new messages