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:
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
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:
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
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With