The Simpson's 1-3 (h / 3) method in Matlab - matlab

The C code that finds the following integral according to the Simpson's 1-3 (h / 3) method is given below. Fill in the blanks on the code appropriately.
I want to solve this question below in Matlab but i didn't do it. This is simple question but i can't do it. If someone will help me, i will be very happy.
C code version
[C code version2
I tried this code block in Matlab:
% Ask for user input
% Lower bound (a)
a = input('What is your lower bound (a)?')
% Upper bound (b)
b = input('What is your upper bound (b)?')
% Subintervals
N = input('How many subintervals (N)?')
% Defining function
f = #(x,e) (e*x+sin(x))
% Finding h
h=(b-a)/N;
% Finding the values of x for each interval
x=linspace(a,b,N);
% Calculating the integral
for i = 1:N-1
I(i)= (h/3)*(f(x(i))+(4*f((x(i)+x(i+1))/2))+f(x(i+1)));
end
answer1 = sum(I)
disp(I)
% adding f(b) to sum
val2=ff(length(xx));
sum=val1+val2+sum;% set sum
% set result
result=sum*h/3;

Note that MATLAB does not use the symbol e as Neperian Number (Euler's number). To produce Euler's number in MATLAB, you can use exponential function exp(x), e = exp(1),
Therefore, First, correct your function definition:
F = #(x) exp(1).^x + sin(x) % Always try to use Upper-Case letters for your variable/function name
Then, you can use the following snippet to calculate the Integral using Simpson's 1/3:
a = 0; b = 3; N = 1e4;
F = #(x) exp(1).^x + sin(x);
h = ((b-a)/2)/N;
x = linspace(a,b,N);
I = 0;
for i = 1:N-1
I = I + h/3*(F(x(i)) + 4*F((x(i)+x(i+1))/2) + F(x(i+1)));
end
disp(I)
% To compare your result:
Itz = trapz(x, F(x))

Related

How to plot and define with Matlab a function defined on different subintervals, which enters an ODE

I am trying to plot and then to use it with Matlab
in an ODE as coefficient, the function
f : [2,500] -> [0,1],
But I don't know how to write the code for the definition of the function, since it is given on different subintervals.
Below is an example that uses anonymous functions/function handles. It uses each region/condition and evaluates the boundaries numerically and stores them into variables Bounds_1 and Bounds_2. These boundaries are then used to truncate each signal by multiplying each section of the piecewise function by its corresponding condition which is a logical array. It's also good to note that this plot will almost be seen as an impulse since the bounds are really small. Alternatively, you can probably achieve the same results using the built-in piecewise() function but I think this method gives a little more insight. As i increases you'll see a plot that resembles more and more of an impulse. To plot this for multiple values or i this can be run in a for-loop.
clc;
i = 3;
Bounds_1 = [i - (1/i^2),i];
Bounds_2 = [i,i + (1/i^2)];
Bounds = [Bounds_1 Bounds_2];
Min = min(Bounds);
Max = max(Bounds);
f1 = #(x) (i^2.*x - i^3 + 1).*(Bounds_1(1) < x & x <= Bounds_1(2));
f2 = #(x) (-i^2.*x + i^3 + 1).*(Bounds_2(1) < x & x <= Bounds_2(2));
f = #(x) f1(x) + f2(x);
fplot(f);
xlim([Min-2 Max+2]);
ylim([0 1.1]);
Here is another solution. You can specify the steps along the x-axis withxstep. With xlower and xupper you can specify the range of the x-axis:
figure ; hold on;
xlabel('x'); ylabel('f(x)');
for i= 2:500
[f,x] = myfunction(0.5,i);
plot (x,f,'DisplayName',sprintf('%i',i));
end
% legend
function [f,x]=myfunction(xstep,i)
%xstep: specifies steps for the x values
% specify max range x \in = [xlower -> xupper]
xlower = -10;
xupper = 600;
x2 = (i-1/i^2): xstep: i;
f2 = i^2*x2 - i^3 + 1;
x3 = i+xstep:xstep:(1+1/i^2);
f3 = -i^2*x3 + i^3 +1;
x1 = xlower:xstep:(i-1/i^2);
f1 = 0*x1;
x4 = (i+1/i^2):xstep:xupper;
f4 = 0*x4;
f = [f1,f2,f3,f4];
x = [x1,x2,x3,x4];
end
Here is what I get
Besides, I am not exactly sure what you mean with ODE (ordinary differential equation) in f(x). For me it seems like an algebraic equation.

Why is my third MATLAB function outputing only zeros when using ode45?

I need to model negative, positive and simple regulation of a gene for my systems biology class using MATLAB. The problem is that the functions for negative and simple regulation work but the positive regulation function is only outputting zeros.
My script is as follows:
% Simulation of simple regulation, negative autoregulation and positive
% autoregulation
% Define constants
global a b K n
a = 1;
b = 1;
K = 0.5;
n = 2; % Hill coefficient
% Simulation time
tspan = [0,10];
% Initial condition
X0 = 0;
% Run simulations
[t1,X1] = ode45(#autoregulation_f0,tspan,X0); % Simple regulation
[t2,X2] = ode45(#autoregulation_f1,tspan,X0); % Negative autoregulation
[t3,X3] = ode23(#autoregulation_f2,tspan,X0); % Positive autoregulation
% Plot results
figure;
plot(t1,X1,t2,X2,t3,X3);
legend('simple','negative','Location','southeast');
And my functions are:
function dxdt = autoregulation_f0(t,X)
global a b
dxdt = b - a*X;
end
function dxdt = autoregulation_f1(t,X)
global a b K n
dxdt = b/(1+(X^n)/(K^n)) - a*X;
end
function dxdt = autoregulation_f2(t,X)
global a b K n
dxdt = b*X.^n./(K.^n+X.^n) + a*X;
end
The third function "autoregulation_f2(t,X)" is the one that outputs zeros and therefore when plotting the graph I just get a straight line.
Does anyone know what could be causing this?
Thanks in advance!
It looks to be the correct result for the given function. Your provided dxdt has an X in every term. The initial X0=0 will result in dxdt=0, giving you no change in X. As a result you just end up with a flat line.

Taylor Method ODE

I am trying to implement the Taylor method for ODEs in MatLab:
My code (so far) looks like this...
function [x,y] = TaylorEDO(f, a, b, n, y0)
% syms t
% x = sym('x(t)'); % x(t)
% f = (t^2)*x+x*(1-x);
h = (b - a)/n;
fprime = diff(f);
f2prime = diff(fprime);
y(0) = y0,
for i=1:n
T((i-1)*h, y(i-1), n) = double(f((i-1)*h, y(i-1)))+(h/2)*fprime((i-1)*h, y(i-1))
y(i+1) = w(i) + h*T(t(i), y(i), n);
I was trying to use symbolic variables, but I donĀ“t know if/when I have to use double.
I also tried this other code, which is from a Matlab function, but I do not understand how f should enter the code and how this df is calculated.
http://www.mathworks.com/matlabcentral/fileexchange/2181-numerical-methods-using-matlab-2e/content/edition2/matlab/chap_9/taylor.m
As error using the function from this link, I got:
>> taylor('f',0,2,0,20)
Error using feval
Undefined function 'df' for input arguments of type 'double'.
Error in TaylorEDO (line 28)
D = feval('df',tj,yj)
The f I used here was
syms t
x = sym('x(t)'); % x(t)
f = (t^2)*x+x*(1-x);
This is a numerical method, so it needs numerical functions. However, some of them are computed from the derivatives of the function f. For that, you need symbolic differentiation.
Relevant Matlab commands are symfun (create a symbolic function) and matlabFunction (convert a symbolic function to numerical).
The code you have so far doesn't seem salvageable. You need to start somewhere closer to basics, e.g., "Matlab indices begin at 1". So I'll fill the gap (computation of df) in the code you linked to. The comments should explain what is going on.
function [T,Y] = taylor(f,a,b,ya,m)
syms t y
dfs(1) = symfun(f, [t y]); % make sure that the function has 2 arguments, even if the user passes in something like 2*y
for k=1:3
dfs(k+1) = diff(dfs(k),t)+f*diff(dfs(k),y); % the idea of Taylor method: calculate the higher derivatives of solution from the ODE
end
df = matlabFunction(symfun(dfs,[t y])); % convert to numerical function; again, make sure it has two variables
h = (b - a)/m; % the rest is unchanged except one line
T = zeros(1,m+1);
Y = zeros(1,m+1);
T(1) = a;
Y(1) = ya;
for j=1:m
tj = T(j);
yj = Y(j);
D = df(tj,yj); % syntax change here; feval is unnecessary with the above approach to df
Y(j+1) = yj + h*(D(1)+h*(D(2)/2+h*(D(3)/6+h*D(4)/24)));
T(j+1) = a + h*j;
end
end
Example of usage:
syms t y
[T, Y] = taylor(t*y, 0, 1, 2, 100);
plot(T,Y)

Implement finite difference method in matlab

I am trying to implement the finite difference method in matlab. I did some calculations and I got that y(i) is a function of y(i-1) and y(i+1), when I know y(1) and y(n+1). However, I don't know how I can implement this so the values of y are updated the right way. I tried using 2 fors, but it's not going to work that way.
EDIT
This is the script and the result isn't right
n = 10;
m = n+1;
h = 1/m;
x = 0:h:1;
y = zeros(m+1,1);
y(1) = 4;
y(m+1) = 6;
s = y;
for i=2:m
y(i) = y(i-1)*(-1+(-2)*h)+h*h*x(i)*exp(2*x(i));
end
for i=m:-1:2
y(i) = (y(i) + (y(i+1)*(2*h-1)))/(3*h*h-2);
end
The equation is:
y''(x) - 4y'(x) + 3y(x) = x * e ^ (2x),
y(0) = 4,
y(1) = 6
Thanks.
Consider the following code. The central differential quotient is discretized.
% Second order diff. equ.
% y'' - 4*y' + 3*y = x*exp(2*x)
% (y(i+1)-2*y(i)+y(i-1))/h^2-4*(y(i+1)-y(i-1))/(2*h) + 3*y(i) = x(i)*exp(2*x(i));
The solution region is specified.
x = (0:0.01:1)'; % Solution region
h = min(diff(x)); % distance
As said in my comment, using this method, all points have to be solved simultaneously. Therefore, above numerical approximation of the equation is transformed in a linear system of euqations.
% System of equations
% Matrix of coefficients
A = zeros(length(x));
A(1,1) = 1; % known solu for first point
A(end,end) = 1; % known solu for last point
% y(i) y'' y
A(2:end-1,2:end-1) = A(2:end-1,2:end-1)+diag(repmat(-2/h^2+3,[length(x)-2 1]));
% y(i-1) y'' -4*y'
A(1:end-1,1:end-1) = A(1:end-1,1:end-1)+diag(repmat(1/h^2+4/(2*h),[length(x)-2 1]),-1);
% y(i+1) y'' -4*y'
A(2:end,2:end) = A(2:end,2:end)+diag(repmat(1/h^2-4/(2*h),[length(x)-2 1]),+1);
With the rhs of the differential equation. Note that the known values are calculated by 1 in the matrix and the actual value in the solution vector.
Y = x.*exp(2*x);
Y(1) = 4; % known solu for first point
Y(end) = 6; % known solu for last point
y = A\Y;
Having an equation to approximate the first order derivative (see above) you can verify the solution. (note, ddx2 is an own function)
f1 = ddx2(x,y); % first derivative (own function)
f2 = ddx2(x,f1); % second derivative (own function)
figure;
plot(x,y);
saveas(gcf,'solu1','png');
figure;
plot(x,f2-4*f1+3*y,x,x.*exp(2*x),'ko');
ylim([0 10]);
legend('lhs','rhs','Location','nw');
saveas(gcf,'solu2','png');
I hope the solution shown below is correct.

Using MATLAB to write a function that implements Newton's method in two dimensions

I am trying to write a function that implements Newton's method in two dimensions and whilst I have done this, I have to now adjust my script so that the input parameters of my function must be f(x) in a column vector, the Jacobian matrix of f(x), the initial guess x0 and the tolerance where the function f(x) and its Jacobian matrix are in separate .m files.
As an example of a script I wrote that implements Newton's method, I have:
n=0; %initialize iteration counter
eps=1; %initialize error
x=[1;1]; %set starting value
%Computation loop
while eps>1e-10&n<100
g=[x(1)^2+x(2)^3-1;x(1)^4-x(2)^4+x(1)*x(2)]; %g(x)
eps=abs(g(1))+abs(g(2)); %error
Jg=[2*x(1),3*x(2)^2;4*x(1)^3+x(2),-4*x(2)^3+x(1)]; %Jacobian
y=x-Jg\g; %iterate
x=y; %update x
n=n+1; %counter+1
end
n,x,eps %display end values
So with this script, I had implemented the function and the Jacobian matrix into the actual script and I am struggling to work out how I can actually create a script with the input parameters required.
Thanks!
If you don't mind, I'd like to restructure your code so that it is more dynamic and more user friendly to read.
Let's start with some preliminaries. If you want to make your script truly dynamic, then I would recommend that you use the Symbolic Math Toolbox. This way, you can use MATLAB to tackle derivatives of functions for you. You first need to use the syms command, followed by any variable you want. This tells MATLAB that you are now going to treat this variable as "symbolic" (i.e. not a constant). Let's start with some basics:
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
Because this is 2D, we're going to need 2D functions... so let's define x and y as variables. The way you call the subs command will be slightly different:
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
One more thing... we can place equations into vectors or matrices and use subs to simultaneously substitute all values of x and y into each equation.
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]
We can do the same thing for matrices, but for brevity I won't show you how to do that. I will defer to the code and you can see it then.
Now that we have that established, let's tackle your code one piece at a time to truly make this dynamic. Your function requires the initial guess x0, the function f(x) as a column vector, the Jacobian matrix as a 2 x 2 matrix and the tolerance tol.
Before you run your script, you will need to generate your parameters:
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;
Now, make your script into a function:
% 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');
I should probably tell you that when you're doing computation using the Symbolic Math Toolbox, the data type of the numbers as you're calculating them are a sym object. You probably want to convert these back into real numbers and so you can use double to cast them back. However, if you leave them in the sym format, it displays your numbers as neat fractions if that's what you're looking for. Cast to double if you want the decimal point representation.
Now when you run this function, it should give you what you're looking for. I have not tested this code, but I'm pretty sure this will work.
Happy to answer any more questions you may have. Hope this helps.
Cheers!