Runge-Kutta Method using matlab - matlab

eaxmple first-order derivative using matlab.if we did for second-order derivative,How does this code change?
% y'=(x+2)/y y(0)=1
% y=sqrt(x^2+4*x+1)
clear all
x(1)=0;
ry(1)=1;
dx=0.1;
for i=1:100
k1=(x(i)+2)/ry(i);
k2=(x(i)+dx/2+2)/(ry(i)+dx/2*k1);
k3=(x(i)+dx/2+2)/(ry(i)+dx/2*k2);
k4=(x(i)+dx+2)/(ry(i)+dx*k3);
ry(i+1)=ry(i)+dx*(k1+2*k2+2*k3+k4)/6;
x(i+1)=x(i)+dx;
end
y=sqrt(x.^2+4*x+1);
plot(x,y,'r-',x,ey,'b-',x,hy,'y-',x,ry,'g-');

maybe this code help you if this is your topic and problem, it is runge kutta code for solving second order derivative problems,this belong to 2 years ago and i wrote it by some help.this problem is defined in the book i said in the last answer.
syms x y1 y2
f=input('input function like:D2y=(-0.1*y2)-x, y1 & y2 subtitute as y & Dy respectively and do not type D2y in front of f input');
f=inline(f);
g=inline(y2);
a1=0;
b1=1;
x1=0;
h=0.5;
n=4;
A=zeros(n,3);
A(1,1)=0;
A(1,2)=a1;
A(1,3)=b1;
for i=1:n
%%%%%%%%%%%%%%k1
F1 = h*(subs(g,[x,y1,y2],[x1,a1,b1]));
F2 = h*(subs(f,[x,y1,y2],[x1,a1,b1]));
W1=F1;
W2=F2;
%%%%%%%%%%%%%%%%k2
a2=a1 + (F1/2);
b2=b1 + (F2/2);
x2= x1 + h/2;
F1 = h*(subs(g,[x,y1,y2],[x2,a2,b2]));
F2 = h*(subs(f,[x,y1,y2],[x2,a2,b2]));
W1= W1+ (2*F1);
W2= W2+ (2*F2);
%%%%%%%%%%%%%%%k3
a3=a1 + (F1/2);
b3=b1 + (F2/2);
x3=x1 + h/2;
F1 = h*(subs(g,[x,y1,y2],[x3,a3,b3]));
F2 = h*(subs(f,[x,y1,y2],[x3,a3,b3]));
W1= W1+ (2*F1);
W2= W2+ (2*F2);
%%%%%%%%%%%%$$k4
a4=a1 + (F1);
b4=b1 + (F2);
x4=x1 + h;
F1 =h*(subs(g,[x,y1,y2],[x4,a4,b4]));
F2 = h*(subs(f,[x,y1,y2],[x4,a4,b4]));
W1= W1+ (F1);
W2= W2+ (F2);
%%%%%%%%%%%%%%%%
W1 = (W1/6);
W2 = (W2/6);
a1=a1+ W1;
b1=b1+ W2;
x1=x1 + h;
A(i+1,1)=x1;
A(i+1,2)=a1;
A(i+1,3)=b1;
end
fprintf('y(2) of runge kutta: %15.14f\n',A(n+1,2));
fprintf('Dy(2)of runge kutta: %15.14f\n',A(n+1,3));

Related

ODE solver using Lobatto IIIA with table of coefficients

So I'm trying to figure out how to solve a given equation y'=-y+2te^(-t+2) for t in [0,10], step of 0.01 and y(0)=0.
I am supposed to solve it using the Lobatto IIIA method following a Butcher tableau:
Coefficients table
So far, this is what I got:
function lob = Lobatto_solver()
h = 0.01;
t = 0:h:10;
y = zeros(size(t));
y(1) = 0;
f = #(t,y) -y + (2*t*(exp(-t+2)));
% Lobatto IIIA Method
for i=1:numel(y)-1
f1 = f(t(i), y(i));
f2 = f(t(i)+(1/2)*h, y(i) + (5/24)*h*f1 + (1/3)*h*f2 + (-1/24)*h*f3);
f3 = f(t(i)+h, y(i) + (1/6)*h*f1 + (2/3)*h*f2 + (1/6)*h*f3);
y(x) = y(i) + h*((-1/2)*f1 + (2)*f2 + (-1/2)*f3);
end
end
It obviously makes no sense from the point when I equal f2 to itself, when the variable is still undefined.
Any help would be much appreciated :)
Cheers
You will need a predictor-corrector loop, in the simple case the corrector uses the slope-equations as basis of a fixed-point iteration. In the code below I use also the value of an explicit Euler step, in principle you could initialize all slopes with f1.
function lob = Lobatto_solver()
h = 0.01;
t = 0:h:10;
y = zeros(size(t));
y(1) = 0;
f = #(t,y) -y + (2*t*(exp(-t+2)));
% Lobatto IIIA Method
for i=1:numel(y)-1
f1 = f(t(i), y(i));
f3 = f(t(i)+h, y(i)+h*f1)
f2 = (f1+f3)/2;
for k=1:3
f2 = f(t(i)+(1/2)*h, y(i) + (5/24)*h*f1 + (1/3)*h*f2 + (-1/24)*h*f3);
f3 = f(t(i)+h, y(i) + (1/6)*h*f1 + (2/3)*h*f2 + (1/6)*h*f3);
end;
y(i+1) = y(i) + h*((-1/2)*f1 + (2)*f2 + (-1/2)*f3);
end
plot(t,y,t,0.05+t.^2.*exp(-t+2))
end
The graph shows that the result (blue) is qualitatively correct, the exact solution curve (green) is shifted so that two distinct curves can be seen.

Solving ODEs in MATLAB using the Runga - Kutta Method

I am required to solve these particular ODEs using numerical methods in MATLAB. The ODEs essentially model the fall of a body of mass m, connected to a piece of elastic with spring constant k. The solutions to these ODEs are to represent the body's position and velocity at discrete positions in time.
The parameters for the ODEs are,
H = 74
D = 31
c = 0.9
m = 80
L = 25
k = 90
g = 9.8
C = c/m
K = k/m
T = 60
n = 10000
I've implemented the following two methods; Euler and Fourth Order Runge -
Kutta to approximate the solutions over the interval [0, 60].
Here is my Runge Kutta function,
function [t, y, v, h] = rk4_approx(T, n, g, C, K, L)
%% calculates interval width h for each iteration
h = (T / n);
%% creates time array t
t = 0:h:T;
%% initialises arrays y and v to hold solutions
y = zeros(1,n+1);
v = zeros(1,n+1);
%% functions
z = #(v) v;
q = #(v, y) (g - C*abs(v)*v - max(0, K*(y - L)));
%% initial values
v(1) = 0;
y(1) = 0;
%% performs iterations
for j = 1:n
%% jumper's position at each time-step
r1 = h*z(v(j));
r2 = h*z(v(j) + 0.5*h);
r3 = h*z(v(j) + 0.5*h);
r4 = h*z(v(j) + h);
y(j+1) = y(j) + (1/6)*(r1 + 2*r2 + 2*r3 + r4); %position solution
%% jumper's velocity at each time-step
k1 = h*q(v(j), y(j));
k2 = h*q(v(j) + 0.5*h, y(j) + 0.5*k1);
k3 = h*q(v(j) + 0.5*h, y(j) + 0.5*k2);
k4 = h*q(v(j) + h, y(j) + k3);
v(j+1) = v(j) + (1/6)*(k1 + 2*k2 + 2*k3 + k4); %velocity solution
end
end
Here is my Euler function,
function [t, y, v, h] = euler_approx(T, n, g, C, K, L)
% calculates interval width h
h = T / n;
% creates time array t
t = 0:h:T;
% initialise solution arrays y and v
y = zeros(1,n+1);
v = zeros(1,n+1);
% perform iterations
for j = 1:n
y(j+1) = y(j) + h*v(j);
v(j+1) = v(j) + h*(g - C*abs(v(j))*v(j) - max(0, K*(y(j) - L)));
end
end
However, after varying the parameter 'n' (where n is the number of 'steps' in the iteration) it appears the Euler solution for the position of the body converges to the maximum value of approximately y = 50 faster then the Runge - Kutta solution does. Since this ODE does not have a closed solution I have nothing to compare my answer to. I suspect the answer to be y = 50 though.
Therefore, I'm doubting my answer.
Is my code for the Runge - Kutta solution incorrect? Should it not converge faster than the Euler solution?
Sorry for my poor formatting.
The Runge-Kutta integration is incorrect.
It is vital to appreciate the difference between independent and dependent (also called state and a host of other names) variables. Time is the independent variable in this problem. Given a time, you can provide a height and a velocity; the reverse is not uniquely true. When you read a Runge-Kutta formula, such as the one provided by Wikipedia, t is the independent variable and y is vector of dependent variables. Also, when performing time integration of systems of equations (here we have a system of two equations), it is very important to keep track of which right-hand side belongs to which equation if you are going to perform the march element-wise, which I will do for simplicity.
All that said, the problem with the current RK integrator is two-fold
v is being stepped as if it were t; this is incorrect. Both v and y are stepped similarly.
y should be stepped with the r variables since the r variables come from y's right-hand side equation z. Similarly, v is stepped with the k variables.
The updated core of the integrator is thus:
r1 = h*z(v(j));
k1 = h*q(v(j), y(j));
r2 = h*z(v(j) + 0.5*k1);
k2 = h*q(v(j) + 0.5*k1, y(j) + 0.5*r1);
r3 = h*z(v(j) + 0.5*k2);
k3 = h*q(v(j) + 0.5*k2, y(j) + 0.5*r2);
r4 = h*z(v(j) + k3);
k4 = h*q(v(j) + k3, y(j) + r3);
y(j+1) = y(j) + (1/6)*(r1 + 2*r2 + 2*r3 + r4); %position solution
v(j+1) = v(j) + (1/6)*(k1 + 2*k2 + 2*k3 + k4); %velocity solution
Notice how both v and y are updated in a similar fashion and, therefore, are required to be updated in lock-step with one another. This form of the integrator will give far better performance than Euler.
Finally, if in doubt in the future about a solution you don't know, always remember you have the MATLAB ODE suite at your disposal, and a quick call to the extensively vetted and very robust ode45 can relieve a lot of concerns. I actually used this call
[t45,w45] = ode45(#(t,w) [z(w(2));q(w(2),w(1))],linspace(0,T,200).',[0;0]);
to check my work.

Solve a system of equations with Runge Kutta 4: Matlab

I want to solve a system of THREE differential equations with the Runge Kutta 4 method in Matlab (Ode45 is not permitted).
After a long time spent looking, all I have been able to find online are either unintelligible examples or general explanations that do not include examples at all. I would like a concrete example on how to implement my solution properly, or the solution to a comparable problem which I can build on.
I have come quite far; my current code spits out a matrix with 2 correct decimals on most of the components, which I am quite happy with.
However, when the step-size is decreased, the errors become enormous. I know the for-loop I have created is not entirely correct. I may have defined the functions incorrectly, but I am quite certain that the problem is solved if some minor changes are made to the for-loop because it appears to be solving the equation-system fairly well already in its current state.
clear all, close all, clc
%{
____________________TASK:______________________
Solve the system of differential equations below
in the interval 0<t<1, with stepsize h = 0.1.
x'= y x(0)=1
y'= -x-2e^t+1 y(0)=0 , where x=x(t), y=y(t), z=z(t)
z'= -x - e^t + 1 z(0)=1
THE EXACT SOLUTIONS for x y and z can be found in this pdf:
archives.math.utk.edu/ICTCM/VOL16/C029/paper.pdf
_______________________________________________
%}
h = 0.1;
t = 0:h:1
N = length(t);
%Defining the functions
x = zeros(N,1);%I am not entierly sure if x y z are supposed to be defined in this way.
y = zeros(N,1)
z = zeros(N,1)
f = #(t, x, y, z) -x-2*exp(t)+1;%Question: Do i need a function for x here as well??
g = #(t, x, y, z) -x - exp(t) + 1;
%Starting conditions
x(1) = 1;
y(1) = 0;
z(1) = 1;
for i = 1:(N-1)
K1 = h * ( y(i));%____I think z(i) is supposed to be here, but i dont know in what way.
L1 = h * f( t(i) , x(i) , y(i) , z(i));
M1 = h * g( t(i) , x(i) , y(i) , z(i));
K2 = h * (y(i) + 1/2*L1 + 1/2*M1);%____Again, z(i) should probably be here somewhere.
L2 = h * f(t(i) + 1/2*h, x(i)+1/2*K1 , y(i)+1/2*L1 , z(i)+1/2*M1);
M2 = h * g(t(i) + 1/2*h, x(i)+1/2*K1 , y(i)+1/2*L1 , z(i)+1/2*M1);
K3 = h * (y(i) + 1/2*L2 + 1/2*M2);%____z(i). Should it just be added, like "+z(i)" ?
L3 = h * f(t(i) + 1/2*h, x(i) + 1/2*K2 , y(i) + 1/2*L2 , z(i) + 1/2*M2);
M3 = h * g(t(i) + 1/2*h, x(i) + 1/2*K2 , y(i) + 1/2*L2 , z(i) + 1/2*M2);
K4 = h * (y(i) + L3 + M3);%_____z(i) ... ?
L4 = h * f( t(i)+h , x(i)+K3 , y(i)+L3, z(i)+M3);
M4 = h * g( t(i)+h , x(i)+K3 , y(i)+L3, z(i)+M3);
x(i+1) = x(i)+1/6*(K1+2*K2+2*K3+K4);
y(i+1) = y(i)+1/6*(L1+2*L2+2*L3+L4);
z(i+1) = z(i)+1/6*(M1+2*M2+2*M3+M4);
end
Answer_Matrix = [t' x y z]
So your main issue was not defining x properly. You were propagating its value using the Runge Kutta 4 (RK4) method, but never actually defined what its derivative was!
At the bottom of this answer is a function which can take any given number of equations and their initial conditions. This has been included to address your need for a clear example for three (or more) equations.
For reference, the equations can be directly lifted from the standard RK4 method described here.
Working Script
This is comparable to yours, but uses slightly clearer naming conventions and structure.
% Initialise step-size variables
h = 0.1;
t = (0:h:1)';
N = length(t);
% Initialise vectors
x = zeros(N,1); y = zeros(N,1); z = zeros(N,1);
% Starting conditions
x(1) = 1; y(1) = 0; z(1) = 1;
% Initialise derivative functions
dx = #(t, x, y, z) y; % dx = x' = dx/dt
dy = #(t, x, y, z) - x -2*exp(t) + 1; % dy = y' = dy/dt
dz = #(t, x, y, z) - x - exp(t) + 1; % dz = z' = dz/dt
% Initialise K vectors
kx = zeros(1,4); % to store K values for x
ky = zeros(1,4); % to store K values for y
kz = zeros(1,4); % to store K values for z
b = [1 2 2 1]; % RK4 coefficients
% Iterate, computing each K value in turn, then the i+1 step values
for i = 1:(N-1)
kx(1) = dx(t(i), x(i), y(i), z(i));
ky(1) = dy(t(i), x(i), y(i), z(i));
kz(1) = dz(t(i), x(i), y(i), z(i));
kx(2) = dx(t(i) + (h/2), x(i) + (h/2)*kx(1), y(i) + (h/2)*ky(1), z(i) + (h/2)*kz(1));
ky(2) = dy(t(i) + (h/2), x(i) + (h/2)*kx(1), y(i) + (h/2)*ky(1), z(i) + (h/2)*kz(1));
kz(2) = dz(t(i) + (h/2), x(i) + (h/2)*kx(1), y(i) + (h/2)*ky(1), z(i) + (h/2)*kz(1));
kx(3) = dx(t(i) + (h/2), x(i) + (h/2)*kx(2), y(i) + (h/2)*ky(2), z(i) + (h/2)*kz(2));
ky(3) = dy(t(i) + (h/2), x(i) + (h/2)*kx(2), y(i) + (h/2)*ky(2), z(i) + (h/2)*kz(2));
kz(3) = dz(t(i) + (h/2), x(i) + (h/2)*kx(2), y(i) + (h/2)*ky(2), z(i) + (h/2)*kz(2));
kx(4) = dx(t(i) + h, x(i) + h*kx(3), y(i) + h*ky(3), z(i) + h*kz(3));
ky(4) = dy(t(i) + h, x(i) + h*kx(3), y(i) + h*ky(3), z(i) + h*kz(3));
kz(4) = dz(t(i) + h, x(i) + h*kx(3), y(i) + h*ky(3), z(i) + h*kz(3));
x(i+1) = x(i) + (h/6)*sum(b.*kx);
y(i+1) = y(i) + (h/6)*sum(b.*ky);
z(i+1) = z(i) + (h/6)*sum(b.*kz);
end
% Group together in one solution matrix
txyz = [t,x,y,z];
Implemented as function
You wanted code which can "be applied to any equation system". To make your script more usable, let's take advantage of vector inputs, where each variable is on its own row, and then make it into a function. The result is something comparable (in how it is called) to Matlab's own ode45.
% setup
odefun = #(t, y) [y(2); -y(1) - 2*exp(t) + 1; -y(1) - exp(t) + 1];
y0 = [1;0;1];
% ODE45 solution
[T, Y] = ode45(odefun, [0,1], y0);
% Custom RK4 solution
t = 0:0.1:1;
y = RK4(odefun, t, y0);
% Compare results
figure; hold on;
plot(T, Y); plot(t, y, '--', 'linewidth', 2)
You can see that the RK4 function (below) gives the same result of the ode45 function.
The function RK4 is simply a "condensed" version of the above script, it will work for however many equations you want to use. For broad use, you would want to include input-checking in the function. I have left this out for clarity.
function y = RK4(odefun, tspan, y0)
% ODEFUN contains the ode functions of the system
% TSPAN is a 1D vector of equally spaced t values
% Y0 contains the intial conditions for the system variables
% Initialise step-size variables
t = tspan(:); % ensure column vector = (0:h:1)';
h = t(2)-t(1);% define h from t
N = length(t);
% Initialise y vector, with a column for each equation in odefun
y = zeros(N, numel(y0));
% Starting conditions
y(1, :) = y0(:)'; % Set intial conditions using row vector of y0
k = zeros(4, numel(y0)); % Initialise K vectors
b = repmat([1 2 2 1]', 1, numel(y0)); % RK4 coefficients
% Iterate, computing each K value in turn, then the i+1 step values
for i = 1:(N-1)
k(1, :) = odefun(t(i), y(i,:));
k(2, :) = odefun(t(i) + (h/2), y(i,:) + (h/2)*k(1,:));
k(3, :) = odefun(t(i) + (h/2), y(i,:) + (h/2)*k(2,:));
k(4, :) = odefun(t(i) + h, y(i,:) + h*k(3,:));
y(i+1, :) = y(i, :) + (h/6)*sum(b.*k);
end
end
Ok, turns out it was just a minor mistake where the x-variable was not defined as a function of y (as x'(t)=y according to the problem.
So: Below is a concrete example on how to solve a differential equation system using Runge Kutta 4 in matlab:
clear all, close all, clc
%{
____________________TASK:______________________
Solve the system of differential equations below
in the interval 0<t<1, with stepsize h = 0.1.
x'= y x(0)=1
y'= -x-2e^t+1 y(0)=0 , where x=x(t), y=y(t), z=z(t)
z'= -x - e^t + 1 z(0)=1
THE EXACT SOLUTIONS for x y and z can be found in this pdf:
archives.math.utk.edu/ICTCM/VOL16/C029/paper.pdf
_______________________________________________
%}
%Step-size
h = 0.1;
t = 0:h:1
N = length(t);
%Defining the vectors where the answer is stored.
x = zeros(N,1);
y = zeros(N,1)
z = zeros(N,1)
%Defining the functions
e = #(t, x, y, z) y;
f = #(t, x, y, z) -x-2*exp(t)+1;
g = #(t, x, y, z) -x - exp(t) + 1;
%Starting/initial conditions
x(1) = 1;
y(1) = 0;
z(1) = 1;
for i = 1:(N-1)
K1 = h * e( t(i) , x(i) , y(i) , z(i));
L1 = h * f( t(i) , x(i) , y(i) , z(i));
M1 = h * g( t(i) , x(i) , y(i) , z(i));
K2 = h * e(t(i) + 1/2*h, x(i)+1/2*K1 , y(i)+1/2*L1 , z(i)+1/2*M1);
L2 = h * f(t(i) + 1/2*h, x(i)+1/2*K1 , y(i)+1/2*L1 , z(i)+1/2*M1);
M2 = h * g(t(i) + 1/2*h, x(i)+1/2*K1 , y(i)+1/2*L1 , z(i)+1/2*M1);
K3 = h * e(t(i) + 1/2*h, x(i) + 1/2*K2 , y(i) + 1/2*L2 , z(i) + 1/2*M2);
L3 = h * f(t(i) + 1/2*h, x(i) + 1/2*K2 , y(i) + 1/2*L2 , z(i) + 1/2*M2);
M3 = h * g(t(i) + 1/2*h, x(i) + 1/2*K2 , y(i) + 1/2*L2 , z(i) + 1/2*M2);
K4 = h * e( t(i)+h , x(i)+K3 , y(i)+L3, z(i)+M3);
L4 = h * f( t(i)+h , x(i)+K3 , y(i)+L3, z(i)+M3);
M4 = h * g( t(i)+h , x(i)+K3 , y(i)+L3, z(i)+M3);
x(i+1) = x(i)+1/6*(K1+2*K2+2*K3+K4);
y(i+1) = y(i)+1/6*(L1+2*L2+2*L3+L4);
z(i+1) = z(i)+1/6*(M1+2*M2+2*M3+M4);
end
Answer_Matrix = [t' x y z]

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)];

The Fastest Method of Solving System of Non-linear Equations in MATLAB

Assume we have three equations:
eq1 = x1 + (x1 - x2) * t - X == 0;
eq2 = z1 + (z1 - z2) * t - Z == 0;
eq3 = ((X-x1)/a)^2 + ((Z-z1)/b)^2 - 1 == 0;
while six of known variables are:
a = 42 ;
b = 12 ;
x1 = 316190;
z1 = 234070;
x2 = 316190;
z2 = 234070;
So we are looking for three unknown variables that are:
X , Z and t
I wrote two method to solve it. But, since I need to run these code for 5.7 million data, it become really slow.
Method one (using "solve"):
tic
S = solve( eq1 , eq2 , eq3 , X , Z , t ,...
'ReturnConditions', true, 'Real', true);
toc
X = double(S.X(1))
Z = double(S.Z(1))
t = double(S.t(1))
results of method one:
X = 316190;
Z = 234060;
t = -2.9280;
Elapsed time is 0.770429 seconds.
Method two (using "fsolve"):
coeffs = [a,b,x1,x2,z1,z2]; % Known parameters
x0 = [ x2 ; z2 ; 1 ].'; % Initial values for iterations
f_d = #(x0) myfunc(x0,coeffs); % f_d considers x0 as variables
options = optimoptions('fsolve','Display','none');
tic
M = fsolve(f_d,x0,options);
toc
results of method two:
X = 316190; % X = M(1)
Z = 234060; % Z = M(2)
t = -2.9280; % t = M(3)
Elapsed time is 0.014 seconds.
Although, the second method is faster, but it still needs to be improved. Please let me know if you have a better solution for that. Thanks
* extra information:
if you are interested to know what those 3 equations are, the first two are equations of a line in 2D and the third equation is an ellipse equation. I need to find the intersection of the line with the ellipse. Obviously, we have two points as result. But, let's forget about the second answer for simplicity.
My suggestion it's to use the second approce,which it's the recommended by matlab for nonlinear equation system.
Declare a M-function
function Y=mysistem(X)
%X(1) = X
%X(2) = t
%X(3) = Z
a = 42 ;
b = 12 ;
x1 = 316190;
z1 = 234070;
x2 = 316190;
z2 = 234070;
Y(1,1) = x1 + (x1 - x2) * X(2) - X(1);
Y(2,1) = z1 + (z1 - z2) * X(2) - X(3);
Y(3,1) = ((X-x1)/a)^2 + ((Z-z1)/b)^2 - 1;
end
Then for solving use
x0 = [ x2 , z2 , 1 ];
M = fsolve(#mysistem,x0,options);
If you may want to reduce the default precision by changing StepTolerance (default 1e-6).
Also for more increare you may want to use the jacobian matrix for greater efficencies.
For more reference take a look in official documentation:
fsolve Nonlinear Equations with Analytic Jacobian
Basically giving the solver the Jacobian matrix of the system(and special options) you can increase method efficency.