/********************************************************************** * junk_worst_seam * * Delete the worst seam from the queue because it is full. **********************************************************************/ void junk_worst_seam(SEAM_QUEUE seams, SEAM *new_seam, float new_priority) { SEAM *seam; float priority; HeapPopWorst(seams, &priority, &seam); if (priority > new_priority) { delete_seam(seam); /*get rid of it */ HeapPush (seams, new_priority, (char *) new_seam); } else { delete_seam(new_seam); HeapPush (seams, priority, (char *) seam); } }
void DcmeDualUpdate(int zz, DcmeBookkeeping* b, heap* twh) { // quick update: dd, ww, ow, twps, int j, k, tw[QUP]; real ent, twps, dd[CUP], ow[NUP], ww[NUP]; NumMulMatVec(weight, b->hh + zz * N, C, N, dd); // dd ent = NumSoftMax(dd, b->hn[zz], C); // ent (sm) NumCopyVec(b->dd + zz * C, dd, C); b->ent[zz] = ent; // dual reset distribution (hh and hn) of zz -------------------------------- if (V_DUAL_RESET_OPT == 1) { // ------------------- 1) clean reset b->hn[zz] = 0; NumFillZeroVec(b->hh + zz * N, N); } else if (V_DUAL_RESET_OPT == 2) { // ------------ 2) half reset b->hn[zz] *= 0.5; NumVecMulC(b->hh + zz * N, 0.5, N); } else if (V_DUAL_RESET_OPT == 3) { // ------------ 3) decay/overshoot reset real v = 0.1; b->hn[zz] *= v; NumVecMulC(b->hh + zz * N, v, N); } // ---------------------------------------------- 4) no reset // -------------------------------------------------------------------------- if (Q > 0) { // top class HeapEmpty(twh); // tw reset for (j = 0; j < C; j++) HeapPush(twh, j, b->dd[zz * C + j]); // tw add for (j = 0; j < Q; j++) tw[j] = twh->d[j].key; // tw load qsort(tw, Q, sizeof(int), cmp_int); // tw sort NumCopyIntVec(b->tw + zz * Q, tw, Q); twps = 0; for (j = 0; j < Q; j++) { k = b->tw[zz * Q + j]; twps += b->dd[zz * C + k]; } b->twps[zz] = twps; } if (V_MICRO_ME) { // Q > 0 required NumFillZeroVec(ow, N); NumFillZeroVec(ww, N); for (j = 0, k = 0; j < C; j++) { // ww, ow: two way merge of tw and ow if (j == b->tw[zz * Q + k]) { // tw NumVecAddCVec(ww, weight + j * N, b->dd[zz * C + j], N); k++; } else NumVecAddCVec(ow, weight + j * N, b->dd[zz * C + j], N); } NumVecAddCVec(b->ww + zz * N, b->ow + zz * N, 1, N); // ww: adding ow NumCopyVec(b->ww + zz * N, ww, N); NumCopyVec(b->ow + zz * N, ow, N); } else { NumMulVecMat(b->dd + zz * C, weight, C, N, ww); // ww NumCopyVec(b->ww + zz * N, ww, N); } b->last_updated_zz = zz; return; }
void DcmeDualUpdate(int zz, DcmeBookkeeping* b, heap* twh) { int j, k; NumMulMatVec(model->tar, b->hh + zz * N, V, N, b->dd + zz * V); // dd b->ent[zz] = NumSoftMax(b->dd + zz * V, b->hn[zz], V); // ent (sm) // dual reset distribution (hh and hn) of zz -------------------------------- if (V_DUAL_RESET_OPT == 1) { // ------------------- 1) clean reset b->hn[zz] = 0; if (V_DUAL_HI) NumFillZeroVec(b->hi + zz * V, V); else NumFillZeroVec(b->hh + zz * N, N); } else if (V_DUAL_RESET_OPT == 2) { // ------------ 2) half reset b->hn[zz] *= 0.5; if (V_DUAL_HI) NumVecMulC(b->hi + zz * V, 0.5, V); else NumVecMulC(b->hh + zz * N, 0.5, N); } else if (V_DUAL_RESET_OPT == 3) { // ------------ 3) decay/overshoot reset real v = 0.1; b->hn[zz] *= v; if (V_DUAL_HI) NumVecMulC(b->hi + zz * V, v, V); else NumVecMulC(b->hh + zz * N, v, N); } // ---------------------------------------------- 4) no reset // -------------------------------------------------------------------------- if (Q > 0) { // top words HeapEmpty(twh); // tw reset for (j = 0; j < V; j++) HeapPush(twh, j, b->dd[zz * V + j]); // tw add for (j = 0; j < Q; j++) b->tw[zz * Q + j] = twh->d[j].key; // tw load qsort(b->tw + zz * Q, Q, sizeof(int), cmp_int); // tw sort b->twps[zz] = 0; for (j = 0; j < Q; j++) { k = b->tw[zz * Q + j]; b->twps[zz] += b->dd[zz * V + k]; } } if (V_MICRO_ME) { NumFillZeroVec(b->ow + zz * N, N); NumFillZeroVec(b->ww + zz * N, N); for (j = 0, k = 0; j < V; j++) { // ww, ow: two way merge of tw and ow if (j == b->tw[zz * Q + k]) { // tw NumVecAddCVec(b->ww + zz * N, model->tar + j * N, b->dd[zz * V + j], N); k++; } else NumVecAddCVec(b->ow + zz * N, model->tar + j * N, b->dd[zz * V + j], N); } NumVecAddCVec(b->ww + zz * N, b->ow + zz * N, 1, N); // ww: adding ow } else { NumMulVecMat(b->dd + zz * V, model->tar, V, N, b->ww + zz * N); // ww } b->last_updated_zz = zz; return; }
int main() { Heap* h; h = HeapCreate(Iintcmp,IintStoreHeapIndex,1); int i,j; for(i=0; i<1000; i++) { j = (i%100)*10 + i/100; Iint* x = (Iint*) malloc(sizeof(Iint)); x->cislo = j; HeapPush(h,(void*) x); printf("%i:%i ", x->heapIndex, ((Iint*)h->array[x->heapIndex])->cislo); } //HeapPrintIint(h); HeapDeleteIndex(h,999); HeapDeleteIndex(h,1); void* x; while(x=HeapPop(h)) { printf("%i\n",((Iint*)x)->cislo); } //HeapPrintInt(h); //x=HeapPop(h); //HeapPrintInt(h); HeapDestroy(h,1); return 0; }
// Pushes data onto the heap only if there is free space left. // Returns true if data was added to the heap, false if the heap was full. bool HeapPushCheckSize(HEAP *Heap, FLOAT32 Key, void *Data) { if (Heap->FirstFree > Heap->Size) return false; HeapPush(Heap, Key, Data); return true; }
void fileKMerge( Data *run_devices, const int k, Data *output_device ) { SPD_ASSERT( output_device->medium == File || output_device->medium == Array, "output_device must be pre-allocated!" ); /* Memory buffer */ Data buffer; DAL_init( &buffer ); DAL_allocBuffer( &buffer, DAL_allowedBufSize() ); const dal_size_t bufferedRunSize = DAL_dataSize(&buffer) / (k + 1); //Size of a single buffered run (+1 because of the output buffer) /* TODO: Handle this case */ SPD_ASSERT( bufferedRunSize > 0 , "fileKMerge function doesn't allow a number of runs greater than memory buffer size" ); /* Runs Buffer */ int* runs = buffer.array.data; /* Output buffer */ int* output = buffer.array.data+k*bufferedRunSize; /* Indexes and Offsets for the k buffered runs */ dal_size_t *run_indexes = (dal_size_t*) calloc( sizeof(dal_size_t), k ); dal_size_t *run_offsets = (dal_size_t*) malloc( k * sizeof(dal_size_t) ); dal_size_t *run_buf_sizes = (dal_size_t*) malloc( k * sizeof(dal_size_t) ); /* The auxiliary heap struct */ Heap heap; HeapInit( &heap, k ); dal_size_t j; /* Initializing the buffered runs and the heap */ for ( j=0; j < k; j++ ) { run_buf_sizes[j] = DAL_dataCopyOS( &run_devices[j], 0, &buffer, j*bufferedRunSize, MIN(bufferedRunSize, DAL_dataSize(&run_devices[j])) ); run_offsets[j] = run_buf_sizes[j]; HeapPush( &heap, runs[j*bufferedRunSize], j ); } /* Merging the runs */ dal_size_t outputSize = 0; dal_size_t outputOffset = 0; dal_size_t i; for ( i=0; i<DAL_dataSize(output_device); i++ ) { Min_val min = HeapTop( &heap ); HeapPop( &heap ); //the run index j = min.run_index; dal_size_t remainingSize = DAL_dataSize(&run_devices[j])-run_offsets[j]; if ( ++(run_indexes[j]) < run_buf_sizes[j] ) //If there are others elements in the buffered run HeapPush( &heap, runs[j*bufferedRunSize+run_indexes[j]], j ); //pushes a new element in the heap else if ( remainingSize > 0 ) { //else, if the run has not been read completely run_buf_sizes[j] = DAL_dataCopyOS( &run_devices[j], run_offsets[j], &buffer, j*bufferedRunSize, MIN(remainingSize, bufferedRunSize) ); run_offsets[j] += run_buf_sizes[j]; run_indexes[j] = 0; HeapPush( &heap, runs[j*bufferedRunSize], j ); } output[outputSize++] = min.val; if ( outputSize == bufferedRunSize || i==DAL_dataSize(output_device)-1 ) { //If the output buffer is full outputOffset += DAL_dataCopyOS( &buffer, k*bufferedRunSize, output_device, outputOffset, outputSize ); outputSize = 0; } } /* Freeing memory */ HeapDestroy( &heap ); DAL_destroy( &buffer ); free( run_indexes ); free( run_offsets ); free( run_buf_sizes ); }