help with MuPAD generate::MATLAB command?

2 Ansichten (letzte 30 Tage)
Andreas
Andreas am 8 Okt. 2013
Kommentiert: Andreas am 9 Okt. 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);

Antworten (2)

Walter Roberson
Walter Roberson am 8 Okt. 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 Kommentare
Walter Roberson
Walter Roberson am 8 Okt. 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 am 9 Okt. 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.

Melden Sie sich an, um zu kommentieren.


Andreas
Andreas am 8 Okt. 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!

Translated by