help with MuPAD generate::MATLAB command?

3 views (last 30 days)
Andreas
Andreas on 8 Oct 2013
Commented: Andreas on 9 Oct 2013
Hello all,
I've been using MuPAD since yesterday so I have zero experience with it, apologies in advance if im asking a fairly "stupid" question.
What Im trying to do is make a function from an equation in a MuPAD notepad. I defined the equations in the notepad like so:
L := (n,x) -> besselI(n,x);
bn := (n,k,r_s,r_e,r_i,r_o,r) -> piecewise(
[r <= r_e, 0],
[r_e < r and r <r_s, L(n,k*r_e)],
[r > r_s, (L(n,k*r_e)*F(n,k,r_s,r_i,r_o))/(k*r_s)]);
and there are more equations that follow similar structure.
My final equation (which works just fine in the MuPAD environment) is:
V := (r,theta,z,r_s,r_e,r_i,r_o) -> (1/(2*PI^2))*numeric::int(cos(k*z)*sum_n(k,r_s,r_e,r_i,r_o,r,theta), k=0..infinity);
which is the one im trying to convert to an .m file with this command:
fprint(Unquoted, Text, "test.m", generate::MATLAB(V)):
to which command I get the warning message:
Warning: Translating MuPAD procedures ("V") is not implemented. [DOM_PROC::CF]
and nothing happens.
I then tried another way suggested from the documentation. In the command prompt I write:
nb = mupad('equation_system.mn');
t =matlabFunction(nb.getVar('V'))
to which I get:
Warning: Translating MuPAD procedures ("V") is not implemented. [DOM_PROC::CF]
Error using mupadmex
Error in MuPAD command: The operand is invalid. [_index]
Evaluating: locgen
Error in sym/matlabFunction>mup2mat (line 316)
res = mupadmex('symobj::generateMATLAB',r.s,0);
Error in sym/matlabFunction>mup2matcell (line 304)
r = mup2mat(c{1});
Error in sym/matlabFunction (line 123)
body = mup2matcell(funs);
Can someone suggest what else I can try? Is there a limitation to the type of functions you can use to convert between MuPAD and Matlab?
Thank you for your time,
Andreas.
---------------------------------------------------------------------------
(edit to include the mupad code):
reset();
L := (n,x) -> besselI(n,x);
K := (n,x) -> besselK(n,x);
L_p := (n,x) -> besselI(n+1,x)+n*besselI(n,x)/x;
K_p := (n,x) -> n*besselK(n,x)/x - besselK(n+1,x);
eps := (r_i,r_o) -> r_i/r_o;
F := (n,k,r_s,r_i,r_o) -> 1/(eps(r_i,r_o)*K_p(n,k*r_s)*L(n,k*r_s)-K(n,k*r_s)*L_p(n,k*r_s));
an := (n,k,r_s,r_e,r_i,r_o,r) -> piecewise(
[r <= r_e, K(n,k*r_e)+(1-eps(r_i,r_o))*L(n,k*r_e)*K(n,k*r_s)*K_p(n,k*r_s)*F(n,k,r_s,r_i,r_o)],
[r_e < r and r <r_s, (1-eps(r_i,r_o))*L(n,k*r_e)*K(n,k*r_s)*K_p(n,k*r_s)*F(n,k,r_s,r_i,r_o)],
[r > r_s, 0]);
bn := (n,k,r_s,r_e,r_i,r_o,r) -> piecewise(
[r <= r_e, 0],
[r_e < r and r <r_s, L(n,k*r_e)],
[r > r_s, (L(n,k*r_e)*F(n,k,r_s,r_i,r_o))/(k*r_s)]);
gam := (n) -> piecewise([n = 0, 1], [Otherwise, 2]);
psi_n := (n,k,r_s,r_e,r_i,r_o,r) -> an(n,k,r_s,r_e,r_i,r_o,r)*L(n,k*r) + bn(n,k,r_s,r_e,r_i,r_o,r)*K(n,k*r);
sum_n := (k,r_s,r_e,r_i,r_o,r,phi) -> numeric::sum(gam(n)*cos(n*phi)*psi_n(n,k,r_s,r_e,r_i,r_o,r), n =0..infinity);
V := (r,phi,z,r_s,r_e,r_i,r_o) -> (1/(2*PI^2))*numeric::int(cos(k*z)*sum_n(k,r_s,r_e,r_i,r_o,r,phi), k=0..infinity);

Answers (2)

Walter Roberson
Walter Roberson on 8 Oct 2013
Try
generate::MATLAB(op(V))
and
generate::MATLAB(V(r,theta,z,r_s,r_e,r_i,r_o))
Your difficulty stems from the fact that you need to pass an expression in to generate::MATLAB, but procedures (and some other objects) evaluate to their own name instead of evaluating to their definition when they are named in isolation.
What is sum_n ? Is that one of your own procedures?
I am not sure that numeric::int can get converted to MATLAB by the generate function; I do not have the toolbox to test that with.
  5 Comments
Walter Roberson
Walter Roberson on 8 Oct 2013
Bleh. Those piecewise's are creating a mess. I wonder if rewriting them as if/else would help?
The infinite numeric summation is a bit problematic to generate as MATLAB code, as MATLAB does not provide any infinite numeric summation routine.
Last time I looked around, it appeared that numeric integration could not be code generated, so you may have to generate the integral() call yourself.
There is a division by 0 when k = 0, as k*r_e becomes 0, and BesselI(n,0) can blow up, especially when n = 0 as well. Have you done an analysis to ensure that a limit exists for that combination? 0*BesselI(0,0) is potentially 0 at the limit, but you would need to prove that, and you would need to adjust the code so that it did not end up propagating NaN from the 0/0 (as 0 * NaN is NaN)
Andreas
Andreas on 9 Oct 2013
Thank you for your reply! I tried before to write it in an .m file and I found these problems of NaN's and Inf's appearing. That is why I tried to solve it in MuPAD. Cases that fail to compute in Matlab, MuPAD works them out, so that is why I wanted to convert that code back into Matlab so I can integrate it with the rest of my project.

Sign in to comment.


Andreas
Andreas on 8 Oct 2013
Following up from my initial question I tried a different approach which also yields an error. I rewrote the equation definitions using:
L := besselI(n,k*r);
I removed the '(parameter_1,parameter_2,...) ->' from the definitions.
This then generated a .m file when used the generate::MATLAB command but the file was broken and not working.
When I used the command prompt I got the following:
Warning: Function "slot" is not verified to be a valid MATLAB function.
Warning: Function "slot" is not verified to be a valid MATLAB function.
Warning: Function "_range" is not verified to be a valid MATLAB function.
Warning: Function "_range" is not verified to be a valid MATLAB function.
Error using symengine>makeFhandle (line 109)
Error: Illegal use of reserved keyword "if".
Error in symengine (line 60)
Error in sym/matlabFunction (line 125)
g = symengine('makeFhandle',varnames,body);
Again not sure how to proceed..any help will be greatly appreciated

Community Treasure Hunt

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

Start Hunting!