Redefining the _mult command in muPad (MATLAB symbolic engine)

2 次查看(过去 30 天)
I have created a user-defined domain in muPad called Bx. Each object in this domain is defined by two variables: n and k.
Bx := newDomain("Bx"):
Bx::new:=
proc(n,k)
begin
if args(0)<>2 then
error("There must be exactly two arguments")
end_if;
new(dom,n,k)
end_proc:
Bx::print:=
proc(x)
begin
"Bx(".expr2text(op(x,1),op(x,2)).")";
end_proc:
If at this point, muPad is instructed 2*Bx(2,3) then the output will look like:
2 Bx(2,3)
If muPad is instructed 2*k*Bx(2,3) then the output will look like:
2 k Bx(2,3)
This is how I would like my domain to behave under multiplication. The exception is when two objects of the Bx domain are multiplied together. If, for example, I instruct Bx(2,3)*Bx(2,3) then I would like to see:
Bx(4,6)
The multiplication rule for two Bx objects is Bx(n1,k1)*Bx(n2,k2)=Bx(n1+n2,k1+k2). How can I redefine _mult for the domain Bx so that it multiplies in this way iff (if and only if) both arguments are Bx objects? If either argument is not Bx, then the multiplication should occur as it would without me having redefined _mult, demonstrated in the examples above.
The current revised definition I have for _mult on Bx is the following, and it works when multiplying two Bx objects, but it messes up when either argument does not belong to Bx, e.g. it does nothing for 2*Bx(1,1):
Bx::_mult:=
proc()
local type1,type2,n,k;
begin
type1:=type(args(1));
type2:=type(args(2));
n:=map(args(),op,1);
k:=map(args(),op,2);
if type1=type2
then dom(_plus(n),_plus(k));
end_if;
end_proc:
I have revised this question many times over the past few days and have really reduced it to its essence. I hope it is clear and that someone can help me with my special _mult definition.

回答(1 个)

Kobye
Kobye 2013-7-29
编辑:Kobye 2013-7-29
I've done the hard bit and have managed to define a method that does what I want. I will provide it here for reference. I would still appreciate if someone who is more conversant than me in muPad could take a look at this code and suggest some efficiencies.
Bx::_mult:=
proc(a,b)
local type1,type2,berns,c,n,k,ni,ki;
begin
lists:=split(args(),testtype,Type::Numeric);
berns:=lists[2];
ni:=op(berns[1],1);
ki:=op(berns[1],2);
delete berns[1];
if nops(berns)>=2
then
while nops(berns)>=1
do
n:=op(berns[1],1);
k:=op(berns[1],2);
prod:=dom(_plus(ni,n),_plus(ki,k));
delete berns[1];
ni:=op(prod,1);
ki:=op(prod,2);
end_while;
c:=_mult(select(args(),testtype, Type::Numeric));
freeze(_mult)(c,dom(ni,ki));
else
c:=_mult(select(args(),testtype, Type::Numeric));
berns:=_mult(select(args(),x -> expr2text(x)[1] = "B"));
freeze(_mult)(c,berns):
end_if;
end_proc:
  2 个评论
Kobye
Kobye 2013-7-29
编辑:Kobye 2013-7-29
On a sidenote - before implementing the _mult method - say I instruct:
c:=Bx(1,1)*Bx(2,1)*Bx(3,2);
elements:=op(c)
Then why does
select(elements,testtype,Type::Bx)
return an empty list? Yet if I query type(elements[1]) then muPad returns Bx.
Kobye
Kobye 2013-7-30
The answer to this side question is to simply use the following instead:
select(elements,testtype,Bx)

请先登录,再进行评论。

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by