Simpson 1/3 rule - matlab

The solution of the problem it is 1.732400451459101 for Simpson 1/3 Rule. Instead the solution that the program give me is 1.73239801
Can anyone help me out? Thanks in advance.
clc
clear
close all
f = #(x) sin(x);
a = 0.1;
g = a;
b = 2.4;
k = 19;
n = 2*k;
S = 0;
h = (b-a)/n;
for i=1:k
S=S+(h/3)*(f(a)+4*f(a+h)+f(a+2*h));
a=a+2*h;
end
fprintf('La integral se aproxima a: %0.8f \n',S)
syms x
y = sin(x);
InT = int(y,g,b);
InT = double(InT)

The error in approximating an integral by Composite Simpson's rule is:
which is about 1.7149e-07 in f(x)=sin(x) case, and that means the absolute error bound is 9.8990e-08, which is palatable to me.
Besides, here is an alternative to the code above:
f = #(x) sin(x);
[a,b,g,k]=deal(0.1,2.4,0.1,19);
[S,n,h]=deal(0,2*k,(b-a)/(2*k));
for i=1:k
S=S+(h/3)*(f(g)+4*f(g+h)+f(g+2*h));
g=g+2*h;
end
Or, we could just call:
f = #(x) sin(x);
[a,b,k]=deal(0.1,2.4,19);
Int = a:(b-a)/(2*k):b;
S=(b-a)/(6*k) * ( f(Int(1)) + 4*sum(f(Int(2:2:end-1))) ...
+ 2*sum(f(Int(3:2:end-2))) + f(Int(end)));

Related

Find roots using fsolve

Basically I would like to use the fsolve command in order to find the roots of an equation.
I think I should create a function handle that evaluates this equation in the form "right hand side - left hand side =0", but I've been struggling to make this work. Does anyone know how to do this?
The equation itself is 1/sqrt(f) = -1.74log((1.254/((1.27310^8)sqrt(f)))+((110^-3)/3.708)). So I would like to find the point of intersection of the left and right side by solving for 1/sqrt(f)+(1.74log((1.254/((1.27310^8)sqrt(f)))+((110^-3)/3.708))) = 0 using fsolve.
Thanks a lot!
The code so far (not working at all)
f = #(x) friction(x,rho,mu,e,D,Q, tol, maxIter) ;
xguess = [0, 1];
sol = fsolve(x, xguess ) ;
function y = friction(x,rho,mu,e,D,Q, tol, maxIter)
D = 0.1;
L = 100
rho = 1000;
mu = 0.001;
e = 0.0001;
Q = 0.01;
U = (4*Q)/(pi*D^2);
Re = (rho*U*D)/mu ;
y = (1/sqrt(x))-(-1.74*log((1.254/(Re*sqrt(x)))+((e/D)/3.708)))
end
Error message:
Error using lsqfcnchk (line 80)
FUN must be a function, a valid character vector expression, or an inline function object.
Error in fsolve (line 238)
funfcn = lsqfcnchk(FUN,'fsolve',length(varargin),funValCheck,gradflag);
Error in Untitled (line 6)
sol = fsolve(x, xguess ) ;
opt = optimset('Display', 'Iter');
sol = fsolve(#(x) friction(x), 1, opt);
function y = friction(x)
D = 0.1;
L = 100; % note -- unused
rho = 1000;
mu = 0.001;
e = 0.0001;
Q = 0.01;
U = (4*Q)/(pi*D^2);
Re = (rho*U*D)/mu ;
y = (1/sqrt(x))-(-1.74*log((1.254/(Re*sqrt(x)))+((e/D)/3.708)));
end
sol = 0.0054
the first argument of fsolve should be the function not variable. Replace:
sol = fsolve(x, xguess );
with
sol = fsolve(f, xguess );
And define Rho, mu, e etc before you define f (not inside the friction function).

solve equation using MATLAB solve

I have the following equation that I want to solve using MATLAB:
X is the unknown variable. I am trying to solve it using MATLAB solve, but I find it hard to code the left part of the equation.
Is it possible to use solve? Are there any other options?
EDIT
Since A and B depends respectively on j and i I have tried to put them in vectors as follows:
A = [A(1) ... A(j) ... A(N)]
B = [B(1) ... B(i) ... B(N)]
I was trying to have something that looks like this:
eqn = sum(A ./ sum(B .* D)) == C;
solve(eqn);
but the whole difficulty is in this part:
because it depends on both i and j.
To write equation you can use this code:
syms x real
C = 1;
beta = 10;
alph = 0.5;
N = 10;
lenA = N;
lenB = N;
A = rand(1,N);
B = rand(1,N);
eq = 0;
for j=2:N
eqaux = 0;
for i=1:N
eqaux = eqaux+B(i)/((alph+beta*x)^(i+j+1));
end
eq = eq+A(j)/eqaux;
end
eq = simplify(eq==C);
If x must be a complex number, delete real of syms x real.
To solve the equation use this code:
sol = solve(eq,x);
sol = vpa(sol);
Of course yu must use your own values of C, alph, beta, A, B and N.

Using interpolation outside function definition in solution using Runge-Kutta 4th order

I have written MATLAB code to solve the following systems of differential equations.
with
where
and z2 = x2 + (1+a)x1
a = 2;
k = 1+a;
b = 3;
ca = 5;
cb = 2;
theta1t = 0:.1:10;
theta1 = ca*normpdf(theta1t-5);
theta2t = 0:.1:10;
theta2 = cb*ones(1,101);
h = 0.05;
t = 1:h:10;
y = zeros(2,length(t));
y(1,1) = 1; % <-- The initial value of y at time 1
y(2,1) = 0; % <-- The initial value of y' at time 1
f = #(t,y) [y(2)+interp1(theta1t,theta1,t,'spline')*y(1)*sin(y(2));
interp1(theta2t,theta2,t,'spline')*(y(2)^2)+y(1)-y(1)-y(1)-(1+a)*y(2)-k*(y(2)+(1+a)*y(1))];
for i=1:(length(t)-1) % At each step in the loop below, changed y(i) to y(:,i) to accommodate multi results
k1 = f( t(i) , y(:,i) );
k2 = f( t(i)+0.5*h, y(:,i)+0.5*h*k1);
k3 = f( t(i)+0.5*h, y(:,i)+0.5*h*k2);
k4 = f( t(i)+ h, y(:,i)+ h*k3);
y(:,i+1) = y(:,i) + (1/6)*(k1 + 2*k2 + 2*k3 + k4)*h;
end
plot(t,y(:,:),'r','LineWidth',2);
legend('RK4');
xlabel('Time')
ylabel('y')
Now what is want to do is define the interpolations/extrapolations outside the function definition like
theta1_interp = interp1(theta1t,theta1,t,'spline');
theta2_interp = interp1(theta2t,theta2,t,'spline');
f = #(t,y) [y(2)+theta1_interp*y(1)*sin(y(2));
theta2_interp*(y(2)^2)+y(1)-y(1)-y(1)-(1+a)*y(2)-k*(y(2)+(1+a)*y(1))];
But this gives the error
Please suggest a solution to this issue.
Note that in your original code:
f = #(t,y) [y(2)+interp1(theta1t,theta1,t,'spline')*y(1)*sin(y(2));
interp1(theta2t,theta2,t,'spline')*(y(2)^2)+y(1)-y(1)-y(1)-(1+a)*y(2)-k*(y(2)+(1+a)*y(1))];
the call to interp1 uses the input variable t. t inside this anonymous function is not the same as the t outside of it, where it is defined as a vector.
This means that, when you do
theta1_interp = interp1(theta1t,theta1,t,'spline');
then theta1_interp is a vector containing interpolated values for all your ts, not just one. One way around this is to create more anonymous functions:
theta1_interp = #(t) interp1(theta1t,theta1,t,'spline');
theta2_interp = #(t) interp1(theta2t,theta2,t,'spline');
f = #(t,y) [y(2)+theta1_interp(t)*y(1)*sin(y(2));
theta2_interp(t)*(y(2)^2)+y(1)-y(1)-y(1)-(1+a)*y(2)-k*(y(2)+(1+a)*y(1))];
Though this doesn't really improve your code in any way over the original.

Solving System of Second Order Ordinary Differential Equation in Matlab

Introduction
I am using Matlab to simulate some dynamic systems through numerically solving systems of Second Order Ordinary Differential Equations using ODE45. I found a great tutorial from Mathworks (link for tutorial at end) on how to do this.
In the tutorial the system of equations is explicit in x and y as shown below:
x''=-D(y) * x' * sqrt(x'^2 + y'^2)
y''=-D(y) * y' * sqrt(x'^2 + y'^2) + g(y)
Both equations above have form y'' = f(x, x', y, y')
Question
However, I am coming across systems of equations where the variables can not be solved for explicitly as shown in the example. For example one of the systems has the following set of 3 second order ordinary differential equations:
y double prime equation
y'' - .5*L*(x''*sin(x) + x'^2*cos(x) + (k/m)*y - g = 0
x double prime equation
.33*L^2*x'' - .5*L*y''sin(x) - .33*L^2*C*cos(x) + .5*g*L*sin(x) = 0
A single prime is first derivative
A double prime is second derivative
L, g, m, k, and C are given parameters.
How can Matlab be used to numerically solve a set of second order ordinary differential equations where second order can not be explicitly solved for?
Thanks!
Your second system has the form
a11*x'' + a12*y'' = f1(x,y,x',y')
a21*x'' + a22*y'' = f2(x,y,x',y')
which you can solve as a linear system
[x'', y''] = A\f
or in this case explicitly using Cramer's rule
x'' = ( a22*f1 - a12*f2 ) / (a11*a22 - a12*a21)
y'' accordingly.
I would strongly recommend leaving the intermediate variables in the code to reduce chances for typing errors and avoid multiple computation of the same expressions.
Code could look like this (untested)
function dz = odefunc(t,z)
x=z(1); dx=z(2); y=z(3); dy=z(4);
A = [ [-.5*L*sin(x), 1] ; [.33*L^2, -0.5*L*sin(x)] ]
b = [ [dx^2*cos(x) + (k/m)*y-g]; [-.33*L^2*C*cos(x) + .5*g*L*sin(x)] ]
d2 = A\b
dz = [ dx, d2(1), dy, d2(2) ]
end
Yes your method is correct!
I post the following code below:
%Rotating Pendulum Sym Main
clc
clear all;
%Define parameters
global M K L g C;
M = 1;
K = 25.6;
L = 1;
C = 1;
g = 9.8;
% define initial values for theta, thetad, del, deld
e_0 = 1;
ed_0 = 0;
theta_0 = 0;
thetad_0 = .5;
initialValues = [e_0, ed_0, theta_0, thetad_0];
% Set a timespan
t_initial = 0;
t_final = 36;
dt = .01;
N = (t_final - t_initial)/dt;
timeSpan = linspace(t_final, t_initial, N);
% Run ode45 to get z (theta, thetad, del, deld)
[t, z] = ode45(#RotSpngHndl, timeSpan, initialValues);
%initialize variables
e = zeros(N,1);
ed = zeros(N,1);
theta = zeros(N,1);
thetad = zeros(N,1);
T = zeros(N,1);
V = zeros(N,1);
x = zeros(N,1);
y = zeros(N,1);
for i = 1:N
e(i) = z(i, 1);
ed(i) = z(i, 2);
theta(i) = z(i, 3);
thetad(i) = z(i, 4);
T(i) = .5*M*(ed(i)^2 + (1/3)*L^2*C*sin(theta(i)) + (1/3)*L^2*thetad(i)^2 - L*ed(i)*thetad(i)*sin(theta(i)));
V(i) = -M*g*(e(i) + .5*L*cos(theta(i)));
E(i) = T(i) + V(i);
end
figure(1)
plot(t, T,'r');
hold on;
plot(t, V,'b');
plot(t,E,'y');
title('Energy');
xlabel('time(sec)');
legend('Kinetic Energy', 'Potential Energy', 'Total Energy');
Here is function handle file for ode45:
function dz = RotSpngHndl(~, z)
% Define Global Parameters
global M K L g C
A = [1, -.5*L*sin(z(3));
-.5*L*sin(z(3)), (1/3)*L^2];
b = [.5*L*z(4)^2*cos(z(3)) - (K/M)*z(1) + g;
(1/3)*L^2*C*cos(z(3)) + .5*g*L*sin(z(3))];
X = A\b;
% return column vector [ed; edd; ed; edd]
dz = [z(2);
X(1);
z(4);
X(2)];

MATLAB sparse matrices: Gauss Seidel and power method using a sparse matrix with CSR (Compressed Sparse Row)

this is my first time here so I hope that someone can help me.
I'm trying to implementing the Gauss-Seidel method and the power method using a matrix with the storage CSR or called Morse storage. Unfortunately I can't manage to do better then the following codes:
GS-MORSE:
function [y] = gs_morse(aa, diag, col, row, nmax, tol)
[n, n] = size(A);
y = [1, 1, 1, 1];
m = 1;
while m < nmax,
for i = 1: n,
k1 = row(i);
k2 = row(i + 1) - 1;
for k = k1: k2,
y(i) = y(i) + aa(k) * x(col(k));
y(col(k)) = y(col(k)) + aa(k) * diag(i);
end
k2 = k2 + 1;
y(i) = y(i) + aa(k) * diag(i);
end
if (norm(y - x)) < tol
disp(y);
end
m = m + 1;
for i = 1: n,
x(i) = y(i);
end
end
POWER-MORSE:
I was able only to implement the power method but I don't understand how to use the former matrix... so my code for power method is:
function [y, l] = potencia_iterada(A, v)
numiter=100;
eps=1e-10;
x = v(:);
y = x/norm(x);
l = 0;
for k = 1: numiter,
x = A * y;
y = x / norm(x);
l0 = x.' * y;
if abs(l0) < eps
return
end
l = l0;
end
Please anyone can help me for completing these codes or can explain me how can I do that? I really don't understand how to do. Thank you very much