Added additional simulation models and cleaned Makefile.

parent 02f831b4
CC=gcc
CFLAGS=-Wall -Wextra -pedantic -std=c99 -D_GNU_SOURCE -g -O0 CFLAGS=-Wall -Wextra -pedantic -std=c99 -D_GNU_SOURCE -g -O0
LFLAGS=-lm LDFLAGS=-lm
all: test harm_osc PROGS=test harm_osc
test: test.o methods.o .PHONY: all clean
$(CC) $(CFLAGS) $(LFLAGS) -o $@ $^
harm_osc: harm_osc.o methods.o all: ${PROGS}
$(CC) $(CFLAGS) $(LFLAGS) -o $@ $^
clean: test: test.o logger.o methods.o
rm *.o test harm_osc harm_osc: harm_osc.o logger.o methods.o
clean: ; rm -vf *.o ${PROGS}
...@@ -2,40 +2,83 @@ ...@@ -2,40 +2,83 @@
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
#include "methods.h" #include "methods.h"
#include "logger.h"
#define DT .001 #define DT .001
#define INTEGRATE(method, t0, t1) { \ #define INTEGRATE(method, t0, t1, FN) { \
if( method(t0, t1, DT, y0, y1, 2, &f_osc, &k) ) \ if( method(t0, t1, DT, y0, y1, 2, &f_ ## FN, args_ ## FN) ) \
puts("FAIL"); \ puts("FAIL"); \
else \ else \
printf("y1 using %-12s s:%.10f\n", #method ":", *y1); \ printf("y1 using %-12s s:%.10f\n", #method ":", *y1); \
} }
#define COMPARE(t0, t1) { \ #define COMPARE(t0, t1, fn) { \
INTEGRATE(Euler, t0, t1); \ printf("Function %s\n", #fn); \
INTEGRATE(RungeKutta2, t0, t1); \ INTEGRATE(Euler, t0, t1, fn); \
INTEGRATE(RungeKutta4, t0, t1); \ INTEGRATE(RungeKutta2, t0, t1, fn); \
INTEGRATE(RungeKutta4, t0, t1, fn); \
} }
extern log_function log_func; //void log(double t, double *y) {
// printf("%f,%f,%f\n", t, y[0], y[1]);
//}
//
void log(double t, double *y) { #define PARAM(n) ((double *) params)[n]
printf("%f,%f,%f\n", t, y[0], y[1]);
}
int f_osc(double t, double *y, double *dy, void *params) { int f_osc(double t, double *y, double *dy, void *params) {
// s' = v
dy[0] = y[1]; dy[0] = y[1];
dy[1] = -*(double *)(params) * y[0]; // v' = -k * s
dy[1] = - PARAM(0) * y[0];
return 0;
}
int f_forced_osc(double t, double *y, double *dy, void *params) {
// s' = v
dy[0] = y[1];
// v' = -k * s - D * v + sin(w * t)
dy[1] = - PARAM(0) * y[0] - PARAM(1) * y[1] + sin(PARAM(2) * t);
return 0;
}
int f_lottka_volt(double t, double *y, double *dy, void *params) {
// x' = -a * x + c * d * x * y
dy[0] = - PARAM(0) * y[0] + PARAM(2) * PARAM(3) * y[0] * y[1];
// y' = b * y - d * x * y
dy[1] = - PARAM(1) * y[1] - PARAM(3) * y[0] * y[1];
return 0;
}
int f_modified_pp(double t, double *y, double *dy, void *params) {
// x' = -a * x + c * d * x * y
dy[0] = - PARAM(0) * y[0] + PARAM(2) * PARAM(3) * y[0] * y[1];
// y' = b * ( 1 - y / y_m ) * y - d * x * y
// = b * y - b * y * y / y_m - d * x * y
double by = PARAM(1) * y[1];
dy[1] = by - by * y[1] / PARAM(4) - PARAM(3) * y[0] * y[1];
return 0; return 0;
} }
int main(void) { int main(void) {
double k = .5, y0[2] = {.0, 5.0}, y1[2] = {.0, .0}; double y0[2] = {.0, 5.0},
y1[2] = {.0, .0};
double args_osc[1] = {.5}, // {k}
args_forced_osc[3] = {1.0, 0.1, 2.0}, // {k, D, w}
args_lottka_volt[4] = {.5, 1.0, .1, .1}, // {a, b, c, d}
args_modified_pp[5] = {.5, 1.0, .1, .1, 100.0}; // {a, b, c, d, y_m}
//printf("number of args: %d\n", sizeof(args_osc) / sizeof(double));
COMPARE(.0, 10.0, osc);
COMPARE(.0, 10.0, forced_osc);
log_func = &log; // TODO: this model is not yet completed.
printf("Function: lottka_volt\n");
INTEGRATE(RungeKutta4, .0, 10.0, lottka_volt);
COMPARE(.0, 10.0) // TODO: this model is not yet completed.
printf("Function: modified_pp\n");
INTEGRATE(RungeKutta4, .0, 10.0, modified_pp);
return 0; return 0;
} }
#include "logger.h"
FILE *logfile = NULL;
void logger(double t, double *y) {
if( !logfile ) {
logfile = fopen("methods.log", "w");
}
fprintf(logfile, "%e,%e\n", t, y[0]);
}
void logger_close() {
if( logfile && fclose(logfile) ) {
printf("Failed to close logfile. Error no: %d", errno);
}
}
#ifndef __LOG_H__
#define __LOG_H__
#include <stdio.h>
#include <errno.h>
//typedef void (*log_function)(double t, double *y);
void logger(double t, double *y);
void logger_close();
#endif // __LOG_H__
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include "methods.h" #include "methods.h"
#include "logger.h"
/* /*
t0 – the start value t0 of t (input) t0 – the start value t0 of t (input)
...@@ -18,11 +19,6 @@ All functions return 0 upon success, or -1 when a computational error ...@@ -18,11 +19,6 @@ All functions return 0 upon success, or -1 when a computational error
occurs (overflow, NaN or such) occurs (overflow, NaN or such)
*/ */
#define LOG(t, y) { \
if( log_func != NULL ) \
log_func(t, y); \
}
int Euler(double t0, double t1, double dt, double *y0, double *y1, int N, int Euler(double t0, double t1, double dt, double *y0, double *y1, int N,
f_ptr f, void *params) { f_ptr f, void *params) {
int i, j, intervals = (t1 - t0) / dt; int i, j, intervals = (t1 - t0) / dt;
...@@ -32,7 +28,7 @@ int Euler(double t0, double t1, double dt, double *y0, double *y1, int N, ...@@ -32,7 +28,7 @@ int Euler(double t0, double t1, double dt, double *y0, double *y1, int N,
for( j = 0; j < N; j++ ) for( j = 0; j < N; j++ )
y1[j] = y0[j]; y1[j] = y0[j];
LOG(t0, y0) logger(t0, y0);
// Estimate for each interval // Estimate for each interval
for( i = 0; i < intervals; i++ ) { for( i = 0; i < intervals; i++ ) {
...@@ -45,7 +41,7 @@ int Euler(double t0, double t1, double dt, double *y0, double *y1, int N, ...@@ -45,7 +41,7 @@ int Euler(double t0, double t1, double dt, double *y0, double *y1, int N,
y1[j] = y1[j] + dy[j] * dt; y1[j] = y1[j] + dy[j] * dt;
// Value can be printed/logged here // Value can be printed/logged here
LOG(t, y1); logger(t, y1);
t = t0 + i * dt; t = t0 + i * dt;
} }
...@@ -62,7 +58,7 @@ int RungeKutta2(double t0, double t1, double dt, double *y0, double *y1, int N, ...@@ -62,7 +58,7 @@ int RungeKutta2(double t0, double t1, double dt, double *y0, double *y1, int N,
for( j = 0; j < N; j++ ) for( j = 0; j < N; j++ )
y1[j] = y0[j]; y1[j] = y0[j];
LOG(t0, y0) logger(t0, y0);
// Estimate for each interval // Estimate for each interval
for( i = 0; i < intervals; i++ ) { for( i = 0; i < intervals; i++ ) {
...@@ -75,7 +71,7 @@ int RungeKutta2(double t0, double t1, double dt, double *y0, double *y1, int N, ...@@ -75,7 +71,7 @@ int RungeKutta2(double t0, double t1, double dt, double *y0, double *y1, int N,
y1[j] = y1[j] + .5 * (dy1[j] + dy2[j]) * dt; y1[j] = y1[j] + .5 * (dy1[j] + dy2[j]) * dt;
// Value can be printed/logged here // Value can be printed/logged here
LOG(t, y1); logger(t, y1);
t = t0 + i * dt; t = t0 + i * dt;
} }
...@@ -92,7 +88,7 @@ int RungeKutta4(double t0, double t1, double dt, double *y0, double *y1, int N, ...@@ -92,7 +88,7 @@ int RungeKutta4(double t0, double t1, double dt, double *y0, double *y1, int N,
for( j = 0; j < N; j++ ) for( j = 0; j < N; j++ )
y[j] = y1[j] = y0[j]; y[j] = y1[j] = y0[j];
LOG(t0, y0) logger(t0, y0);
// Estimate for each interval // Estimate for each interval
for( i = 0; i < intervals; i++ ) { for( i = 0; i < intervals; i++ ) {
...@@ -137,7 +133,7 @@ int RungeKutta4(double t0, double t1, double dt, double *y0, double *y1, int N, ...@@ -137,7 +133,7 @@ int RungeKutta4(double t0, double t1, double dt, double *y0, double *y1, int N,
} }
// Value can be printed/logged here // Value can be printed/logged here
LOG(t, y1); logger(t, y1);
t = t0 + i * dt; t = t0 + i * dt;
} }
......
typedef int (*f_ptr)(double t, double *y, double *dy, void *params); #ifndef __METHODS_H__
typedef void (*log_function)(double t, double *y); #define __METHODS_H__
log_function log_func = NULL; typedef int (*f_ptr)(double t, double *y, double *dy, void *params);
int Euler(double t0, double t1, double dt, double *y0, double *y1, int N, int Euler(double t0, double t1, double dt, double *y0, double *y1, int N,
f_ptr f, void *params); f_ptr f, void *params);
...@@ -10,3 +10,5 @@ int RungeKutta2(double t0, double t1, double dt, double *y0, double *y1, int N, ...@@ -10,3 +10,5 @@ int RungeKutta2(double t0, double t1, double dt, double *y0, double *y1, int N,
int RungeKutta4(double t0, double t1, double dt, double *y0, double *y1, int N, int RungeKutta4(double t0, double t1, double dt, double *y0, double *y1, int N,
f_ptr f, void *params); f_ptr f, void *params);
#endif // __METHODS_H__
#!/usr/bin/env python
from sys import argv, exit from sys import argv, exit
from pylab import figure, clf, plot, show, savefig from pylab import figure, clf, plot, show, savefig
......
mean = [0,0]
cov = [[1,0],[0,100]] # diagonal covariance, points lie on x or y-axis
import matplotlib.pyplot as plt
import numpy as np
x,y = np.random.multivariate_normal(mean, cov, 5000).T
print 'x:', x
print 'y:', y
plt.plot(x,y,'x'); plt.axis('equal'); plt.show()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment