20 views (last 30 days)

I use symbolic expression to calculate sensitivity equasions of ODEs with 19 ODEs and 42 variables. And the error message is "the expression is too large , symengin can't calculate " when using it to calculate the second order sensitivity equations. I checked the dimension is more than 3 ten thousand and it isn't the sparse matrix. I debug into the symbolic there is no sourcecode, how do I do next?

Part codes like next:

function obj = compute_2nd_order_sensitivity_equations(obj)

M = obj.M;

N = obj.N;

if isempty(obj.S) || isempty(obj.dS) || isempty(obj.S0)

obj = obj.compute_1st_order_sensitivity_equations;

end

[SS,dSS,SS0] = sensitivity_equations_another([obj.x;obj.S(:)], obj.theta, [obj.dx;obj.dS(:)], [obj.x0;obj.S0(:)]);

SS(1:M,:)=[]; dSS(1:M,:)=[]; SS0(1:M,:)=[]; % remove the first order sensitivity equations

obj.SS = reshape(SS,M,N,N) ; % reshape the 2nd order equations

obj.dSS = reshape(dSS,M,N,N);

obj.SS0 = reshape(SS0,M,N,N);

obj.ODE_2nd_order_sensitivity_rhs = matlabFunction(obj.dx,obj.dS(:),obj.dSS(:),'vars', {'t', obj.x,obj.S(:),obj.SS(:), obj.theta}); % define the right hand side of the ODE as a function of time, system states + sensitivity, and parameter

obj.ODE_2nd_order_sensitivity_init = matlabFunction(obj.x0,obj.S0(:),obj.SS0(:),'vars', {obj.theta}); % define the initial condition as a function of parameters

end

symengine give error messages in function of matlabFunction

......

else

body = mup2matcell(funs, opts.Sparse);

body = renameInputs(body,vars,inputs);

g = symengine('makeFhandle',varnames,body);

end

Walter Roberson
on 18 Jan 2020 at 7:51

Edited: Walter Roberson
on 18 Jan 2020 at 7:51

Create

eqns = [obj.dx,obj.dS(:);obj.dSS(:)];

Now break that up into chunks. For example:

At_a_time = 10;

num_eqn = length(eqns);

num_chunks = ceil(num_eqn ./ At_a_time);

fh = cell(num_chunks, 1);

for K = 1 : At_a_time : num_eqn - At_a_time

fn{K} = matlabFunction(eqns(K:K+At_a_time-1), 'vars', {'t', obj.x,obj.S(:),obj.SS(:), obj.theta});

end

if num_chunks * At_a_time ~= num_eqn %you should double-check the boundary conditions here

fn{K+1} = matlabFunction(eqns(K+At_a_time:end), 'vars', {'t', obj.x,obj.S(:),obj.SS(:), obj.theta});

end

And now:

obj.ODE_2nd_order_sensitivity_rhs = @(varargin) cell2mat(cellfun(@(FH) FH(varargin{:}), fn, 'uniform', 0));

which should execute the handles one at a time and form a vector of the results.

Yes, this is a bit of a hack, but if it gets the job done then it gets the job done.

Walter Roberson
on 23 Jan 2020 at 5:20

Sign in to comment.

Wang Hong
on 9 Feb 2020 at 14:53

Walter Roberson
on 9 Feb 2020 at 18:21

MATLAB is going to detect that you did not pass a nonlinear constraint function after the boundary conditions. It is then going to see the p_values as an extra parameter that it must pass to the function along with the regular two parameters, so it would pass it along with t and x_values to your anonymous function that you defined as only expecting two parameters.

The function you call does not appear to expect p_values as a parameter.

Sign in to comment.

Sign in to answer this question.

Opportunities for recent engineering grads.

Apply Today
## 1 Comment

## Direct link to this comment

https://nl.mathworks.com/matlabcentral/answers/500833-expression-is-too-large-symengine-can-t-calculate#comment_787275

⋮## Direct link to this comment

https://nl.mathworks.com/matlabcentral/answers/500833-expression-is-too-large-symengine-can-t-calculate#comment_787275

Sign in to comment.