expression is too large, symengine can't calculate

6 ビュー (過去 30 日間)
Wang Hong
Wang Hong 2020 年 1 月 18 日
コメント済み: Walter Roberson 2020 年 2 月 24 日
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 件のコメント
Walter Roberson
Walter Roberson 2020 年 1 月 18 日
It would be more common to use odeFunction() instead of matlabFunction in constructing equations ?

サインインしてコメントする。

回答 (2 件)

Walter Roberson
Walter Roberson 2020 年 1 月 18 日
編集済み: Walter Roberson 2020 年 1 月 18 日
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 件のコメント
Wang Hong
Wang Hong 2020 年 1 月 23 日
@Walter Roberson, Though the origianl problem can be executed, the next steps face another obtacle. Owing to the result of is so different, when we compute ode45 with the function handle,it gives the error information is : the number of input parameters is not enough , and we call it like this:
[t,y] = ode45(@(t,x_values)obj.ODE_2nd_order_sensitivity_rhs(t,x_values,para),obj.time_points_to_evaluate,obj.ODE_2nd_order_sensitivity_init(para));
Walter Roberson
Walter Roberson 2020 年 1 月 23 日
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
Wang Hong 2020 年 2 月 9 日
@Walter Roberson,
I tried different methods, such as:
1. p_values={obj.x,obj.S(:),obj.SS(:)};
options = odeset('RelTol',1e-1);
[t,y] = ode45(@(t,x_values)obj.ODE_2nd_order_sensitivity_rhs(t,obj.dx,obj.dS(:),obj.dSS(:),obj.para),obj.time_points_to_evaluate,obj.ODE_2nd_order_sensitivity_init(para),options,p_values);
and
2. p_values={obj.x,obj.S(:),obj.SS(:)};
options = odeset('RelTol',1e-1);
[t,y] = ode45(@(t,x_values)obj.ODE_2nd_order_sensitivity_rhs(t,x_values,obj.para),obj.time_points_to_evaluate,obj.ODE_2nd_order_sensitivity_init(para),options,p_values);
but the error information are both : too many input arguments, what makes me confusing are the bold parts ODE_2nd_order_sensitivity_rhs(t,obj.dx,obj.dS(:),obj.dSS(:),obj.para) and p_values, I think the p_values is the input arguments and what is the previous?
My God , I don't know how to pass the parameters
  7 件のコメント
Wang Hong
Wang Hong 2020 年 2 月 24 日
Thank you for your suggestion. I will try it! But I am curious about how to do sensitivity analysis when the number of variable is large
Walter Roberson
Walter Roberson 2020 年 2 月 24 日
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.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeNumeric Solvers についてさらに検索

タグ

Community Treasure Hunt

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

Start Hunting!

Translated by