expression is too large, symengine can't calculate
Afficher commentaires plus anciens
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
1 commentaire
Walter Roberson
le 18 Jan 2020
It would be more common to use odeFunction() instead of matlabFunction in constructing equations ?
Réponses (2)
Walter Roberson
le 18 Jan 2020
Modifié(e) : Walter Roberson
le 18 Jan 2020
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.
3 commentaires
Wang Hong
le 19 Jan 2020
Wang Hong
le 23 Jan 2020
Walter Roberson
le 23 Jan 2020
You use matlabFunction with 'vars' and provide a cell array with five elements. That is going to convert into a function that expects five parameters. However you are only passing three parameters to it. It needs t, x S, SS, and theta parameters.
Wang Hong
le 9 Fév 2020
0 votes
7 commentaires
Walter Roberson
le 9 Fév 2020
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.
Wang Hong
le 22 Fév 2020
Walter Roberson
le 22 Fév 2020
The second form is more likely correct. However if you are constructing a function to pass to the ode* numeric routines then you should follow the flow shown in the first example for odeFunction()
Wang Hong
le 23 Fév 2020
Walter Roberson
le 23 Fév 2020
When you list SS as part of var option you are declaring that the system has over 33 thousand variables. You cannot conduct a sensitivity analysis of a system with over 33 thousand variables in any reasonable amount of time and space. Not even if those 33 thousand are to be considered constants for the purpose of the equations. For a sensitivity analysis you would be wanting to create a Jacobian so that you can analyze how changes in two variables at a time influence the equations, and that gets you to a 34000-ish by 34000-ish symbolic array that would be potentially quite complicated.
Wang Hong
le 24 Fév 2020
Walter Roberson
le 24 Fév 2020
You don't do a sensitivity analysis when the number of variables is quite large. Not unless you are only concerned about the change with respect to one variable at a time, not about sensitivity as multiple variables change.
If you only care about one variable at a time then differentiate each equation with respect to each variable. I know that there is a function to do that but the function name is not coming to mind. This would not involve the use of matlabFunction. matlabFunction would only be for numeric work but you want analytic work.
Possibly you would be willing to establish a base numeric point and analyze the effect of changing one variable at a time at that particular numeric point. That would involve looping substituting all the numeric values except that one variable at a time you substitute numeric value plus symbolic delta. In some cases you will get a polynomial output; others might be difficult to analyze, such as if the equations involved the bessel functions.
Catégories
En savoir plus sur Numeric Solvers dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!