// Find prototypes by the MST approach void opf_MSTPrototypes(Subgraph *sg){ int p,q; float weight; RealHeap *Q=NULL; float *pathval = NULL; int pred; float nproto; // initialization pathval = AllocFloatArray(sg->nnodes); Q = CreateRealHeap(sg->nnodes, pathval); for (p = 0; p < sg->nnodes; p++) { pathval[ p ] = FLT_MAX; sg->node[p].status=0; } pathval[0] = 0; sg->node[0].pred = NIL; InsertRealHeap(Q, 0); nproto=0.0; // Prim's algorithm for Minimum Spanning Tree while ( !IsEmptyRealHeap(Q) ) { RemoveRealHeap(Q,&p); sg->node[p].pathval = pathval[p]; pred=sg->node[p].pred; if (pred!=NIL) if (sg->node[p].truelabel != sg->node[pred].truelabel){ if (sg->node[p].status!=opf_PROTOTYPE){ sg->node[p].status=opf_PROTOTYPE; nproto++; } if (sg->node[pred].status!=opf_PROTOTYPE){ sg->node[pred].status=opf_PROTOTYPE; nproto++; } } for (q=0; q < sg->nnodes; q++){ if (Q->color[q]!=BLACK){ if (p!=q){ if(!opf_PrecomputedDistance) weight = opf_ArcWeight(sg->node[p].feat,sg->node[q].feat,sg->nfeats); else weight = opf_DistanceValue[sg->node[p].position][sg->node[q].position]; if ( weight < pathval[ q ] ) { sg->node[q].pred = p; UpdateRealHeap(Q, q, weight); } } } } } DestroyRealHeap(&Q); free( pathval ); }
//read subgraph from opf format file Subgraph *ReadSubgraph(char *file){ Subgraph *g = NULL; FILE *fp = NULL; int nnodes, i, j; char msg[256]; size_t result; if((fp = fopen(file, "rb")) == NULL){ sprintf(msg, "%s%s", "Unable to open file ", file); Error(msg,"ReadSubGraph"); } /*reading # of nodes, classes and feats*/ result = fread(&nnodes, sizeof(int), 1, fp); g = CreateSubgraph(nnodes); result = fread(&g->nlabels, sizeof(int), 1, fp); result = fread(&g->nfeats, sizeof(int), 1, fp); /*reading features*/ for (i = 0; i < g->nnodes; i++){ g->node[i].feat = AllocFloatArray(g->nfeats); result = fread(&g->node[i].position, sizeof(int), 1, fp); result = fread(&g->node[i].truelabel, sizeof(int), 1, fp); for (j = 0; j < g->nfeats; j++) result = fread(&g->node[i].feat[j], sizeof(float), 1, fp); } fclose(fp); return g; }
//retorna apenas um classificador sem nenhuma amostra void empty_ensemble(Subgraph *g, Subgraph *gTraining, int posicao,int k, Subgraph **out){ //Subgraph *out = (Subgraph *)calloc(k, sizeof(Subgraph)); int i,j; //Subamostragem int n = g->nnodes; int m = (n/2)/k; printf("alocar\n"); out[posicao] = CreateSubgraph(m);//cria um novo out[posicao]->nfeats = g->nfeats;//copia o numero dos atributos out[posicao]->nlabels = g->nlabels;//copia o numero de rotulos for (j = 0; j <m; j++)//aloca a quantidade de atributos out[posicao]->node[j].feat = AllocFloatArray(out[posicao]->nfeats); printf("Novo grafo vazio criado!\n"); }
// Normalized cut computed only for sg->bestk neighbors float opf_NormalizedCutToKmax( Subgraph *sg ) { int l, p, q, k; const int kmax = sg->bestk; Set *Saux; float ncut, dist; float *acumIC; //acumulate weights inside each class float *acumEC; //acumulate weights between the class and a distinct one ncut = 0.0; acumIC = AllocFloatArray( sg->nlabels ); acumEC = AllocFloatArray( sg->nlabels ); for ( p = 0; p < sg->nnodes; p++ ) { const int nadj = sg->node[p].nplatadj + kmax; //for plateaus the number of adjacent //nodes will be greater than the current //kmax, but they should be considered for ( Saux = sg->node[ p ].adj, k = 1; k <= nadj; Saux = Saux->next, k++ ) { q = Saux->elem; if(!opf_PrecomputedDistance) dist = opf_ArcWeight(sg->node[p].feat,sg->node[q].feat,sg->nfeats); else dist = opf_DistanceValue[sg->node[p].position][sg->node[q].position]; if ( dist > 0.0 ) { if ( sg->node[ p ].label == sg->node[ q ].label ) { acumIC[ sg->node[ p ].label ] += 1.0 / dist; // intra-class weight } else // inter - class weight { acumEC[ sg->node[ p ].label ] += 1.0 / dist; // inter-class weight } } } } for ( l = 0; l < sg->nlabels; l++ ) { if ( acumIC[ l ] + acumEC[ l ] > 0.0 ) ncut += (float) acumEC[ l ] / ( acumIC[ l ] + acumEC[ l ] ); } free( acumEC ); free( acumIC ); return( ncut ); }
// PDF computation only for sg->bestk neighbors void opf_PDFtoKmax(Subgraph *sg) { int i,nelems; const int kmax = sg->bestk; double dist; float *value=AllocFloatArray(sg->nnodes); Set *adj=NULL; sg->K = (2.0*(float)sg->df/9.0); sg->mindens = FLT_MAX; sg->maxdens = FLT_MIN; for (i=0; i < sg->nnodes; i++) { adj=sg->node[i].adj; value[i]=0.0; nelems=1; int k; //the PDF is computed only for the kmax adjacents //because it is assumed that there will be no plateau //neighbors yet, i.e. nplatadj = 0 for every node in sg for (k = 1; k <= kmax; k++) { if(!opf_PrecomputedDistance) dist = opf_ArcWeight(sg->node[i].feat,sg->node[adj->elem].feat,sg->nfeats); else dist = opf_DistanceValue[sg->node[i].position][sg->node[adj->elem].position]; value[i] += exp(-dist/sg->K); adj = adj->next; nelems++; } value[i] = (value[i]/(float)nelems); if (value[i] < sg->mindens) sg->mindens = value[i]; if (value[i] > sg->maxdens) sg->maxdens = value[i]; } if (sg->mindens==sg->maxdens) { for (i=0; i < sg->nnodes; i++) { sg->node[i].dens = opf_MAXDENS; sg->node[i].pathval= opf_MAXDENS-1; } } else { for (i=0; i < sg->nnodes; i++) { sg->node[i].dens = ((float)(opf_MAXDENS-1)*(value[i]-sg->mindens)/(float)(sg->maxdens-sg->mindens))+1.0; sg->node[i].pathval=sg->node[i].dens-1; } } free(value); }
// Normalized cut float opf_NormalizedCut( Subgraph *sg ){ int l, p, q; Set *Saux; float ncut, dist; float *acumIC; //acumulate weights inside each class float *acumEC; //acumulate weights between the class and a distinct one ncut = 0.0; acumIC = AllocFloatArray( sg->nlabels ); acumEC = AllocFloatArray( sg->nlabels ); for ( p = 0; p < sg->nnodes; p++ ) { for ( Saux = sg->node[ p ].adj; Saux != NULL; Saux = Saux->next ) { q = Saux->elem; if (!opf_PrecomputedDistance) dist = opf_ArcWeight(sg->node[p].feat,sg->node[q].feat,sg->nfeats); else dist = opf_DistanceValue[sg->node[p].position][sg->node[q].position]; if ( dist > 0.0 ) { if ( sg->node[ p ].label == sg->node[ q ].label ) { acumIC[ sg->node[ p ].label ] += 1.0 / dist; // intra-class weight } else // inter - class weight { acumEC[ sg->node[ p ].label ] += 1.0 / dist; // inter-class weight } } } } for ( l = 0; l < sg->nlabels; l++ ) { if ( acumIC[ l ] + acumEC[ l ] > 0.0 ) ncut += (float) acumEC[ l ] / ( acumIC[ l ] + acumEC[ l ] ); } free( acumEC ); free( acumIC ); return( ncut ); }
//Training function ----- void opf_OPFTraining(Subgraph *sg){ int p,q, i; float tmp,weight; RealHeap *Q = NULL; float *pathval = NULL; // compute optimum prototypes opf_MSTPrototypes(sg); // initialization pathval = AllocFloatArray(sg->nnodes); Q=CreateRealHeap(sg->nnodes, pathval); for (p = 0; p < sg->nnodes; p++) { if (sg->node[p].status==opf_PROTOTYPE){ sg->node[p].pred = NIL; pathval[p] = 0; sg->node[p].label = sg->node[p].truelabel; InsertRealHeap(Q, p); }else{ // non-prototypes pathval[p] = FLT_MAX; } } // IFT with fmax i=0; while ( !IsEmptyRealHeap(Q) ) { RemoveRealHeap(Q,&p); sg->ordered_list_of_nodes[i]=p; i++; sg->node[p].pathval = pathval[p]; for (q=0; q < sg->nnodes; q++){ if (p!=q){ if (pathval[p] < pathval[q]){ if(!opf_PrecomputedDistance) weight = opf_ArcWeight(sg->node[p].feat,sg->node[q].feat,sg->nfeats); else weight = opf_DistanceValue[sg->node[p].position][sg->node[q].position]; tmp = MAX(pathval[p],weight); if ( tmp < pathval[ q ] ) { sg->node[q].pred = p; sg->node[q].label = sg->node[p].label; UpdateRealHeap(Q, q, tmp); } } } } } DestroyRealHeap( &Q ); free( pathval ); }
// Create adjacent list in subgraph: a knn graph void opf_CreateArcs(Subgraph *sg, int knn){ int i,j,l,k; float dist; int *nn=AllocIntArray(knn+1); float *d=AllocFloatArray(knn+1); /* Create graph with the knn-nearest neighbors */ sg->df=0.0; for (i=0; i < sg->nnodes; i++) { for (l=0; l < knn; l++) d[l]=FLT_MAX; for (j=0; j < sg->nnodes; j++) { if (j!=i) { if (!opf_PrecomputedDistance) d[knn] = opf_ArcWeight(sg->node[i].feat,sg->node[j].feat,sg->nfeats); else d[knn] = opf_DistanceValue[sg->node[i].position][sg->node[j].position]; nn[knn]= j; k = knn; while ((k > 0)&&(d[k]<d[k-1])) { dist = d[k]; l = nn[k]; d[k] = d[k-1]; nn[k] = nn[k-1]; d[k-1] = dist; nn[k-1] = l; k--; } } } for (l=0; l < knn; l++) { if (d[l]!=INT_MAX) { if (d[l] > sg->df) sg->df = d[l]; //if (d[l] > sg->node[i].radius) sg->node[i].radius = d[l]; InsertSet(&(sg->node[i].adj),nn[l]); } } } free(d); free(nn); if (sg->df<0.00001) sg->df = 1.0; }
// opf_PDF computation void opf_PDF(Subgraph *sg){ int i,nelems; double dist; float *value=AllocFloatArray(sg->nnodes); Set *adj=NULL; sg->K = (2.0*(float)sg->df/9.0); sg->mindens = FLT_MAX; sg->maxdens = FLT_MIN; for (i=0; i < sg->nnodes; i++) { adj=sg->node[i].adj; value[i]=0.0; nelems=1; while (adj != NULL) { if (!opf_PrecomputedDistance) dist = opf_ArcWeight(sg->node[i].feat,sg->node[adj->elem].feat,sg->nfeats); else dist = opf_DistanceValue[sg->node[i].position][sg->node[adj->elem].position]; value[i] += exp(-dist/sg->K); adj = adj->next; nelems++; } value[i] = (value[i]/(float)nelems); if (value[i] < sg->mindens) sg->mindens = value[i]; if (value[i] > sg->maxdens) sg->maxdens = value[i]; } // printf("df=%f,K1=%f,K2=%f,mindens=%f, maxdens=%f\n",sg->df,sg->K1,sg->K2,sg->mindens,sg->maxdens); if (sg->mindens==sg->maxdens) { for (i=0; i < sg->nnodes; i++) { sg->node[i].dens = opf_MAXDENS; sg->node[i].pathval= opf_MAXDENS-1; } } else { for (i=0; i < sg->nnodes; i++) { sg->node[i].dens = ((float)(opf_MAXDENS-1)*(value[i]-sg->mindens)/(float)(sg->maxdens-sg->mindens))+1.0; sg->node[i].pathval=sg->node[i].dens-1; } } free(value); }
//Copy nodes void CopySNode(SNode *dest, SNode *src, int nfeats){ dest->feat = AllocFloatArray(nfeats); memcpy(dest->feat, src->feat, nfeats*sizeof(float)); dest->pathval = src->pathval; dest->dens = src->dens; dest->label = src->label; dest->root = src->root; dest->pred = src->pred; dest->truelabel = src->truelabel; dest->position = src->position; dest->status = src->status; dest->relevant = src->relevant; dest->radius = src->radius; dest->nplatadj = src->nplatadj; dest->adj = CloneSet(src->adj); }
/****************************************************************************** BIC_Modified() : Calculate BIC value between all the states input: posterior probability matrix, stateSequence matrix , numMixEachState- to estimate free parameters, numStates, outputs : compute BIC for each state ******************************************************************************/ void CalculateBIC( float **deltaBIC, VECTOR_OF_F_VECTORS *features, VECTOR_OF_F_VECTORS *allMixtureMeans, VECTOR_OF_F_VECTORS *allMixtureVars, int *numStates, int totalNumFeatures, int *stateSeq, int *numMixEachState, int *numElemEachState, float **posterior) { int s = 0, i = 0, j = 0, k = 0, count = 0, d= 0; float L0 = 0, L1 = 0; //extern VECTOR_OF_F_VECTORS *mixtureMeans, *mixtureVars, *featuresForClustering; for(i = 0; i < *numStates; i++){ for(j = i+1; j < *numStates; j++){ //calculate Delta BIC between state i and state j L0 = 0, L1 = 0; //calculate L1 logSum of probs from original models count = 0; int checker = 0; for(k = 0; k < totalNumFeatures; k++){ if( stateSeq[k] == i || stateSeq[k] == j ){ for( d = 0; d < DIM; d++){ featuresForClustering[count]->array[d] = features[k]->array[d]; featuresForClustering[count]->numElements = DIM; } count++; } if( stateSeq[k] == i ){ L1 += posterior[i][k]; if(checker < 100){ printf("p: %f\t", posterior[i][k]); checker++; } } else if( stateSeq[k] == j){ L1 += posterior[j][k]; if(checker < 100){ printf("p: %f\t", posterior[j][k]); checker++; } } } checker = 0; //printf("sum of log likelihood from both models L1: %f\n", L1); //Calculate L0 // Model elements of both these models using single gaussian extern float probScaleFactor; extern int varianceNormalize, ditherMean; int numFeatures = count; int numMixtures = numMixEachState[i] + numMixEachState[j]; float *mixtureElemCount = (float *) AllocFloatArray(mixtureElemCount, numMixtures); int VQIter = 10, GMMIter = 20; ComputeGMM(featuresForClustering, numFeatures, mixtureMeans, mixtureVars, mixtureElemCount, numMixtures, VQIter, GMMIter, probScaleFactor, ditherMean, varianceNormalize, time(NULL)); // now calculate likelihood of each feature from newly obtained model extern F_VECTOR *mean, *var, *x; int mix = 0; for(k = 0; k < numFeatures; k++){ float P = 0; for(mix = 0; mix < numMixtures; mix++){ for(d = 0; d < DIM; d++){ x->array[d] = featuresForClustering[k]->array[d]; x->numElements = DIM; mean->array[d] = mixtureMeans[mix]->array[d]; mean->numElements = DIM; var->array[d] = mixtureVars[mix]->array[d]; var->numElements = DIM; } float p = 0; extern float probScaleFactor; float priorProb = 1.0; p = ComputeProbability(mean, var, priorProb, x, probScaleFactor); float wt = mixtureElemCount[mix] / numFeatures; P = P + wt * p; } if(checker < 100){ printf("A: %f\t", P); checker++; } L0 += P; } //printf("total log sum probability from new Model is L0: %f\n", L0); // Now we have both L0 and L1 int n1 = numMixEachState[i]; int n2 = numMixEachState[j]; int deltaK = 1; float Penalty = 0.5 * LAMBDA * deltaK * log(numFeatures); deltaBIC[i][j] = L1 - L0 - Penalty; printf("i:%d j:%d deltaBIC: %f L1: %f L0: %f\n", i, j , deltaBIC[i][j], L1, L0); } } }
// Split subgraph into two parts such that the size of the first part // is given by a percentual of samples. void opf_SplitSubgraph(Subgraph *sg, Subgraph **sg1, Subgraph **sg2, float perc1){ int *label=AllocIntArray(sg->nlabels+1),i,j,i1,i2; int *nelems=AllocIntArray(sg->nlabels+1),totelems; srandom((int)time(NULL)); for (i=0; i < sg->nnodes; i++) { sg->node[i].status = 0; label[sg->node[i].truelabel]++; } for (i=0; i < sg->nnodes; i++) { nelems[sg->node[i].truelabel]=MAX((int)(perc1*label[sg->node[i].truelabel]),1); } free(label); totelems=0; for (j=1; j <= sg->nlabels; j++) totelems += nelems[j]; *sg1 = CreateSubgraph(totelems); *sg2 = CreateSubgraph(sg->nnodes-totelems); (*sg1)->nfeats = sg->nfeats; (*sg2)->nfeats = sg->nfeats; for (i1=0; i1 < (*sg1)->nnodes; i1++) (*sg1)->node[i1].feat = AllocFloatArray((*sg1)->nfeats); for (i2=0; i2 < (*sg2)->nnodes; i2++) (*sg2)->node[i2].feat = AllocFloatArray((*sg2)->nfeats); (*sg1)->nlabels = sg->nlabels; (*sg2)->nlabels = sg->nlabels; i1=0; while(totelems > 0){ i = RandomInteger(0,sg->nnodes-1); if (sg->node[i].status!=NIL){ if (nelems[sg->node[i].truelabel]>0){// copy node to sg1 (*sg1)->node[i1].position = sg->node[i].position; for (j=0; j < (*sg1)->nfeats; j++) (*sg1)->node[i1].feat[j]=sg->node[i].feat[j]; (*sg1)->node[i1].truelabel = sg->node[i].truelabel; i1++; nelems[sg->node[i].truelabel] = nelems[sg->node[i].truelabel] - 1; sg->node[i].status = NIL; totelems--; } } } i2=0; for (i=0; i < sg->nnodes; i++){ if (sg->node[i].status!=NIL){ (*sg2)->node[i2].position = sg->node[i].position; for (j=0; j < (*sg2)->nfeats; j++) (*sg2)->node[i2].feat[j]=sg->node[i].feat[j]; (*sg2)->node[i2].truelabel = sg->node[i].truelabel; i2++; } } free(nelems); }
void opf_OPFClustering(Subgraph *sg){ Set *adj_i,*adj_j; char insert_i; int i,j; int p, q, l; float tmp,*pathval=NULL; RealHeap *Q=NULL; Set *Saux=NULL; // Add arcs to guarantee symmetry on plateaus for (i=0; i < sg->nnodes; i++){ adj_i = sg->node[i].adj; while (adj_i != NULL){ j = adj_i->elem; if (sg->node[i].dens==sg->node[j].dens){ // insert i in the adjacency of j if it is not there. adj_j = sg->node[j].adj; insert_i = 1; while (adj_j != NULL){ if (i == adj_j->elem){ insert_i=0; break; } adj_j=adj_j->next; } if (insert_i) InsertSet(&(sg->node[j].adj),i); } adj_i=adj_i->next; } } // Compute clustering pathval = AllocFloatArray(sg->nnodes); Q = CreateRealHeap(sg->nnodes, pathval); SetRemovalPolicyRealHeap(Q, MAXVALUE); for (p = 0; p < sg->nnodes; p++){ pathval[ p ] = sg->node[ p ].pathval; sg->node[ p ].pred = NIL; sg->node[ p ].root = p; InsertRealHeap(Q, p); } l = 0; i = 0; while (!IsEmptyRealHeap(Q)){ RemoveRealHeap(Q,&p); sg->ordered_list_of_nodes[i]=p; i++; if ( sg->node[ p ].pred == NIL ){ pathval[ p ] = sg->node[ p ].dens; sg->node[p].label=l; l++; } sg->node[ p ].pathval = pathval[ p ]; for ( Saux = sg->node[ p ].adj; Saux != NULL; Saux = Saux->next ){ q = Saux->elem; if ( Q->color[q] != BLACK ) { tmp = MIN( pathval[ p ], sg->node[ q ].dens); if ( tmp > pathval[ q ] ){ UpdateRealHeap(Q,q,tmp); sg->node[ q ].pred = p; sg->node[ q ].root = sg->node[ p ].root; sg->node[ q ].label = sg->node[ p ].label; } } } } sg->nlabels = l; DestroyRealHeap( &Q ); free( pathval ); }
// OPFClustering computation only for sg->bestk neighbors void opf_OPFClusteringToKmax(Subgraph *sg) { Set *adj_i,*adj_j; char insert_i; int i,j; int p, q, l, ki,kj; const int kmax = sg->bestk; float tmp,*pathval=NULL; RealHeap *Q=NULL; Set *Saux=NULL; // Add arcs to guarantee symmetry on plateaus for (i=0; i < sg->nnodes; i++) { adj_i = sg->node[i].adj; ki = 1; while (ki <= kmax) { j = adj_i->elem; if (sg->node[i].dens==sg->node[j].dens) { // insert i in the adjacency of j if it is not there. adj_j = sg->node[j].adj; insert_i = 1; kj = 1; while (kj <= kmax) { if (i == adj_j->elem) { insert_i=0; break; } adj_j=adj_j->next; kj++; } if (insert_i) { InsertSet(&(sg->node[j].adj),i); sg->node[j].nplatadj++; //number of adjacent nodes on //plateaus (includes adjacent plateau //nodes computed for previous kmax's) } } adj_i=adj_i->next; ki++; } } // Compute clustering pathval = AllocFloatArray(sg->nnodes); Q = CreateRealHeap(sg->nnodes, pathval); SetRemovalPolicyRealHeap(Q, MAXVALUE); for (p = 0; p < sg->nnodes; p++) { pathval[ p ] = sg->node[ p ].pathval; sg->node[ p ].pred = NIL; sg->node[ p ].root = p; InsertRealHeap(Q, p); } l = 0; i = 0; while (!IsEmptyRealHeap(Q)) { RemoveRealHeap(Q,&p); sg->ordered_list_of_nodes[i]=p; i++; if ( sg->node[ p ].pred == NIL ) { pathval[ p ] = sg->node[ p ].dens; sg->node[p].label=l; l++; } sg->node[ p ].pathval = pathval[ p ]; const int nadj = sg->node[p].nplatadj + kmax; // total amount of neighbors for ( Saux = sg->node[ p ].adj, ki = 1; ki <= nadj; Saux = Saux->next, ki++ ) { q = Saux->elem; if ( Q->color[q] != BLACK ) { tmp = MIN( pathval[ p ], sg->node[ q ].dens); if ( tmp > pathval[ q ] ) { UpdateRealHeap(Q,q,tmp); sg->node[ q ].pred = p; sg->node[ q ].root = sg->node[ p ].root; sg->node[ q ].label = sg->node[ p ].label; } } } } sg->nlabels = l; DestroyRealHeap( &Q ); free( pathval ); }
// Create adjacent list in subgraph: a knn graph. // Returns an array with the maximum distances // for each k=1,2,...,kmax float* opf_CreateArcs2(Subgraph *sg, int kmax) { int i,j,l,k; float dist; int *nn=AllocIntArray(kmax+1); float *d=AllocFloatArray(kmax+1); float *maxdists=AllocFloatArray(kmax); /* Create graph with the knn-nearest neighbors */ sg->df=0.0; for (i=0; i < sg->nnodes; i++) { for (l=0; l < kmax; l++) d[l]=FLT_MAX; for (j=0; j < sg->nnodes; j++) { if (j!=i) { if(!opf_PrecomputedDistance) d[kmax] = opf_ArcWeight(sg->node[i].feat,sg->node[j].feat,sg->nfeats); else d[kmax] = opf_DistanceValue[sg->node[i].position][sg->node[j].position]; nn[kmax]= j; k = kmax; while ((k > 0)&&(d[k]<d[k-1])) { dist = d[k]; l = nn[k]; d[k] = d[k-1]; nn[k] = nn[k-1]; d[k-1] = dist; nn[k-1] = l; k--; } } } sg->node[i].radius = 0.0; sg->node[i].nplatadj = 0; //zeroing amount of nodes on plateaus //making sure that the adjacent nodes be sorted in non-decreasing order for (l=kmax-1; l >= 0; l--) { if (d[l]!=FLT_MAX) { if (d[l] > sg->df) sg->df = d[l]; if (d[l] > sg->node[i].radius) sg->node[i].radius = d[l]; if(d[l] > maxdists[l]) maxdists[l] = d[l]; //adding the current neighbor at the beginnig of the list InsertSet(&(sg->node[i].adj),nn[l]); } } } free(d); free(nn); if (sg->df<0.00001) sg->df = 1.0; return maxdists; }
void ComputeGMM(VECTOR_OF_F_VECTORS *vfv, int numVectors, VECTOR_OF_F_VECTORS *mixtureMeans, VECTOR_OF_F_VECTORS *mixtureVars, float *mixtureElemCnt, int numMixtures, int VQIter, int GMMIter, float probScaleFactor, int ditherMean, int varianceNormalize, int seed) { int i,j,k; static VECTOR_OF_F_VECTORS *tempMeans, *tempVars; static float *tempMixtureElemCnt; int mixtureNumber; int featLength; int flag; //int total; //int minIndex, maxIndex; //int minMixtureSize, maxMixtureSize; // printf("computing GMM......\n"); probScaleFactor = 1.0; featLength = vfv[0]->numElements; tempMeans = (VECTOR_OF_F_VECTORS *) calloc (numMixtures, sizeof(VECTOR_OF_F_VECTORS)); tempVars = (VECTOR_OF_F_VECTORS *) calloc (numMixtures, sizeof(VECTOR_OF_F_VECTORS)); for (i = 0; i < numMixtures; i++) { tempMeans[i] = (F_VECTOR *) AllocFVector(featLength); tempVars[i] = (F_VECTOR *) AllocFVector(featLength); } tempMixtureElemCnt = (float *) AllocFloatArray(tempMixtureElemCnt, numMixtures); // printf("temp mixtures allocated\n"); fflush(stdout); //InitGMM (vfv, numVectors, mixtureMeans, mixtureVars, numMixtures, seed); ComputeVQ(vfv, numVectors, mixtureMeans, mixtureVars, mixtureElemCnt, numMixtures, varianceNormalize, ditherMean, VQIter, seed); for ( k = 0; k < GMMIter; k++) { // printf(" GMM iteration number = %d\n", k); fflush(stdout); for (i = 0; i < numMixtures; i++) { for (j = 0; j < vfv[0]->numElements; j++) { tempMeans[i]->array[j] = 0; tempVars[i]->array[j] = 0; } tempMixtureElemCnt[i] = 0; } for (i = 0; i < numVectors; i++) { mixtureNumber = DecideWhichMixture(vfv[i], mixtureMeans, mixtureVars, numMixtures, mixtureElemCnt, numVectors, probScaleFactor); tempMixtureElemCnt[mixtureNumber] = tempMixtureElemCnt[mixtureNumber]+1; for (j = 0; j < featLength; j++){ tempMeans[mixtureNumber]->array[j] = tempMeans[mixtureNumber]->array[j] + vfv[i]->array[j]; } } /* for (i = 0; i < numMixtures; i++) printf("mixElemCnt %d = %e\n", i, tempMixtureElemCnt[i]); */ /* scanf("%*c"); */ for (i = 0; i < numMixtures; i++) { for (j = 0; j < featLength; j++){ if (tempMixtureElemCnt[i] != 0) tempMeans[i]->array[j] = tempMeans[i]->array[j]/tempMixtureElemCnt[i]; else tempMeans[i]->array[j] = mixtureMeans[i]->array[j]; } } for (i = 0; i < numVectors; i++) { mixtureNumber = DecideWhichMixture(vfv[i], mixtureMeans, mixtureVars, numMixtures, mixtureElemCnt, numVectors, probScaleFactor); for (j = 0; j < featLength; j++){ tempVars[mixtureNumber]->array[j] = tempVars[mixtureNumber]->array[j] + (vfv[i]->array[j] - tempMeans[mixtureNumber]->array[j]) * (vfv[i]->array[j] - tempMeans[mixtureNumber]->array[j]); } } /*for (i = 0; i < numMixtures; i++) printf("mixElemCnt %d = %f\n", i, tempMixtureElemCnt[i]); scanf("%*c");*/ for (i = 0; i < numMixtures; i++){ flag = ZeroFVector(tempMeans[i]); flag = (flag || ZeroFVector(tempVars[i])); for (j = 0; j < featLength; j++) { if ((tempMixtureElemCnt[i] > 1) && !flag){ mixtureMeans[i]->array[j] = tempMeans[i]->array[j]; mixtureVars[i]->array[j] = tempVars[i]->array[j] /tempMixtureElemCnt[i]; if (mixtureVars[i]->array[j] < 1.0E-10) mixtureVars[i]->array[j] = 0.0001; mixtureElemCnt[i] = tempMixtureElemCnt[i]; } else { // mixtureMeans[i]->array[j] = tempMeans[i]->array[j]; mixtureVars[i]->array[j] = 0.0001; mixtureElemCnt[i] = 0; /* printf("Mixture %d %d mean = %e var = %e mixElemCnt = %e\n",i,j, mixtureMeans[i]->array[j], mixtureVars[i]->array[j], mixtureElemCnt[i]);*/ fflush(stdout); } } } } /* for (i = 0; i < numMixtures; i++) for (j = 0; j < featLength; j++) { printf("mean %d %d = %f var %d %d = %f\n",i,j, mixtureMeans[i]->array[j], i, j, mixtureVars[i]->array[j]); fflush(stdout); }*/ // printf("computing GMM finished.\n"); }