Determining symbolic function values without using matlabFunction

1 回表示 (過去 30 日間)
M Al Mamun
M Al Mamun 2020 年 5 月 2 日
コメント済み: Star Strider 2020 年 5 月 2 日
Hello all, I am trying to evaluate a symbolic matrix at a certain point. The symbolic functions are as follows:
clc, clear all
x=sym("x",[1 3]);
f(1,1)=x(1)^2 + 2*x(2) +x(3);
f(2,1)=2*x(1) + x(2)^3 + x(2)^2;
f(3,1)=x(1) + x(2) + 2*x(3)^2;
% Finding the jacobian
for i=1:length(f)
for j=1:length(f)
jac(i,j)=diff(f(i), x(j));
end
end
Now, I would like to evaluate the jac at x=[1 2 3].
x=[1 2 3]; % point where jac will be evaluated
It can be done by several ways.
First method:
fv1=tic;
jac_n=matlabFunction(jac);
x_n=num2cell(x);
J1=jac_n(x_n{:})
t_fv1=toc(fv1)
time taken = 0.2255 s.
Second method:
fv2=tic;
J2=[2*x(1) 2 1; 2 3*x(2)^2 2*x(3); 1 1 2] % jac matrix is written manually
t_fv2=toc(fv2
time taken = 4.2230e-04 s
First method takes way longer time than the second method. Also, the first method may not work if all x variables are not present in jac. Now, I want to use the second method as it takes very less time. But I have to write the expressions of jac manually. Is there any way that I can write the expressions of jac automatically? Also, it would be great if anybody can suggest any method faster than those two mentioned. Thank you.

採用された回答

Star Strider
Star Strider 2020 年 5 月 2 日
You are creating ‘jac_n’ inside the timing block in the code you posted, and creating a cell array from ‘x’.
If you create the function first, and define the ‘x’ values as a vector (they appear in order as ‘in1’ in ‘jac_n’ in my code here), the code is much faster:
jac_n = matlabFunction(jac, 'Vars',{[x]})
x=[1 2 3];
fv1 = tic
J1 = jac_n(x)
fv2 = toc(fv1)
with:
fv2 =
4.436000000000000e-04
and:
in1 = x;
fv3 = tic
out = reshape([in1(:,1).*2.0,2.0,1.0,2.0,in1(:,2).*2.0+in1(:,2).^2.*3.0,1.0,1.0,0.0,in1(:,3).*4.0],[3,3]);
fv4 = toc(fv3)
with:
fv2 =
1.782000000000000e-04
Function calls are always going to be a bit slower than running the code ourside the function. The times I get are nowhere near as disparate as yours.
Running this:
jac_n = matlabFunction(jac, 'Vars',{[x]})
x=[1 2 3];
for k = 1:100
fv1 = tic
J1 = jac_n(x)
fv2 = toc(fv1)
in1 = x;
fv3 = tic
out = reshape([in1(:,1).*2.0,2.0,1.0,2.0,in1(:,2).*2.0+in1(:,2).^2.*3.0,1.0,1.0,0.0,in1(:,3).*4.0],[3,3]);
fv4 = toc(fv3)
ratio(k) = fv2 / fv4;
end
ratio_stats = [mean(ratio) std(ratio)]
produces:
ratio_stats =
3.146795126810789e+00 8.189169834987492e+00
so the direct code is about three times faster than the function, however there is wide variation.
.
  3 件のコメント
M Al Mamun
M Al Mamun 2020 年 5 月 2 日
@Star Strider, anyway, your code helped me a lot. Now I have solved the problem in my original code. Thanks a lot.
Star Strider
Star Strider 2020 年 5 月 2 日
As always, my pleasure!
Creating the function using matlabFunction does take time, however it only needs to be done once.

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

その他の回答 (1 件)

Walter Roberson
Walter Roberson 2020 年 5 月 2 日
without having done the x=[1 2 3];
xv = [1 2 3];
subs(jac, x, xv)
time about 0.0157 on my system.

カテゴリ

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

Community Treasure Hunt

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

Start Hunting!

Translated by