Commit 70ef3d00 authored by Arnaud Blanchard's avatar Arnaud Blanchard

Test to learn sensorimotor association with information theory

parent 83faab8d
# Set the minimum version of cmake required to build this project
cmake_minimum_required(VERSION 2.6)
# Set the name of the project as the directory basename
project(f_pinobo_stats)
find_package(blc_channel)
find_package(blc_program)
add_definitions(${BL_DEFINITIONS} -march=native)
include_directories(${BL_INCLUDE_DIRS} )
add_executable(f_pinobo_stats f_pinobo_stats.cpp)
target_link_libraries(f_pinobo_stats ${BL_LIBRARIES})
//
// Created by Arnaud Blanchard on 22/12/15.
// Copyright ETIS 2015. All rights reserved.
//
#include <iostream>
#include "blc_channel.h"
#include "blc_program.h"
#include <unistd.h>
#include <math.h>
static uchar gaussian_cdf(uint32_t s, float mu, float var);
int prob_div(int num, unsigned denom){
int correction;
div_t result;
result=div(num, denom);
/* We look rem chances over denom i.e. rem/denom > rand()/(RAND_MAX+1) */
correction=(rand()/((RAND_MAX+1u)/denom)<result.rem); // 1u ootherwise it is overflow
return result.quot+correction;
}
static void prob_uchar_increment(uchar *value){
*value+=prob_div((255-*value),255);
}
struct neuron{
uint32_t min=0, max=UINT32_MAX;
float mu=0, var=0;
uint32_t it=1;
uchar value;
uchar probas[256];
uchar previous_values[256];
uchar current=0;
uchar update (uint32_t s){
float err;
err=s-mu;
mu+=err/(float)it;
if (it != 1) var+=(pow(s-mu, 2)-var)/(float)(it-1); //This is not an exact estimator as mu should be the final one, not the stochastic one
it++;
value=gaussian_cdf(s, mu, var+1); //(1+erf((s-mu)/sqrt(2*var+1)))*255/2.; //var+1 is to be sure it is not null
previous_values[current]=value;
prob_uchar_increment(&probas[value]);
current++;
return value;
}
uchar previous(uchar iterations){
return previous_values[(uchar)(current-iterations)];
}
};
static uchar gaussian_cdf(uint32_t s, float mu, float var){
return (1+erf((s-mu)/sqrt(2*var)))*255/2; //var+1 is to be sure it is not null
}
static int read_iteration(FILE *input_file, uint32_t *time, uint32_t *left_pos, uint32_t *right_pos, uint8_t *left_motor, uint8_t *right_motor){
int ret;
ret=fread(time, sizeof(uint32_t), 1, input_file);
if (ret!=1) return 0;
fread(left_pos, sizeof(uint32_t), 1, input_file);
fread(right_pos, sizeof(uint32_t), 1, input_file);
fread(left_motor, sizeof(uint8_t), 1, input_file);
fread(right_motor, sizeof(uint8_t), 1, input_file);
return 1;
}
int main(int argc, char **argv){
blc_channel input, output, coordinates, parameters, histo, stats, neurons, infos, mutual;
char const *output_name, *input_name, *input_filename, *period_str;
char *default_output_name=NULL;
int period;
FILE *input_file;
uchar previous_p1;
struct neuron d, p1, p2, m1, m2;
uint32_t time, left_pos, right_pos, delta, previous_time;
uint8_t left_motor, right_motor;
SYSTEM_ERROR_CHECK(asprintf(&default_output_name,":%s%d", blc_program_name, getpid()), -1, nullptr);
histo.create_or_open("/pinobo.histo", BLC_CHANNEL_WRITE, 'UIN8', 'NDEF', 2, 256, 5);
stats.create_or_open("/pinobo.stats", BLC_CHANNEL_WRITE, 'FL32', 'NDEF', 1, 10);
neurons.create_or_open("/pinobo.neurons", BLC_CHANNEL_WRITE, 'UIN8', 'NDEF', 1, 5);
infos.create_or_open("/pinobo.infos", BLC_CHANNEL_WRITE, 'UIN8', 'NDEF', 2, 256, 256);
mutual.create_or_open("/pinobo.mutual", BLC_CHANNEL_WRITE, 'UIN8', 'NDEF', 2, 256, 256);
histo.publish();
bzero(histo.data, histo.size);
bzero(stats.data, stats.size);
bzero(infos.data, infos.size);
bzero(mutual.data, mutual.size);
blc_program_set_description("Learning pinobo data");
// blc_program_add_option(&output_name, 'o', "output", "blc_channel-out", "channel name", default_output_name);
blc_program_add_option(&period_str, 'p', "period", "integer", "period in (µs)", 0);
blc_program_add_parameter(&input_filename, "filename", 1, "file from where take the data", nullptr);
blc_program_init(&argc, &argv, blc_quit);
period=strtol(period_str, nullptr, 10);
SYSTEM_ERROR_CHECK(input_file=fopen(input_filename, "r"), nullptr, "Opening '%s'", input_filename);
read_iteration(input_file, &time, &left_pos, &right_pos, &left_motor, &right_motor);
BLC_COMMAND_LOOP(period){
if (read_iteration(input_file, &time, &left_pos, &right_pos, &left_motor, &right_motor)==0) blc_command_ask_quit();
delta=time-previous_time;
/*
histo.uchars[delta*128/100000]+=prob_div(1,1000);
histo.uchars[left_pos*256/1000+256]+=prob_div(1,250);
histo.uchars[right_pos*256/1000+256*2]+=prob_div(1,250);
histo.uchars[left_motor+256*3]+=prob_div(1,250);
histo.uchars[right_motor+256*4]+=prob_div(1,250);
*/
previous_time=time;
stats.floats[0]=d.mu/1000;
stats.floats[1]=d.var/1000000;
stats.floats[2]=p1.mu;
stats.floats[3]=p1.var;
stats.floats[4]=p2.mu;
stats.floats[5]=p2.var;
stats.floats[6]=m1.mu;
stats.floats[7]=m1.var;
stats.floats[8]=m2.mu;
stats.floats[9]=m2.var;
previous_p1=neurons.uchars[1];
neurons.uchars[0]=d.update(delta);
neurons.uchars[1]=p1.update(left_pos);
neurons.uchars[2]=p2.update(right_pos);
neurons.uchars[3]=m1.update(left_motor);
neurons.uchars[4]=m2.update(right_motor);
prob_uchar_increment(&infos.uchars[p1.value+256*p2.value]);
prob_uchar_increment(&histo.uchars[neurons.uchars[0]]);
prob_uchar_increment(&histo.uchars[neurons.uchars[1]+256]);
prob_uchar_increment(&histo.uchars[neurons.uchars[2]+256*2]);
prob_uchar_increment(&histo.uchars[neurons.uchars[3]+256*3]);
prob_uchar_increment(&histo.uchars[neurons.uchars[4]+256*4]);
}
fprintf(stderr, "%f %f, %f %f, %f %f, %f %f, %f %f\n", d.mu, d.var, p1.mu, p1.var, p2.mu, p2.var, m1.mu, m1.var, m2.mu, m2.var);
SYSTEM_ERROR_CHECK(fclose(input_file), -1, nullptr);
return EXIT_SUCCESS;
}
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