よろしければ、コードを再構築して、より動的でユーザー フレンドリーに読みやすくしたいと思います。
いくつかの準備から始めましょう。スクリプトを真に動的にしたい場合は、Symbolic Math Toolbox を使用することをお勧めします。このように、MATLAB を使用して関数の導関数に取り組むことができます。最初にsyms
コマンドを使用し、その後に必要な変数を使用する必要があります。これは、この変数を "シンボリック" (つまり、定数ではない) として扱うことを MATLAB に伝えます。いくつかの基本から始めましょう。
syms x;
y = 2*x^2 + 6*x + 3;
dy = diff(y); % Derivative with respect to x. Should give 4*x + 6;
out = subs(y, 3); % The subs command will substitute all x's in y with the value 3
% This should give 2*(3^2) + 6*3 + 3 = 39
x
これは 2D であるため、2D 関数が必要になります...とy
を変数として定義しましょう。コマンドを呼び出す方法はsubs
少し異なります。
syms x, y; % Two variables now
z = 2*x*y^2 + 6*y + x;
dzx = diff(z, 'x'); % Differentiate with respect to x - Should give 2*y^2 + 1
dzy = diff(z, 'y'); % Differentiate with respect to y - Should give 4*x*y + 6
out = subs(z, {x, y}, [2, 3]); % For z, with variables x,y, substitute x = 2, y = 3
% Should give 56
もう 1 つ... 方程式をベクトルまたは行列に配置し、 と のすべての値を各方程式に同時に代入するために使用できますsubs
。x
y
syms x, y;
z1 = 3*x + 6*y + 3;
z2 = 3*y + 4*y + 4;
f = [z1; z2];
out = subs(f, {x,y}, [2, 3]); % Produces a 2 x 1 vector with [27; 25]
行列に対しても同じことができますが、簡潔にするために、その方法は示しません。私はコードを延期します、そしてあなたはそれを見ることができます。
これで確立されたので、これを真に動的なものにするために、一度に 1 つずつコードに取り組みましょう。関数には、初期推定値、列ベクトルとしてx0
の関数f(x)
、2 x 2 行列としてのヤコビ行列、および許容範囲が必要tol
です。
スクリプトを実行する前に、パラメーターを生成する必要があります。
syms x y; % Make x,y symbolic
f1 = x^2 + y^3 - 1; % Make your two equations (from your example)
f2 = x^4 - y^4 + x*y;
f = [f1; f2]; % f(x) vector
% Jacobian matrix
J = [diff(f1, 'x') diff(f1, 'y'); diff(f2, 'x') diff(f2, 'y')];
% Initial vector
x0 = [1; 1];
% Tolerance:
tol = 1e-10;
次に、スクリプトを関数にします。
% To run in MATLAB, do:
% [n, xout, tol] = Jacobian2D(f, J, x0, tol);
% disp('n = '); disp(n); disp('x = '); disp(xout); disp('tol = '); disp(tol);
function [n, xout, tol] = Jacobian2D(f, J, x0, tol)
% Just to be sure...
syms x, y;
% Initialize error
ep = 1; % Note: eps is a reserved keyword in MATLAB
% Initialize counter
n = 0;
% For the beginning of the loop
% Must transpose into a row vector as this is required by subs
xout = x0';
% Computation loop
while ep > tol && n < 100
g = subs(f, {x,y}, xout); %g(x)
ep = abs(g(1)) + abs(g(2)); %error
Jg = subs(J, {x,y}, xout); %Jacobian
yout = xout - Jg\g; %iterate
xout = yout; %update x
n = n + 1; %counter+1
end
% Transpose and convert back to number representation
xout = double(xout');
おそらく、Symbolic Math Toolbox を使用して計算を行っている場合、計算中の数値のデータ型はオブジェクトであることをお伝えしておく必要がありsym
ます。おそらくこれらを実数に変換し直したいので、 を使用double
してそれらをキャストバックできます。ただし、それらをsym
フォーマットのままにしておくと、探しているものであれば、数値がきちんとした分数として表示されます。double
小数点表現が必要な場合はにキャストします。
この関数を実行すると、探しているものが得られるはずです。このコードはまだテストしていませんが、うまくいくと確信しています。
ご不明な点がございましたら、お気軽にお問い合わせください。お役に立てれば。
乾杯!