Now the program works, but is it correct? Sometimes it works in C anyway. Could I improve it somehow (not numerically, just C-wise)? I need to allocate the array as I do right? Since I am returning it and not just using it inside the function.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/* Approximates a solution to a differential equation on the form:
y'(t) + ay(t) = x(t)
y(0) = b
*/
double* runge_kutta_2nd_order(double stepSize, double a, double b, double (*x) (double), double upto)
{
int resultSize = ((int) (upto / stepSize)) + 2;
double yt = b;
double time;
double k1,k2,ystar1,ystar2;
int index = 1;
//double *results = (double*) malloc(resultSize * (sizeof(double)));
double *results = malloc(resultSize * sizeof(*results));
if(results == NULL)
{
printf("\nCould not allocate memory. Exiting program.");
exit(0);
}
results[0] = b;
for(time = 0; time < upto; time += stepSize) //<=
{
k1 = x(time) - a * yt;
ystar1 = yt + stepSize * k1;
k2 = x(time + stepSize) - a * ystar1;
ystar2 = yt + (k1 + k2) / 2 * stepSize;
yt = ystar2;
results[index] = ystar2;
index++;
}
return results;
}
void free_results(double **r)
{
free(*r);
*r = NULL;
}
double insignal(double t)
{
return exp(t/2)*(sin(5*t) - 10*cos(5*t));
}
int main(void)
{
int i;
double *res = runge_kutta_2nd_order(0.01,-1,0,&insignal,10);
printf("\nRunge Kutta 2nd order approximation of the differential equation:");
printf("\ny'(t) - y(t) = e^(t/2) * (sin(5t) - 10cos(5t))");
printf("\ny(0) = 0");
printf("\n0 <= t <= 10");
for(i=0; i<1001; i+=100){
printf("\ni = %lf => y = ", 0.01*i);
printf("%lf", res[i]);
}
printf("\n");
free_results(&res);
return 0;
}
for
loop condition. Because of rounding errors, it's essentially random how often the loop body is executed. Instead, passresultSize
torunge_kutta_2nd_order
, computestepSize
fromresultSize
, and useindex < resultSize
as loop condition. \$\endgroup\$