#include "Connections.h"
// t 0
// e 1
// i 2
Connections::Connections()
{
throw "don't use this constructor";
}
Connections::Connections(Random* rand_Gen, SystemConstants* SC)
{
randGen = rand_Gen;
sc = SC;
//CreateConnectionMatrix(sc->N,sc->mat_prob, randGen);
// ********************TREE ARRAY VERSION******************
connections = new int ***[pop_num]; //post populations
delay_mat = new double***[pop_num];//rand delay
inDegree_prob = new double**[pop_num];
inDegrees_K = new double**[pop_num];
//randVals = new double***[pop_num];
for (int post_pop = 0; post_pop <pop_num; post_pop++) {
connections[post_pop] = new int **[pop_num + 1]; //pre-populations
delay_mat[post_pop] = new double **[pop_num + 1];
inDegree_prob[post_pop] = new double *[pop_num + 1];
inDegrees_K[post_pop] = new double *[pop_num + 1];
//randVals[post_pop] = new double **[pop_num + 1];
for (int pre_pop = 0; pre_pop < pop_num + 1; pre_pop++) {
connections[post_pop][pre_pop] = new int *[sc->N[pre_pop]];
delay_mat[post_pop][pre_pop] = new double *[sc->N[pre_pop]];
inDegree_prob[post_pop][pre_pop] = new double[sc->N[post_pop + 1]];
inDegrees_K[post_pop][pre_pop] = new double[sc->N[post_pop + 1]];
//randVals[post_pop][pre_pop] = new double*[sc->N[pre_pop ]];
//for (int pre_n = 0; pre_n < sc->N[pre_pop]; pre_n++) {
//randVals[post_pop][pre_pop][pre_n] = new double[sc->N[post_pop + 1]];
//}
}
}
gap_prematrix = new int *[sc->N[pop_num]];
gap_mat = new int *[sc->N[pop_num]];
gap_con_num = new int[sc->N[pop_num]];
for (int i_n = 0; i_n < sc->N[pop_num]; i_n++) {
gap_prematrix[i_n] = new int[sc->N[pop_num]];
}
// *********************************************************
CreateConnectionMatrix(randGen);
}
void Connections::CreateConnectionMatrix (Random* randGen) {
//ofstream connections;
//connections.open(sc->IO_path);
sc->setSpikevals_and_matprob();
//cout << "conmat1" << endl;
for (int ind_post_pop = 0; ind_post_pop < pop_num ; ind_post_pop++) {
//Set_ki_Prob_FULLCOR(sc->mat_prob[0][0],sc->mat_prob[0][1],sc->sig_ki[0][0],sc->sig_ki[0][1]);
//cout << "conmat2, postpop "<<ind_post_pop << endl;
for (int ind_pre_pop = 0; ind_pre_pop < pop_num + 1; ind_pre_pop++) {
//cout << "conmat3, postpop " << ind_post_pop <<", prepop "<<ind_pre_pop<< endl;
//cout << "prob: " << sc->mat_prob[ind_post_pop][ind_pre_pop] << endl;
Set_ki_Prob(sc->mat_prob[ind_post_pop][ind_pre_pop], sc->sig_ki[ind_post_pop][ind_pre_pop],ind_post_pop,ind_pre_pop);
//cout << "conmat4, postpop " << ind_post_pop << ", prepop " << ind_pre_pop << endl;
partial_matrix_fill(ind_post_pop, sc->N[ind_post_pop+1], ind_pre_pop,
sc->N[ind_pre_pop]/*, sc->mat_prob[ind_post_pop][ind_pre_pop] */,randGen);
//cout << "createMatrix " << ind_post_pop << ": " << randGen->count << endl;
}
}
//cout << "conmat5" << endl;
if(sc->flag_el==1) CreateGapMatrix();
}
void Connections::Set_ki_Prob(double mean_prob, double relative_deviation, int post_pop,int pre_pop) {
//ki_dist = Normaldev_BM(mean_prob, mean_prob*relative_deviation,seed+time(NULL));
for (int ki_ind=0; ki_ind < sc->N[post_pop + 1]; ki_ind++) {
inDegree_prob[post_pop][pre_pop][ki_ind] = mean_prob+ mean_prob*relative_deviation*randGen->normaldist.dev();
if ((inDegree_prob[post_pop][pre_pop][ki_ind] < 0)||(inDegree_prob[post_pop][pre_pop][ki_ind] > 1)){
ki_ind--;//special case choice
}
}
}
void Connections::Set_ki_Prob_FULLCOR(double mean_prob_it, double mean_prob_ii, double sigit, double sigii) {
if(pop_num!=1){
printf("error: Set_ki_Prob_FULLCOR only works with pop_num==1, line %d file %s",__LINE__,__FILE__);
throw "error";
}
if (1== 1) {
printf("FULLCOR is deprecated (time(NULL) for seed) pop_num==1, line %d file %s", __LINE__, __FILE__);
throw "error";
}
ki_dist = Normaldev_BM(mean_prob_it, mean_prob_it*sigit, time(NULL));///FIXXXXX SEEDDDDD
for (int ki_ind=0; ki_ind < sc->N[1]; ki_ind++) {
inDegree_prob[0][0][ki_ind] = ki_dist.dev();
inDegree_prob[0][1][ki_ind]=inDegree_prob[0][0][ki_ind]*mean_prob_ii/mean_prob_it;
if ((inDegree_prob[0][0][ki_ind] < 0)||(inDegree_prob[0][0][ki_ind] > 1)){
ki_ind--;//special case choice
}
}
}
void Connections::partial_matrix_fill(int post_pop_ind, int post_num_neurons, int pre_pop_ind,
int pre_num_neurons/*, double connection_p */, Random *randGen) {
double rand_x;
int* buffer = new int[post_num_neurons];
for (int post_n_ind = 0; post_n_ind < post_num_neurons; post_n_ind++) {
inDegrees_K[post_pop_ind][pre_pop_ind][post_n_ind] = 0;
}
for (int pre_ind = 0; pre_ind < pre_num_neurons; pre_ind++) {
int count_connections = 0;
for (int post_ind = 0; post_ind < post_num_neurons; post_ind++) {
rand_x = randGen->RandomUniform0_to_1();
//randVals[post_pop_ind][pre_pop_ind][pre_ind][post_ind] = rand_x;
if (rand_x < inDegree_prob[post_pop_ind][pre_pop_ind][post_ind]) {
buffer[count_connections] = post_ind;
count_connections++;
inDegrees_K[post_pop_ind][pre_pop_ind][post_ind]++; //indegrees probability distribution
}
}
connections[post_pop_ind ][pre_pop_ind][pre_ind] = new int[count_connections+1];
delay_mat[post_pop_ind ][pre_pop_ind][pre_ind] = new double[count_connections];
for (int e_ind_toMat = 0; e_ind_toMat < count_connections; e_ind_toMat++) {
connections[post_pop_ind ][pre_pop_ind][pre_ind][e_ind_toMat] = buffer[e_ind_toMat];
if (sc->d_tau[post_pop_ind][pre_pop_ind] != 0) {
printf("need to uncomment code dealing with delay variability, line %d file %s", __LINE__, __FILE__);
}
//double rand_del = sc->d_tau[post_pop_ind][pre_pop_ind] * (2 * randGen->RandomUniform0_to_1() - 1); //for DELAY VARIABILITY
delay_mat[post_pop_ind][pre_pop_ind][pre_ind][e_ind_toMat] = 0;// rand_del;
}
connections[post_pop_ind][pre_pop_ind][pre_ind][count_connections] = -1;
}
delete[] buffer;
}
void Connections::clean_connection_matrix() {
for (int post_pop = pop_num - 1; post_pop >= 0; post_pop--) {
for (int pre_pop = pop_num; pre_pop >= 0; pre_pop--) {
for (int pre_indNeur = 0; pre_indNeur < sc->N[pre_pop]; pre_indNeur++) {
delete[] connections[post_pop][pre_pop][pre_indNeur];
delete[] delay_mat[post_pop][pre_pop][pre_indNeur];
}
}
}
if (sc->flag_el == 1) {
for (int i_n = 0; i_n < sc->N[pop_num]; i_n++) {
delete[] gap_mat[i_n];
}
}
}
int Connections::num_connections(int post_pop_num, int pre_pop_num, int pre_ind) {
int count_con = 0;
while (connections[post_pop_num][pre_pop_num][pre_ind][count_con] != -1) count_con++;
return count_con;
}
void Connections::Print_inDegrees(string path) {
ofstream inDegrees_wr;
inDegrees_wr.open(path);
for (int inh_n = 0; inh_n < sc->N[pop_num]; inh_n++) {
inDegrees_wr << inh_n << " " << inDegrees_K[0][0][inh_n] << " " << inDegrees_K[0][1][inh_n]<<" "<<
inDegree_prob[0][0][inh_n] << " " <<inDegree_prob[0][1][inh_n] << endl;
}
}
void Connections::CreateGapMatrix() {
for (int i_n = 0; i_n < sc->N[pop_num]; i_n++) {
for (int j_n = 0; j_n <= i_n; j_n++) {
double x_rand = randGen->RandomUniform0_to_1();
double p = double(sc->Kel) / sc->N[pop_num];
if (x_rand < p) {
gap_prematrix[i_n][j_n] = 1;
}
else {
gap_prematrix[i_n][j_n] = 0;
}
}
}
for (int i_n = 0; i_n < sc->N[pop_num]; i_n++) {
for (int j_n = i_n + 1; j_n <sc->N[pop_num]; j_n++) {
gap_prematrix[i_n][j_n] = gap_prematrix[j_n][i_n];
}
}
int con_count;
int *buffer = new int[sc->N[pop_num]];
for (int i_n = 0; i_n < sc->N[pop_num]; i_n++) {
con_count = 0;
for (int j_n = 0; j_n <sc->N[pop_num]; j_n++) {
if (i_n == j_n) continue;
if (gap_prematrix[i_n][j_n] == 1) {
buffer[con_count] = j_n;
con_count++;
}
}
gap_con_num[i_n] = con_count;
//cout << "gap_con_num[i_n]: " << gap_con_num[i_n] << endl;
gap_mat[i_n] = new int[con_count];
for (int con_ind = 0; con_ind < con_count; con_ind++) {
gap_mat[i_n][con_ind] = buffer[con_ind];
}
}
delete[] buffer;
}
Connections::~Connections()
{
if (connections != nullptr) {
//**************************TREE ARRAY VERSION*******************
for (int post_pop = pop_num-1; post_pop >= 0; post_pop--) {
for (int pre_pop =pop_num; pre_pop >=0; pre_pop--) {
for (int pre_indNeur = 0; pre_indNeur < sc->N[pre_pop]; pre_indNeur++) {
delete[] connections[post_pop][pre_pop][pre_indNeur];
delete[] delay_mat[post_pop][pre_pop][pre_indNeur];
//delete[] randVals[post_pop][pre_pop][pre_indNeur];
}
delete[] connections[post_pop][pre_pop];
delete[] delay_mat[post_pop][pre_pop];
delete[] inDegree_prob[post_pop][pre_pop];
delete[] inDegrees_K[post_pop][pre_pop];
//delete[] randVals[post_pop][pre_pop];
}
delete[] connections[post_pop];
delete[] delay_mat[post_pop];
delete[] inDegree_prob[post_pop];
delete[] inDegrees_K[post_pop];
//delete[] randVals[post_pop];
}
delete[] connections;
delete[] delay_mat;
delete[] inDegree_prob;
delete[] inDegrees_K;
//delete[] randVals;
for (int i_n = 0; i_n < sc->N[pop_num]; i_n++) {
delete[] gap_prematrix[i_n];
}
delete[] gap_prematrix;
delete[] gap_mat;
delete[] gap_con_num;
//**************************************************************
}
}