Matlab newton method with finite differences - matlab

I would like some help with my program. I still don’t understand where my problem is, since it’s kind of a big mess. So it consists of the main program:
function x = NewtonM(funcF,JacF)
x= zeros(2,1);
x(1) = 1
x(2) = 5
k = 1;
kmax = 100;
TOL = 10^(-7);
while k < kmax
s = J(x)\(-F(x));
x= x + s
if (norm(s,2)< TOL)
break;
endif
end
and these are the fellow functions:
function y = F(x)
x1 = x(1);
x2 = x(2);
y = zeros(2,1);
y(1) = x1+x2-3;
y(2) = x1^2 + x2^2 -9;
end
function z = Z(x)
x1 = x(1);
x2 = x(2);
z = zeros(3,1);
z(1) = x1+x2-3+10^(-7);
z(2) = (x1+10^(-7))^2 + x2^2 -9;
z(3) = x1^2 + (x2+10^(-7))^2 -9;
end
function J = J(x)
x1 = x(1);
x2 = x(2);
J = zeros(2,2);
J(1,1) = (Z(1)-F(1))/(10^(-7))
J(1,2) = (Z(1)-F(1))/(10^(-7))
J(2,1) = (Z(2)-F(2))/(10^(-7))
J(2,2) = (Z(3)-F(2))/(10^(-7))
end
These are the error messages:

The problem is that you are calling both Z and F with only one input, in the function J.
Then, the first thing you do is try to interpret the input as a 2 valued array (x1,x2) but they don't exist, as you defined x as e.g. 1, by doing Z(1).
I wonder if instead of using Z(1) etc, you meant to do z=Z(x) and then use z(1), inside J.

Related

Steepest Descent using Armijo rule

I want to determine the Steepest descent of the Rosenbruck function using Armijo steplength where x = [-1.2, 1]' (the initial column vector).
The problem is, that the code has been running for a long time. I think there will be an infinite loop created here. But I could not understand where the problem was.
Could anyone help me?
n=input('enter the number of variables n ');
% Armijo stepsize rule parameters
x = [-1.2 1]';
s = 10;
m = 0;
sigma = .1;
beta = .5;
obj=func(x);
g=grad(x);
k_max = 10^5;
k=0; % k = # iterations
nf=1; % nf = # function eval.
x_new = zeros([],1) ; % empty vector which can be filled if length is not known ;
[X,Y]=meshgrid(-2:0.5:2);
fx = 100*(X.^2 - Y).^2 + (X-1).^2;
contour(X, Y, fx, 20)
while (norm(g)>10^(-3)) && (k<k_max)
d = -g./abs(g); % steepest descent direction
s = 1;
newobj = func(x + beta.^m*s*d);
m = m+1;
if obj > newobj - (sigma*beta.^m*s*g'*d)
t = beta^m *s;
x = x + t*d;
m_new = m;
newobj = func(x + t*d);
nf = nf+1;
else
m = m+1;
end
obj=newobj;
g=grad(x);
k = k + 1;
x_new = [x_new, x];
end
% Output x and k
x_new, k, nf
fprintf('Optimal Solution x = [%f, %f]\n', x(1), x(2))
plot(x_new)
function y = func(x)
y = 100*(x(1)^2 - x(2))^2 + (x(1)-1)^2;
end
function y = grad(x)
y(1) = 100*(2*(x(1)^2-x(2))*2*x(1)) + 2*(x(1)-1);
end

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.

system of equation Runge-Kutta 4th order for system of equation using matlab [duplicate]

This question already has answers here:
Solve a system of equations with Runge Kutta 4: Matlab
(2 answers)
Closed 4 years ago.
I need to do matlab code to solve the system of equation by using Runge-Kutta method 4th order but in every try i got problem and can't solve
the derivative is
(d^2 y)/dx^(2) +dy/dx-2y=0
, h=0.1 Y(0)=1 , dy/dx (0)=-2
{clear all, close all, clc
%{
____________________TASK:______________________
Solve the system of differential equations below
in the interval 0<x<1, with stepsize h = 0.1.
y= y1 y(0)=0
y3= 2y1-y2 y2(0)=-2
_______________________________________________
%}
h = 0.1;
x = 0:h:1
N = length(x);
y = zeros(N,1);
y3 = zeros(N,1);
g = #(x, y, y1, y2) y1;
f = #(x, y, y1, y2) 2*y1-y2;
y1(1) = 0;
y2(1) =-2;
for i = 1:(N-1)
k_1 = x(i)+y(i)
k_11=g(x(i),y,y(i))
k_2 = (x(i)+h/2)+(y(i)+0.5*h*k_1)
k_22=g((x(i)+0.5*h),y,(y(i)+0.5*h*k_11))
k_3 = (x(i)+h/2)+(y(i)+0.5*h*k_2)
k_33=g((X(i)+0.5*h),y,(y(i)+0.5*h*k_22));
k_4 = (x(i)+h)+(y(i)+h*k_33)
k_44=g((x(i)+h),y,(y(i)+k_33*h));
y3(i+1) = y(i) + (1/6)*(k_1+2*k_2+2*k_3+k_4)*h
y3(:,i)=y;
end
Answer_Matrix = [x' y3 ];}
You used functions, that's not really necessary, but it might be easier that way to see the formula more clearly. In your functions however, you list arguments that used present in the function. That's not needed, and creates unwanted overhead.
In your initial conditions you should use y and y3, since that are the ones you use in the loop. Also in the first condition you've made a typo.
In the loop you forget to call the function f, and to update the y vector.
Making these changes in your code results in the following:
h = 0.1;
x = 0:h:1;
N = length(x);
y = zeros(N,1);
y3 = zeros(N,1);
g = #(y2) y2;
f = #(y1, y2) 2*y1-y2;
y(1) = 1;
y3(1) = -2;
for i = 1:(N-1)
k_1 = f(y(i), y3(i));
k_11 = g(y3(i));
k_2 = f(y(i)+0.5*h*k_1, y3(i) +0.5*h*k_11);
k_22 = g((y3(i)+0.5*h*k_11));
k_3 = f(y(i)+0.5*h*k_2, y3(i) +0.5*h*k_22);
k_33 = g((y3(i)+0.5*h*k_22));
k_4 = f(y(i)+h*k_3, y3(i) +h*k_33);
k_44 = g((y3(i)+h*k_33));
y3(i+1) = y3(i) + (1/6)*(k_1+2*k_2+2*k_3+k_4)*h ;
y(i+1) = y(i) + (1/6)*(k_11+2*k_22+2*k_33+k_44)*h ;
end
Answer_Matrix = [x' y];
% solution of DE is exp(-2x) and is plotted as reference
plot(x,y,x,exp(-2*x))
As mentioned before, you can also solve this without the use of functions:
h = .1;
x = 0:h:1;
N = length(x);
% allocate memory
y = zeros(N,1);
z = zeros(N,1);
% starting values
y(1) = 1;
z(1) = -2;
for i=1:N-1
ky1 = z(i);
kz1 = -z(i) + 2*y(i);
ky2 = z(i) + h/2*kz1;
kz2 = -z(i) - h/2*kz1 + 2*y(i) + 2*h/2*ky1;
ky3 = z(i) + h/2*kz2;
kz3 = -z(i) - h/2*kz2 + 2*y(i) + 2*h/2*ky2;
ky4 = z(i) + h*kz3;
kz4 = -z(i) - h*kz3 + 2*y(i) + 2*h*ky3;
y(i+1) = y(i) + h/6*(ky1 + 2*ky2 + 2*ky3 + ky4);
z(i+1) = z(i) + h/6*(kz1 + 2*kz2 + 2*kz3 + kz4);
end
% exp(-2*x) is solution of DE and is plotted as reference
plot(x,y,x,exp(-2*x))

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

How to iterate over functions?

I would like to apply loop over a function. I have the following "mother" code:
v = 1;
fun = #root;
x0 = [0,0]
options = optimset('MaxFunEvals',100000,'MaxIter', 10000 );
x = fsolve(fun,x0, options)
In addition, I have the following function in a separate file:
function D = root(x)
v = 1;
D(1) = x(1) + x(2) + v - 2;
D(2) = x(1) - x(2) + v - 1.8;
end
Now, I would like to find roots when v = sort(rand(1,1000)). In other words, I would like to iterate over function for each values of v.
You will need to modify root to accept an additional variable (v) and then change the function handle to root to an anonymous function which feeds in the v that you want
function D = root(x, v)
D(1) = x(1) + x(2) + v - 2;
D(2) = x(1) - x(2) + v - 1.8;
end
% Creates a function handle to root using a specific value of v
fun = #(x)root(x, v(k))
Just in case that equation is your actual equation (and not a dummy example): that equation is linear, meaning, you can solve it for all v with a simple mldivide:
v = sort(rand(1,1000));
x = [1 1; 1 -1] \ bsxfun(#plus, -v, [2; 1.8])
And, in case those are not your actual equations, you don't need to loop, you can vectorize the whole thing:
function x = solver()
options = optimset('Display' , 'off',...
'MaxFunEvals', 1e5,...
'MaxIter' , 1e4);
v = sort(rand(1, 1000));
x0 = repmat([0 0], numel(v), 1);
x = fsolve(#(x)root(x,v'), x0, options);
end
function D = root(x,v)
D = [x(:,1) + x(:,2) + v - 2
x(:,1) - x(:,2) + v - 1.8];
end
This may or may not be faster than looping, it depends on your actual equations.
It may be slower because fsolve will need to compute a Jacobian of 2000×2000 (4M elements), instead of 2×2, 1000 times (4k elements).
But, it may be faster because the startup cost of fsolve can be large, meaning, the overhead of many calls may in fact outweigh the cost of computing the larger Jacobian.
In any case, providing the Jacobian as a second output will speed everything up rather enormously:
function solver()
options = optimset('Display' , 'off',...
'MaxFunEvals', 1e5,...
'MaxIter' , 1e4,...
'Jacobian' , 'on');
v = sort(rand(1, 1000));
x0 = repmat([1 1], numel(v), 1);
x = fsolve(#(x)root(x,v'), x0, options);
end
function [D, J] = root(x,v)
% Jacobian is constant:
persistent J_out
if isempty(J_out)
one = speye(numel(v));
J_out = [+one +one
+one -one];
end
% Function values at x
D = [x(:,1) + x(:,2) + v - 2
x(:,1) - x(:,2) + v - 1.8];
% Jacobian at x:
J = J_out;
end
vvec = sort(rand(1,2));
x0 = [0,0];
for v = vvec,
fun = #(x) root(v, x);
options = optimset('MaxFunEvals',100000,'MaxIter', 10000 );
x = fsolve(fun, x0, options);
end
with function definition:
function D = root(v, x)
D(1) = x(1) + x(2) + v - 2;
D(2) = x(1) - x(2) + v - 1.8;
end