How to substitute matrix into function handle
7 views (last 30 days)
Show older comments
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 Comment
Torsten
on 6 Mar 2022
It's a really bad idea to program Newton's method symbolically since it will perform much too inefficient in higher dimensions.
Answers (1)
Infinite_king
on 18 Oct 2023
Edited: Infinite_king
on 18 Oct 2023
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 Comments
See Also
Categories
Find more on Calculus in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!