My code wont run, keep getting error "Not enough input arguments"

9 ビュー (過去 30 日間)
Nizar Sharkas
Nizar Sharkas 2021 年 10 月 9 日
編集済み: Walter Roberson 2021 年 10 月 13 日
The following is my code for secant method optimization search. I have my objective function in one file called f.m and the algorithm in another named secant.m. Whenever I run my code I keep getting an error: Not enough input arguments. I am using MATLAB 2019b
Additionlly, could someone please let me know if the logic of my code is correct? after many iterations I should reach a value z which minimizes my function and I would like to take all the "z"s that were calculated each iteration and calculate an error and then plot those error values per iteration as my y axis and iteration on the x axis to get my graph. If someone if familiar with the secant method could you please let me know if this is correct? Thanks alot.
code in f.m file:
function g = f(x)
g = 2*((x-3)^2)+exp(0.5*x^2);
code in secant.m file:
f_prime = diff(f);
a = 0;
b = 3;
epsilon = 0.0001;
x1 = a;
x2 = b;
k = 0;
iteration = 100;
f1 = f_prime(x1);
f2 = f_prime(x2);
z = x1 - (f1/((f1-f2)*(x1-x2)));
f3 = f_prime(z);
while (abs(f3) > epsilon) && (k<iteration)
k = k+1;
if (f1>f2)
x2 = z;
z = x1 - (f1/((f1-f2)*(x1-x2)));
f3 = f_prime(z);
error = abs(f(z)-f(3));
else
x1 = z;
z = x1 - (f1/((f1-f2)*(x1-x2)));
f3 = f_prime{z};
error = abs(f(z)-f(3));
end
end
plot (iteration, error, 'rx')

回答 (1 件)

Walter Roberson
Walter Roberson 2021 年 10 月 9 日
f_prime = diff(f);
That line starts by looking to see if there is a variable named f that is in scope. If there is no such variable, then it looks to see if there is a function named f that is in scope. MATLAB sees the f.m file so Yes there is a function named f in scope. Having located the function named f, that syntax would attempt to invoke f without any arguments, just as if the code had written
f_prime = diff(f());
So the code in f.m starts running, with variable x (from the function definition line for function f) internally marked as missing. Then the second line of f is reached,
g = 2*((x-3)^2)+exp(0.5*x^2);
and the reference to x is seen. x is searched for as a variable in scope, and is located in the function header -- but since no parameters were passed, x is marked as missing. And MATLAB then complains that you invoked a function (namely f) with insufficient arguments.
Now... you need information beyond just the above.
What you need to know at this point is that MATLAB has two diff functions. (Well, more than two.)
The main diff function is designed to take numeric differences -- for a vector x and no optional arguments, it would output [x(2)-x(1), x(3)-x(2), x(4)-x(3), x(5)-x(4)] and so on to x(end)-x(end-1) . That kind of subtraction of adjacent elements is used for almost all data types. It is the "difference" operator, not the "differentiation" operator.
The second important diff function only applies to symbolic expressions and symbolic functions created by the Symbolic Toolbox, and in the context of symbolic expressions and symbolic functions, it is the differentiation operator.
But... your function f is a regular function, not a symbolic function. So you cannot invoke the differentiation operator on it -- not directly .
If you have access to the Symbolic Toolbox, what you could do would be to change
f_prime = diff(f);
into
syms x
f_prime = matlabFunction(diff(f(x)))
Creating x as symbolic, and passing it to x specifically results in function f being invoked with symbolic variable x as a parameter. The particular function you defined happens to be fine receiving a symbolic parameter, and would do a calculation that would return a symbolic expression. The symbolic expression would then get passed to the symbolic differentiation operator, returning a symbolic expression as a result. Then matlabFunction() would convert the symbolic expression into an anonymous function that can receive (and return) numeric values.
  14 件のコメント
Walter Roberson
Walter Roberson 2021 年 10 月 13 日
That error is not occuring when I execute your code unchanged.
syms x
f(x) = 2*((x-3)^2)+exp(0.5*x^2);
f_prime = matlabFunction(diff(f(x)));
a = 0;
b = 3;
epsilon = 0.0001;
x1 = a;
x2 = b;
k = 0;
iteration = 100;
f1 = f_prime(x1);
f2 = f_prime(x2);
z(1) = x1 - (f1/((f1-f2)/(x1-x2)));
fpz(1) = f_prime(z);
error = [];
while (abs(fpz(end)) > epsilon) && (k<iteration)
k = k+1;
if (f1>f2)
x2 = z(end);
z(end+1) = x1 - (f1/((f1-f2)/(x1-x2)));
fpz(end+1) = f_prime(z(end));
error(end+1) = abs(f(z(end))-fpz(end));
sprintf('x_min=%f', z(end))
else
x1 = z(end);
z(end+1) = x1 - (f1/((f1-f2)/(x1-x2)));
fpz(end+1) = f_prime(z(end));
error(end+1) = abs(f(z(end))-fpz(end));
sprintf('x_min=%f', z(end))
end
end
ans = 'x_min=0.249842'
ans = 'x_min=0.366849'
ans = 'x_min=0.478878'
ans = 'x_min=0.586140'
ans = 'x_min=0.688839'
ans = 'x_min=0.787168'
ans = 'x_min=0.881314'
ans = 'x_min=0.971454'
ans = 'x_min=1.057760'
ans = 'x_min=1.140393'
ans = 'x_min=1.219511'
ans = 'x_min=1.295263'
ans = 'x_min=1.367791'
ans = 'x_min=1.437234'
ans = 'x_min=1.503723'
ans = 'x_min=1.567383'
ans = 'x_min=1.628334'
ans = 'x_min=1.686692'
ans = 'x_min=1.742567'
ans = 'x_min=1.796065'
ans = 'x_min=1.847287'
ans = 'x_min=1.896330'
ans = 'x_min=1.943286'
ans = 'x_min=1.988244'
ans = 'x_min=2.031290'
ans = 'x_min=2.072504'
ans = 'x_min=2.111965'
ans = 'x_min=2.149747'
ans = 'x_min=2.185921'
ans = 'x_min=2.220557'
ans = 'x_min=2.253718'
ans = 'x_min=2.285469'
ans = 'x_min=2.315869'
ans = 'x_min=2.344976'
ans = 'x_min=2.372844'
ans = 'x_min=2.399527'
ans = 'x_min=2.425074'
ans = 'x_min=2.449535'
ans = 'x_min=2.472954'
ans = 'x_min=2.495378'
ans = 'x_min=2.516847'
ans = 'x_min=2.537403'
ans = 'x_min=2.557085'
ans = 'x_min=2.575929'
ans = 'x_min=2.593971'
ans = 'x_min=2.611246'
ans = 'x_min=2.627785'
ans = 'x_min=2.643621'
ans = 'x_min=2.658784'
ans = 'x_min=2.673301'
ans = 'x_min=2.687200'
ans = 'x_min=2.700509'
ans = 'x_min=2.713251'
ans = 'x_min=2.725450'
ans = 'x_min=2.737131'
ans = 'x_min=2.748315'
ans = 'x_min=2.759023'
ans = 'x_min=2.769276'
ans = 'x_min=2.779092'
ans = 'x_min=2.788491'
ans = 'x_min=2.797489'
ans = 'x_min=2.806105'
ans = 'x_min=2.814355'
ans = 'x_min=2.822253'
ans = 'x_min=2.829815'
ans = 'x_min=2.837056'
ans = 'x_min=2.843988'
ans = 'x_min=2.850626'
ans = 'x_min=2.856981'
ans = 'x_min=2.863066'
ans = 'x_min=2.868892'
ans = 'x_min=2.874470'
ans = 'x_min=2.879811'
ans = 'x_min=2.884924'
ans = 'x_min=2.889820'
ans = 'x_min=2.894508'
ans = 'x_min=2.898996'
ans = 'x_min=2.903293'
ans = 'x_min=2.907408'
ans = 'x_min=2.911347'
ans = 'x_min=2.915119'
ans = 'x_min=2.918730'
ans = 'x_min=2.922188'
ans = 'x_min=2.925498'
ans = 'x_min=2.928668'
ans = 'x_min=2.931703'
ans = 'x_min=2.934609'
ans = 'x_min=2.937391'
ans = 'x_min=2.940054'
ans = 'x_min=2.942605'
ans = 'x_min=2.945047'
ans = 'x_min=2.947385'
ans = 'x_min=2.949623'
ans = 'x_min=2.951767'
ans = 'x_min=2.953819'
ans = 'x_min=2.955784'
ans = 'x_min=2.957665'
ans = 'x_min=2.959466'
ans = 'x_min=2.961190'
ans = 'x_min=2.962842'
plot(error, 'rx')
title('error vs iteration')
Walter Roberson
Walter Roberson 2021 年 10 月 13 日
編集済み: Walter Roberson 2021 年 10 月 13 日
my error is the absolute value of f(zi) - f(xopt) where zi is the values of z after each iteration and xopt is the value of z that finally breaks my while loop (optimum point).
In that case, do not calculate error inside the loop: keep track of all of the z values (which you are already doing), and after the loop,
fz = f(z);
error = fz - fz(end);
This of course only being valid if you converged within the allocated iterations: if you do not converge then fz(end) could be just about anything, and calculating the error relative to it would not be useful.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeConversion Between Symbolic and Numeric についてさらに検索

製品


リリース

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by