#include <cstdlib>
#include <cmath>
#include <iostream>
#include <fstream>
#include <time.h>
#include <vector>
#include <algorithm>
using namespace ukf::parameter;
#define VERBOSE true
#define NB_INPUTS 2
#define NB_HIDDEN 8
#define NB_OUTPUTS 2
double transfer(double x, double a, double b, double u , double c)
{
return a / (1.0 + exp(-b * (x-u)))+c;
}
void my_func(gsl_vector * param, gsl_vector * input, gsl_vector * output)
{
double y[NB_HIDDEN];
double z=0.0;
double a0 = gsl_vector_get(param,(NB_INPUTS+1) * NB_HIDDEN + (NB_HIDDEN+1)* NB_OUTPUTS);
double b0 = gsl_vector_get(param,(NB_INPUTS+1) * NB_HIDDEN + (NB_HIDDEN+1)* NB_OUTPUTS+1);
double u0 = gsl_vector_get(param,(NB_INPUTS+1) * NB_HIDDEN + (NB_HIDDEN+1)* NB_OUTPUTS+2);
double c0 = gsl_vector_get(param,(NB_INPUTS+1) * NB_HIDDEN + (NB_HIDDEN+1)* NB_OUTPUTS+3);
double a1 = gsl_vector_get(param,(NB_INPUTS+1) * NB_HIDDEN + (NB_HIDDEN+1)* NB_OUTPUTS+4);
double b1 = gsl_vector_get(param,(NB_INPUTS+1) * NB_HIDDEN + (NB_HIDDEN+1)* NB_OUTPUTS+5);
double u1 = gsl_vector_get(param,(NB_INPUTS+1) * NB_HIDDEN + (NB_HIDDEN+1)* NB_OUTPUTS+6);
double c1 = gsl_vector_get(param,(NB_INPUTS+1) * NB_HIDDEN + (NB_HIDDEN+1)* NB_OUTPUTS+7);
for(int i = 0 ; i < NB_HIDDEN ; i++)
y[i] = 0.0;
int i_param = 0;
gsl_vector_set_zero(output);
for(int j = 0 ; j < NB_HIDDEN ; j++)
{
for(int k = 0 ; k < NB_INPUTS ; k++)
{
y[j] += gsl_vector_get(param, i_param) * gsl_vector_get(input, k);
i_param++;
}
y[j] += gsl_vector_get(param, i_param);
i_param++;
y[j] = transfer(y[j], 1.0, 1.0, 0.0, 0.0);
}
z = 0.0;
for(int j = 0 ; j < NB_HIDDEN ; j++)
{
z += gsl_vector_get(param,i_param) * y[j];
i_param++;
}
z += gsl_vector_get(param, i_param);
i_param++;
z = transfer(z,a0,b0,u0,c0);
gsl_vector_set(output, 0, z);
z = 0.0;
for(int j = 0 ; j < NB_HIDDEN ; j++)
{
z += gsl_vector_get(param,i_param) * y[j];
i_param++;
}
z += gsl_vector_get(param, i_param);
i_param++;
z = transfer(z,a1,b1,u1,c1);
gsl_vector_set(output, 1, z);
}
typedef struct {
float theta;
float phi;
float x;
float y;
} Sample;
int main(int argc, char* argv[]) {
srand(time(NULL));
p.
n = (NB_INPUTS+1) * NB_HIDDEN + (NB_HIDDEN+1)* NB_OUTPUTS + 8 ;
for(
int i = 0 ; i < p.
n ; i++)
gsl_vector_set(s.
w,i,0.01*(2.0 * rand()/
double(RAND_MAX-1) - 1.0));
gsl_vector * xi = gsl_vector_alloc(NB_INPUTS);
gsl_vector * yi = gsl_vector_alloc(NB_OUTPUTS);
double errorBound = 8e-3;
int nbStepsLimit = 1000;
double error = 2*errorBound;;
std::vector< Sample > samples;
FILE * inputs_file = fopen ("Data/Mackay-inputs.data","r");
FILE * outputs_file = fopen ("Data/Mackay-outputs.data","r");
char c;
double mintheta=0.0;
double maxtheta=0.0;
double minphi=0.0;
double maxphi =0.0;
bool is_init = false;
do
{
Sample s;
fscanf(inputs_file,"%f",&s.theta);
fscanf(inputs_file,"%f",&s.phi);
fscanf(outputs_file,"%f",&s.x);
fscanf(outputs_file,"%f",&s.y);
if(!is_init)
{
mintheta = s.theta;
maxtheta = s.theta;
minphi = s.phi;
maxphi = s.phi;
is_init = true;
}
else
{
mintheta = s.theta < mintheta ? s.theta : mintheta;
maxtheta = s.theta > maxtheta ? s.theta : maxtheta;
minphi = s.phi < minphi ? s.phi : minphi;
maxphi = s.phi > maxphi ? s.phi : maxphi;
}
samples.push_back(s);
c = getc (inputs_file);
} while(c != EOF);
if(VERBOSE) std::cout << "I found : " << samples.size() << " samples " << std::endl;
if(VERBOSE) std::cout << mintheta << " < theta < " << maxtheta << std::endl;
if(VERBOSE) std::cout << minphi << " < phi < " << maxphi << std::endl;
int epoch = 0;
error = 2 * errorBound;
while( epoch <= nbStepsLimit && error > errorBound)
{
std::random_shuffle(samples.begin(), samples.end());
for(unsigned int j = 0 ; j < samples.size() ; j++)
{
gsl_vector_set(xi,0,samples[j].theta);
gsl_vector_set(xi,1,samples[j].phi);
gsl_vector_set(yi, 0, samples[j].x);
gsl_vector_set(yi, 1, samples[j].y);
}
error = 0.0;
for(unsigned int j = 0 ; j < samples.size() ; j++)
{
gsl_vector_set(xi,0,samples[j].theta);
gsl_vector_set(xi,1,samples[j].phi);
my_func(s.w,xi,yi);
error += pow(samples[j].x - gsl_vector_get(yi,0),2.0)+pow(samples[j].y - gsl_vector_get(yi,1),2.0);
}
error = sqrt(error / double(samples.size()));
if(VERBOSE)
std::cout << "Epoch " << epoch << " error = " << error << std::endl;
epoch++;
}
std::cout << "Run on " << epoch << " epochs ; RMS = " << error << "\n" << std::endl ;
std::ofstream outfile("example-005.data");
std::cout << " You can plot them using e.g. gnuplot : " << std::endl;
for(unsigned int i = 0 ; i < samples.size() ; i++)
{
gsl_vector_set(xi, 0, samples[i].theta);
gsl_vector_set(xi, 1, samples[i].phi);
my_func(s.w,xi, yi);
outfile << gsl_vector_get(xi, 0) << " " << gsl_vector_get(xi, 1) << " " << gsl_vector_get(yi, 0) << " " << gsl_vector_get(yi,1) << std::endl;
}
outfile.close();
}