Falsi method algorithm - matlab

I wrote a falsi method code and I got problem with fa function. My general function is in interval [a,b]=[2,12], as I defined in main script:
a=2;
b=12;
%Function
syms x real;
f=1.2*sin(x)+2*log(x+2)-5;
I wonder how to correctly pass argument a to the function fa and, in general, to falsi method function . I guess, it cannot be just '2', it must be dynamic somehow. Thanks for tips ! :)
function [ x ] = task1_falsi( f, x, a)
% Defining functions
a=2;
fa=feval(f,a);
f=inline(f);
fa=inline(fa);
err=1;
% Falsi's loop.
% Stops when error is negligible or number of iterations becomes prohibitive
it=0;
while (it<1000) && (err>10e-5)
% Falsi's algorithm
x1=x-feval(f,x)*(x-a)/fa;
% Calculating error
err=abs(x1-x);
% New zero is previous value
x=x1;
it=it+1;
%Showing steps
fprintf('%d\t%f \n',it, x);
end
disp('Root:');
disp(x);
disp('Iterations:');
disp(it);
end

%Task 1
% Falsi's method algorithm
function [ x ] = task1_falsi( f, x)
err=1;
y = 7; % Starting point
z = 8;
f=inline(f);
% Ending point
maxIteration = 1000; % Maximum number of iterations
epsilon = 0.001; % Accuracy
it=0; % Vector with number of iterations
xold = z; % Variable used for calculations
solutionRegulaFalsix=zeros(10,1); % Error vector
for j=0:20
while (it <= maxIteration)
x1 = y - ((feval(f,y)*(z-y))/(feval(f,z)-feval(f,y))); % Calculating the root
it= it+ 1;
if (abs(x1-xold)<epsilon*abs(x1)) % Accuracy condition
break;
else
xold = x1;
if feval(f,y)*feval(f,z) > 0
y = x1; % Starting point is being changed
else
z = x1; % Ending point is being changed
end
end
end
err = abs(x1-x); % Calculating the error
% epsilon = epsilon/10;
%Showing steps
fprintf('%d\t%f \n',it, x);
y=2;
z=3;
disp('Root:');
disp(x1);
disp('Iterations:');
disp(it);
end
end

Related

Linear Congruential generator graph

I implemented a simple code for a linear congruential generator
clear all; clc
% Input
m = 59; % module
a = 17; % multiplier
c = 43; % increase
X0 = 27; % seed
n = 100; % sample length
y = [X0 zeros(1,n-1)];
% recursive formula
% X(n+1) = (a*X(n) + c) mod m
for i = 2:n
y(i) = mod(a*y(i-1)+c,m);
end
x = 0:1:n-1;
%for i = 1:n
% plot(x,y);
%end
What I would like to do is a plot where each time the period repeats it draws a vertical line upward as in this graph
I think I have to use the plot function inside a FOR loop and an IF-ELSE to see if the value of the subsequence X(n) is equal to the seed X(0) but I have no idea how to implement it
I think I have to use the plot function inside a FOR loop and an IF-ELSE to see if the value of the subsequence X(n) is equal to the seed X(0) but I have no idea how to implement it

Matlab can't solve the collocation equations. Encountered a singular jacobian

function bvp()
solinit = bvpinit(linspace(0,1,10),[0, 0.3, 0, 0.5]);
sol = bvp4c(#myprojec,#mybounds, solinit);
plot(sol.x,sol.y(1,:),'.');
%Hold on can be used to suspend the graph so as to plot another graph on
%the same axis with different parameters
xlabel('\c');
ylabel('\theta');
function dydx = myprojec(x,y)
% enter the parameter
% x represents c
% y(i) represents f,theta
% f = y(1), f' = y(2), theta = y(4), theta' = y(5)
% star (*) replaced by 0
% infinity =5
% Max infinity = 10
% B = input('input the value of Beta:');
B = 5;
% M = input('input the value of M:');
M = 1;
% Km = input('input the value of Km:');
Km = 1.5;
% Br = input ('input the value of Br:');
Br = 12;
dydx=[ y(2);(B^2-M)*y(1)-Km;y(4);Br*((M- B^2)*y(1)-y(2)^2)];
% Now d bcs
function res = mybounds(ya,yb)
% where to denote initial values of y at zero(0)
% finf denotes initial vlue of y at infinity (5 or 10)
% n = input('input the value of n:');
res = [ya(1)
yb(1)-1
ya(4)
yb(4)-(1)];
The error I got is that Matlab cannot solve the collocation equations. A singular Jacobian encountered. I would appreciate your suggestions.

MATLAB Simpson's 1/3 Rule and Romberg

I'm just starting to learn MATLAB.
The purpose of the exercise is to approximate/integrate using Simpson's 1/3 rule and romberg. The problem is to integrate x^(1/2) from 0 to 2
When I execute: simpson(fun,0,2,10)
I get an error on line 2: fun = x^(1/2);
or on line 16 of simpson: f = feval(fun,x);
Thanks for the help!
Here is my equation code:
function [fun] = ff(x)
fun = x^(1/2);
end
My simpson code:
function I = simpson(fun,a,b,npanel)
% Multiple Segment Simpson's rule
%
% Synopsis: I = simpson(fun,a,b,npanel)
%
% Input: fun = (string) name of m-file that evaluates f(x)
% a, b = lower and upper limits of the integral
% npanel = number of panels to use in the integration
% Total number of nodes = 2*npanel + 1
%
% Output: I = approximate value of the integral from a to b of f(x)*dx
n = 2*npanel + 1; % total number of nodes
h = (b-a)/(n-1); % stepsize
x = a:h:b; % divide the interval
f = feval(fun,x); % evaluate integrand
I = (h/3)*( f(1) + 4*sum(f(2:2:n-1)) + 2*sum(f(3:2:n-2)) + f(n) );
% f(a) f_even f_odd f(b)
My romberg code:
function [R,quad,err,h]=romberg(fun,a,b,n,tol)
%Input - fun is the integrand input as a string 'fun'
% - a and b are upper and lower limits of integration
% - n is the maximum number of rows in the table
% - tol is the tolerance
%Output - R is the Romberg table
% - quad is the quadrature value
% - err is the error estimate
% - h is the smallest step size used
M=1;
h=b-a;
err=1;
J=0;
R=zeros(4,4);
R(1,1)=h*(feval(fun,a)+feval(fun,b))/2;
while((err>tol)&(J<n))|(J<4)
J=J+1;
h=h/2;
s=0;
for p=1:M
x=a+h*(2*p-1);
s=s+feval(fun,x);
end
R(J+1,1)=R(J,1)/2+h*s;
M=2*M;
for K=1:J
R(J+1,K+1)=R(J+1,K)+(R(J+1,K)-R(J,K))/(4^K-1);
end
err=abs(R(J,J)-R(J+1,K+1));
end
quad=R(J+1,J+1);

How to debug this Matlab code to model glider descent?

I have this Matlab project but for some reason I just cannot stop thinking about it because I could not get it to work.
Objective:
This is a MATLAB script that would calculate the change of pressure, temperature and density of a glider that is being dropped from 10000 feet. As it falls, we want to use those new values calculated and then plugged in a function that has 4 equations that need to be differentiated at every point using ode45 as well as the new values of P T and Rho.
Here is the main code:
% HouseKeeping:
clc
clear all
close all
% Constants:
S = 232; % ft^2
Cd0 = 0.02;
K = 0.07;
W = 11000; % lbf
Cl_max = sqrt(Cd0/K);
Cd_max = 2*K*Cl_max^2;
Rho_10000 = .001756; % slugs/ ft^3
%Initial conditions:
t = 0; % Sec
x = 0; % ft
h = 10000; % ft
v = sqrt((2*W)/(Rho_10000*S*Cl_max)); %ft/s
gamma = -Cd_max/Cl_max;
% Find Endurance:
V_RD= sqrt((2*W)/(S* Rho_10000* sqrt(3*Cd0/K)));
RD= V_RD/((sqrt(3*Cd0/K))/(2*Cd0)) ; % ft/s
Endurcance= h/RD; % 958.3515 sec
% Sea Level values:
TSL = 518.69; % Rankine
PSL = 2116.199414; % lbs/ft^2
RhoSL = 0.0023769; % slugs/ft^3
while h > 0
tspan = [t t+1];
i=1;
X = [x;h;v;gamma;Rho_10000];
Time(i)= t;
% Calling ODE45:
[F] = ode45(# D,tspan, X)
% Hight Varying Parameters:
T = TSL - 0.00356616*h;
P = (1.137193514E-11)*(T)^5.2560613;
Rho = (RhoSL * TSL / PASL)*(P / T);
a = 49.0214 * (T)^.5;
H_Del(i) = (-Cd_max/Cl_max)*(plotted_x(i))+10000;
V_Del(i) = sqrt((2*W)/(Rho*S*Cl_max));
Gamma_Del(i) = -Cd_max/Cl_max;
i= i+1;
X = [ x ; H_Del(i); V_Del(i); Gamma_Del(i); Rho];
end
% Plots:
%1
figure (1)
plot(F(:,1),'-r',F(:,3),'-b')
title('Velocity vs Distance');
xlabel('x (ft)');
ylabel('v (ft/s)');
%2
Figure (2)
plot(F(:,1),'-r',F(:,2),'-b')
title('Altitude vs Distance ');
xlabel('x (ft)');
ylabel('h (ft)');
%3
figure (3)
plot(F(:,1),'-r',F(:,4),'-b')
title('Gamma vs Distance');
xlabel('x (ft)');
ylabel('Gamma (rad)');
%4
figure (4)
plot(t,'-r',F(:,3),'-b')
title('Velocity vs Time');
xlabel(' t (s)');
ylabel('v (ft/s)');
%5
figure (5)
plot(t,'-r',F(:,1),'-b')
title(' Distance vs Time ');
xlabel('t (s)');
ylabel('x (ft)');
%6
figure (6)
plot(t,'-r',F(:,4),'-b')
title('Gamma vs Time ');
xlabel('t (s)');
ylabel('Gamma (rad)');
%7
figure (7)
plot(t,'-r',F(:,3),'-b')
title('Velocity vs Time');
xlabel('t (s)');
ylabel('V (ft/s)');
Here is the Function
function [F] = D(X)
% Constants:
S = 232; % ft^2
Cd0 = 0.02;
K = 0.07;
W = 11000; % lbf
Cl_max = sqrt(Cd0/K);
Cd_max = 2*K*Cl_max^2;
Rho_10000 = .001756; % slugs/ ft^3
% Initial conditions:
t = 0; % Sec
x = 0; % ft
h = 10000; % ft
v = sqrt((2*W)/(Rho_10000*S*Cl_max)); % ft/s
gamma = -Cd_max/Cl_max;
g= 32.2; % ft/s^2
% Equations:
X_Pr = X(3)*cos(X(4));
H_Pr = X(3)*sin(X(4));
V_Pr = (-32.2./W)*(0.5*X(5)*Cd_max*S*X(3)^2 + W*sin(X(4)));
G_Pr = (32.2./(W*X(3)))*(0.5*X(5)*Cl_max*S*X(3)^2 - W*cos(X(4)));
F = [X_Pr;H_Pr;V_Pr;G_Pr];
I am not very good with Matlab but I did my very best! I went to my professors for help but they said they were too busy. I even stalked every senior I knew and they all said they did not know how to do it. My next project will be assigned soon and I think that if I cannot do this then I would not be able to do the next one.
Your code produces the following error:
Error using main>D
Too many input arguments.
This means that ode45 tries to call your provided function D with too many input arguments. You should check the desired odefun format in the ode45 documentation: dydt = odefun(t,y)
So, you should change your function declaration of D to
function [F] = D(t, X)
This should solve your first problem, but a following error pops up:
D returns a vector of length 4, but the length of initial conditions
vector is 5. The vector returned by D and the initial conditions
vector must have the same number of elements.
Again, you should check the ode45 documentation. Your function should return the derivatives of all your input variables X: F = dX/dt. You should also return the derivate of the fifth element Rho_10000.
Next, I got some error about undefined variables such as PASL. Probably because you did not post your full code.
Besides of the errors, you should really check your code again. You have written an infinite while loop while h > 0. You never change h in the loop, nor you use the output of ode45 in your loop. Furthermore you always overwrite your i and X value at the beginning of the loop, which is probably not what you want.
This is not a full answer to your question, but I hope you will be able to continue and post smaller, well defined problems, instead of one big problem which is very difficult to answer completely.

Finite difference - wave equation - boundary conditions and setting things up

I am working on a project that has to do with solving the wave equation in 2D (x, y, t) numericaly using the central difference approximation in MATLAB with the following boundary conditions:
The general assembly formula is:
I understand some of the boundary conditions (BC), like
du/dy=0 at j=m,
,
but I am not sure how to implement these boundary conditions in MATLAB.
A friend has given me these equations:
Here is my try with the MATLAB code,
but I am not able to progress any further:
% The wave function
% Explicit
% Universal boundary conditions for all 3 cases:
% u=0 at t=0
% du/dt=0 at t=0
% Case 1 boundary conditions
% At x=0, u=2sin(2*pi*t/5);
% At y=0, du/dy=0;
% At y=2, du/dy=0;
% At x=5, du/dx=0;
% u=0 and du/dt=0 at t=0;
%-------------------------------------------------------------------------%
% Setting up
clc; clear all; close all;
% length, time, height
L = 5; % [m]
h = 2; % [m]
T = 10; % [s]
% Constants
c_x = 1; % arbitrary
c_y = 1; % arbitrary
dx = 0.1; % <x> increment
dy = 0.1; % <y> increment
dt = 0.1; % time increment
nx = L/dx + 1; % number of <x> samples
ny = h/dy + 1; % number of <y> samples
nt = T/dt + 1; % number of time samples
t(:,1) = linspace(0, T, nt);
theta_x = c_x*(dt^2)/(dx^2);
theta_y = c_y*(dt^2)/(dy^2);
% theta_x = theta_y
theta = theta_x;
%-------------------------------------------------------------------------%
% The matrix
U = zeros(nt, nx, ny);
% Setting up the <U> matrix with the boundary conditions - case 1
U(1, :, :) = 0; % U=0 at t=0
for tt=1:nt % U=2sin(2pi/5*t) at x=0
for jj=1:ny
U(tt, 1, jj)=2*sin(2*pi/5.*t(tt));
end
end
for it=2:t
for ix=2:nx-1
for iy=2:ny-1
% Boundary conditions
% General case (internal):
U1 = -U(it-1, ix, iy);
U2 = 2*(1-2*theta)*u(it, ix, iy);
U3 = theta*U(it, ix-1, iy);
U4 = theta*U(it, ix+1, iy);
U5 = theta*U(it, ix, iy-1);
U6 = theta*U(it, ix, iy+1);
end
end
end
The general assembly formula you have kind of applies to the boundaries as well.
The complication is that when you apply the formula when j = 1 and j = m, you have j = 0 and j = m+1 term that are off of your grid.
To ameliorate this problem, boundary conditions give you a relationship between the points off the grid and on the grid.
As you have indicated, the dudy = 0 condition has given you the relation that u(i,m-1) == u(u,m+1) on the boundary. So you use the general assembly formula and replace all of the m+1 terms with m-1 on the boundary. You'll have a similar relation for the lower boundary as well.