How to substitute matrix into function handle
8 次查看(过去 30 天)
显示 更早的评论
I am trying to make this function work with any number of functions F{} and starting variable xx[]
I have distilled it down to this code:
clearvars
tic
% Needs to be edited regardless
xx = [1;1;1;1];
% End edit
nx = length(xx);
X = transpose(sym('x',[1;nx]));
F = cell(nx,1);
% Needs to be edited regardless
F{1} = matlabFunction(5*X(1)*X(3) - 2*X(1)*X(2) +4*X(3)^2 - X(2)*X(4)-9.75);
F{2} = matlabFunction(6*X(1) + 3*X(2) + X(3) - X(4)-5.5);
F{3} = matlabFunction(2*X(1)^(2) + X(2)*X(3)-5*X(3)+X(1)*X(4)+3.50);
F{4} = matlabFunction(-3*X(1)*X(4) -2*X(2)^2+6*X(3)*X(4)+X(3)*X(4)-16.00);
% End edit
J = {sym(zeros(nx))};
for i = 1:length(xx)
for j = 1:length(xx)
J{i,j} = matlabFunction(diff(F{i},X(j)));
end
end
for i = 1:nx
F{i} = matlabFunction(-sym(F{i}));
end
for i = 1:200
% X = transpose(sym('x',[1;nx]));
% Currently needs to be edited if number of x changes
syms x1 x2 x3 x4
x1 = xx(1);
x2 = xx(2);
x3 = xx(3);
x4 = xx(4);
% End edit
JJ = subs(J);
FF = subs(F);
dx = JJ\FF;
xx = xx + dx;
if abs(dx) < 0.0000001
break
end
% Currently needs to be edited if number of x changes
clear x1 x2
% End edit
end
formatSpec = 'Ans =';
for i = 1:nx
formatSpec = append(formatSpec,' %#.8g');
end
fprintf(formatSpec,xx);
toc
in the second half, and substiture xx(1) number into X(1) symbolic variable and so on into the function handles?
Is there a way to maybe replace the "Currently needs to be edited if number of x changes" parts?
Edit1: Revised code and formatting
Edit2: Selected MATLAB version
1 个评论
Torsten
2022-3-6
It's a really bad idea to program Newton's method symbolically since it will perform much too inefficient in higher dimensions.
回答(1 个)
Infinite_king
2023-10-18
编辑:Infinite_king
2023-10-18
Hi Phuwanut Pataratawinun,
I understand that you want to make code modifications that minimize the changes needed when the input size varies.
You can achieve this by using the 'subs' function. The 'subs' function takes an array of old symbols and an array of new symbols, replacing the old symbols with the new ones and re-evaluating the expressions. To meet your requirements, you should make the following changes,
Modification 1 : Change the ‘F’ and ‘J’ type to sym arrays.
Modification 2 : Change the shape of X to array of shape [1, size]
Modification 3 : Use the ‘subs(expression_matrx, old_sym, new_sym)’ variant instead of ‘subs(expression)’ and pass X as old symbols and xx’ as new symbols.
Please find the complete code after modifications below,
clearvars
tic
% Needs to be edited regardless
xx = [1;1;1;1];
% End edit
nx = length(xx);
X = transpose(sym('x',[1;nx]));
% Modification 1
% -------------------------------
F = sym(zeros(4,1));
% Needs to be edited regardless
F(1) = matlabFunction(5*X(1)*X(3) - 2*X(1)*X(2) +4*X(3)^2 - X(2)*X(4)-9.75);
F(2) = matlabFunction(6*X(1) + 3*X(2) + X(3) - X(4)-5.5);
F(3) = matlabFunction(2*X(1)^(2) + X(2)*X(3)-5*X(3)+X(1)*X(4)+3.50);
F(4) = matlabFunction(-3*X(1)*X(4) -2*X(2)^2+6*X(3)*X(4)+X(3)*X(4)-16.00);
% End edit
J = sym(zeros(nx));
for i = 1:length(xx)
for j = 1:length(xx)
J(i,j) = matlabFunction(diff(F(i),X(j)));
end
end
for i = 1:nx
F(i) = matlabFunction(-sym(F(i)));
end
% -----------------------------
% Modification 2 <----------
X = reshape(X,[1,4]);
for i = 1:200
% Modification 3
%-----------------------
JJ = subs(J,X,xx');
FF = subs(F,X,xx');
%-----------------------
dx = JJ\FF;
xx = xx + dx;
if abs(dx) < 0.0000001
break
end
end
formatSpec = 'Ans =';
for i = 1:nx
formatSpec = append(formatSpec,' %#.8g');
end
fprintf(formatSpec,xx);
toc
For more information refer the following MATLAB documentation,
- https://www.mathworks.com/help/symbolic/subs.html
- https://www.mathworks.com/help/matlab/ref/reshape.html
- https://www.mathworks.com/help/symbolic/conversion.html
Hope this is helpful.
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Calculus 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!