help with MuPAD generate::MATLAB command?
Show older comments
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
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
on 8 Oct 2013
Would it be practical to show us the complete value for V(r,phi,z,r_s,r_e,r_i,r_o) including the definition for any routines it calls?
Andreas
on 8 Oct 2013
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
on 9 Oct 2013
Andreas
on 8 Oct 2013
Categories
Find more on Functional Programming in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!