#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "../kernel/coco.h"
#include "../kernel/series.h" /**only for COMMAND**/
#include "local.h" /**only for single_circ_gauss**/
/****************************** single_ptr2act *******************************/
/* Target act's will be set to cmd-pointer's float_val. */
DOUBLE single_ptr2act (PARAMS *g, AREA *A, COMMAND *cmd, int ct_t, int ct_n) {
return (DOUBLE)(cmd->pointers[0]->float_val);
}
/****************************** set_ptr_int_val ******************************/
/* Can be used in all contexts ("nevermind" status). */
/* Later move all ptr-related functions to an extra file. */
DOUBLE set_ptr_int_val (PARAMS *g, AREA *A, COMMAND *cmd, int ct_t, int ct_n) {
cmd->pointers[0]->int_val = (int)(cmd->quantum[0][0]);
return (DOUBLE)(0);
}
/******************************* set_ptr_val *********************************/
/* Set int_val and float_val of the pointer to S_from1. */
DOUBLE set_ptr_val (PARAMS *g, AREA *A, COMMAND *cmd, int ct_t, int ct_n) {
cmd->pointers[0]->int_val = (int)(cmd->S_from1[0][ct_t][ct_n]);
cmd->pointers[0]->float_val = cmd->S_from1[0][ct_t][ct_n];
fprintf (stderr, "\nset_ptr_val to %f ", cmd->S_from1[0][ct_t][ct_n]);
return (cmd->S_from1[0][ct_t][ct_n]);
}
/****************************** single_copy **********************************/
/* Copys old source to new time. */
/* One source allowed only ("here" or another area of the same size). */
/* Previously feed_l_copy or feed_copy. */
DOUBLE single_copy (PARAMS *g, AREA *A, COMMAND *cmd, int ct_t, int ct_n) {
const int t_old = ct_t + (int)(cmd->quantum[0][0]);
if (t_old < 0)
return (cmd->S_from1[0][ 0 ][ct_n]);
else
return (cmd->S_from1[0][t_old][ct_n]);
}
/****************************** single_copy_limited **************************/
/* Copys, but only the first q[0][0] neurons. */
/* One source (prob. another area). q[0][0] must NOT be larger than this d_r.*/
/* Has only special functionality in hacked version for saccade learning ... */
double single_copy_limited (PARAMS *g, AREA *A, COMMAND *cmd, int ct_t, int ct_n) {
if (ct_n < cmd->quantum[0][0])
return (cmd->S_from1[0][ct_t][ct_n]);
else
return (0.0);
}
/****************************** single_mean_back *****************************/
/* Averages acts between rlen time q[0][0] and q[1][0] and returns mean. */
DOUBLE single_mean_back (PARAMS *g, AREA *A, COMMAND *cmd, int ct_t, int ct_n) {
if (ct_t != 0)
fprintf (stderr, "\nsingle_mean_back wants to operate only at t=0!\n");
if (cmd->anz_quantums != 2)
fprintf (stderr, "\nsingle_mean_back wants begin and end\n");
int begin = (int)(cmd->quantum[0][0]);
int end = (int)(cmd->quantum[1][0]);
if (end <= begin)
fprintf (stderr, "\nsingle_mean_back wants end > begin\n");
DOUBLE average = 0.0;
for (int t = begin; t < end; ++t)
average += cmd->S_from1[0][t][ct_n];
return (average / (DOUBLE)(end - begin));
}
/******************************* single_circ_gauss ***************************/
/* Uses local_circ_gauss, but shift the mean by mu = 2PI / rlen * ct_t. */
DOUBLE single_circ_gauss (PARAMS *g, AREA *A, COMMAND *cmd, int ct_t, int ct_n) {
DOUBLE params[2];
params[0] = 2.0 * M_PI * (DOUBLE)ct_t / cmd->quantum[0][0];
params[1] = cmd->quantum[0][1];
return local_circ_gauss (params, cmd->S_from1[0][ct_t][ct_n], 0.0);
}
/****************************** single_l_add *********************************/
/* Updates old source with eps_r-correction of new estimation. */
/* One source allowed only ("here" or another area of the same size). */
/* Could be local (_l_) if there was no offset. */
DOUBLE single_l_add (PARAMS *g, AREA *A, COMMAND *cmd, int ct_t, int ct_n) {
int t_old = (cmd->anz_quantums == 2) ? 0 /**functions as dummy here**/
: fprintf (stderr, "\nsingle_l_add wants 2 quantums!\n");
const DOUBLE eps_r = cmd->quantum[1][0];
t_old = ct_t + (int)(cmd->quantum[0][0]);
if (t_old < 0)
return ( cmd->S_target[ 0 ][ct_n]); /*was from1[0]-->target*/
else
return ( cmd->S_target[t_old][ct_n] /*first was from1[0]-->target*/
+ cmd->S_from1[0][ct_t][ct_n] * eps_r);
}
/****************************** feed_l_replace *******************************/
/* Like feed_l_add, but NOT solely additive. */
DOUBLE feed_l_replace (PARAMS *g, AREA *A, COMMAND *cmd, int ct_t, int ct_n) {
int t_old = (cmd->anz_quantums == 2) ? 0 /**functions as dummy here**/
: fprintf (stderr, "\nfeed_l_replace wants 2 quantums!\n");
const DOUBLE eps_r = cmd->quantum[1][0];
t_old = ct_t + (int)(cmd->quantum[0][0]);
if (t_old < 0)
return ( cmd->S_target[ 0 ][ct_n]); /*was from1[0]-->target*/
else
return ( cmd->S_target[t_old][ct_n] * (1.0 - eps_r) /**!**/
+ cmd->S_from1[0][ct_t][ct_n] * eps_r);
}
/****************************** feed_l_rand_from *****************************/
/* Set to random values taken from a given set and with given probabilities. */
/* No input. Local. Parameters like: */
/* q[0][.]: -1+-0.5+0.5+1 the states */
/* q[1][.]: 0.25+0.25+0.25+0.25 their probabilities (need not sum to one). */
DOUBLE feed_l_rand_from (PARAMS *g, AREA *A, COMMAND *cmd, int ct_t, int ct_n) {
DOUBLE part_sum = 0.0;
DOUBLE choose;
int i;
for (i = 0; i < cmd->anz_quant[1]; ++i)
part_sum += cmd->quantum[1][i];
choose = drand48 () * part_sum;
i = -1;
do {
i += 1;
choose -= cmd->quantum[1][i];
} while (choose > 0.0);
return (cmd->quantum[0][i]);
}
/****************************** get_l_covar **********************************/
/* Get "diagonalized correlation matrix" for act based on 1000 iterations(!!)*/
/* One source allowed only ("here"). */
/* Could be local (_l_) if there was no average over time. */
DOUBLE feed_l_covar (PARAMS *g, AREA *A, COMMAND *cmd, int ct_t, int ct_n) {
int ilen = 1000; /**!!! cannot get from g->ilen ; how about z->ilen? **/
static int listlen = 0;
int sel = -1;
int i;
struct liste { int area ; char letter ; int zaehler ; int maxzaehl ;
DOUBLE *values ; DOUBLE *oldvals ; };
static struct liste *list;
int area = cmd->area;
/** use area and target value to distinguish different computations **/
for (i = 0; i < listlen; ++i)
if ((list[i].area == area) && (list[i].letter == cmd->ch_target))
sel = i;
/**allocate and initialize**/
if (sel == -1) {
list = (struct liste *)realloc (list,
(listlen + 1) * sizeof (struct liste));
sel = listlen;
list[sel].area = area;
list[sel].letter = cmd->ch_target;
list[sel].zaehler = 0;
list[sel].maxzaehl= ilen * A[area].d_n * (int)(1.0/cmd->moment + 0.01);
list[sel].values = (DOUBLE *)calloc(A[area].d_n, sizeof(DOUBLE));
list[sel].oldvals = (DOUBLE *)calloc(A[area].d_n, sizeof(DOUBLE));
for (i = 0; i < A[area].d_n; ++i) {
list[sel].values[i] = 0.0; /*init with 0*/
list[sel].oldvals[i] = 1.0; /*init with 1*/
}
fprintf (stderr, "\n adding %d %c to the %d-iteration covar list ",
list[sel].area, list[sel].letter, ilen);
listlen += 1;
}
/**compute**/
list[sel].values[ct_n] += cmd->S_from1[0][ct_t][ct_n]
* cmd->S_from1[0][ct_t][ct_n];
/**avarage, also over time, and initialize**/
if ((list[sel].zaehler % list[sel].maxzaehl < A[area].d_n) &&
(list[sel].zaehler >= A[area].d_n)) {
/* fprintf (stderr, "%d", area); */
list[sel].oldvals[ct_n] = list[sel].values[ct_n]
/ (DOUBLE)(list[sel].maxzaehl) * (DOUBLE)(A[area].d_n);
list[sel].values[ct_n] = 0.0;
}
if (list[sel].zaehler % list[sel].maxzaehl == A[area].d_n)
list[sel].zaehler = A[area].d_n;
list[sel].zaehler += 1;
return (list[sel].oldvals[ct_n]); /** =1 at first time**/
}