Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Application of overloaded operators

2 views
Skip to first unread message

Andreas Kabel

unread,
Feb 9, 2007, 6:38:39 PM2/9/07
to
Hi all,

I am scratching my head over the logic behind
Maple's (I'm using version 10) overloaded operators.

Consider the code attached below, it is a verbatim
copy of the operator overloading example from the
Maple online help. Using this example, it calculates
the product of two quaternions, which yields the correct
result, and then the dot product of two quaternion-valued
'LinearAlgebra,Vector's -- resulting in the unevaluated
product of two quaternions, in the wrong order to boot:

> a := Quaternion(0,1,0,0):
> b := Quaternion(0,0,1,0):
>
> A := Transpose(Vector([a])):
> B := Vector([b]):
>
>
> lprint(a*b):
QUATERNION(0,0,0,1)
> lprint(b*a):
QUATERNION(0,0,0,-1)
>
> lprint(A . B);
QUATERNION(0,0,1,0)*QUATERNION(0,1,0,0)


What do I have to do to have the overloaded `*` rule correctly applied
to the result? I have played around with 'eval', 'simplify',
'unprotect', and 'use' to no avail. Any help would be greatly appreciated.

Andreas

# Code: below

Quaternion := module()
export `?[]`, `*`, `+`, `-`:
local `?[assign]`, `?[select]`, ModuleLoad, ModuleApply:
ModuleApply := proc( h, i, j, k )
QUATERNION(h,i,j,k);
end proc:
ModuleLoad := proc()
global `print/QUATERNION`;
`print/QUATERNION` := proc(h,i,j,k)
h + `i `*i + `j `*j + `k `*k;
end proc:

TypeTools[AddType]( tQuaternion, t->evalb(op(0,t) = 'QUATERNION')\
);
end proc:
ModuleLoad();
`+` := proc(a::tQuaternion, b::tQuaternion)
option overload:
QUATERNION(op(1,a)+op(1,b), op(2,a)+op(2,b),
op(3,a)+op(3,b), op(4,a)+op(4,b));
end proc;
`-` := proc(a::tQuaternion)
option overload:
QUATERNION(-op(1,a), -op(2,a), -op(3,a), -op(4,a));
end proc;
`*` := proc(a::tQuaternion, b::tQuaternion)
option overload:
local A, B;
A := [op(a)]: B := [op(b)]:
QUATERNION(A[1]*B[1] - A[2]*B[2] - A[3]*B[3] - A[4]*B[4],
A[1]*B[2] + A[2]*B[1] + A[3]*B[4] - A[4]*B[3],
A[1]*B[3] - A[2]*B[4] + A[3]*B[1] + A[4]*B[2],
A[1]*B[4] + A[2]*B[3] - A[3]*B[2] + A[4]*B[1]);
end proc;
`?[]` := proc(q::uneval, index::[{1,2,3,4}], val)
option overload:
if nargs = 2 then
`?[select]`(eval(q),op(index));
else
`?[assign]`(q,eval(q),op(index),op(val));
end if;
end proc:
`?[select]` := proc(q::tQuaternion, index::{1,2,3,4} )
op(index, q)
end proc:
`?[assign]` := proc(var::uneval, q::tQuaternion, index::{1,2,3,4},
val::integer )
var := subsop(index = val, q);
end proc:
end module:

with(Quaternion):
with(LinearAlgebra):

a := Quaternion(0,1,0,0):
b := Quaternion(0,0,1,0):


A := Transpose(Vector([a])):

B := Vector([b]):


lprint(a*b):
lprint(b*a):

lprint(A . B);

Joe Riel

unread,
Feb 10, 2007, 1:46:19 AM2/10/07
to
Andreas Kabel <andrea...@gmail.com> writes:


> Hi all,
>
> I am scratching my head over the logic behind
> Maple's (I'm using version 10) overloaded operators.
>
> Consider the code attached below, it is a verbatim
> copy of the operator overloading example from the
> Maple online help. Using this example, it calculates
> the product of two quaternions, which yields the correct
> result, and then the dot product of two quaternion-valued
> 'LinearAlgebra,Vector's -- resulting in the unevaluated
> product of two quaternions, in the wrong order to boot:
>
>> a := Quaternion(0,1,0,0):
>> b := Quaternion(0,0,1,0):
>>
>> A := Transpose(Vector([a])):
>> B := Vector([b]):

I suspect that overloading the infix * operator was a poor decision.
Maple's infix * is inherently commutative, so I wouldn't expect it to
always work properly with the noncommutative Quaternion operator. The
real problem here, however, is that a procedure assigned before
Quaternion was 'withed' will use the non-overloade multiplication. To
see this, do

restart;

<assign Quaterion>

f1 := proc(a,b) a*b end proc:
with(Quaternion):
f2 := proc(a,b) a*b end proc:

a := Quaternion(0,1,0,0):
b := Quaternion(0,0,1,0):

f1(a,b)<>f2(a,b);
i * j <> k

--
Joe Riel

Andreas Kabel

unread,
Feb 10, 2007, 2:43:44 AM2/10/07
to
Joe Riel <jo...@san.rr.com> writes:

> Andreas Kabel <andrea...@gmail.com> writes:
>
>
>> Hi all,
>>
>> I am scratching my head over the logic behind
>> Maple's (I'm using version 10) overloaded operators.
>>
>> Consider the code attached below, it is a verbatim
>> copy of the operator overloading example from the
>> Maple online help. Using this example, it calculates
>> the product of two quaternions, which yields the correct
>> result, and then the dot product of two quaternion-valued
>> 'LinearAlgebra,Vector's -- resulting in the unevaluated
>> product of two quaternions, in the wrong order to boot:
>>
>>> a := Quaternion(0,1,0,0):
>>> b := Quaternion(0,0,1,0):
>>>
>>> A := Transpose(Vector([a])):
>>> B := Vector([b]):
>
> I suspect that overloading the infix * operator was a poor decision.

Well, it wasn't my decision ... the code above was only
an example, lifted from the Maple documentation. I was
surprised they did it this way myself.

> Maple's infix * is inherently commutative, so I wouldn't expect it to
> always work properly with the noncommutative Quaternion operator. The
> real problem here, however, is that a procedure assigned before
> Quaternion was 'withed' will use the non-overloade multiplication.

Ok, that was what I suspected. Do you know where this behavior
is documented? I couldn't find anything in the documentation.

Thanks for your help,

Andreas


> To
> see this, do
>
> restart;
>
> <assign Quaterion>
>
> f1 := proc(a,b) a*b end proc:
> with(Quaternion):
> f2 := proc(a,b) a*b end proc:
>
> a := Quaternion(0,1,0,0):
> b := Quaternion(0,0,1,0):
>
> f1(a,b)<>f2(a,b);
> i * j <> k
>
> --
> Joe Riel

--

0 new messages