3 views (last 30 days)

I'm looking for a way to solve my implicit equation without using syms. The reason is that I want to compile an application with this equation and I can't do it because Matlab Compiler doesn't work with symbolic math toolbox.

This is my equation:

syms R

g = ((1+nu)*(1-2*nu)*(1-1/(R/b0)^2))/((alpha-1)-(1-2*nu)*(1+alpha)/(R/b0)^2);

omega = -(2*(1-2*nu)*(1-nu^2))/(delta*(alpha-1))*((alpha+1/beta)-(nu/(1-nu))*(1+alpha/beta))/((alpha-1)-((1-2*nu)*(1+alpha)/(R/b0)^2))/(R/b0)^2;

S1 = 0;

for n=0:1:10

if n==gam

S = k*omega^n/factorial(n)*log(R/a);

else

S = (omega^n/(factorial(n)*(n-gam))*((R/a)^(k*(n-gam))-1));

end

S1=S1+S;

end

eqn = (nn/gam)*((1-g/delta)^((beta+1)/beta)-(a0/R)^((beta+1)/beta)) == S1;

sol_R = vpasolve(eqn, R, [a0 Rpl_max]);

Walter Roberson
on 27 Mar 2020

In an interactive session:

syms any of the names corresponding to variables you will need to change. Calculate lhs(eqn)-rhs(eqn) and assign that to a variable.

Now call matlabFunction on the variable. Pass it the 'file' option and a file name. For example EQN.m . Pass it the 'vars' option using a cell array. In the first entry of the cell array put a vector of variable names of the variables you want solved for, in the order you want returned. The rest of the variables, the ones that will be provided as numeric parameters rather than solved for, you can either put into a vector in the second cell entry, or you can list them one at a time as cell entries.

That done, switch to the code you will be using for building the compiled application. In it, build an anonymous function that takes a single parameter, and calls EQN passing that parameter straight through, and then passing the numeric values in the same order as you specified in the 'vars' option.

Now you can pass that function handle to fsolve.

Notice that the symbolic work is done only at the interactive session, and is used to write an m file that does not use the symbolic toolbox. Notice that the code to be compiled does not use the symbolic toolbox: it only calls the m file and that file is purely numeric.

By the way, it is safer if your interactive session code initializes S1 to sym(0) instead of 0.

Walter Roberson
on 27 Mar 2020

An interactive session is just the MATLAB application rather than something compiled.

Most of the complication of the generated code comes from not knowing gam ahead of time.

Note: if gam is a fixed constant rather than a parameter, then you would need to switch back from piecewise() to if/else like you had.

%in MATLAB, desktop or command line only, do not compile this part

syms a a0 alpha b0 beta delta gam k nn nu

syms R

g = ((1+nu)*(1-2*nu)*(1-1/(R/b0)^2))/((alpha-1)-(1-2*nu)*(1+alpha)/(R/b0)^2);

omega = -(2*(1-2*nu)*(1-nu^2))/(delta*(alpha-1))*((alpha+1/beta)-(nu/(1-nu))*(1+alpha/beta))/((alpha-1)-((1-2*nu)*(1+alpha)/(R/b0)^2))/(R/b0)^2;

S1 = sym(0);

for n=0:1:10

%piecewise is needed to test against a value to be determined later

S = piecewise(n == gam, ...

k*omega^n/factorial(n)*log(R/a), ...

(omega^n/(factorial(n)*(n-gam))*((R/a)^(k*(n-gam))-1)) );

S1=S1+S;

end

EQN = (nn/gam)*((1-g/delta)^((beta+1)/beta)-(a0/R)^((beta+1)/beta)) - S1;

matlabFunction(EQN, 'file', 'EQN.m', 'vars', {R, [a, a0, alpha, b0, beta, delta, gam, k, nn, nu]})

Now you can switch to the function that used to contain the code to build eqn, the one that had the vpasolve() call in it. Rewrite it:

%his section can be compiled, but you have to have created EQN.m first.

%assign the parameters. None of the below can involve symbolic computation!

a = whatever

a0 = whatever

alpha = whatever

b0 = whatever

beta = whatever

delta = whatever

gam = whatever

k = whatever

nn = whatever

nu = whatever

Rpl_max = whatever %not a parameter

parameters = [a, a0, alpha, b0, beta, delta, gam, k, nn, nu]; %do not include RPL_max

obj = @(R) EQN(R, parameters);

%The function to be solved has a single variable. We can use fzero, which

%permits us to pass in a range of values to solve over.

%notice that nothing here uses the Symbolic Toolbox

R = fzero(obj, [a0, Rpl_max]);

if isempty(R) || isnan(R)

%suppose there was no solution in that range?

end

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

Start Hunting!
## 0 Comments

Sign in to comment.