Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pretty MuPad: Output of assignment, expression and result in one line - How to create that function?

I'm trying to get Matlabs's MuPad as pretty and convenient as MathCad.

Assume two variable assignments:

x_a:=2*unit::mm;
y_b:=5*unit::mm;

and I want a prettyfied (typeset with Tex) output like

z = x_a + y_b = 7 mm

I already managed to do so by using output::mathText(...):

output::mathText(hold(z)," = " , (z:=hold(x_a+y_b)) , " = " , z)

which looks as desired:

enter image description here

But this is not really convenient and not readable. So I'm trying to wrap it into a macro or a function:

evalPrint(z,x_a+y_b)

How can I do that?


What I tried:

I wrote a procedure as follows:

evalPrint :=
proc(x,y) begin
  output::mathText(hold(x)," = " , (x:=hold(y)) , " = " , x)
end_proc:

but I just get

enter image description here

What am I missing?


Regarding horchler's answer: his first solution does somehow not work, while the second does:

procedures:

evalPrintVal := proc(x,y) option hold;
begin
    output::mathText(x, " = ", evalassign(x,y));
end_proc:
evalPrintEq := proc(x,y) option hold;
begin
    output::mathText(x, " = ", evalassign(x,y), " = ", context(y));
end_proc:
evalPrintEq2 := proc(x,y) option hold;
begin
    output::mathText(x, " = ", y, " = ", evalassign(x,y));
end_proc:

call:

evalPrintVal(U_1,15000*unit::V);
evalPrintEq(E_h, U_1*1.05);
evalPrintEq2(E_h, U_1*1.05);

output:

enter image description here

like image 363
Robert Seifert Avatar asked Jul 28 '15 09:07

Robert Seifert


1 Answers

This is a problem of scope. MuPAD is no different from most other programming languages in that methods/functions/procedures have a limited lexical scope. The DOM_VAR domain type refers to a local variable of a procedure (a bit more here). You can't directly see the name of a variable before it's passed into a Matlab function (use inputname for this), and MuPAD is no different. Additionally, arguments are normally evaluated before they get passed into the functions or procedure.

Luckily, the fix is pretty easy in terms of coding. First, you need to use the hold option for your proc. This appears to both prevent evaluation of input arguments and allow access to "the actual parameter in the form that was used in the procedure call." Then you need to use context to evaluate the last part of your output. The resultant procedure looks like this:

evalPrint := proc(x,y) option hold;
begin
    output::mathText(x, " = ", y, " = ", context(y));
end_proc:

Then

x_a := 2*unit::mm;
y_b := 5*unit::mm;
evalPrint(z, x_a+y_b);
z;

returns

MuPAD output one

However, since this was done in a procedure, the value of z wasn't assigned a value in the global scope like in your inline expression. To handle this, the evalassign function can be used:

evalPrint := proc(x,y) option hold;
begin
    output::mathText(x, " = ", evalassign(x,hold(y)), " = ", context(y));
end_proc:

which now returns 7 mm for z like your inline expression:

MuPAD output two

This form works as well and is slightly more concise:

evalPrint := proc(x,y) option hold;
begin
    output::mathText(x, " = ", y, " = ", evalassign(x,y));
end_proc:

Tested in R2015a.

like image 184
horchler Avatar answered Nov 17 '22 19:11

horchler