#include <cstdlib>
#include <cmath>
#include <iostream>
#include <fstream>
#include <sys/time.h>
using namespace ekf;
#define SIGMA 10.0
#define RHO 28.0
#define BETA 8.0/3.0
#define DT 0.01
#define X0 0.1
#define Y0 1.2
#define Z0 0.4
#define NOISE_AMPLITUDE 2.0
#define VERBOSE true
void f(gsl_vector * params, gsl_vector * xk_1, gsl_vector * xk)
{
double x = gsl_vector_get(xk_1,0);
double y = gsl_vector_get(xk_1,1);
double z = gsl_vector_get(xk_1,2);
double sigma = gsl_vector_get(xk_1,3);
double rho = gsl_vector_get(xk_1,4);
double beta = gsl_vector_get(xk_1,5);
double dt = gsl_vector_get(params, 0);
gsl_vector_set(xk, 0, x + dt * (sigma*( y - x)));
gsl_vector_set(xk, 1, y + dt * ( rho * x - y - x * z));
gsl_vector_set(xk, 2, z + dt * (x * y - beta * z));
gsl_vector_set(xk, 3, sigma);
gsl_vector_set(xk, 4, rho);
gsl_vector_set(xk, 5, beta);
}
void df(gsl_vector * params, gsl_vector * xk_1, gsl_matrix * Fxk)
{
double x = gsl_vector_get(xk_1,0);
double y = gsl_vector_get(xk_1,1);
double z = gsl_vector_get(xk_1,2);
double sigma = gsl_vector_get(xk_1,3);
double rho = gsl_vector_get(xk_1,4);
double beta = gsl_vector_get(xk_1,5);
double dt = gsl_vector_get(params, 0);
gsl_matrix_set(Fxk, 0, 0, 1.0 - sigma * dt);
gsl_matrix_set(Fxk, 0, 1, sigma * dt);
gsl_matrix_set(Fxk, 0, 2, 0.0);
gsl_matrix_set(Fxk, 0, 3, dt * (y - x));
gsl_matrix_set(Fxk, 0, 4, 0.0);
gsl_matrix_set(Fxk, 0, 5, 0.0);
gsl_matrix_set(Fxk, 1, 0, dt * (rho - z));
gsl_matrix_set(Fxk, 1, 1, 1.0 - dt);
gsl_matrix_set(Fxk, 1, 2, - dt * x);
gsl_matrix_set(Fxk, 1, 3, 0.0);
gsl_matrix_set(Fxk, 1, 4, dt * x);
gsl_matrix_set(Fxk, 1, 5, 0.0);
gsl_matrix_set(Fxk, 2, 0, dt * y);
gsl_matrix_set(Fxk, 2, 1, dt * x);
gsl_matrix_set(Fxk, 2, 2, 1.0 - beta * dt);
gsl_matrix_set(Fxk, 2, 3, 0.0);
gsl_matrix_set(Fxk, 2, 4, 0.0);
gsl_matrix_set(Fxk, 2, 5, -dt * z);
gsl_matrix_set(Fxk, 3, 0, 0.0);
gsl_matrix_set(Fxk, 3, 1, 0.0);
gsl_matrix_set(Fxk, 3, 2, 0.0);
gsl_matrix_set(Fxk, 3, 3, 1.0);
gsl_matrix_set(Fxk, 3, 4, 0.0);
gsl_matrix_set(Fxk, 3, 5, 0.0);
gsl_matrix_set(Fxk, 4, 0, 0.0);
gsl_matrix_set(Fxk, 4, 1, 0.0);
gsl_matrix_set(Fxk, 4, 2, 0.0);
gsl_matrix_set(Fxk, 4, 3, 0.0);
gsl_matrix_set(Fxk, 4, 4, 1.0);
gsl_matrix_set(Fxk, 4, 5, 0.0);
gsl_matrix_set(Fxk, 5, 0, 0.0);
gsl_matrix_set(Fxk, 5, 1, 0.0);
gsl_matrix_set(Fxk, 5, 2, 0.0);
gsl_matrix_set(Fxk, 5, 3, 0.0);
gsl_matrix_set(Fxk, 5, 4, 0.0);
gsl_matrix_set(Fxk, 5, 5, 1.0);
}
void h(gsl_vector * params, gsl_vector * xk , gsl_vector * yk)
{
for(unsigned int i = 0 ; i < yk->size ; ++i)
gsl_vector_set(yk, i, gsl_vector_get(xk,i) + NOISE_AMPLITUDE*rand()/ double(RAND_MAX));
}
void dh(gsl_vector * params, gsl_vector * xk , gsl_matrix * Hyk)
{
gsl_matrix_set_zero(Hyk);
gsl_matrix_set(Hyk, 0, 0, 1.0);
gsl_matrix_set(Hyk, 1, 1, 1.0);
gsl_matrix_set(Hyk, 2, 2, 1.0);
}
int main(int argc, char* argv[]) {
struct timeval before, after;
srand(time(NULL));
s.
params = gsl_vector_alloc(1);
for(
int i = 0 ; i < p.
n ; i++)
gsl_vector_set(s.
xk,i,5.0*(2.0*rand()/
double(RAND_MAX-1)-1.0));
gsl_vector * xi = gsl_vector_alloc(p.
n);
gsl_vector * yi = gsl_vector_alloc(p.
no);
gsl_vector_set_zero(yi);
int epoch = 0;
xi->data[0] = X0;
xi->data[1] = Y0;
xi->data[2] = Z0;
xi->data[3] = SIGMA;
xi->data[4] = RHO;
xi->data[5] = BETA;
std::ofstream outfile("example-009.data");
std::ofstream outfile_rms("example-009-rms.data");
double rms= 0.0;
double errorBound = NOISE_AMPLITUDE/2.0;
int count_time=0;
int nb_steps_below_error=1000;
gettimeofday(&before, NULL);
outfile << epoch << " ";
for(int i = 0 ; i < 6 ; ++i)
outfile << xi->data[i] << " " ;
for(int i = 0 ; i < 3 ; ++i)
outfile << yi->data[i] << " " ;
for(int i = 0 ; i < 6 ; ++i)
outfile << s.
xk->data[i] <<
" " ;
outfile << std::endl;
while( epoch < 8000)
{
epoch++;
rms = 0.0;
for(
int i = 0 ; i < p.
n ; ++i)
rms += gsl_pow_2(xi->data[i] - s.
xk->data[i]);
rms = sqrt(rms);
if(rms <= errorBound)
{
count_time++;
if(count_time >= nb_steps_below_error)
break;
}
else
{
count_time = 0;
}
printf("[%i] True state : %e %e %e %e %e %e, estimated : %e %e %e %e %e %e\n", epoch,
xi->data[0],
xi->data[1],
xi->data[2],
xi->data[3],
xi->data[4],
xi->data[5],
outfile << epoch << " ";
for(int i = 0 ; i < 6 ; ++i)
outfile << xi->data[i] << " " ;
for(int i = 0 ; i < 3 ; ++i)
outfile << yi->data[i] << " " ;
for(int i = 0 ; i < 6 ; ++i)
outfile << s.
xk->data[i] <<
" " ;
outfile << std::endl;
outfile_rms << rms << std::endl;
}
gettimeofday(&after, NULL);
double sbefore = before.tv_sec + before.tv_usec * 1E-6;
double safter = after.tv_sec + after.tv_usec * 1E-6;
double total = safter - sbefore;
outfile.close();
outfile_rms.close();
std::cout << " Run on " << epoch << " epochs ;" << std::scientific << total / double(epoch) << " s./step " << std::endl;
printf(
"I found the following parameters : %e %e %e ; The true parameters being : %e %e %e \n", s.
xk->data[3], s.
xk->data[4],s.
xk->data[5],SIGMA, RHO, BETA);
std::cout << " Outputs are saved in example-009*.data " << std::endl;
std::cout << " You can plot them using e.g. gnuplot : " << std::endl;
}