/** Update centroid images for 1 channel * @param d * @param images * @param weighParameter */ static void _Cig_UpdateCentroidImages(Destin * d, float *** images, // preallocated images to update float weightParameter, // higher value means higher contrast int channel ){ int child_section, i, l, c; _Cig_UpdateLayerZeroImages(d, images, channel); int child_image_width = sqrt(GetNodeFromDestin(d, 0, 0, 0)->ni); for(l = 1 ; l < d->nLayers ; l++){ Node * n = GetNodeFromDestin(d, l, 0, 0); float ** combined_images; MALLOC(combined_images, float *, 4); for(i = 0 ; i < 4 ; i++){ MALLOC(combined_images[i], float, child_image_width * child_image_width); } for(c = 0 ; c < d->nb[l]; c++){ // combine the child layer's shared centroids according // to the weights given in for(child_section = 0 ; child_section < 4 ; child_section++){ // For the current sub section of the current centroid, // generate its representative image and store it in // the appropriate section of combined_images; _Cig_BlendImages(images[l - 1], &n->mu[c][child_section * d->nb[l - 1]], d->nb[l - 1], child_image_width * child_image_width, weightParameter, combined_images[child_section]); } Cig_ConcatImages(combined_images, child_image_width, child_image_width, images[l][c] ); } for(i = 0 ; i < 4 ; i++){ FREE(combined_images[i]); combined_images[i] = NULL; } FREE(combined_images); combined_images = NULL; child_image_width = child_image_width * 2; } return; }
void DestinNetworkAlt::Uniform_addRescaledCentroids(Destin *destin,int layer,int iter,int rescaleiter,int toplayer) { int row,col,width; int i,j,k,l,m; int index=0; float newmu[50000]; Node *currnode,*destnode; std::vector<float> v; v.clear(); currnode=GetNodeFromDestin(destin,toplayer,0,0); i=layer; { width=sqrt(destin->layerSize[i]); row=0;col=0; for(row=0;row<width;row++) { for(col=0;col<width;col++) { destnode=GetNodeFromDestin(destin,i,row,col); for(j=0;j<currnode->nb;j++) { v=rescaleCentroid(toplayer,j,i); if(iter>rescaleiter) { DeleteUniformCentroid(destin,i,j); } memset(newmu,0,sizeof(newmu)); for(k=0;k<v.size();k++) { newmu[k]=v[k]; } AddRescaledCentroids(destin,i,newmu,0,index); } } } } destin->rescale=1; }
// CZT: uniform; void Uniform_ApplyDeltas(Destin * d, uint layer, float ** layerSharedSigma){ uint c, s, ns; float diff, learnRate, dt; //iterate over shared centroids Node * n = GetNodeFromDestin(d, layer, 0,0); for(c = 0 ; c < d->nb[layer]; c++){ //use learning strategy function pointer to get the learning rate learnRate = d->centLearnStratFunc(d, NULL, layer, c); //get the first node of the current layers ns = n->ns; for(s = 0 ; s < ns ; s++){ //move the centroid with the averaged delta dt = d->uf_avgDelta[layer][c][s]; diff = dt * learnRate; n->mu[c][s] += diff; //all nodes in a layer share this n->mu pointer #ifdef CHECK_BIG_MU if ( n->mu[c][s] > 1.0){ oops("Big mu value:%e at line %i\n",n->mu[c][s],__LINE__ ); } #endif n->muSqDiff += diff * diff; //only 0th node of each layer gets a muSqDiff //TODO: write unit test for layerSharedSigma //layerSharedSigma[c * ns + s] += n->beta * (dt * dt - layerSharedSigma[c * ns + s]); layerSharedSigma[c][s] += n->beta * (d->uf_avgSquaredDelta[layer][c][s] - layerSharedSigma[c][s]); } } for(s = 0 ; s < ns ; s++){ d->uf_absvar[layer][s] += n->beta * (d->uf_avgAbsDelta[layer][s] - d->uf_absvar[layer][s]); } return; }
void Uniform_AddNewCentroids(Destin *d) { uint l, i; float absvar; for (l = 0; l < d->nLayers; l++) { // layer not trained or belief dimensionality reached if (d->layerMask[l] == 0 || d->nb[l] >= d->layerMaxNb[l]) { continue; } Node * n = GetNodeFromDestin(d, l, 0, 0); absvar = 0; for (i = 0; i < n->ns; i++) { absvar += d->uf_absvar[l][i]; } absvar /= n->ns; float rnd = (float) rand() / (float) RAND_MAX; if (rnd < d->addCoeff * absvar) { AddUniformCentroid(d, l); } } }
void Uniform_AddRescale(Destin *d,float *rcentroid,int destlayer,int srclayer) { uint l, i,j; float absvar; l=destlayer; //for(l=srclayer-1;l>=0;l--) { if (d->layerMask[l] == 0 || d->nb[l] >= d->layerMaxNb[l]) { //continue; return; } Node *n=GetNodeFromDestin(d, l, 0, 0); absvar=0; for (i = 0; i < n->ns; i++) { absvar += d->uf_absvar[l][i]; } absvar /= n->ns; float rnd = (float) rand() / (float) RAND_MAX; //float rnd=0.654; if (rnd < d->addCoeff * absvar) { //for(j=0;j<min(n->nb,d->nb[srclayer]);j++) { AddRescaledCentroids(d,l,rcentroid,0,n->ns+1); } } } }
void _generateNewUniformCentroidMu(Destin *d, uint l, uint vicinity, float * newMu) { uint i, j, k, ni, nb, np, ns; float sigma; Node * n = GetNodeFromDestin(d, l, 0, 0); ni = n->ni; nb = n->nb; np = n->np; ns = n->ns; float weights[nb]; uint picked[vicinity]; float pickedWeights[vicinity]; // calculate weights float sumWeight = 0; for (i = 0; i < nb; i++) { sigma = 0; for (j = 0; j < ns; j++) { sigma += d->uf_sigma[l][i][j]; } weights[i] = sigma; // d->uf_winFreqs[l][i] * sigma; sumWeight += weights[i]; } // pick centroids with probability proportional to weights float sumPickedWeights = 0; for (i = 0; i < vicinity; i++) { float pickWeight = 0; float rnd = sumWeight * rand() / (float) RAND_MAX; for (j = 0; (j < nb) && (rnd >= pickWeight); j++) { pickWeight += weights[j]; } picked[i] = j - 1; pickedWeights[i] = rand() / (float) RAND_MAX; sumPickedWeights += pickedWeights[i]; } float centerMu[ns]; float centerSigma[ns]; for (i = 0; i < ns; i++) { centerMu[i] = 0; centerSigma[i] = INIT_SIGMA; for (j = 0; j < vicinity; j++) { centerMu[i] += d->uf_mu[l][picked[j]][i] * pickedWeights[j] / sumPickedWeights; } } _sampleNormalDistributedCentroid(newMu, centerMu, centerSigma, ns); // TODO: in recurrent mode take care about position nb+1 _normalizeMu(newMu, ni, nb+1, np); }
void DestinNetworkAlt::printWinningCentroidGrid(int layer){ uint width = (uint)sqrt(destin->layerSize[layer]); uint nidx = 0; Node * nodelist = GetNodeFromDestin(destin, layer, 0, 0); printf("Winning centroids grid - layer %i:\n", layer); for( int r = 0 ; r < width ; r++){ for(int c = 0 ; c < width ; c++ , nidx++){ printf("%i ", nodelist[nidx].winner); } printf("\n"); } }
static void _Cig_UpdateLayerZeroImages(Destin * d, float *** images, // preallocated images to update int channel ){ int pixel, c; Node * n = GetNodeFromDestin(d, 0, 0, 0); for(c = 0 ; c < d->nb[0]; c++){ for(pixel = 0 ; pixel < n->ni ; pixel++){ //images[layer][centroid][pixel] images[0][c][pixel] = n->mu[c][pixel]; // layer 0 centroids directly represent their images } if(channel > 0){ for(pixel=0; pixel < n->ni; ++pixel){ images[0][c][pixel] = n->mu[c][n->ni*channel + n->nb + n->np + pixel]; } } } }
void DestinNetworkAlt::load(const char * fileName){ if(centroidImages != NULL){ Cig_DestroyCentroidImages(destin, centroidImages); centroidImages = NULL; } destin = LoadDestin(destin, fileName); if(destin == NULL){ throw std::runtime_error("load: could not open destin file.\n"); } Node * n = GetNodeFromDestin(destin, 0, 0, 0); this->gamma = n->gamma; this->isUniform = destin->isUniform; this->lambdaCoeff = n->lambdaCoeff; if(temperatures != NULL){ delete [] temperatures; } temperatures = new float[getLayerCount()]; memcpy(temperatures, destin->temp, sizeof(float) * getLayerCount()); imageMode = extRatioToImageMode(destin->extRatio); }
int Cig_GetCentroidImageWidth(Destin * d, int layer){ return sqrt(GetNodeFromDestin(d, 0, 0, 0)->ni) * pow(2, layer); }
void Cig_UpdateCentroidImages(Destin * d, float *** images, // preallocated images to update float weighParameter // higher value means higher contrast ){ int p, l, c, prev_image_width,image_width; Node * n; image_width = sqrt(GetNodeFromDestin(d, 0, 0, 0)->ni); prev_image_width = image_width; for(l = 0 ; l < 1 ; l++){ n = GetNodeFromDestin(d, l, 0, 0); for(c = 0 ; c < d->nb[l]; c++){ for(p = 0 ; p < n->ni ; p++){ images[l][c][p] = n->mu[c * n->ns + p]; } int nRatio; for(nRatio=1; nRatio < d->extRatio; ++nRatio) { for(p=0; p<n->ni; ++p) { images[l][c][n->ni*nRatio + p] = n->mu[c*n->ns + n->ni*nRatio + n->nb + n->np + p]; } } } prev_image_width = image_width; image_width *= 2; } int child_section, i; for(l = 1 ; l < d->nLayers ; l++){ n = GetNodeFromDestin(d, l, 0, 0); float ** combined_images; MALLOC(combined_images, float *, 4); for(i = 0 ; i < 4 ; i++){ MALLOC(combined_images[i], float, prev_image_width * prev_image_width); } for(c = 0 ; c < d->nb[l]; c++){ // combine the child layer's shared centroids according // to the weights given in for(child_section = 0 ; child_section < 4 ; child_section++){ // For the current sub section of the current centroid, // generate its representative image and store it in // the appropriate section of combined_images; Cig_BlendImages(images[l - 1], &n->mu[c * n->ns + child_section * d->nb[l - 1]], d->nb[l - 1], prev_image_width * prev_image_width, weighParameter, combined_images[child_section], l, d->extRatio); } Cig_ConcatImages(combined_images, prev_image_width, prev_image_width, images[l][c] ); } for(i = 0 ; i < 4 ; i++){ FREE(combined_images[i]); combined_images[i] = NULL; } FREE(combined_images); combined_images = NULL; prev_image_width = image_width; image_width *= 2; } return; }
// The method used to distribute values of beliefs associated with centroid that // is going to be deleted. It helps when deleted centroid is very close to good // learned centroids. This centroids from neighbourhood get additional weighted // belief of deleted centroid where more weights have centroids that are closer. void _distributeEvidenceOfDeletedCentroidToNeighbours(Destin *d, uint l, uint idx, uint nearest) { uint i, j, k, nb, ns; Node * n = GetNodeFromDestin(d, l, 0, 0); nb = n->nb; ns = n->ns; if (nb < 2) { fprintf (stderr, "DistributeWeightsOfDeletedCentroid(): called when the layer %d has only single centroid!", l); return; } _Neighbour neighbours[nb]; for (i = 0; i < nb; i++) { neighbours[i].index = i; neighbours[i].distance = _calcNeighboursDistanceEuc(d->uf_mu[l][i], d->uf_mu[l][idx], ns) + EPSILON; neighbours[i].weight = 0; } qsort((void *)neighbours, nb, sizeof(_Neighbour), (void *)&_compareNeighboursByDistance); nearest = _MIN(nearest, nb-1); float sumDistance = 0; for (i = 1; i <= nearest; i++) { sumDistance += neighbours[i].distance; } float sumWeights = 0; for (i = 1; i <= nearest; i++) { neighbours[i].weight = sumDistance / neighbours[i].distance; sumWeights += neighbours[i].weight; } for (i = 1; i <= nearest; i++) { neighbours[i].weight /= sumWeights; } // Layer l+1 if (l+1 < d->nLayers) { n = GetNodeFromDestin(d, l+1, 0, 0); for (i = 0; i < n->nb; i++) { for (j = 0; j < n->nChildren; j++) { for (k = 1; k <= nearest; k++) { d->uf_mu[l+1][i][nb*j + neighbours[k].index] += d->uf_mu[l+1][i][nb*j + idx] * neighbours[k].weight; d->uf_sigma[l+1][i][nb*j + neighbours[k].index] += d->uf_sigma[l+1][i][nb*j + idx] * neighbours[k].weight; } // centroid evidence has been distributed d->uf_mu[l+1][i][nb*j + idx] = 0; d->uf_sigma[l+1][i][nb*j + idx] = 0; } } } // TODO: RECURRENT MODE: move evidence for l layer and l-1 layer }
void AddUniformCentroid(Destin *d, uint l) { uint i, j, ni, nb, np, ns, idx; Node * n = GetNodeFromDestin(d, l, 0, 0); nb = n->nb; ni = n->ni; np = n->np; ns = n->ns; idx = ni + nb; // Layer l float * newMu, * newSigma, * newAvgDelta, * newAvgSquaredDelta; MALLOCV(newMu, float, (ns+1)); MALLOCV(newSigma, float, (ns+1)); MALLOCV(newAvgDelta, float, (ns+1)); MALLOCV(newAvgSquaredDelta, float, (ns+1)); _generateNewUniformCentroidMu(d, l, VICINITY_OF_ADDED_CENTROID, newMu); for (j=0; j < ns+1; j++) { newSigma[j] = INIT_SIGMA; newAvgDelta[j] = 0; newAvgSquaredDelta[j] = 0; } for (i = 0; i < nb; i++) { ArrayInsertFloat(&d->uf_mu[l][i], ns, idx, 0); _normalizeMu(d->uf_mu[l][i], ni, nb+1, np); ArrayInsertFloat(&d->uf_sigma[l][i], ns, idx, INIT_SIGMA); ArrayInsertFloat(&d->uf_avgDelta[l][i], ns, idx, 0); ArrayInsertFloat(&d->uf_avgSquaredDelta[l][i], ns, idx, 0); } ArrayInsertFloat(&d->uf_absvar[l], ns, idx, 0); ArrayInsertFloat(&d->uf_avgAbsDelta[l], ns, idx, 0); ArrayAppendPtr((void *)&d->uf_mu[l], nb, newMu); ArrayAppendPtr((void *)&d->uf_sigma[l], nb, newSigma); ArrayAppendUInt(&d->uf_winCounts[l], nb, 0); ArrayAppendLong(&d->uf_persistWinCounts[l], nb, 0); ArrayAppendLong(&d->uf_persistWinCounts_detailed[l], nb, 0); ArrayAppendPtr((void *)&d->uf_avgDelta[l], nb, newAvgDelta); ArrayAppendPtr((void *)&d->uf_avgSquaredDelta[l], nb, newAvgSquaredDelta); ArrayAppendFloat(&d->uf_starv[l], nb, 1); ArrayAppendFloat(&d->uf_winFreqs[l], nb, 1/(float) nb); _normalizeFloatArray(d->uf_winFreqs[l], nb+1); d->nb[l]++; // increase global number of centroids for layer l for (j = 0; j < d->layerSize[l]; j++) { n =& d->nodes[d->layerNodeOffsets[l] + j]; ArrayAppendFloat(&n->belief, nb, 0); ArrayAppendFloat(&n->beliefEuc, nb, 0); ArrayAppendFloat(&n->beliefMal, nb, 0); ArrayAppendFloat(&n->outputBelief, nb, 0); ArrayInsertFloat(&n->delta, ns, idx, 0); ArrayInsertFloat(&n->observation, ns, idx, 0); // increase centroid dimensionality for each node from layer l UpdateNodeSizes(n, n->ni, nb+1, n->np, n->nc); // pointers may change due to reallocation n->mu = d->uf_mu[l]; n->starv = d->uf_starv[l]; } // Layer l+1 if (l+1 < d->nLayers) { n = GetNodeFromDestin(d, l+1, 0, 0); ns = n->ns; uint childIndexes[n->nChildren]; // indexes of added centroids for all childs float childValues[n->nChildren]; // initial values for all childs float childSigmas[n->nChildren]; for (i = 0; i < n->nChildren; i++) { childIndexes[i] = (i+1)*nb; childValues[i] = 0; childSigmas[i] = INIT_SIGMA; } for (i = 0; i < n->nb; i++) { ArrayInsertFloats(&d->uf_mu[l+1][i], ns, childIndexes, childValues, n->nChildren); ArrayInsertFloats(&d->uf_sigma[l+1][i], ns, childIndexes, childSigmas, n->nChildren); ArrayInsertFloats(&d->uf_avgDelta[l+1][i], ns, childIndexes, childValues, n->nChildren); ArrayInsertFloats(&d->uf_avgSquaredDelta[l+1][i], ns, childIndexes, childValues, n->nChildren); } ArrayInsertFloats(&d->uf_absvar[l+1], ns, childIndexes, childValues, n->nChildren); ArrayInsertFloats(&d->uf_avgAbsDelta[l+1], ns, childIndexes, childValues, n->nChildren); for (j = 0; j < d->layerSize[l+1]; j++) { n =& d->nodes[d->layerNodeOffsets[l+1] + j]; ArrayInsertFloats(&n->delta, ns, childIndexes, childValues, n->nChildren); ArrayInsertFloats(&n->observation, ns, childIndexes, childValues, n->nChildren); // increase centroid dimensionality for each node from layer l+1 UpdateNodeSizes(n, n->ni + n->nChildren, n->nb, n->np, n->nc); // pointers may change due to reallocation n->mu = d->uf_mu[l+1]; n->starv = d->uf_starv[l+1]; } } // Layer l-1 if (l > 0) { n = GetNodeFromDestin(d, l-1, 0, 0); ns = n->ns; uint pIdx = n->ni + n->nb + n->np; // index of added parent centroid for (i = 0; i < n->nb; i++) { ArrayInsertFloat(&d->uf_mu[l-1][i], ns, pIdx, 0); _normalizeMu(d->uf_mu[l-1][i], n->ni, n->nb, n->np+1); ArrayInsertFloat(&d->uf_sigma[l-1][i], ns, pIdx, INIT_SIGMA); ArrayInsertFloat(&d->uf_avgDelta[l-1][i], ns, pIdx, 0); ArrayInsertFloat(&d->uf_avgSquaredDelta[l-1][i], ns, pIdx, 0); } ArrayInsertFloat(&d->uf_absvar[l-1], ns, pIdx, 0); ArrayInsertFloat(&d->uf_avgAbsDelta[l-1], ns, pIdx, 0); for (j = 0; j < d->layerSize[l-1]; j++) { n =& d->nodes[d->layerNodeOffsets[l-1] + j]; ArrayInsertFloat(&n->delta, ns, pIdx, 0); ArrayInsertFloat(&n->observation, ns, pIdx, 0); // increase centroid dimensionality for each node from layer l-1 UpdateNodeSizes(n, n->ni, n->nb, n->np+1, n->nc); // pointers may change due to reallocation n->mu = d->uf_mu[l-1]; n->starv = d->uf_starv[l-1]; } } }
//function for adding rescaled centroids to the existing system. //Here each node has an extra belief dimensionality(an extra centroid) void AddRescaledCentroids(Destin *destin,uint l,float * rcentroid,uint centid) { uint i,j,ns,nb,np,idx,ni; Node * n = GetNodeFromDestin(destin, l, 0, 0); nb = n->nb;ni = n->ni;np = n->np;ns = n->ns; idx = ni + nb; float * rMu, * rSigma, * rAvgDelta, * rAvgSquaredDelta; //if rescaled function was already called before we delete duplicate centroids if(destin->rescale==1) { for(i=rindex;i<destin->nb[l];i++) { DeleteUniformCentroid(destin,l,i); } } //allocate space for uniform centroid location destin->rindex=ni+nb; MALLOCV(rMu, float, (ns+1)); MALLOCV(rSigma, float, (ns+1)); MALLOCV(rAvgDelta, float, (ns+1)); MALLOCV(rAvgSquaredDelta, float, (ns+1)); //initializing rMu with rescaled centroid size for(i=0;i<ns;i++) { rMu[i]=rcentroid[i]; } //initializing rsigma,rAvgDelta and rAvgSquaredDelta for (j=0; j < ns+1; j++) { rSigma[j] = INIT_SIGMA; rAvgDelta[j] = 0; rAvgSquaredDelta[j] = 0; } //similiar to add uniform centroids in centroid.c for (i = 0; i < nb; i++) { ArrayInsertFloat(&destin->uf_mu[l][i], ns, idx, 0); _normalizeMu(destin->uf_mu[l][i], ni, nb+1, np); ArrayInsertFloat(&destin->uf_sigma[l][i], ns, idx, INIT_SIGMA); ArrayInsertFloat(&destin->uf_avgDelta[l][i], ns, idx, 0); ArrayInsertFloat(&destin->uf_avgSquaredDelta[l][i], ns, idx, 0); } ArrayInsertFloat(&destin->uf_absvar[l], ns, idx, 0); ArrayInsertFloat(&destin->uf_avgAbsDelta[l], ns, idx, 0); ArrayAppendPtr((void *)&destin->uf_mu[l], nb, rMu); ArrayAppendPtr((void *)&destin->uf_sigma[l], nb, rSigma); ArrayAppendUInt(&destin->uf_winCounts[l], nb, 0); ArrayAppendLong(&destin->uf_persistWinCounts[l], nb, 0); ArrayAppendLong(&destin->uf_persistWinCounts_detailed[l], nb, 0); ArrayAppendPtr((void *)&destin->uf_avgDelta[l], nb, rAvgDelta); ArrayAppendPtr((void *)&destin->uf_avgSquaredDelta[l], nb, rAvgSquaredDelta); ArrayAppendFloat(&destin->uf_starv[l], nb, 1); ArrayAppendFloat(&destin->uf_winFreqs[l], nb, 1/(float) nb); _normalizeFloatArray(destin->uf_winFreqs[l], nb+1); destin->nb[l]++; // increase global number of centroids for layer l for (j = 0; j < destin->layerSize[l]; j++) { n =& destin->nodes[destin->layerNodeOffsets[l] + j]; ArrayAppendFloat(&n->belief, nb, 0); ArrayAppendFloat(&n->beliefEuc, nb, 0); ArrayAppendFloat(&n->beliefMal, nb, 0); ArrayAppendFloat(&n->outputBelief, nb, 0); ArrayInsertFloat(&n->delta, ns, idx, 0); ArrayInsertFloat(&n->observation, ns, idx, 0); // increase centroid dimensionality for each node from layer l UpdateNodeSizes(n, n->ni, nb+1, n->np, n->nc); // pointers may change due to reallocation n->mu = destin->uf_mu[l]; n->starv = destin->uf_starv[l]; } if (l+1 < destin->nLayers) { n = GetNodeFromDestin(destin, l+1, 0, 0); ns = n->ns; uint childIndexes[n->nChildren]; // indexes of added centroids for all childs float childValues[n->nChildren]; // initial values for all childs float childSigmas[n->nChildren]; for (i = 0; i < n->nChildren; i++) { childIndexes[i] = (i+1)*nb; childValues[i] = 0; childSigmas[i] = INIT_SIGMA; } for (i = 0; i < n->nb; i++) { ArrayInsertFloats(&destin->uf_mu[l+1][i], ns, childIndexes, childValues, n->nChildren); ArrayInsertFloats(&destin->uf_sigma[l+1][i], ns, childIndexes, childSigmas, n->nChildren); ArrayInsertFloats(&destin->uf_avgDelta[l+1][i], ns, childIndexes, childValues, n->nChildren); ArrayInsertFloats(&destin->uf_avgSquaredDelta[l+1][i], ns, childIndexes, childValues, n->nChildren); } ArrayInsertFloats(&destin->uf_absvar[l+1], ns, childIndexes, childValues, n->nChildren); ArrayInsertFloats(&destin->uf_avgAbsDelta[l+1], ns, childIndexes, childValues, n->nChildren); for (j = 0; j < destin->layerSize[l+1]; j++) { n =& destin->nodes[destin->layerNodeOffsets[l+1] + j]; ArrayInsertFloats(&n->delta, ns, childIndexes, childValues, n->nChildren); ArrayInsertFloats(&n->observation, ns, childIndexes, childValues, n->nChildren); // increase centroid dimensionality for each node from layer l+1 UpdateNodeSizes(n, n->ni + n->nChildren, n->nb, n->np, n->nc); // pointers may change due to reallocation n->mu = destin->uf_mu[l+1]; n->starv = destin->uf_starv[l+1]; } } // Layer l-1 if (l > 0) { n = GetNodeFromDestin(destin, l-1, 0, 0); ns = n->ns; uint pIdx = n->ni + n->nb + n->np; // index of added parent centroid for (i = 0; i < n->nb; i++) { ArrayInsertFloat(&destin->uf_mu[l-1][i], ns, pIdx, 0); _normalizeMu(destin->uf_mu[l-1][i], n->ni, n->nb, n->np+1); ArrayInsertFloat(&destin->uf_sigma[l-1][i], ns, pIdx, INIT_SIGMA); ArrayInsertFloat(&destin->uf_avgDelta[l-1][i], ns, pIdx, 0); ArrayInsertFloat(&destin->uf_avgSquaredDelta[l-1][i], ns, pIdx, 0); } ArrayInsertFloat(&destin->uf_absvar[l-1], ns, pIdx, 0); ArrayInsertFloat(&destin->uf_avgAbsDelta[l-1], ns, pIdx, 0); for (j = 0; j < destin->layerSize[l-1]; j++) { n =& destin->nodes[destin->layerNodeOffsets[l-1] + j]; ArrayInsertFloat(&n->delta, ns, pIdx, 0); ArrayInsertFloat(&n->observation, ns, pIdx, 0); // increase centroid dimensionality for each node from layer l-1 UpdateNodeSizes(n, n->ni, n->nb, n->np+1, n->nc); // pointers may change due to reallocation n->mu = destin->uf_mu[l-1]; n->starv = destin->uf_starv[l-1]; } } return; }
void DeleteUniformCentroid(Destin *d, uint l, uint idx) { uint i, j, ni, nb, np, ns; Node * n = GetNodeFromDestin(d, l, 0, 0); nb = n->nb; ni = n->ni; np = n->np; ns = n->ns; _distributeEvidenceOfDeletedCentroidToNeighbours(d, l, idx, NEAREST_OF_DELETED_CENTROID); // Layer l for (i = 0; i < nb; i++) { ArrayDeleteFloat(&d->uf_mu[l][i], ns, ni+idx); _normalizeMu(d->uf_mu[l][i], ni, nb-1, np); ArrayDeleteFloat(&d->uf_sigma[l][i], ns, ni+idx); ArrayDeleteFloat(&d->uf_avgDelta[l][i], ns, ni+idx); ArrayDeleteFloat(&d->uf_avgSquaredDelta[l][i], ns, ni+idx); } ArrayDeleteFloat(&d->uf_absvar[l], ns, ni+idx); ArrayDeleteFloat(&d->uf_avgAbsDelta[l], ns, ni+idx); ArrayDeleteArray((void *)&d->uf_mu[l], nb, idx); ArrayDeleteArray((void *)&d->uf_sigma[l], nb, idx); ArrayDeleteUInt(&d->uf_winCounts[l], nb, idx); ArrayDeleteLong(&d->uf_persistWinCounts[l], nb, idx); ArrayDeleteLong(&d->uf_persistWinCounts_detailed[l], nb, idx); ArrayDeleteArray((void *)&d->uf_avgDelta[l], nb, idx); ArrayDeleteArray((void *)&d->uf_avgSquaredDelta[l], nb, idx); ArrayDeleteFloat(&d->uf_starv[l], nb, idx); ArrayDeleteFloat(&d->uf_winFreqs[l], nb, idx); _normalizeFloatArray(d->uf_winFreqs[l], nb - 1); d->nb[l]--; // decrease global number of centroids for layer l for (j = 0; j < d->layerSize[l]; j++) { n =& d->nodes[d->layerNodeOffsets[l] + j]; ArrayDeleteFloat(&n->belief, nb, idx); ArrayDeleteFloat(&n->beliefEuc, nb, idx); ArrayDeleteFloat(&n->beliefMal, nb, idx); ArrayDeleteFloat(&n->outputBelief, nb, idx); ArrayDeleteFloat(&n->delta, ns, ni+idx); ArrayDeleteFloat(&n->observation, ns, ni+idx); // decrease centroid dimensionality for each node from layer l UpdateNodeSizes(n, n->ni, nb-1, n->np, n->nc); // pointers may change due to reallocation n->mu = d->uf_mu[l]; n->starv = d->uf_starv[l]; } // Layer l+1 if (l+1 < d->nLayers) { n = GetNodeFromDestin(d, l+1, 0, 0); ns = n->ns; uint childIndexes[n->nChildren]; // indexes of deleted centroids for all childs for (i = 0; i < n->nChildren; i++) { childIndexes[i] = i*nb + idx; } for (i = 0; i < n->nb; i++) { ArrayDeleteFloats(&d->uf_mu[l+1][i], ns, childIndexes, n->nChildren); ArrayDeleteFloats(&d->uf_sigma[l+1][i], ns, childIndexes, n->nChildren); ArrayDeleteFloats(&d->uf_avgDelta[l+1][i], ns, childIndexes, n->nChildren); ArrayDeleteFloats(&d->uf_avgSquaredDelta[l+1][i], ns, childIndexes, n->nChildren); } ArrayDeleteFloats(&d->uf_absvar[l+1], ns, childIndexes, n->nChildren); ArrayDeleteFloats(&d->uf_avgAbsDelta[l+1], ns, childIndexes, n->nChildren); for (j = 0; j < d->layerSize[l+1]; j++) { n =& d->nodes[d->layerNodeOffsets[l+1] + j]; ArrayDeleteFloats(&n->delta, ns, childIndexes, n->nChildren); ArrayDeleteFloats(&n->observation, ns, childIndexes, n->nChildren); // decrease centroid dimensionality for each node from layer l+1 UpdateNodeSizes(n, n->ni - n->nChildren, n->nb, n->np, n->nc); // pointers may change due to reallocation n->mu = d->uf_mu[l+1]; n->starv = d->uf_starv[l+1]; } } // Layer l-1 if (l > 0) { n = GetNodeFromDestin(d, l-1, 0, 0); ns = n->ns; uint pIdx = n->ni + n->nb + idx; // index of deleted parent centroid for (i = 0; i < n->nb; i++) { ArrayDeleteFloat(&d->uf_mu[l-1][i], ns, pIdx); _normalizeMu(d->uf_mu[l-1][i], n->ni, n->nb, n->np-1); ArrayDeleteFloat(&d->uf_sigma[l-1][i], ns, pIdx); ArrayDeleteFloat(&d->uf_avgDelta[l-1][i], ns, pIdx); ArrayDeleteFloat(&d->uf_avgSquaredDelta[l-1][i], ns, pIdx); } ArrayDeleteFloat(&d->uf_absvar[l-1], ns, pIdx); ArrayDeleteFloat(&d->uf_avgAbsDelta[l-1], ns, pIdx); for (j = 0; j < d->layerSize[l-1]; j++) { n =& d->nodes[d->layerNodeOffsets[l-1] + j]; ArrayDeleteFloat(&n->delta, ns, pIdx); ArrayDeleteFloat(&n->observation, ns, pIdx); // decrease centroid dimensionality for each node from layer l-1 UpdateNodeSizes(n, n->ni, n->nb, n->np-1, n->nc); // pointers may change due to reallocation n->mu = d->uf_mu[l-1]; n->starv = d->uf_starv[l-1]; } } }