0% found this document useful (0 votes)
21 views

Computer Science Project 1

Computer science project which i passed

Uploaded by

Mikołaj Kmin
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views

Computer Science Project 1

Computer science project which i passed

Uploaded by

Mikołaj Kmin
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

Final project

Mikolaj Kmin
June 5, 2024

1 The problem

We assume
...
f (x) = 4 x − 6ẍ + 4ẋ

a=1
α=0
β=4
γ = −6
δ=4
2 Initial transformations
Our system of differential equations: 

z1 =x

z
2 = ẋ
z3 = ẍ
...


z4 = x

Our system of differential equations:




 z˙1 = z2

z˙ = z
2 3

 z˙3 = z4

z˙4 = δz4 + γz3 + βz2 + αz1 − ax

Initial conditions: 

 z1 (0) =0

z (0)
2 =1

 z3 (0) =0

z4 (0) =0

3 Number of iterations
There is not an arbitrary best choice of the number of iterations, it depends on the desired
accuracy, and the computer specifications, as well as the problem we are trying to solve.

4 Number of iterations
There is not an arbitrary best choice of the number of iterations, it depends on the desired
accuracy, and the computer specifications, as well as the problem we are trying to solve.

Table 1: The table below shows the results of numerical integration together with their errors
in comparison with the real solution
Number of iterations Result error
2 11.534722 3.244629
4 14.374674 0.404678
8 14.742856 0.036495
16 14.775511 0.003840
32 14.777936 0.001416
64 14.778101 0.001251

Here the graph and the code for the computation of optimal number of iterations
Figure 1: The graph shows us that for our problem, the optimal number of iterations is about
32, as increasing it further doesn’t improve accuracy by an significant amount

#include <stdio.h>
#include <math.h>

// Define the system of ODEs


void f(double t, double x[], double dxdt[]) {
dxdt[0] = x[1];
dxdt[1] = x[2];
dxdt[2] = x[3];
dxdt[3] = 4 * x[3] - 6 * x[2] + 4 * x[1] - x[0];
}

// Runge-Kutta 4 method for systems of ODEs


void RungeKutta4(double t_0, double x[], double h, int n, double dxdt[]) {
double k1[4], k2[4], k3[4], k4[4];
double x_temp[4];
for (int i = 0; i < n; i++) {
f(t_0 + i * h, x, k1);
for (int j = 0; j < 4; j++) {
x_temp[j] = x[j] + h * k1[j] / 2;
}
f(t_0 + i * h + h / 2, x_temp, k2);
for (int j = 0; j < 4; j++) {
x_temp[j] = x[j] + h * k2[j] / 2;
}
f(t_0 + i * h + h / 2, x_temp, k3);
for (int j = 0; j < 4; j++) {
x_temp[j] = x[j] + h * k3[j];
}
f(t_0 + i * h + h, x_temp, k4);
for (int j = 0; j < 4; j++) {
x[j] = x[j] + (k1[j] + 2 * k2[j] + 2 * k3[j] + k4[j]) * h / 6;
}
}
}

// Exact solution for the fourth-order ODE


double xExact(double t) {
return 0.5 * exp(t) * (t * t * t - 2 * t * t + 2 * t) + 0.5 * exp(-3 * t);
}

// Error calculation for the fourth-order ODE


double error(double t, double approx[]) {
double exact = xExact(t);
return fabs(approx[0] - exact); // Compare the approximate solution at time t with the
exact solution
}

int main() {
int n;
double x_0[4] = {0, 0, 1, 0}; // initial conditions
double t_0 = 0;
double t = 2; // final time
double exact = xExact(t);
printf("\n\n------The exact solution is %lf\n\n", exact);
for (int j = 1; j < 7; j++) {
printf("\n<< N = 2^ %d >>\n", j);
n = pow(2, j);
double h = (t - t_0) / n; // step size

double approx_rk4[4];
for (int i = 0; i < 4; i++) {
approx_rk4[i] = -x_0[i];
}
RungeKutta4(t_0, approx_rk4, h, n, approx_rk4);

double err_rk4 = error(t, approx_rk4);

printf("Runge-Kutta 4 method:\n");
printf("Approximate solution at t=%f: %f\n", t, approx_rk4[0]);
printf("Error: %f\n", err_rk4);
}
return 0;
}
5 Computation of x, v, and a, for t=2 together with the
graph presenting itterative process

N x(t) Velocity Acceleration


1 0.062503 1.000172 0.008446
2 0.125044 1.001464 0.036516
3 0.187737 1.00524 0.088787
4 0.250785 1.013175 0.170532
5 0.314512 1.027295 0.287813
6 0.379376 1.050035 0.447575
7 0.446005 1.084291 0.657754
8 0.515223 1.133491 0.927396
9 0.588086 1.201666 1.26679
10 0.665923 1.293533 1.68761
11 0.750384 1.414586 2.203082
12 0.843486 1.571199 2.828159
13 0.947676 1.770738 3.579717
14 1.065897 2.021691 4.476777
15 1.20166 2.333808 5.540743
16 1.359127 2.718257 6.795663
17 1.543212 3.187801 8.268529
18 1.759675 3.756988 9.989592
19 2.015252 4.442369 11.992719
20 2.317779 5.262736 14.315784
21 2.676345 6.239381 17.001093
22 3.101455 7.396394 20.09586
23 3.605213 8.760981 23.652724
24 4.201534 10.363822 27.730318
25 4.906367 12.239466 32.393895
26 5.737953 14.426765 37.716015
27 6.717106 16.969353 43.777298
28 7.867534 19.916175 50.667254
29 9.216181 23.322074 58.485183
30 10.793624 27.24843 67.341178
31 12.634494 31.763867 77.357205
32 14.777962 36.945037 88.668304
Table 2: Table of values for x, velocity, and acceleration for the same constants and initial
conditions as in previous sections
Figure 2: x(t),v(t) and a(t) are approaching their true values

#include <stdio.h>
#include <math.h>

double z_1(double x, double x_prime, double x_double_prime, double x_triple_prime) {


return x_prime;
}

double z_2(double x, double x_prime, double x_double_prime, double x_triple_prime) {


return x_double_prime;
}

double z_3(double x, double x_prime, double x_double_prime, double x_triple_prime) {


return x_triple_prime;
}

double z_4(double x, double x_prime, double x_double_prime, double x_triple_prime) {

return 4*x_triple_prime-6*x_double_prime+4*x_prime-x;
}
void runge_kutta_4 (double *x, double *x_prime, double *x_double_prime,
double *x_triple_prime, double h, double t, int n_steps)
{
double k1[4], k2[4], k3[4], k4[4];

double x_temp, x_prime_temp, x_double_prime_temp, x_triple_prime_temp;

for (int i = 0; i < n_steps; i++)


{

k1[0] = h * z_1 (*x, *x_prime, *x_double_prime, *x_triple_prime);

k1[1] = h * z_2 (*x, *x_prime, *x_double_prime, *x_triple_prime);

k1[2] = h * z_3 (*x, *x_prime, *x_double_prime, *x_triple_prime);

k1[3] = h * z_4 (*x, *x_prime, *x_double_prime, *x_triple_prime);

x_temp = *x + 0.5 * k1[0];

x_prime_temp = *x_prime + 0.5 * k1[1];

x_double_prime_temp = *x_double_prime + 0.5 * k1[2];

x_triple_prime_temp = *x_triple_prime + 0.5 * k1[3];

k2[0] =
h * z_1 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

k2[1] =
h * z_2 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

k2[2] =
h * z_3 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

k2[3] =
h * z_4 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

x_temp = *x + 0.5 * k2[0];

x_prime_temp = *x_prime + 0.5 * k2[1];

x_double_prime_temp = *x_double_prime + 0.5 * k2[2];

x_triple_prime_temp = *x_triple_prime + 0.5 * k2[3];


k3[0] =
h * z_1 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

k3[1] =
h * z_2 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

k3[2] =
h * z_3 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

k3[3] =
h * z_4 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

x_temp = *x + k3[0];

x_prime_temp = *x_prime + k3[1];

x_double_prime_temp = *x_double_prime + k3[2];

x_triple_prime_temp = *x_triple_prime + k3[3];

k4[0] =
h * z_1 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

k4[1] =
h * z_2 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

k4[2] =
h * z_3 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

k4[3] =
h * z_4 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

*x += (k1[0] + 2 * k2[0] + 2 * k3[0] + k4[0]) / 6;

*x_prime += (k1[1] + 2 * k2[1] + 2 * k3[1] + k4[1]) / 6;

*x_double_prime += (k1[2] + 2 * k2[2] + 2 * k3[2] + k4[2]) / 6;

*x_triple_prime += (k1[3] + 2 * k2[3] + 2 * k3[3] + k4[3]) / 6;


printf("%f;%f;%f\n", *x, *x_prime, *x_double_prime);
}
}
int main() {
int n =32;
double x_0[4] = {0, 1, 0, 0};
double t_0 = 0;
double t = 2;

double h = (t - t_0) / n;

double x = x_0[0];
double x_prime = x_0[1];
double x_double_prime = x_0[2];
double x_triple_prime = x_0[3];

runge_kutta_4(&x, &x_prime, &x_double_prime, &x_triple_prime, h, t, n);

//printf("Runge-Kutta 4 method:\n");
//printf("Approximate solution at t=%f: %f\n", t, x_prime);
// printf("Error: %f\n", err_rk4); // uncomment if you have defined err_rk4

return 0;
}

6 x(t),v(t) and a(t)


In this sectuion we treat x,v,and a as functions of time, and check how their values change
when t changes.
t x(t) v(t) a(t)
0 0 1 0
0.05 0.050001 1.000087 0.005322
0.1 0.100018 1.000732 0.022656
0.15 0.150094 1.00259 0.054243
0.2 0.20031 1.006436 0.102598
0.25 0.250786 1.013176 0.170535
0.3 0.301693 1.023868 0.261198
0.35 0.353259 1.039733 0.378093
0.4 0.405776 1.062179 0.525122
0.45 0.459613 1.09282 0.706623
0.5 0.515225 1.133496 0.927406
0.55 0.573165 1.186303 1.192803
0.6 0.634097 1.253618 1.508714
0.65 0.698813 1.338125 1.88166
0.7 0.768247 1.442854 2.318836
0.75 0.843492 1.571211 2.828179
0.8 0.925825 1.727019 3.41843
0.85 1.016722 1.914562 4.099207
0.9 1.117889 2.138624 4.881081
0.95 1.231282 2.404547 5.775665
1 1.35914 2.71828 6.795702
1.05 1.504016 3.08644 7.955161
1.1 1.668813 3.516373 9.269349
1.15 1.856818 4.01623 10.755022
1.2 2.07175 4.595036 12.430509
1.25 2.317802 5.262775 14.315848
1.3 2.599691 6.030479 16.432929
1.35 2.922716 6.910324 18.805652
1.4 3.292813 7.915734 21.460092
1.45 3.716624 9.061495 24.424682
1.5 4.201568 10.363879 27.730408
1.55 4.755914 11.840773 31.411023
1.6 5.388873 13.511829 35.503268
1.65 6.110683 15.398612 40.047121
1.7 6.932713 17.524774 45.086061
1.75 7.867569 19.916234 50.667345
1.8 8.929215 22.601376 56.842323
1.85 10.1331 25.611259 63.666758
1.9 11.496296 28.979847 71.201185
1.95 13.037654 32.74426 79.511286
2 14.777962 36.945037 88.668304
Table 3: Table af x(t), v(t), and a(t), for t ∈ ⟨0, 2⟩
#include <stdio.h>
#include <math.h>

double z_1(double x, double x_prime, double x_double_prime, double x_triple_prime) {


return x_prime;
}

double z_2(double x, double x_prime, double x_double_prime, double x_triple_prime) {


return x_double_prime;
}

double z_3(double x, double x_prime, double x_double_prime, double x_triple_prime) {


return x_triple_prime;
}

double z_4(double x, double x_prime, double x_double_prime, double x_triple_prime) {

return 4*x_triple_prime-6*x_double_prime+4*x_prime-x;
}
void runge_kutta_4 (double *x, double *x_prime, double *x_double_prime,
double *x_triple_prime, double h, double t, int n_steps)
{

double k1[4], k2[4], k3[4], k4[4];

double x_temp, x_prime_temp, x_double_prime_temp, x_triple_prime_temp;


for (int i = 0; i < n_steps; i++)
{

k1[0] = h * z_1 (*x, *x_prime, *x_double_prime, *x_triple_prime);

k1[1] = h * z_2 (*x, *x_prime, *x_double_prime, *x_triple_prime);

k1[2] = h * z_3 (*x, *x_prime, *x_double_prime, *x_triple_prime);

k1[3] = h * z_4 (*x, *x_prime, *x_double_prime, *x_triple_prime);

x_temp = *x + 0.5 * k1[0];

x_prime_temp = *x_prime + 0.5 * k1[1];

x_double_prime_temp = *x_double_prime + 0.5 * k1[2];

x_triple_prime_temp = *x_triple_prime + 0.5 * k1[3];

k2[0] =
h * z_1 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

k2[1] =
h * z_2 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

k2[2] =
h * z_3 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

k2[3] =
h * z_4 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

x_temp = *x + 0.5 * k2[0];

x_prime_temp = *x_prime + 0.5 * k2[1];

x_double_prime_temp = *x_double_prime + 0.5 * k2[2];

x_triple_prime_temp = *x_triple_prime + 0.5 * k2[3];

k3[0] =
h * z_1 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);
k3[1] =
h * z_2 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

k3[2] =
h * z_3 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

k3[3] =
h * z_4 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

x_temp = *x + k3[0];

x_prime_temp = *x_prime + k3[1];

x_double_prime_temp = *x_double_prime + k3[2];

x_triple_prime_temp = *x_triple_prime + k3[3];

k4[0] =
h * z_1 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

k4[1] =
h * z_2 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

k4[2] =
h * z_3 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

k4[3] =
h * z_4 (x_temp, x_prime_temp, x_double_prime_temp,
x_triple_prime_temp);

*x += (k1[0] + 2 * k2[0] + 2 * k3[0] + k4[0]) / 6;

*x_prime += (k1[1] + 2 * k2[1] + 2 * k3[1] + k4[1]) / 6;

*x_double_prime += (k1[2] + 2 * k2[2] + 2 * k3[2] + k4[2]) / 6;

*x_triple_prime += (k1[3] + 2 * k2[3] + 2 * k3[3] + k4[3]) / 6;


//printf("%f;%f\n", *x, *x_prime);

}
}
int main() {
int n = 32;
double x_0[4] = {0, 1, 0, 0}; // initial conditions
double t_0 = 0;
double step = 0.1;
for(double i = 0; i <= 2.01;){
double t = i; // final time
double h = (t - t_0) / n; // step size

double x = x_0[0];
double x_prime = x_0[1];
double x_double_prime = x_0[2];
double x_triple_prime = x_0[3];

runge_kutta_4(&x, &x_prime, &x_double_prime, &x_triple_prime, h, t, n);


printf("%f;%f;%f;%f\n",t, x, x_prime, x_double_prime);
i=i+0.05;
}

return 0;
}

7 Results for modified initial conditions, values of α, β, γ, δ, a


We will be checking how x(t), v(t), and a(t) behave for applied changes

7.1 First we modify the initial conditions, the new initial conditions
are:


x(0) = 1

ẋ(0) = 2
ẍ(0) = 3
 ...


x (0) = 4
Figure 3: Results for new initial conditions

7.2 Now let’s change the range of t, returning to the orginal starting
conditions
(
t0 = 0.5
tn = 1
We also need to decrease the iteration step to 0.02, to acquire accurate results
Figure 4: Results for t ∈ ⟨ 12 , 1⟩

7.3 Finaly we will modify α, β, γ, δ

a=2
α=3
β = −2
γ=4
δ = −2
Figure 5: Results for new parameters

You might also like