Determining symbolic function values without using matlabFunction
조회 수: 1 (최근 30일)
이전 댓글 표시
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.
댓글 수: 0
채택된 답변
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
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
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.
댓글 수: 0
참고 항목
카테고리
Help Center 및 File Exchange에서 Assumptions에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!