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!