Amplitude increasing in the verlet method in backward difference - numerical-methods

I am facing trouble in the increasing oscillation on a simple harmonic oscillator using a backward difference. here is my code in Scilab
function [x] = back(h, tf)
k = 2;
m = 1;
i = 2;
t(i - 1) = 0;
x(i - 1) = 10;
v(i - 1) = 0;
t(i) = t(i - 1) + h
v(i) = v(i - 1) - h * (k / m) * x(i - 1)
while t(i) < tf
t(i + 1) = t(i) + h
x(i + 1) = x(i - 1) - 2 * (k / m) * v(i) * h
i = i + 1
end
plot(t, x, 'b');
endfunction

From your code, I suppose that you are trying to implement the velocity-Verlet scheme. Here is its implementation for a simple oscillator with the differential equation:
function [x] = back(h, tf)
k = 2;
m = 1;
t = 0:h:tf;
x(1) = 10;
v(1) = 0;
for i=2:length(t)
x(i) = x(i - 1) + v(i - 1) * h - k / m * x(i-1) * h^2 / 2;
v(i) = v(i - 1) - k / m * (x(i) + x(i-1)) * h / 2;
end
plot(t, x, 'b');
endfunction
[x] = back(0.01, 10)

I'm not quite sure what you are trying to achieve, neither if your math is correct. But assuming that you want to solve the numerical problem of:
//coefficients of:
k = 2.;
m = 1.;
// with an initial condition of:
t(1) = 0.;
x(1) = 10.;
v(1) = 0.;
// time paramters:
N = 50;
tf = 10;
h = tf / 50.;
for ii = 2:N
t(ii) = t(ii - 1) + h;
x(ii) = x(ii - 1) - 2 * (k / m) * v(ii - 1) * h
v(ii) = v(ii - 1) - h * (k / m) * x(ii - 1)
disp(x(ii))
end
plot(t, x, 'b');
will result in:
which doesn't seem right but anyway. Please check your math again.

Related

Octave changes scale of y axis when I change the x-axis

When I used this code, it plots two functions like this:
a = 2;
t0 = 1;
N = 100;
epsilon = 1e-5;
function t = metodoDeNewton(a, t0, N, epsilon)
t = zeros(1, N+1);
t(1) = t0;
for i = 1:N
t(i+1) = t(i) - (t(i).^2 - (a - sin(t(i)))) ./ (2 .* t(i) - cos(t(i)));
if abs(t(i+1) - t(i)) < epsilon
break;
endif
endfor
endfunction
t = metodoDeNewton(a, t0, N, epsilon);
x = 0:0.01:1;
y1 = t;
y2 = a - sin(t);
l = plot(x, y1, x, y2);
legend({'g(a)', 'h(a)'});
xlabel('a');
ylabel('y');
But, when I try to change the x to x = 0:0.01:0.2 the graph's y-axis scale changes and I'm no longer able to see the functions I believe.
How can I fix this, any help would be appreciated!

Implementing Euler's Method in GNU Octave

I am reading "Numerical Methods for Engineers" by Chapra and Canale. In it, they've provided pseudocode for the implementation of Euler's method (for solving ordinary differential equations). Here is the pseucode:
Pseucode for implementing Euler's method
I tried implementing this code in GNU Octave, but depending on the input values, I am getting one of two errors:
The program doesn't give any output at all. I have to press 'Ctrl + C' in order to break execution.
The program gives this message:
error: 'ynew' undefined near line 5 column 21
error: called from
Integrator at line 5 column 9
main at line 18 column 7
I would be very grateful if you could get this program to work for me. I am actually an amateur in GNU Octave. Thank you.
Edit 1: Here is my code. For main.m:
%prompt user
y = input('Initial value of y:');
xi = input('Initial value of x:');
xf = input('Final value of x:');
dx = input('Step size:');
xout = input('Output interval:');
x = xi;
m = 0;
xpm = x;
ypm = y;
while(1)
xend = x + xout;
if xend > xf
xend = xf;
h = dx;
Integrator(x,y,h,xend);
m = m + 1;
xpm = x;
ypm = y;
if x >= xf
break;
endif
endif
end
For Integrator.m:
function Integrator(x,y,h,xend)
while(1)
if xend - x < h
h = xend - x;
Euler(x,y,h,ynew);
y = ynew;
if x >= xend
break;
endif
endif
end
endfunction
For Euler.m:
function Euler(x,y,h,ynew)
Derivs(x,y,dydx);
ynew = y + dydx * h;
x = x + h;
endfunction
For Derivs.m:
function Derivs(x,y,dydx)
dydx = -2 * x^3 + 12 * x^2 - 20 * x + 8.5;
endfunction
Edit 2: I shoud mention that the differential equation which Chapra and Canale have given as an example is:
y'(x) = -2 * x^3 + 12 * x^2 - 20 * x + 8.5
That is why the 'Derivs.m' script shows dydx to be this particular polynomial.
Here is my final code. It has four different M-files:
main.m
%prompt the user
y = input('Initial value of y:');
x = input('Initial value of x:');
xf = input('Final value of x:');
dx = input('Step size:');
xout = dx;
%boring calculations
m = 1;
xp = [x];
yp = [y];
while x < xf
[x,y] = Integrator(x,y,dx,min(xf, x+xout));
m = m+1;
xp(m) = x;
yp(m) = y;
end
%plot the final result
plot(xp,yp);
title('Solution using Euler Method');
ylabel('Dependent variable (y)');
xlabel('Independent variable (x)');
grid on;
Integrator.m
%This function takes in 4 inputs (x,y,h,xend) and returns 2 outputs [x,y]
function [x,y] = Integrator(x,y,h,xend)
while x < xend
h = min(h, xend-x);
[x,y] = Euler(x,y,h);
end
endfunction
Euler.m
%This function takes in 3 inputs (x,y,h) and returns 2 outputs [x,ynew]
function [x,ynew] = Euler(x,y,h)
dydx = Derivs(x,y);
ynew = y + dydx * h;
x = x + h;
endfunction
Derivs.m
%This function takes in 2 inputs (x,y) and returns 1 output [dydx]
function [dydx] = Derivs(x,y)
dydx = -2 * x^3 + 12 * x^2 - 20 * x + 8.5;
endfunction
Your functions should look like
function [x, y] = Integrator(x,y,h,xend)
while x < xend
h = min(h, xend-x)
[x,y] = Euler(x,y,h);
end%while
end%function
as an example. Depending on what you want to do with the result, your main loop might need to collect all the results from the single steps. One variant for that is
m = 1;
xp = [x];
yp = [y];
while x < xf
[x,y] = Integrator(x,y,dx,min(xf, x+xout));
m = m+1;
xp(m) = x;
yp(m) = y;
end%while

Storing cost history in a vector

I wrote following code for gradientDescent in Octave in .m file as follows:
function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters)
% Test values:
X = [1 5; 1 2; 1 4; 1 5];
y = [1 6 4 2]';
theta = [0 0]';
alpha = 0.01;
num_iters = 1000;
% Initialize some useful values:
m = length(y); % number of training examples
J_history = zeros(num_iters, 1);
for iter = 1:num_iters
x = X(:,2);
h = theta(1) + (theta(2)*x);
theta_zero = theta(1) - alpha * (1/m) * sum(h-y);
theta_one = theta(2) - alpha * (1/m) * sum((h - y) .* x);
theta = [theta_zero; theta_one];
% ============================================================
% Save the cost J in every iteration
J_history(iter) = computeCost(X, y, theta); % History of J
end
disp(min(J_history));
end
% Code for computeCost function is as follows:
function J = computeCost(X, y, theta)
data =
6.1101 17.5920
5.5277 9.1302
8.5186 13.6620
7.0032 11.8540
5.8598 6.8233
8.3829 11.8860
7.4764 4.3483
8.5781 12.0000
6.4862 6.5987
m = length(y);
J = 0;
X = data(:, 1);
y = data(:, 2);
predictions = X*theta'; % predictions of hypothesis on examples
sqrErrors = (predictions - y).^2; % squared errors
J = 1/(2*m) * sum(sqrErrors);
end
When I run this from octave workspace I get the following error:
Error: A(I) = X: X must have the same size as I
error: called from
gradientDescent at line 55 column 21
I tried many things but unsuccessfully and mentors never replied properly.
Can you please tell me where I may be making a mistake.
Thanks in advance.
Bharat.

Canvas quadraticCurve center point

I want need to know how detect center coordinates of quadraticCurve in HTML5 canvas. I want to draw arrow in this center point of curve.
There is my draw curve method:
function draw_curve(Ax, Ay, Bx, By, M, context) {
var dx = Bx - Ax,
dy = By - Ay,
dr = Math.sqrt(dx * dx + dy * dy);
// side is either 1 or -1 depending on which side you want the curve to be on.
// Find midpoint J
var Jx = Ax + (Bx - Ax) / 2
var Jy = Ay + (By - Ay) / 2
// We need a and b to find theta, and we need to know the sign of each to make sure that the orientation is correct.
var a = Bx - Ax
var asign = (a < 0 ? -1 : 1)
var b = By - Ay
var bsign = (b < 0 ? -1 : 1)
var theta = Math.atan(b / a)
// Find the point that's perpendicular to J on side
var costheta = asign * Math.cos(theta)
var sintheta = asign * Math.sin(theta)
// Find c and d
var c = M * sintheta
var d = M * costheta
// Use c and d to find Kx and Ky
var Kx = Jx - c
var Ky = Jy + d
// context.bezierCurveTo(Kx, Ky,Bx,By, Ax, Ax);
context.quadraticCurveTo(Kx, Ky, Bx, By);
// draw the ending arrowhead
var endRadians = Math.atan((dx) / (dy));
context.stroke();
var t = 0.5; // given example value
var xx = (1 - t) * (1 - t) * Ax + 2 * (1 - t) * t * Kx + t * t * Bx;
var yy = (1 - t) * (1 - t) * Ay + 2 * (1 - t) * t * Ky + t * t * By;
var k = {};
k.x = xx;
k.y = yy;
SOLVED BY THIS CODE, T is parameter which set position on the curve:
var t = 0.5; // given example value
var xx = (1 - t) * (1 - t) * Ax + 2 * (1 - t) * t * Kx + t * t * Bx;
var yy = (1 - t) * (1 - t) * Ay + 2 * (1 - t) * t * Ky + t * t * By;
var k = {};
k.x = xx;
k.y = yy;

Convert a list of commands into a function

I have made this
f[x_] := x - 2
x0 = 999.; imax = 5;
Module[{i, x}, x[0] = x0;
For[i = 0, i < imax, x[i + 1] = x[i] - f[x[i]]/f'[x[i]];
Print[x[i]];
i++]]
and am trying to turn this into a newton rhapson function. I need to be able to input the Function F[x],an initial guess,and imax.
A little bit more Mathematica-ish:
newt[f_, x0_, imax_] := NestList[# - f##/f'## &, x0, imax];
f[x_] := x - 2
x0 = 999; imax = 5;
newt[f, x0, imax]
(*
-> {999, 2, 2, 2, 2, 2}
*)
Mathematica is that simple:
newtonraph = Function[{f,x0,imax},Module[{i,x},
x[0] = x0;
For[i=0, i < imax, x[i+1] = x[i] - f[x[i]]/f'[x[i]];
Print[x[i]];
i++
];
];
];
and call the function:
func[t_] = 23 + t + 2*(t^2)
newtonraph[func,10,100]