Boost logo

Ublas :

From: dvir schirman (dvir.boost_at_[hidden])
Date: 2006-06-08 05:33:08


Hi
When I try to run a program which use ublas I get a Segmentation fault error.
I suspect my mistake is with the ublas vector.
I debuged the program using ddd.
And I saw that the program exit when calling to

b_functions->update(state,0.5,1,3);

(the full code is below).

At the second time, the first time when I call this function its all fine.
When I tried to step into this function, I got to
boost/numeric/ublas/vector.hpp line 64:

vector (size_type size, const array_type &data):
            vector_container<self_type> (),
            data_ (data) {}

When I tried to put breakpoint inside
void base_functions::update(ublas::vector<float> x,float eta, float
noise,float delta)

I saw that the program exit with segmentation fault at:

new_x.resize( x.size());

I am not sure that my mistake is with ublas, but it seems to me that it is.
I'm using Cygwin g++ 3.4.4

here is my code:

main.C
------------

#include "base_functions.H"
#include <iostream>
#include <vector>

using namespace boost::numeric::ublas;
namespace ublas = boost::numeric::ublas;

int main()
{
base_functions* b_functions;
vector<float> cov(2);
for (unsigned int i=0; i<cov.size(); i++)
cov(i)=i+1;
vector<float> state(2);
for (unsigned int i=0; i<state.size(); i++)
state(i)=0;
b_functions = new base_functions(cov, state);
b_functions->compute_function(state);
float v=b_functions->compute_v();
std::cout<<"value="<<v<<std::endl;
b_functions->update(state,0.5,1,3);
b_functions->compute_function(state);
v=b_functions->compute_v();
std::cout<<"value="<<v<<std::endl;

b_functions->compute_function(state);
b_functions->update(state,0.5,1,3);
v=b_functions->compute_v();
std::cout<<"value="<<v<<std::endl;

return 1;

}

base_functions.H
----------------------------
#ifndef BASE_FUNCTIONS_H
#define BASE_FUNCTIONS_H

#ifndef BASIS
#define BASIS

#define DT 0.01

#include "weights.H"
#include <math.h>
#include<iostream>

struct basis
{
boost::numeric::ublas::matrix<float> cov;
boost::numeric::ublas::vector<float> mu;
float a;
float b;
float previous_b;
};

#define ETA_C 0.1
#define ETA_M 0.1
#define INITIAL_VALUE 1.0
#define INITIAL_DELTA 1

class base_functions
{

private:

int N;

boost::numeric::ublas::matrix<float> diag
(boost::numeric::ublas::vector<float> v);
int function_num;
boost::numeric::ublas::vector<float> initial_cov;
basis* functions_vec;
C_weights* weights;
void get_previous_b_vec();
float* b_vec;

public:
base_functions(boost::numeric::ublas::vector<float> covariance,
boost::numeric::ublas::vector<float> x);
~base_functions();
int get_function_num();
bool build_new_function(float func_value, float
delta,boost::numeric::ublas::vector<float> x);
void update(boost::numeric::ublas::vector<float> x,float eta, float
noise,float delta);
float get_previous_b(int index);
float get_b(int index);
float get_max_a();
void compute_function(boost::numeric::ublas::vector<float> x);
float compute_v();
float compute_final_v();

};

#endif
#endif

base_functions.C
------------------------------
base_functions::base_functions(ublas::vector<float> covariance,
ublas::vector<float> x)
: weights(new C_weights())

{
function_num=0;
initial_cov=covariance;
//weights=new_weights;
build_new_function((float)INITIAL_VALUE,(float) INITIAL_DELTA,x);

}

base_functions::~base_functions()
{

}

void base_functions::compute_function(ublas::vector<float> x)
{
int i;
float sum=0;
for(i=0;i<function_num;i++)
{
functions_vec[i].previous_b=functions_vec[i].b;
functions_vec[i].a = expf(-0.5*pow(norm_2(x-functions_vec[i].mu),2));
sum+=functions_vec[i].a;
}
for(i=0;i<function_num;i++)
functions_vec[i].b=functions_vec[i].a/sum;
}

void base_functions::update(ublas::vector<float> x,float eta, float
noise,float delta)
{

get_previous_b_vec();
weights->update_weights(eta, noise,delta,b_vec ,get_function_num());

boost::numeric::ublas::vector<float> new_x, vec, vec2, vec3, delta_mu;
boost::numeric::ublas::matrix<float> mat, delta_cov;
float scalar, scalar2;

new_x.resize( x.size());
vec.resize(x.size());
vec2.resize(x.size());
vec3.resize(x.size());
delta_mu.resize(x.size());
mat.resize(x.size(),x.size());
delta_cov.resize(x.size(),x.size());

for(int i=0;i<function_num;i++)
{
new_x=x-functions_vec[i].mu;
vec=prod(functions_vec[i].cov,new_x);
mat=outer_prod(vec,new_x);
scalar=-ETA_M*DT*delta*weights->get_current_weight(i)*(functions_vec[i].b-1)*functions_vec[i].b;
delta_cov=scalar*mat;
functions_vec[i].cov=functions_vec[i].cov+delta_cov;

scalar2=-ETA_C*DT*delta*weights->get_current_weight(i)*(functions_vec[i].b-1)*functions_vec[i].b;
vec2=prod(functions_vec[i].cov,new_x);
vec3=prod(trans(functions_vec[i].cov),vec2);
delta_mu=scalar2*vec3;
functions_vec[i].mu=functions_vec[i].mu+delta_mu;
}

}

float base_functions::compute_v()
{
float v=0;
for(int i=0;i<get_function_num();i++)
v+=weights->get_current_weight(i)*get_b(i);
/////we changed from previous weight to current weight.
return v;
}

bool base_functions::build_new_function(float func_value,float
delta,ublas::vector<float> x)
{
basis new_func;
    new_func.cov=diag(initial_cov);
new_func.mu=x;
    function_num++;
basis* point=(basis*)malloc((function_num)*sizeof(basis));
if (point==NULL)
{
std::cout<<"memory error at base_functions::build_new_function()"<<std::endl;
return false;
}
else
{
if(!weights->new_weight(func_value,delta,get_function_num()))
return false;
else
{
for (int i=0;i<function_num-1;i++)
point[i]=functions_vec[i];
point[function_num-1]=new_func;
free(functions_vec);
functions_vec=point;
functions_vec[function_num-1].b=1; compute_function(x);
return true;
}
}
}

weights.H
----------------
#ifndef WEIGHTS_H
#define WEIGHTS_H

#ifndef WEIGHT
#define WEIGHT

#define DT 0.01

#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/matrix_proxy.hpp>
#include <boost/numeric/ublas/vector_proxy.hpp>

struct weight
{
float current_value;
float prev_value;
};

class C_weights
{

private:
weight* weights_vec;

public:
C_weights();
~C_weights();
float get_previous_weight(int i);
float get_current_weight(int i);
void update_weights(float eta, float noise, float delta, float*
prev_b_vec, int func_num);
bool new_weight(float func_value, float delta,int func_num);

};

#endif
#endif

weights.C
----------------
#include "weights.H"
#include <iostream>

namespace ublas = boost::numeric::ublas;
using namespace boost::numeric::ublas;

C_weights::C_weights()
{
new_weight((float)1,(float)1, 1);

}

C_weights::~C_weights()
{

}

float C_weights::get_previous_weight(int i)
{
return weights_vec[i].prev_value;
}

float C_weights::get_current_weight(int i)
{
return weights_vec[i].current_value;
}

void C_weights::update_weights(float eta, float noise, float delta,
float* prev_b_vec, int func_num)
{
int i;
for (i=0;i<func_num;i++)
{
weights_vec[i].prev_value=weights_vec[i].current_value;
    weights_vec[i].current_value+=DT*(eta*delta*noise*prev_b_vec[i]);
}
return;

}

bool C_weights::new_weight(float func_value, float delta,int func_num)
{

weight* point=(weight*)malloc((func_num)*sizeof(weight));
if (point==NULL)
{
std::cout<<"memory error at weights::new_weight()"<<std::endl;
return false;
}
else
{
for (int i=0;i<func_num-1;i++)
point[i]=weights_vec[i];
point[func_num-1].current_value=func_value-DT*delta;
point[func_num-1].prev_value=0;
free(weights_vec);
weights_vec=point;

return true;
}
}

Thanks for your help.
Dvir