/* * * Calculates the expected counts * based on the observed counts class * member. It must be called after * calculate observed counts for * meaningful results. */ void WFST_Trainer_Local::calculate_expected_counts() { int arc_id = 0; for (StateIterator<VectorFst<LogArc> > siter(*fst); !siter.Done(); siter.Next()) { int state_id = siter.Value(); int tmp_arc_id = arc_id; vector<double> total_traversals(symbol_bound,-DBL_MAX); for (ArcIterator<VectorFst<LogArc> > aiter(*fst,state_id); !aiter.Done(); aiter.Next()) { const LogArc &arc = aiter.Value(); total_traversals[arc.ilabel] = logadd(total_traversals[arc.ilabel],this->observed_counts[tmp_arc_id]); tmp_arc_id += 1; } for (ArcIterator<VectorFst<LogArc> > aiter(*fst,state_id); !aiter.Done(); aiter.Next()) { const LogArc &arc = aiter.Value(); double arc_prob = arc.weight.Value(); this->expected_counts[arc_id] = logadd(this->expected_counts[arc_id], total_traversals[arc.ilabel] - arc_prob); arc_id += 1; } } }
void mpeg3audio_ac3_ba_compute_psd(int start, int end, short exps[], short psd[], short bndpsd[]) { int bin,i,j,k; int lastbin = 0; /* Map the exponents into dBs */ for (bin = start; bin < end; bin++) { psd[bin] = (3072 - (exps[bin] << 7)); } /* Integrate the psd function over each bit allocation band */ j = start; k = mpeg3_masktab[start]; do { lastbin = mpeg3_min(mpeg3_bndtab[k] + mpeg3_bndsz[k], end); bndpsd[k] = psd[j]; j++; for(i = j; i < lastbin; i++) { bndpsd[k] = logadd(bndpsd[k], psd[j]); j++; } k++; }while(end > lastbin); }
void S_remake(double a) { int N, M; for (N=2; N<usedN; N++) { S_m[1][N] = log(N-a-1.0) + S_m[1][N-1]; for (M=2; M<=usedM && M<N; M++) { tblSNM(N,M) = logadd(tblSNM(N-1,M-1),log(N-(M*a)-1.0)+tblSNM(N-1,M)); } } }
static prob_t prombs_simple_( prob_t *result, size_t j, prob_t (*f)(int, int, void*), void *data) { if (j == 0) { return (*f)(0, 0, data); } else { size_t i; prob_t sum = -HUGE_VAL; for (i = 0; i < j; i++) { if (result[i] == -HUGE_VAL) { result[i] = prombs_simple_(result, i, f, data); } sum = logadd(sum, result[i] + f(i+1, j, data)); } return logadd(sum, f(0, j, data)); } }
void update_prob() { float pisum = - INFINITY; float gmmsum[nstates]; float xisum[nstates]; size_t i, j; for (i = 0; i < nstates; i++) { gmmsum[i] = - INFINITY; xisum[i] = - INFINITY; pisum = logadd(pi[i], pisum); } for (i = 0; i < nstates; i++) { prior[i] = pi[i] - pisum; } for (i = 0; i < nstates; i++) { for (j = 0; j < nstates; j++) { xisum[i] = logadd(xisum[i], xi[IDX(i,j,nstates)]); } for (j = 0; j < nobvs; j++) { gmmsum[i] = logadd(gmmsum[i], gmm[IDX(i,j,nobvs)]); } } for (i = 0; i < nstates; i++) { for (j = 0; j < nstates; j++) { trans[IDX(i,j,nstates)] = xi[IDX(i,j,nstates)] - xisum[i]; } for (j = 0; j < nobvs; j++) { obvs[IDX(i,j,nobvs)] = gmm[IDX(i,j,nobvs)] - gmmsum[i]; } } }
void ba_compute_psd (int16_t start) { int i,j,k; int16_t lastbin = 4; j = start; k = masktab[start]; bndpsd[k] = psd[j]; j++; for (i = j; i < lastbin; i++) { bndpsd[k] = logadd(&bndpsd[k], &psd[j]); j++; } }
double prob_locus_coal_recon_topology_samples( int *ptree, int nnodes, int *recon, int *plocus_tree, int nlocus_nodes, int *locus_recon, int *locus_events, double *popsizes, int *pstree, int nsnodes, double *stimes, int *daughters, int ndaughters, double birth, double death, int nsamples, double pretime, double premean) { // alloc datastructures double *ltimes = new double [nlocus_nodes]; intnode *iltree = make_itree(nlocus_nodes, plocus_tree); int *stack = new int [nnodes]; // integrate over duplication times using sampling double prob = -INFINITY; for (int i=0; i<nsamples; i++) { // sample duplication times sample_dup_times(ltimes, iltree, nlocus_nodes, pstree, nsnodes, stimes, locus_recon, locus_events, birth, death, pretime, premean, stack); // coal topology probability double const coal_prob = prob_locus_coal_recon_topology( ptree, nnodes, recon, plocus_tree, iltree, nlocus_nodes, popsizes, ltimes, daughters, ndaughters); prob = logadd(prob, coal_prob); } // clean up delete [] ltimes; free_itree(iltree); delete [] stack; return prob - log(nsamples); }
/* * Calculates the observed counts (without parallelization) * * @param exemplar_num - the training examplar number * @param fst - the FST in with FeatureArcs * @param fst_log - the FST with the actual weights in log space * @param alpha - the alpha values * @param beta - the beta values * */ void WFST_Trainer_Local::calculate_observed_counts(int exemplar_num, VectorFst<FeatureArc> *fst, VectorFst<LogArc> *fst_log, vector<LogWeight> *alpha, vector<LogWeight> *beta) { //normalizing constant LogWeight Z = Times((*alpha)[0], (*beta)[0]); int arc_id = 0; for (StateIterator<VectorFst<FeatureArc> > siter(*fst); !siter.Done(); siter.Next()) { int state_id = siter.Value(); map<int,int> arc_mapper; int tmp = arc_id; for (ArcIterator<VectorFst<FeatureArc> > aiter1(*fst,state_id); !aiter1.Done(); aiter1.Next()) { const FeatureArc &arc = aiter1.Value(); int old_arc_id = round(exp(-arc.weight.Value2().Value())); arc_mapper[tmp] = old_arc_id - 1; ++tmp; } for (ArcIterator<VectorFst<LogArc> > aiter2(*fst_log,state_id); !aiter2.Done(); aiter2.Next()) { const LogArc &arc = aiter2.Value(); int old_arc_id2 = arc_mapper[arc_id]; LogWeight val = ((Times(Times((*alpha)[state_id],arc.weight.Value()), (*beta)[arc.nextstate]))); double log_val = Divide(val,Z).Value(); this->observed_counts[old_arc_id2] = logadd(this->observed_counts[old_arc_id2],-log_val); ++arc_id; } } }
AUD_Int32s wov_adapt_gmm_si() { AUD_Error error = AUD_ERROR_NONE; AUD_Int32s ret = 0; AUD_Int8s wavPath[256] = { 0, }; AUD_Int32s data; setbuf( stdout, NULL ); setbuf( stdin, NULL ); AUDLOG( "pls give adapt wav stream's folder path:\n" ); wavPath[0] = '\0'; data = scanf( "%s", wavPath ); AUDLOG( "adapt wav stream's folder path is: %s\n", wavPath ); // step 1: read UBM model from file void *hUbm = NULL; FILE *fpUbm = fopen( WOV_UBM_GMMMODEL_FILE, "rb" ); if ( fpUbm == NULL ) { AUDLOG( "cannot open ubm model file: [%s]\n", WOV_UBM_GMMMODEL_FILE ); return AUD_ERROR_IOFAILED; } error = gmm_import( &hUbm, fpUbm ); AUD_ASSERT( error == AUD_ERROR_NONE ); fclose( fpUbm ); fpUbm = NULL; // AUDLOG( "ubm GMM as:\n" ); // gmm_show( hUbm ); AUD_Int32s i = 0, j = 0; entry *pEntry = NULL; dir *pDir = NULL; AUD_Int32s totalWinNum = 0; pDir = openDir( (const char*)wavPath ); if ( pDir == NULL ) { AUDLOG( "cannot open folder: %s\n", wavPath ); return -1; } while ( ( pEntry = scanDir( pDir ) ) ) { AUD_Int8s keywordFile[256] = { 0, }; AUD_Summary fileSummary; AUD_Int32s sampleNum = 0; snprintf( (char*)keywordFile, 256, "%s/%s", wavPath, pEntry->name ); // AUDLOG( "%s\n", keywordFile ); ret = parseWavFromFile( keywordFile, &fileSummary ); if ( ret < 0 ) { continue; } AUD_ASSERT( fileSummary.channelNum == CHANNEL_NUM && fileSummary.bytesPerSample == BYTES_PER_SAMPLE && fileSummary.sampleRate == SAMPLE_RATE ); // request memeory for template sampleNum = fileSummary.dataChunkBytes / fileSummary.bytesPerSample; for ( j = 0; j * FRAME_STRIDE + FRAME_LEN <= sampleNum; j++ ) { ; } j = j - MFCC_DELAY; totalWinNum += j; } closeDir( pDir ); pDir = NULL; AUD_Matrix featureMatrix; featureMatrix.rows = totalWinNum; featureMatrix.cols = MFCC_FEATDIM; featureMatrix.dataType = AUD_DATATYPE_INT32S; ret = createMatrix( &featureMatrix ); AUD_ASSERT( ret == 0 ); AUD_Int32s currentRow = 0; pDir = openDir( (const char*)wavPath ); while ( ( pEntry = scanDir( pDir ) ) ) { AUD_Int8s keywordFile[256] = { 0, }; AUD_Summary fileSummary; AUD_Int32s sampleNum = 0; void *hMfccHandle = NULL; snprintf( (char*)keywordFile, 256, "%s/%s", wavPath, pEntry->name ); // AUDLOG( "%s\n", keywordFile ); ret = parseWavFromFile( keywordFile, &fileSummary ); if ( ret < 0 ) { continue; } AUD_ASSERT( fileSummary.channelNum == CHANNEL_NUM && fileSummary.bytesPerSample == BYTES_PER_SAMPLE && fileSummary.sampleRate == SAMPLE_RATE ); AUD_Int32s bufLen = fileSummary.dataChunkBytes; AUD_Int16s *pBuf = (AUD_Int16s*)calloc( bufLen, 1 ); AUD_ASSERT( pBuf ); sampleNum = readWavFromFile( (AUD_Int8s*)keywordFile, pBuf, bufLen ); AUD_ASSERT( sampleNum > 0 ); // pre-processing // pre-emphasis sig_preemphasis( pBuf, pBuf, sampleNum ); // calc framing number for ( j = 0; j * FRAME_STRIDE + FRAME_LEN <= sampleNum; j++ ) { ; } // XXX: select salient frames AUD_Feature feature; feature.featureMatrix.rows = j - MFCC_DELAY; feature.featureMatrix.cols = MFCC_FEATDIM; feature.featureMatrix.dataType = AUD_DATATYPE_INT32S; feature.featureMatrix.pInt32s = featureMatrix.pInt32s + currentRow * feature.featureMatrix.cols; feature.featureNorm.len = j - MFCC_DELAY; feature.featureNorm.dataType = AUD_DATATYPE_INT64S; ret = createVector( &(feature.featureNorm) ); AUD_ASSERT( ret == 0 ); error = mfcc16s32s_init( &hMfccHandle, FRAME_LEN, WINDOW_TYPE, MFCC_ORDER, FRAME_STRIDE, SAMPLE_RATE, COMPRESS_TYPE ); AUD_ASSERT( error == AUD_ERROR_NONE ); error = mfcc16s32s_calc( hMfccHandle, pBuf, sampleNum, &feature ); AUD_ASSERT( error == AUD_ERROR_NONE ); error = mfcc16s32s_deinit( &hMfccHandle ); AUD_ASSERT( error == AUD_ERROR_NONE ); free( pBuf ); pBuf = NULL; bufLen = 0; ret = destroyVector( &(feature.featureNorm) ); AUD_ASSERT( ret == 0 ); currentRow += feature.featureMatrix.rows; } closeDir( pDir ); pDir = NULL; AUD_Matrix llrMatrix; llrMatrix.rows = totalWinNum; llrMatrix.cols = gmm_getmixnum( hUbm ); llrMatrix.dataType = AUD_DATATYPE_DOUBLE; ret = createMatrix( &llrMatrix ); AUD_ASSERT( ret == 0 ); AUD_Double llr = 0.; for ( j = 0; j < featureMatrix.rows; j++ ) { AUD_Vector componentLLR; componentLLR.len = llrMatrix.cols; componentLLR.dataType = AUD_DATATYPE_DOUBLE; componentLLR.pDouble = llrMatrix.pDouble + j * llrMatrix.cols; llr = gmm_llr( hUbm, &(featureMatrix), j, &componentLLR ); } AUD_Vector sumLlr; sumLlr.len = llrMatrix.cols; sumLlr.dataType = AUD_DATATYPE_DOUBLE; ret = createVector( &sumLlr ); AUD_ASSERT( ret == 0 ); AUD_Double *pSumLlr = sumLlr.pDouble; for ( j = 0; j < llrMatrix.cols; j++ ) { pSumLlr[j] = llrMatrix.pDouble[j]; } for ( i = 1; i < llrMatrix.rows; i++ ) { for ( j = 0; j < llrMatrix.cols; j++ ) { pSumLlr[j] = logadd( pSumLlr[j], *(llrMatrix.pDouble + i * llrMatrix.cols + j) ); } } #if 0 AUD_Vector bestIndex; bestIndex.len = TOP_N; bestIndex.dataType = AUD_DATATYPE_INT32S; ret = createVector( &bestIndex ); AUD_ASSERT( ret == 0 ); // get top TOP_N component ret = sortVector( &sumLlr, &bestIndex ); AUD_ASSERT( ret == 0 ); #else llr = pSumLlr[0]; for ( j = 1; j < sumLlr.len; j++ ) { llr = logadd( llr, pSumLlr[j] ); } // AUDLOG( "llr: %.f\n", llr ); AUD_Vector sortIndex; sortIndex.len = sumLlr.len; sortIndex.dataType = AUD_DATATYPE_INT32S; ret = createVector( &sortIndex ); AUD_ASSERT( ret == 0 ); ret = sortVector( &sumLlr, &sortIndex ); AUD_ASSERT( ret == 0 ); int num = 0; double val = 0.; for ( i = 0; i < sortIndex.len; i++ ) { // ln( 0.001 ) ~= -7. val = pSumLlr[sortIndex.pInt32s[i]] - llr + 7.; // AUDLOG( "%f, \n", val ); if ( val < 0 ) { break; } num++; } // AUDLOG( "\n" ); AUD_ASSERT( num > 0 ); AUDLOG( "computed component num: %d\n", num ); num = AUD_MAX( num, TOP_N ); AUDLOG( "normalized component num: %d\n", num ); AUD_Vector bestIndex; bestIndex.len = num; bestIndex.dataType = AUD_DATATYPE_INT32S; bestIndex.pInt32s = sortIndex.pInt32s; #endif int slash = '/'; char *ptr = strrchr( (char*)wavPath, slash ); ptr++; // select imposter GMM void *hImposterGmm = NULL; AUD_Int8s imposterGmmName[256] = { 0, }; snprintf( (char*)imposterGmmName, 256, "%s-imposter", ptr ); error = gmm_select( &hImposterGmm, hUbm, &bestIndex, 0 | GMM_INVERTSELECT_MASK, imposterGmmName ); AUD_ASSERT( error == AUD_ERROR_NONE ); gmm_show( hImposterGmm ); // export gmm char imposterFile[256] = { 0 }; snprintf( imposterFile, 256, "%s/%s-imposter.gmm", WOV_IMPOSTER_GMMMODEL_DIR, ptr ); AUDLOG( "Export imposter GMM Model to: %s\n", imposterFile ); FILE *fpImposterGmm = fopen( imposterFile, "wb" ); AUD_ASSERT( fpImposterGmm ); error = gmm_export( hImposterGmm, fpImposterGmm ); AUD_ASSERT( error == AUD_ERROR_NONE ); AUDLOG( "Export imposter GMM Model File Done\n" ); fclose( fpImposterGmm ); fpImposterGmm = NULL; error = gmm_free( &hImposterGmm ); AUD_ASSERT( error == AUD_ERROR_NONE ); // select keyword GMM void *hAdaptedGmm = NULL; AUD_Int8s adaptedGmmName[256] = { 0, }; snprintf( (char*)adaptedGmmName, 256, "%s", ptr ); // AUDLOG( "%s\n", adaptedGmmName ); error = gmm_select( &hAdaptedGmm, hUbm, &bestIndex, 0, adaptedGmmName ); AUD_ASSERT( error == AUD_ERROR_NONE ); ret = destroyVector( &sumLlr ); AUD_ASSERT( ret == 0 ); ret = destroyMatrix( &llrMatrix ); AUD_ASSERT( ret == 0 ); #if 0 ret = destroyVector( &bestIndex ); AUD_ASSERT( ret == 0 ); #else ret = destroyVector( &sortIndex ); AUD_ASSERT( ret == 0 ); #endif #if 1 // adapt GMM error = gmm_adapt( hAdaptedGmm, &featureMatrix ); AUD_ASSERT( error == AUD_ERROR_NONE ); #endif gmm_show( hAdaptedGmm ); // export gmm char modelFile[256] = { 0 }; snprintf( modelFile, 256, "%s/%s.gmm", WOV_KEYWORD_GMMMODEL_DIR, ptr ); AUDLOG( "Export GMM Model to: %s\n", modelFile ); FILE *fpGmm = fopen( modelFile, "wb" ); AUD_ASSERT( fpGmm ); error = gmm_export( hAdaptedGmm, fpGmm ); AUD_ASSERT( error == AUD_ERROR_NONE ); AUDLOG( "Export GMM Model File Done\n" ); fclose( fpGmm ); fpGmm = NULL; ret = destroyMatrix( &featureMatrix ); AUD_ASSERT( ret == 0 ); error = gmm_free( &hAdaptedGmm ); AUD_ASSERT( error == AUD_ERROR_NONE ); error = gmm_free( &hUbm ); AUD_ASSERT( error == AUD_ERROR_NONE ); AUDLOG( "keyword model adapt2 done\n" ); return 0; }
/* forward backward algoritm: return observation likelihood */ float forward_backward(int *data, size_t len, int backward) { /* construct trellis */ float alpha[len][nstates]; float beta[len][nstates]; size_t i, j, k; float p, e; float loglik; for (i = 0; i < len; i++) { for (j = 0; j < nstates; j++) { alpha[i][j] = - INFINITY; beta[i][j] = - INFINITY; } } /* forward pass */ for (i = 0; i < nstates; i++) { alpha[0][i] = prior[i] + obvs[IDX(i,data[0],nobvs)]; } for (i = 1; i < len; i++) { for (j = 0; j < nstates; j++) { for (k = 0; k < nstates; k++) { p = alpha[i-1][k] + trans[IDX(k,j,nstates)] + obvs[IDX(j,data[i],nobvs)]; alpha[i][j] = logadd(alpha[i][j], p); } } } loglik = -INFINITY; for (i = 0; i < nstates; i++) { loglik = logadd(loglik, alpha[len-1][i]); } if (! backward) return loglik; /* backward pass & update counts */ for (i = 0; i < nstates; i++) { beta[len-1][i] = 0; /* 0 = log (1.0) */ } for (i = 1; i < len; i++) { for (j = 0; j < nstates; j++) { e = alpha[len-i][j] + beta[len-i][j] - loglik; gmm[IDX(j,data[len-i],nobvs)] = logadd(gmm[IDX(j,data[len-i],nobvs)], e); for (k = 0; k < nstates; k++) { p = beta[len-i][k] + trans[IDX(j,k,nstates)] + obvs[IDX(k,data[len-i],nobvs)]; beta[len-1-i][j] = logadd(beta[len-1-i][j], p); e = alpha[len-1-i][j] + beta[len-i][k] + trans[IDX(j,k,nstates)] + obvs[IDX(k,data[len-i],nobvs)] - loglik; xi[IDX(j,k,nstates)] = logadd(xi[IDX(j,k,nstates)], e); } } } p = -INFINITY; for (i = 0; i < nstates; i++) { p = logadd(p, prior[i] + beta[0][i] + obvs[IDX(i,data[0],nobvs)]); e = alpha[0][i] + beta[0][i] - loglik; gmm[IDX(i,data[0],nobvs)] = logadd(gmm[IDX(i,data[0],nobvs)], e); pi[i] = logadd(pi[i], e); } #ifdef DEBUG /* verify if forward prob == backward prob */ if (fabs(p - loglik) > 1e-3) { fprintf(stderr, "Error: forward and backward incompatible: %f, %f\n", loglik, p); } #endif return loglik; }
void bit_alloc( int8_t *bap, // [256] int8_t *exp, // [256] int deltbae, int8_t *deltba, // [50] int start, int end, int fscod, int halfratecod, int sdecay, int fdecay, int sgain, int fgain, int dbknee, int floor, int fastleak, int slowleak, int snroffset) { int bin, lastbin, i, j, k, begin, bndstrt, bndend, lowcomp; int psd[256]; // PSD int bndpsd[50]; // integrated PSD int excite[50]; // excitation int mask[50]; // masking value // Step 1: Exponent mapping into PSD for (bin = start; bin < end; bin++) psd[bin] = (3072 - (exp[bin] << 7)); // Step 2: PSD integration j = start; k = masktab[start]; do { lastbin = min(bndtab[k] + bndsz[k], end); bndpsd[k] = psd[j]; j++; for (i = j; i < lastbin; i++) { bndpsd[k] = logadd(bndpsd[k], psd[j]); j++; } k++; } while (end > lastbin); // Step 3: Compute excition function bndstrt = masktab[start]; bndend = masktab[end - 1] + 1; if (bndstrt == 0) // for fbw and lfe channels { // note: do not calc_lowcomp() for the last band of the lfe channel, (bin = 6) lowcomp = 0; lowcomp = calc_lowcomp(lowcomp, bndpsd[0], bndpsd[1], 0); excite[0] = bndpsd[0] - fgain - lowcomp; lowcomp = calc_lowcomp(lowcomp, bndpsd[1], bndpsd[2], 1); excite[1] = bndpsd[1] - fgain - lowcomp; begin = 7; for (bin = 2; bin < 7; bin++) { if ((bndend != 7) || (bin != 6)) // skip for last bin of lfe channel lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin); fastleak = bndpsd[bin] - fgain; slowleak = bndpsd[bin] - sgain; excite[bin] = fastleak - lowcomp; if ((bndend != 7) || (bin != 6)) // skip for last bin of lfe channel { if (bndpsd[bin] <= bndpsd[bin+1]) { begin = bin + 1; break; } } } for (bin = begin; bin < min(bndend, 22); bin++) { if ((bndend != 7) || (bin != 6)) // skip for last bin of lfe channel lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin); fastleak -= fdecay; fastleak = max(fastleak, bndpsd[bin] - fgain); slowleak -= sdecay; slowleak = max(slowleak, bndpsd[bin] - sgain); excite[bin] = max(fastleak - lowcomp, slowleak); } begin = 22; } else // for coupling channel begin = bndstrt; for (bin = begin; bin < bndend; bin++) { fastleak -= fdecay; fastleak = max(fastleak, bndpsd[bin] - fgain); slowleak -= sdecay; slowleak = max(slowleak, bndpsd[bin] - sgain); excite[bin] = max(fastleak, slowleak); } // Step 4: Compute masking curve for (bin = bndstrt; bin < bndend; bin++) { if (bndpsd[bin] < dbknee) excite[bin] += ((dbknee - bndpsd[bin]) >> 2); mask[bin] = max(excite[bin], hth[fscod][bin >> halfratecod]); } // Step 5: Apply delta bit allocation if (deltbae == DELTA_BIT_NEW || deltbae == DELTA_BIT_REUSE) for (i = 0; i < 50; i++) mask[i] += deltba[i]; // Step 6: Compute bit allocation i = start; j = masktab[start]; do { lastbin = min(bndtab[j] + bndsz[j], end); mask[j] -= snroffset; mask[j] -= floor; if (mask[j] < 0) mask[j] = 0; mask[j] &= 0x1fe0; // 0001 1111 1110 0000 mask[j] += floor; for (k = i; k < lastbin; k++) { int address = (psd[i] - mask[j]) >> 5; address = min(63, max(0, address)); bap[i] = baptab[address]; i++; } j++; } while (end > lastbin); }
/* * assumes s->usedN/M already set to new values and memory filled * startN/M = 0 ---> refill everything * startN/M > 0 ---> memory extended so refill from here, * i.e., these were *last* values set, start +1 */ static int S_remake_part(stable_t *sp, double a, unsigned startN, unsigned startM, unsigned usedN, unsigned usedM, unsigned usedN1) { int N, M; if ( startN==0 ) startM = 0; sp->a = a; sp->lga = lgamma(1.0-a); // yaps_message("S_remake_part(a=%lf,N=%u, M=%u)\n", a, startN, startM); /* * need to reset at sp->S1[] least to usedN1; * up to usedN used by sp->S[][], * and data needs overwriting up to usedN1 */ if ( startN==0 ) { sp->S1[0] = 0; N = 2; } else { N = startN+1; assert(sp->S1[startN-1]>0 ); } for ( ; N<=usedN; N++) sp->S1[N-1] = sp->S1[N-2] + log(N-1-a); if ( startN==0 ) // a has changed, so reset others for ( ; N<=usedN1; N++) sp->S1[N-1] = 0; if ( sp->flags&S_STABLE ) { if ( (sp->flags&S_FLOAT)==0 ) { if ( startM>0 && startM<usedM ) { /* * extend for M upto startN */ for (N=startM+1; N<=startN; N++) { for (M=startM+1; M<N && M<=usedM; M++) { sp->S[N-3][M-2] = logadd(log(N-M*a-1.0)+((M<N-1)?sp->S[N-4][M-2]:0), sp->S[N-4][M-3]); assert(isfinite(sp->S[N-3][M-2])); } } } /* * now fill from 0 after startN ... just like usual */ if ( startN==0 ) { sp->S[0][0] = logadd(sp->S1[1],log(2-2*a)); N = 4; } else { N = startN+1; assert(sp->S[N-4][0]>0); } for (; N<=usedN; N++) { sp->S[N-3][0] = logadd(log(N-2*a-1.0)+sp->S[N-4][0], sp->S1[N-2]); for (M=3; M<=usedM && M<N; M++) { sp->S[N-3][M-2] = logadd(log(N-M*a-1.0)+((M<N-1)?sp->S[N-4][M-2]:0), sp->S[N-4][M-3]); assert(isfinite(sp->S[N-3][M-2])); } } } else { /* * computation done in double by storing in sp->SfrontN+M[] */ if ( startM>0 && startM<usedM ) { /* * extend for M upto startN */ for (N=startM+2; N<=startN; N++) { double lastS; if (startM+1<N-1) lastS = sp->Sf[N-4][startM-1]; else lastS = 0 ; sp->Sf[N-3][startM-1] = sp->SfrontN[startM-1] = logadd(log(N-(startM+1)*a-1.0)+lastS, sp->SfrontM[N-startM-2]); for (M=startM+2; M<N && M<=usedM; M++) { double saveS = sp->SfrontN[M-2]; if ( M==N-1 ) saveS = 0; sp->SfrontN[M-2] = logadd(log(N-M*a-1.0)+saveS, lastS); sp->Sf[N-3][M-2] = sp->SfrontN[M-2]; assert(isfinite(sp->Sf[N-3][M-2])); lastS = saveS; } // save the SfrontM value if ( N>usedM ) sp->SfrontM[N-usedM-1] = sp->SfrontN[usedM-2]; } } if ( startN==0 ) { sp->Sf[0][0] = sp->SfrontN[0] = logadd(sp->S1[1],log(2-2*a)); N = 4; } else { N = startN+1; assert(sp->Sf[N-4][0]>0); } for ( ; N<=usedN; N++) { double lastS; lastS = sp->SfrontN[0]; sp->Sf[N-3][0] = sp->SfrontN[0] = logadd(log(N-2*a-1.0)+lastS, sp->S1[N-2]); for (M=3; M<=usedM && M<N; M++) { double saveS = sp->SfrontN[M-2]; if (M==N-1) saveS = 0; sp->SfrontN[M-2] = logadd(log(N-M*a-1.0)+saveS, lastS); sp->Sf[N-3][M-2] = sp->SfrontN[M-2]; #ifndef NDEBUG if ( !isfinite(sp->Sf[N-3][M-2]) ) yaps_quit("Building '%s' N to %d, sp->Sf[%d][%d] not finite, from %lf,%lf\n", sp->tag, usedN, N-3, M-2, saveS, lastS); #endif assert(isfinite(sp->Sf[N-3][M-2])); lastS = saveS; } // save the SfrontM value if ( N>usedM ) sp->SfrontM[N-usedM-1] = sp->SfrontN[usedM-2]; } } } if ( sp->flags&S_UVTABLE ) { if ( (sp->flags&S_FLOAT)==0 ) { if ( startM>0 && startM<usedM ) { /* * extend for M upto startN */ for (N=startM+1; N<=startN; N++) { for (M=startM+1; M<=N && M<=usedM; M++) { sp->V[N-2][M-2] = (1.0+((M<N)?((N-1-M*a)*sp->V[N-3][M-2]):0)) / (1.0/sp->V[N-3][M-3]+(N-1-(M-1)*a)); } } } /* * now fill from 0 after startN ... just like usual */ if ( startN==0 ) { sp->V[0][0] = 1.0/(1.0-a); N = 3; } else { N = startN+1; assert(sp->V[N-3][0]>0); } for (; N<=usedN; N++) { sp->V[N-2][0] = (1.0+(N-1-2*a)*sp->V[N-3][0])/(N-1-a); for (M=3; M<=usedM && M<=N; M++) { sp->V[N-2][M-2] = (1.0+((M<N)?((N-1-M*a)*sp->V[N-3][M-2]):0)) / (1.0/sp->V[N-3][M-3]+(N-1-(M-1)*a)); } } } else { if ( startM>0 && startM<usedM ) { /* * extend for M upto startN */ for (N=startM+1; N<=startN; N++) { double lastS; if ( startM+1<N) lastS = sp->VfrontN[startM-1]; else lastS = 0; sp->Vf[N-2][startM-1] = sp->VfrontN[startM-1] = (1.0+(N-1-(startM+1)*a)*lastS) / (1.0/sp->VfrontM[N-1-startM]+(N-1-(startM)*a)); for (M=startM+2; M<=N && M<=usedM; M++) { double saveS = sp->VfrontN[M-2]; assert(lastS!=0); sp->Vf[N-2][M-2] = sp->VfrontN[M-2] = (1.0+((M<N)?((N-1-M*a)*saveS):0)) / (1.0/lastS+(N-1-(M-1)*a)); lastS = saveS; } // save the VfrontM value if ( N>=usedM ) sp->VfrontM[N-usedM] = sp->VfrontN[usedM-2]; } } /* * now fill from 0 after startN ... just like usual */ if ( startN==0 ) { sp->Vf[0][0] = sp->VfrontN[0] = 1.0/(1.0-a); N = 3; } else { N = startN+1; assert(sp->Vf[N-3][0]>0); } for (; N<=usedN; N++) { double lastS; lastS = sp->VfrontN[0]; sp->Vf[N-2][0] = sp->VfrontN[0] = (1.0+(N-1-2*a)*lastS)/(N-1-a); for (M=3; M<=usedM && M<=N; M++) { double saveS = sp->VfrontN[M-2]; assert(lastS!=0); sp->Vf[N-2][M-2] = sp->VfrontN[M-2] = (1.0+((M<N)?((N-1-M*a)*saveS):0)) / (1.0/lastS+(N-1-(M-1)*a)); lastS = saveS; } // save the VfrontM value if ( N>=usedM ) sp->VfrontM[N-usedM] = sp->VfrontN[usedM-2]; } } } /* * change bounds at end only after data filled; * in case other threads running */ sp->usedN = usedN; sp->usedN1 = usedN1; sp->usedM = usedM; return 0; }