I am trying to write a program for the Bisection method, but I am not fully understanding how to properly define a function and run the script. I have searched google and watched YouTube videos and MATLAB tutorials on this stuff, but I just don't get it. I hope someone here can help me once I present my code, and the error messages I am getting, as well as what I should expect to see...
Code:
function [f] = Bisection(a,b,Nmax,TOL)
f(x)= x^3 - x^2 + x;
i=1;
BisectA=f(a);
while i <= Nmax
p=a+(b-a)/2;
BisectP=f(p);
if BisectP == 0 || (b-a)/2 < TOL
disp('p');
end
i=i+1;
if BisectA*BisectP > 0
a=p;
BisectA=BisectP;
else
b=p;
end
end
disp('Method failed after num2str(Nmax) iterations, Nmax=', Nmax);
When I run this code, I get the error message:
??? Undefined function or variable 'x'.
Error in ==> Bisection at 2
f(x)= x^3 - x^2 + x;
I am unable to figure out how to define 'x'?? Also, should I create more than one function? I would like to have them all in one file.
Thanks.
You error is occurring because x is indeed undefined. If you'r trying to create an anonymous function that takes x as an argument, you'd do that like this:
f = #(x)x.^3-x.^2+x;
Then you can call f(a) as you do later on. Another potential issue is that your Bisection function is returning f. Do you want it to return the function handle?
Related
i have problem solving a series of a function.
how should i solve series like Σ F(k)*F(k-1) ?
actually i want to solve the below series in Matlab
"image of the function"
it's only dependent of K variable.
i tried by defining a function as bellow and saving it as an .m file (for testing i simplified it by neglecting B)
function out = teta(x)
if x==9./5
out=(25./(36*1));
else
out=(10./(9.*1.*x.*(x-1))).*(x-9./5).*teta(x-9./5);
end
and wrote this in the main file:
sum(teta(18/5:9/5:72/5))
as i want a sum of the serie from k=18/5 to 72/5
when i run it i get these errors:
Not enough input arguments.
Error in teta (line 2)
if x==9./5
and
Out of memory. The likely cause is an infinite recursion within the program.
Error in teta (line 5)
out=(10./(9*1.*x.*(x-1))).*(x-9./5).*teta(x-9./5);
so where i'm wrong and "how should i solve these kind of series?"
For a start, you shouldn't an equality test on a floating double precision number, but instead compare the difference to a small threshold value.
Not using a vectorised approach (feel free to vectorise if you so desire), the following works:
function out = teta(x)
if abs(x-9/5)<1e-3
out=25/36;
else
out=(10/(9*x*(x-1)))*(x-9/5)*teta(x-9/5);
end
and then use it as such:
kk = 18/5:9/5:72/5;
teta_vec = zeros(size(kk));
for k=1:length(kk)
teta_vec(k) = teta(kk(k));
end
which gives me:
>> sum(teta_vec)
ans = 0.17714
I can't understand what the problem is with this code. If anyone can help I will be thankful.
function [out] = detj(in1)
%DETJ Summary of this function goes here
%Detailed explanation goes here: N is 2*50 matrix and in1 is scaler
global N
out=(1/8)*(N(1,in1));
end
The error is :
Input argument "in1" is undefined.
Error in ==> detj at 7
out=(1/8)*(N(1,in1));
I defined N in another file
N=importdata('Nodes.txt'); %Matrix of nodes
No thing wrong with your code, you just used the function the wrong way.
To use a Function in Matlab you need to call it, NOT to run it directly.
This is your original function code
function [out] = detj(in1,in2,in3,in4)
%DETJ Summary of this function goes here
% Detailed explanation goes here %N is 2*50 Matrix
global N r s
out=zeros(2,2);
for m=1:2
for n=1:2
out(m,n)=(1/8)*(((N(1,in1)-N(1,in3))*(N(2,in2)-N(2,in4))-(N(2,in1)-N(2,in3))*(N(1,in2)-N(1,in4)))-r(1,m)*((N(1,in3)-N(1,in4))*(N(2,in1)-N(2,in2))-(N(2,in3)-N(2,in4))*(N(1,in1)-N(1,in2)))+s(1,n)*((N(1,in2)-N(1,in3))*(N(2,in1)-N(2,in4))-(N(2,in2)-N(2,in3))*(N(1,in1)-N(1,in4))));
end
end
end
To use your function I tried a simple code,
clc;clear;
global N
global r
global s
N=ones(2,50);
r=ones(2,2);
s=ones(2,2);
detj(1,2,3,4)
And I got answer as
ans =
0 0
0 0
So no thing wrong with your function, just you need to know how to use it.
Let me know if my answer is not clear else good luck.
i want to understand what is a error in the following code?code is given below
function x0=secand2d(f,g,x,dx,tol)
% find solution of f(x,y)=0 and g(x,y)=0
for i=1:20
x0=x;
f0=[feval(f,x0),feval(g,x0)];
x0=x+[dx(1),0];
fx=[feval(f,x0),feval(g,x0)];
fx=(fx-f0)/dx(1);
x0=x+[0 dx(2)];
fy=[feval(f,x0),feval(g,x0)];
fy=(fy-f0)/dx(2);
A=[fx;fy]+eps;
x=x+dx;
dx=(-A\f0'-dx')';
if(norm(dx)<tol) ;return; end;
end;
disp(norm(dx));
pause;
end
which represents of two dimensional secant method,where function f and g is defined by following form
f=#(x,y) (x-sin(x+y)); and g=#(x,y) y-cos(x-y);
i have also checked and these to function works fine on it's parameters
f(3,3)
ans =
3.2794
and
g(1,1)
ans =
0
also
x=[0.9 0.9];
dx=[0.1 0.1];
tol=1e-5;
but following code generated such kind of errors
secand2d(f,g,x,dx,tol)
Error using #(x,y)(x-sin(x+y))
Not enough input arguments.
Error in secand2d (line 5)
f0=[feval(f,x0),feval(g,x0)];
please help me to clarify reasons of this errors
You are getting that error because you are passing only x0 to f here:
f0=[feval(f,x0),feval(g,x0)];
f and g are expecting two inputs. You can fix the error like this:
f0=[feval(f,x0,y0),feval(g,x0,y0)];
If there is not a particular reason you are using feval you can do it like this:
f0 = [f(x0, y0) g(x0, y0)];
I am getting the following error when I type in CalculateIntegral(2,5) into the MATLAB Command Window:
??? Error: File: CalculateIntegral.m Line: 2 Column: 1
Function definitions are not permitted at the prompt or in scripts.
I am not sure how to resolve this error. Thanks.
clear all;
function g = CalculateIntegral(s,N)
a=0;
b=1;
h=(b-a)/N;
x = 0:h:1;
g = ff(x).*exp(-s*x);
% compute the exact answer of the integral
exact_answer=antiderivative(b,s)-antiderivative(a,s);
% compute the composite trapezoid sum
If=0;
for i=1:(N-1)
If=If+g(i)*h;
end;
If=If+g(1)*h/2+g(N)*h/2;
If;
You can't have a clear all before your function definition (and you don't need one). Just remove that first line to make your code work. MATLAB functions need to be by themselves in their own file, named like the function (CalculateIntegral.m in your case).
I have the same kind of problem described in this topic:
Using fzero: Undefined function or method 'isfinite' for input arguments of type 'sym'
Their answers really helped me, but I am still stuck.
I also have to find the zeros of a function of w, this function is defined in several steps:
So the only unknown is w, and I defined other objects such as:
lambda= #(w) ((16*rho(i)*A(i)*w^2*Lprime(i)^2)/(E(j)*I(i)))^0.25;
beta=#(w) lambda*b(i)^0.5;
gamma=#(w) lambda*Lprime(i)^0.5;
Then, I define a 4*4 matrix M2:
M2=#(w) [besselj(4,beta) bessely(4,beta) besseli(4,beta) besselk(4,beta);
besselj(3,beta) bessely(3,beta) besseli(3,beta) -besselk(3,beta);
besselj(2,gamma) bessely(2,gamma) besseli(2,gamma) besselk(2,gamma);
besselj(4,gamma) bessely(4,gamma) besseli(4,gamma) besselk(4,gamma)];
Then the equation to be solved is: det(M2)=0. But w=0 is one of the solutions, and I want the first non-zero solution, so I wrote:
delta = #(w) det(M2);
S(i,j)=fzero(delta,500);
Then I run the program, and Matlab says:
??? Error using ==> fzero at 235
FZERO cannot continue because user supplied function_handle ==> #(w)det(M2)
failed with the error below.
Undefined function or method 'det' for input arguments of type 'function_handle'.
Error in ==> frequencies at 57
S(i,j)=fzero(delta,500);
I also tried with the subs and the eval methods, and they don't work either, the error messages are in those cases:
??? Undefined function or method 'isfinite' for input arguments of type 'sym'.
Error in ==> fzero at 323
elseif ~isfinite(fx) || ~isreal(fx)
Error in ==> frequencies at 58
S(i,j)=fzero(#(w) subs(delta,'w',w),500);
Which is the same error as edio's I guess. And:
??? Error using ==> fzero at 307
FZERO cannot continue because user supplied function_handle ==> #(w)eval(delta)
failed with the error below.
Undefined function or method 'eval' for input arguments of type 'function_handle'.
Error in ==> frequencies at 59
S(i,j)=fzero(#(w)eval(delta),500);
Can you help me please?
Your problem appears to be that you are never evaluating your anonymous functions when you place them within other anonymous functions. For example, you define the function lambda as such:
lambda = #(w) ((16*rho(i)*A(i)*w^2*Lprime(i)^2)/(E(j)*I(i)))^0.25;
But when you use it in beta, you need to evaluate it using the input value for w, like so:
beta = #(w) lambda(w)*b(i)^0.5;
%# ^--------------Pass w to lambda to evaluate the function
As such, I believe your other anonymous functions should be defined as follows:
gamma = #(w) lambda(w)*Lprime(i)^0.5;
M2 = #(w) [besselj(4,beta(w)) bessely(4,beta(w)) besseli(4,beta(w)) ...
besselk(4,beta(w)); ...
besselj(3,beta(w)) bessely(3,beta(w)) besseli(3,beta(w)) ...
-besselk(3,beta(w)); ...
besselj(2,gamma(w)) bessely(2,gamma(w)) besseli(2,gamma(w)) ...
besselk(2,gamma(w)); ...
besselj(4,gamma(w)) bessely(4,gamma(w)) besseli(4,gamma(w)) ...
besselk(4,gamma(w))];
delta = #(w) det(M2(w));
A note about efficiency...
There is a GLARING efficiency problem I'm noticing here. By using anonymous functions instead of any other type of function (primary functions, nested functions, or subfunctions) you are going to end up evaluating the same function with the same input multiple times over.
For example, each time you evaluate M2 to create your matrix you will be evaluating both beta and gamma 8 times with the same input! Notice the improvement you could make by placing M2 in a function and passing as input w and the two function handles beta and gamma:
function newMatrix = M2(w,betaFcn,gammaFcn)
bw = betaFcn(w); %# Evaluate the beta function once
gw = gammaFcn(w); %# Evaluate the gamma function once
newMatrix = [besselj(4,bw) bessely(4,bw) besseli(4,bw) besselk(4,bw); ...
besselj(3,bw) bessely(3,bw) besseli(3,bw) -besselk(3,bw); ...
besselj(2,gw) bessely(2,gw) besseli(2,gw) besselk(2,gw); ...
besselj(4,gw) bessely(4,gw) besseli(4,gw) besselk(4,gw)];
end
And your new delta function would look like this:
delta = #(w) det(M2(w,beta,gamma));
Hi thank you very much for your help.
It works, but the last line has to change, obviously (it still took me 10 minuts for figure it out):
lambda= #(w) ((16*rho(i)*A(i)*w^2*Lprime(i)^2)/(E(j)*I(i)))^0.25;
beta=#(w) lambda(w)*b(i)^0.5;
gamma=#(w) lambda(w)*Lprime(i)^0.5;
M2=#(w) [besselj(4,beta(w)) bessely(4,beta(w)) besseli(4,beta(w)) besselk(4,beta(w));
besselj(3,beta(w)) bessely(3,beta(w)) besseli(3,beta(w)) -besselk(3,beta(w));
besselj(2,gamma(w)) bessely(2,gamma(w)) besseli(2,gamma(w)) besselk(2,gamma(w));
besselj(4,gamma(w)) bessely(4,gamma(w)) besseli(4,gamma(w)) besselk(4,gamma(w))];
delta = #(w) det(M2(w));
S(i,j)=fzero(#(w) delta(w),500);
And now it is really faster than before, in another case where the function solve could handle the resolution, it took like 10 seconds for each loop, now it's like 0.06 seconds
I will try your other solution to see the improvements.
Thank you a lot.