Redefining the _mult command in muPad (MATLAB symbolic engine)

조회 수: 2 (최근 30일)
Kobye
Kobye 2013년 7월 27일
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