double KL_V_alpha_g (const gsl_vector *v_V_alpha_g) { int i = *params->i; int d; int G = *params->G, g = *params->g; double tmpsum = 0.0, tmp; int N = *params->N; double KL; double V_alpha_g = gsl_vector_get(v_V_alpha_g, 0); for (i = 0; i < SUBSET; i++) { tmp = 0.0; for (d=0; d<*params->D; d++) tmp += pow(params->V_z[i * *params->D + d] - params->V_eta[g * *params->D + d], 2.0); tmpsum += params->V_lambda[*params->g * N + i] * (*params->D*gsl_sf_psi(*params->inv_sigma02*V_alpha_g) - 0.5* *params->inv_sigma02*V_alpha_g*(params->V_sigma2[i]+params->V_omega2[g]+tmp)); } tmp = 0.0; for (g=0; g<G; g++) if (g!=*params->g) tmp += params->V_alpha[g]; KL = fabs (tmpsum*(tmp+V_alpha_g) + lgamma(0.5*V_alpha_g) + 0.5*(params->alpha[*params->g]-V_alpha_g)*(gsl_sf_psi(0.5*V_alpha_g))); //-gsl_sf_psi(params->alpha[*params->g]))); return KL; }
void fbst_loginorm(gsl_rng *r, gsl_vector_uint *x, gsl_vector_uint *sums, double alpha, double beta, double *_ev,double *_err, FBSTConfig *config) { size_t i,j; double mean; double var; double a,b; assert(x->size == sums->size); gsl_vector *means=gsl_vector_alloc(x->size); gsl_vector *sd=gsl_vector_alloc(x->size); for(i=0;i<x->size;i++) { a=ELT(x,i)+alpha; b=ELT(sums,i)+beta-a; mean=gsl_sf_psi(a)-gsl_sf_psi(b); var=gsl_sf_psi_1(a)+gsl_sf_psi_1(b); printf("x%i=N(%lg %lg)\n",i,mean,var); gsl_vector_set(means,i,mean); gsl_vector_set(sd,i,var); } fbst_normal(r,means,sd,_ev,_err,config); gsl_vector_free(means); gsl_vector_free(sd); }
double KL_V_nu_g (const gsl_vector *v_V_nu_g) { int i = *params->i; int g, G = *params->G; double tmpsum = 0.0, tmp; int N = *params->N; double KL; double V_nu_g = gsl_vector_get(v_V_nu_g, 0); tmp = 0.0; for (g = 0; g < G; g++) if (g!=*params->g) tmp += params->V_nu[g]; for (i = 0; i < SUBSET; i++) tmpsum += params->V_lambda[*params->g * N + i] * (gsl_sf_psi (V_nu_g) - gsl_sf_psi (tmp+V_nu_g)); KL = tmpsum - lgamma (tmp+V_nu_g); tmp = 0.0; for (g = 0; g < G; g++) if (g!=*params->g) tmp += lgamma (params->V_nu[g]); KL = fabs (KL + tmp + lgamma (V_nu_g) - (V_nu_g - params->nu[*params->g]) * (gsl_sf_psi (V_nu_g) - gsl_sf_psi (params->nu[*params->g]))); return KL; }
void my_df (const gsl_vector *v, void *params, gsl_vector *df) { cclda_alphaopt * alphaopt=(cclda_alphaopt *) params; double f = 0.0; double sumalpha, sumpsialpha, temp; int j, c; f = 0.0; c = alphaopt->c; sumalpha = 0.0; sumpsialpha = 0.0; for (j = 0; j < alphaopt->m; j++){ alphaopt->alpha[j] = exp(gsl_vector_get(v, j)); sumalpha += alphaopt->alpha[j]; f += (alphaopt->alpha[j] - 1)*alphaopt->ss2[j][c]; temp = gsl_sf_psi(alphaopt->alpha[j]); sumpsialpha += temp; alphaopt->grad[j] = alphaopt->ss2[j][c] -alphaopt->ss1[c]*temp; } f += alphaopt->ss1[c]*(gsl_sf_psi(sumalpha) - sumpsialpha); for (j = 0; j < alphaopt->m; j++){ alphaopt->grad[j] += gsl_sf_psi(sumalpha)*alphaopt->ss1[c]; gsl_vector_set(df, j, -alphaopt->alpha[j]*alphaopt->grad[j]); } f *= -1; }
double lda_m_step(lda* model, lda_suff_stats* ss) { int k, w; double lhood = 0; for (k = 0; k < model->ntopics; k++) { gsl_vector ss_k = gsl_matrix_column(ss->topics_ss, k).vector; gsl_vector log_p = gsl_matrix_column(model->topics, k).vector; if (LDA_USE_VAR_BAYES == 0) { gsl_blas_dcopy(&ss_k, &log_p); normalize(&log_p); vct_log(&log_p); } else { double digsum = sum(&ss_k)+model->nterms*LDA_TOPIC_DIR_PARAM; digsum = gsl_sf_psi(digsum); double param_sum = 0; for (w = 0; w < model->nterms; w++) { double param = vget(&ss_k, w) + LDA_TOPIC_DIR_PARAM; param_sum += param; double elogprob = gsl_sf_psi(param) - digsum; vset(&log_p, w, elogprob); lhood += (LDA_TOPIC_DIR_PARAM - param) * elogprob + gsl_sf_lngamma(param); } lhood -= gsl_sf_lngamma(param_sum); } } return(lhood); }
/* Computes psi (digamma) vector function */ int vector_psi(long n, double *a, double *x) { long i; double tot=0, psi_tot; for (i=0; i<n; i++) { tot += a[i]; } psi_tot = gsl_sf_psi(tot); for (i=0; i<n; i++) { x[i] = gsl_sf_psi(a[i]) - psi_tot; } return 1; }
void binom_transform (const double* rs, const double* fq, double* out) { double r=rs[0]; double s=rs[1]; double f=fq[0]; double q=fq[1]; double E = gsl_sf_psi(r) - gsl_sf_psi(s); double V = gsl_sf_psi_1(r) + gsl_sf_psi_1(s); out[0] = E - f; out[1] = V - q; // Rprintf("r=%g, s=%g, f=%g, q=%g, out=%g, %g\n", r, s, f, q, out[0], out[1]); }
static void hessian(gsl_matrix* ptHessian, const double* adLambda, const struct data_t *data) { const int S = data->S, N = data->N, *aanX = data->aanX; const double *adPi = data->adPi; int i = 0, j = 0; double adAlpha[S], adAJK[S], adCJK[S], adAJK0[S], adCJK0[S]; double dCK0 = 0.0, dAK0; double dCSum, dAlphaSum = 0.0, dW = 0.0, dCK = 0.0, dAK; for (j = 0; j < S; j++) { adAlpha[j] = exp(adLambda[j]); dAlphaSum += adAlpha[j]; adAJK0[j] = adAJK[j] = adCJK0[j] = adCJK[j] = 0.0; const double dPsiAlpha = gsl_sf_psi(adAlpha[j]); const double dPsi1Alpha = gsl_sf_psi_1(adAlpha[j]); for (i = 0; i < N; i++) { const int n = aanX[j * N + i]; adCJK0[j] += adPi[i] * n ? gsl_sf_psi(adAlpha[j] + n) : dPsiAlpha; adAJK0[j] += adPi[i] * dPsiAlpha; adCJK[j] += adPi[i] * n ? gsl_sf_psi_1(adAlpha[j] + n): dPsi1Alpha; adAJK[j] += adPi[i] * dPsi1Alpha; } } for (i = 0; i < N; i++) { dW += adPi[i]; dCSum = 0.0; for (j = 0; j < S; j++) dCSum += adAlpha[j] + aanX[j * N + i]; dCK += adPi[i]*gsl_sf_psi_1(dCSum); dCK0 += adPi[i]*gsl_sf_psi(dCSum); } dAK = dW * gsl_sf_psi_1(dAlphaSum); dAK0 = dW * gsl_sf_psi(dAlphaSum); for (i = 0; i < S; i++) for (j = 0; j < S; j++) { double dVal = 0.0; if (i == j) { double dG1 = -adAlpha[i] * (dAK0 - dCK0 + adCJK0[i] - adAJK0[i]); double dG2 = -adAlpha[i] * adAlpha[i]*(dAK - dCK + adCJK[i] - adAJK[i]); double dG3 = adAlpha[i]*GAMMA_NU; dVal = dG1 + dG2 + dG3; } else dVal = -adAlpha[i] * adAlpha[j] * (dAK - dCK); gsl_matrix_set(ptHessian, i, j, dVal); } }
double compute_lda_lhood(lda_post* p) { int k, n; int K = p->model->ntopics, N = p->doc->nterms; double gamma_sum = sum(p->gamma); double lhood = gsl_sf_lngamma(sum(p->model->alpha)) - gsl_sf_lngamma(gamma_sum); vset(p->lhood, K, lhood); double influence_term = 0.0; double digsum = gsl_sf_psi(gamma_sum); for (k = 0; k < K; k++) { if (p->doc_weight != NULL) { // outlog("doc weight size: %d", p->doc_weight->size); assert (K == p->doc_weight->size); double influence_topic = gsl_vector_get(p->doc_weight, k); if (FLAGS_model == "dim" || FLAGS_model == "fixed") { influence_term = - ((influence_topic * influence_topic + FLAGS_sigma_l * FLAGS_sigma_l) / 2.0 / (FLAGS_sigma_d * FLAGS_sigma_d)); // Note that these cancel with the entropy. // - (log(2 * PI) + log(FLAGS_sigma_d)) / 2.0); } } double e_log_theta_k = gsl_sf_psi(vget(p->gamma, k)) - digsum; double lhood_term = (vget(p->model->alpha, k)-vget(p->gamma, k)) * e_log_theta_k + gsl_sf_lngamma(vget(p->gamma, k)) - gsl_sf_lngamma(vget(p->model->alpha, k)); for (n = 0; n < N; n++) { if (mget(p->phi, n, k) > 0) { lhood_term += p->doc->count[n]* mget(p->phi, n, k) * (e_log_theta_k + mget(p->model->topics, p->doc->word[n], k) - mget(p->log_phi, n, k)); } } vset(p->lhood, k, lhood_term); lhood += lhood_term; lhood += influence_term; } return(lhood); }
double NBinGlm::getfAfAdash(double k0, unsigned int id, unsigned int limit) { unsigned int i, it=0; double sum=1, num=0, k; double y, m, dl, ddl, tol; double phi, dl_dphi, d2l_dphi2, del_phi; if (k0==0) { for (i=0; i<nRows; i++) { y = gsl_matrix_get(Yref, i, id); m = gsl_matrix_get(Mu, i, id); if (m>0) { sum = sum+(y/m-1)*(y/m-1); num = num+1; } } k = num/sum; if (num==0) printf("num=0\n"); } else k=k0; k = MAX(k, mintol); phi = 1/k; while ( it<limit ) { it++; dl=nRows*(1+log(k)-gsl_sf_psi(k)); ddl=nRows*(gsl_sf_psi_1(k)-1/k); for ( i=0; i<nRows; i++ ) { y = gsl_matrix_get(Yref, i, id); m = gsl_matrix_get(Mu, i, id); dl = dl + gsl_sf_psi(y+k)-log(m+k)-(y+k)/(m+k); ddl = ddl - gsl_sf_psi_1(y+k)+2/(m+k)-(y+k)/((m+k)*(m+k)); } dl_dphi = - exp(2*log(k))*dl; d2l_dphi2 = 2*exp(3*log(k))*dl + exp(4*log(k))*ddl; if (ABS(ddl) < mintol) ddl = GSL_SIGN(ddl)*mintol; del_phi = dl_dphi/ABS(d2l_dphi2); tol = ABS(del_phi*dl_dphi); if (tol<eps) break; phi = phi + del_phi; if (phi<0) {k=0; break;} k = 1/MAX(ABS(phi),mintol); if (k>maxth) break; } return k; }
double KL_V_z_i (const gsl_vector *v_V_z_i) { int i = *params->i, d = *params->d; int D = *params->D; int g; double tmpsum = 0.0, tmp; int N = *params->N; double KL; for (d=0; d<D; d++) params->V_z[i*D+d] = gsl_vector_get(v_V_z_i, d); tmpsum = loglikefunc(); KL = tmpsum; tmpsum = 0; for (g = 0; g < *params->G; g++) { tmp = 0.0; for (d=0; d<D; d++) tmp += pow(params->V_z[i*D+d] - params->V_eta[g * D + d], 2.0); tmp = GSQRT(tmp + params->V_sigma2[i] + params->V_omega2[g]); tmpsum += params->V_lambda[g * N + i] * (D * gsl_sf_psi (0.5 * *params->inv_sigma02 * params->V_alpha[g]) -0.5 * *params->inv_sigma02 * params->V_alpha[g] * tmp); } KL = fabs (KL + tmpsum); return KL; }
void update_phi(int doc_number, int time, lda_post* p, lda_seq* var, gsl_matrix* g) { int i, k, n, K = p->model->ntopics, N = p->doc->nterms; double dig[p->model->ntopics]; for (k = 0; k < K; k++) { dig[k] = gsl_sf_psi(vget(p->gamma, k)); } for (n = 0; n < N; n++) { // compute log phi up to a constant int w = p->doc->word[n]; for (k = 0; k < K; k++) { mset(p->log_phi, n, k, dig[k] + mget(p->model->topics, w, k)); } // normalize in log space gsl_vector log_phi_row = gsl_matrix_row(p->log_phi, n).vector; gsl_vector phi_row = gsl_matrix_row(p->phi, n).vector; log_normalize(&log_phi_row); for (i = 0; i < K; i++) { vset(&phi_row, i, exp(vget(&log_phi_row, i))); } } }
void init(bool deserialize) { LOG(debug) << "global.min_gamma_shape=" << options.get<double>("global.min_gamma_shape"); layer_size = options.get<int>("layer.size"); lf = get_link_function(options.get<string>("lf")); min_gamma_sample = options.get<double>("global.min_gamma_sample"); wshape.set_size(layer_size, n_examples); wscale.set_size(layer_size, n_examples); ScoreFunction score_shape = [=](double z, arma::uword i, arma::uword j) { auto shape0 = wshape(i,j); auto shape = lf->f(shape0); auto scale = lf->f(wscale(i,j)); return lf->g(shape0) * (- gsl_sf_psi(shape) - log(scale) + log(z)); }; register_param(&wshape, score_shape, deserialize); ScoreFunction score_scale = [=](double z, arma::uword i, arma::uword j) { auto shape = lf->f(wshape(i,j)); auto scale0 = wscale(i,j); auto scale = lf->f(scale0); return lf->g(scale0) * (- shape/scale + z/scale/scale); }; register_param(&wscale, score_scale, deserialize); }
double NBinGlm::thetaML(double k0, unsigned int id, unsigned int limit) { // equivalent to theta.ml() in MASS // Note that theta here is the dispersion parameter // So phi = 1/theta; unsigned int i, it=0; double del=1, sum=1, num=0, k; double y, m, dl, ddl, tol; if (k0==0) { for (i=0; i<nRows; i++) { y = gsl_matrix_get(Yref, i, id); m = gsl_matrix_get(Mu, i, id); if (m>0) { sum = sum+(y/m-1)*(y/m-1); num = num+1; } } k = num/sum; } else k=k0; k = MAX(k, mintol); while ( it<=limit ) { it++; k = ABS(k); dl=nRows*(1+log(k)-gsl_sf_psi(k)); ddl=nRows*(gsl_sf_psi_1(k)-1/k); for ( i=0; i<nRows; i++ ) { y = gsl_matrix_get(Yref, i, id); m = gsl_matrix_get(Mu, i, id); dl = dl + gsl_sf_psi(y+k)-log(m+k)-(y+k)/(m+k); ddl = ddl - gsl_sf_psi_1(y+k)+2/(m+k)-(y+k)/((m+k)*(m+k)); } if (ABS(ddl) < mintol) ddl = GSL_SIGN(ddl)*mintol; del = dl/ABS(ddl); tol = ABS(del*dl); if (tol<eps) break; k = k+del; // Normal Newton use - instead of + for -ddl if (k>maxth) break; if (k<0) { k = 0; break; } } // if (k<0) k=0; return k; }
void vdigamma(const gsl_vector* v, gsl_vector* digamma_v) { for (unsigned int ii = 0; ii < v->size; ++ii) { // gsl_sf_psi throws an error when its argument is 0, whereas digamma // returns inf. gsl_vector_set(digamma_v, ii, gsl_sf_psi(gsl_vector_get(v, ii))); // gsl_vector_set(digamma_v, ii, digamma(gsl_vector_get(v, ii))); } }
static void neg_log_derive_evidence_lambda_pi(const gsl_vector *ptLambda, void *params, gsl_vector* g) { const struct data_t *data = (const struct data_t *) params; const int S = data->S, N = data->N, *aanX = data->aanX; const double *adPi = data->adPi; int i, j; double adDeriv[S], adStore[N], adAlpha[S]; double dSumStore = 0.0, dStore = 0.0; double dWeight = 0; for (i = 0; i < N; i++) { adStore[i] = 0.0; dWeight += adPi[i]; } for (j = 0; j < S; j++) { adAlpha[j] = exp(gsl_vector_get(ptLambda, j)); dStore += adAlpha[j]; adDeriv[j] = dWeight* gsl_sf_psi(adAlpha[j]); double alphaS0 = gsl_sf_psi(adAlpha[j]); for (i = 0; i < N; i++) { int dN = aanX[j * N + i]; double dAlphaN = adAlpha[j] + dN; double psiAlphaN = dN ? gsl_sf_psi(dAlphaN) : alphaS0; adDeriv[j] -= adPi[i] * psiAlphaN; adStore[i] += dAlphaN; } } for (i = 0; i < N; i++) dSumStore += adPi[i] * gsl_sf_psi(adStore[i]); dStore = dWeight * gsl_sf_psi(dStore); for (j = 0; j < S; j++) { double value = adAlpha[j] * (GAMMA_NU + adDeriv[j] - dStore + dSumStore) - GAMMA_ITA; gsl_vector_set(g, j, value); } }
double SPF::update_theta(int user) { double change = accu(abs(theta(user) - (a_theta(user) / b_theta(user)))); double total = accu(theta(user)); theta(user) = a_theta(user) / b_theta(user); for (int k = 0; k < settings->k; k++) logtheta(k, user) = gsl_sf_psi(a_theta(k, user)); logtheta(user) = logtheta(user) - log(b_theta(user)); return change / total; }
inline typename ICR::EnsembleLearning::Gamma<T>::moments_t ICR::EnsembleLearning::Gamma<T>::CalcMoments(NP_parameter NP) { const data_t shape = NP[1]+1.0; const data_t iscale = -NP[0]; BOOST_ASSERT(iscale>0); return moments_t(shape/iscale, gsl_sf_psi(shape) - std::log(iscale) ); }
void SPF::update_beta(int item) { if (settings->svi) { double rho = pow(iter_count[item] + settings->delay, -1 * settings->forget); a_beta(item) = (1 - rho) * a_beta_old(item) + rho * a_beta(item); a_beta_old(item) = a_beta(item); } beta(item) = a_beta(item) / b_beta(item); for (int k = 0; k < settings->k; k++) logbeta(k, item) = gsl_sf_psi(a_beta(k, item)); logbeta(item) = logbeta(item) - log(b_beta(item)); }
void gr_KL_V_nu_g (const gsl_vector *v_V_nu_g, void *null, gsl_vector *df) { int i = *params->i; //, j, d = *params->d; int g, G = *params->G; double tmpsum = 0.0, tmp; int N = *params->N; double KL; double V_nu_g = gsl_vector_get(v_V_nu_g, 0); tmp = 0.0; for (g = 0; g < G; g++) if (g!=*params->g) tmp += params->V_nu[g]; for (i = 0; i < SUBSET; i++) tmpsum = tmpsum + params->V_lambda[*params->g * N + i] * (gsl_sf_psi_1 (V_nu_g) - gsl_sf_psi_1 (tmp+V_nu_g)); KL = tmpsum - gsl_sf_psi (tmp+V_nu_g) - gsl_sf_psi (params->nu[*params->g]) - V_nu_g * gsl_sf_psi_1 (V_nu_g) + params->nu[*params->g] * gsl_sf_psi_1 (V_nu_g); gsl_vector_set(df, 0, -KL); return; }
double my_f (const gsl_vector *v, void *params) { cclda_alphaopt * alphaopt=(cclda_alphaopt *) params; double f = 0.0; double sumalpha, sumpsialpha; int j, c; f = 0.0; c = alphaopt->c; sumalpha = 0.0; sumpsialpha = 0.0; for (j = 0; j < alphaopt->m; j++){ alphaopt->alpha[j] = exp(gsl_vector_get(v, j)); sumalpha += alphaopt->alpha[j]; f += (alphaopt->alpha[j] - 1)*alphaopt->ss2[j][c]; sumpsialpha += gsl_sf_psi(alphaopt->alpha[j]); } f += alphaopt->ss1[c]*(gsl_sf_psi(sumalpha) - sumpsialpha); f = -f; return(f); }
inline typename ICR::EnsembleLearning::Gamma<T>::moments_t ICR::EnsembleLearning::Gamma<T>::CalcMoments(vector_data_param mean, vector_data_param var) { const data_t m = mean[0]; const data_t p = 1.0/var[0]; const data_t shape = std::pow(m,2)*p; const data_t iscale = m*p; BOOST_ASSERT(iscale>0); return moments_t(shape/iscale, gsl_sf_psi(shape) - std::log(iscale) ); }
double SPF::update_tau(int user) { int neighbor, n; double old, change, total; change = 0; total = 0; for (n = 0; n < data->neighbor_count(user); n++) { neighbor = data->get_neighbor(user, n); old = tau(neighbor, user); total += tau(neighbor, user); tau(neighbor, user) = a_tau(neighbor, user) / b_tau(neighbor, user); // fake log! logtau(neighbor, user) = exp(gsl_sf_psi(a_tau(neighbor, user)) - log(b_tau(neighbor, user))); change += abs(old - tau(neighbor, user)); } return total==0 ? 0 : change / total; }
double dWishartExpectLogDet(gsl_matrix *ptW, double dNu, int nD) { int i = 0; double dRet = 0.0, dLogDet = 0.0, dD = (double) nD; gsl_matrix* ptTemp = gsl_matrix_alloc(nD,nD); gsl_matrix_memcpy(ptTemp, ptW); dLogDet = decomposeMatrix(ptW, nD); dRet = dD*log(2.0) + dLogDet; for(i = 0; i < nD; i++){ dRet += gsl_sf_psi(0.5*(dNu - (double) i)); } gsl_matrix_free(ptTemp); return dRet; }
/// gsl_wrappers double digamma(double x) { return gsl_sf_psi(x); }
//Fitting. Allow fitting multiple q curves simultaneously to decrease the chance of converging to local minimum. void ddm::fitting() { int cnum_fit=num_fit; int ctimeWindow=timeWindow; //Find the truncation time if time window is set for (int itert=0; itert<num_fit; ++itert) { if (tau[itert]>ctimeWindow) { cnum_fit=itert; break; } } //Local variables int cqsize=qsize-qIncreList[num_qCurve-1]; //number of fitting result int cnum_qCurve=num_qCurve; int ctnum_fit=cnum_fit*num_qCurve; int cnumOfPara=numOfPara+2*num_qCurve; //Total number of parameters fittedPara=gsl_matrix_alloc(cqsize, cnumOfPara); //To store the fitting result and error. fitErr=gsl_matrix_alloc(cqsize, cnumOfPara); status = new int[cqsize]; //Record the status of fitting. //Using Levenberg-Marquardt algorithm as implemented in the scaled lmder routine in minpack. Jacobian is given. const gsl_multifit_fdfsolver_type *solverType = gsl_multifit_fdfsolver_lmsder; int progress=0; //Indicator of progress. //Objects to do numerical inverse Laplace transformation #ifdef ISFRTD NILT NILT1(OMP_NUM_THREADS), NILT2(OMP_NUM_THREADS), NILT3(OMP_NUM_THREADS), NILT4(OMP_NUM_THREADS); #endif #ifdef ISFRTDP NILT NILT1(OMP_NUM_THREADS), NILT2(OMP_NUM_THREADS), NILT3(OMP_NUM_THREADS), NILT4(OMP_NUM_THREADS), NILT5(OMP_NUM_THREADS); #endif #ifdef ISFRTDPTT NILT NILT1(OMP_NUM_THREADS), NILT2(OMP_NUM_THREADS), NILT3(OMP_NUM_THREADS), NILT4(OMP_NUM_THREADS), NILT5(OMP_NUM_THREADS), NILT6(OMP_NUM_THREADS); #endif #ifdef ISFRTDPfix NILT NILT1(OMP_NUM_THREADS), NILT2(OMP_NUM_THREADS); const long double vbar=vbarGuess; const long double sigma=sigmaGuess; const long double vbsigma2=vbar/sigma/sigma; const long double vb2sigma2=vbsigma2*vbar; const long double logvbsigma2=log(vbsigma2); const long double logfactor=vb2sigma2*logvbsigma2-gsl_sf_lngamma(vb2sigma2); const long double cpsiz1=logvbsigma2-gsl_sf_psi(vb2sigma2); const long double vb2sigma3=vb2sigma2/sigma; #endif #ifdef ISFRTDPTTfix NILT NILT1(OMP_NUM_THREADS), NILT2(OMP_NUM_THREADS), NILT3(OMP_NUM_THREADS); const long double vbar=vbarGuess; const long double sigma=sigmaGuess; const long double vbsigma2=vbar/sigma/sigma; const long double vb2sigma2=vbsigma2*vbar; const long double logvbsigma2=log(vbsigma2); const long double logfactor=vb2sigma2*logvbsigma2-gsl_sf_lngamma(vb2sigma2); const long double cpsiz1=logvbsigma2-gsl_sf_psi(vb2sigma2); const long double vb2sigma3=vb2sigma2/sigma; #endif #pragma omp parallel for for (int iterq=0; iterq<cqsize; ++iterq) { //Data array which is going to present to the fitting algorithm double* datafit=new double[ctnum_fit]; double* qList=new double[cnum_qCurve]; double* time=new double[ctnum_fit]; //Truncate the data, and put multiple curves into one array for (int iterqc=0; iterqc<cnum_qCurve; ++iterqc) { for (int iterf = 0; iterf < cnum_fit; ++iterf) { datafit[iterf+iterqc*cnum_fit]=(gsl_matrix_get(datag, iterq+qIncreList[iterqc], iterf)); //Fitting in log scale. time[iterf+iterqc*cnum_fit]=tau[iterf]; } qList[iterqc]=qabs[iterq+qIncreList[iterqc]]; } gsl_multifit_function_fdf fitfun; //Pointer of function to fit. dataStruct sdata; //GSL data structure //Data is passed to ISFfun by sdata sdata.data=datafit; sdata.tau=time; sdata.q=qList; sdata.num_fit=cnum_fit; sdata.num_qCurve=cnum_qCurve; #ifdef ISFRTD sdata.ISFILT=&NILT1; sdata.dvISFILT=&NILT2; sdata.dDISFILT=&NILT3; sdata.dlambdaISFILT=&NILT4; #endif #ifdef ISFRTDP sdata.ISFILT=&NILT1; sdata.dvbarISFILT=&NILT2; sdata.dsigmaISFILT=&NILT3; sdata.dDISFILT=&NILT4; sdata.dlambdaISFILT=&NILT5; #endif #ifdef ISFRTDPTT sdata.ISFILT=&NILT1; sdata.dvbarISFILT=&NILT2; sdata.dsigmaISFILT=&NILT3; sdata.dDISFILT=&NILT4; sdata.dlambdaISFILT=&NILT5; sdata.dTTISFILT=&NILT6; #endif #ifdef ISFRTDPfix sdata.alpha=alphaGuess; sdata.D=DGuess; sdata.vbar=vbar; sdata.sigma=sigma; sdata.vbsigma2=vbsigma2; sdata.logfactor=logfactor; sdata.vb2sigma2=vb2sigma2; sdata.cpsiz1=cpsiz1; sdata.vb2sigma3=vb2sigma3; sdata.ISFILT=&NILT1; sdata.dlambdaISFILT=&NILT2; #endif #ifdef ISFRTDPTTfix sdata.alpha=alphaGuess; sdata.D=DGuess; sdata.vbar=vbar; sdata.sigma=sigma; sdata.vbsigma2=vbsigma2; sdata.logfactor=logfactor; sdata.vb2sigma2=vb2sigma2; sdata.cpsiz1=cpsiz1; sdata.vb2sigma3=vb2sigma3; sdata.ISFILT=&NILT1; sdata.dlambdaISFILT=&NILT2; sdata.dTTISFILT=&NILT3; #endif //API fitfun.f=&ISFfun; #ifdef NoJacobian fitfun.df=0; fitfun.fdf=0; #else fitfun.df=&dISFfun; fitfun.fdf=&fdISFfun; #endif fitfun.n=ctnum_fit; fitfun.p=cnumOfPara; fitfun.params=&sdata; //Initialization of the parameters double* localinipara=new double[cnumOfPara]; for (int iterp=0; iterp<numOfPara; ++iterp) { localinipara[iterp]=inipara[iterp]; } //Estimation of A(q) and B(q) for (int iterqc=0; iterqc<num_qCurve; ++iterqc) { localinipara[numOfPara+1+2*iterqc] = gsl_matrix_get(datag, iterq+qIncreList[iterqc], 0); localinipara[numOfPara+2*iterqc] = gsl_matrix_get(datag, iterq+qIncreList[iterqc], num_fit-1)-localinipara[numOfPara+1+2*iterqc]; } //Initiallization of the solver gsl_vector_view para=gsl_vector_view_array(localinipara, cnumOfPara); gsl_multifit_fdfsolver* solver = gsl_multifit_fdfsolver_alloc(solverType, ctnum_fit, cnumOfPara); gsl_multifit_fdfsolver_set(solver, &fitfun, ¶.vector); int iter=0; //gsl_vector* g=gsl_vector_alloc(numOfPara); //For debugging and monitering the iterations // cout << qList[0] << ' ' << qList[1] << '\n'; // for (int iterpara=0; iterpara<cnumOfPara; ++iterpara) // { // cout << gsl_vector_get(solver->x, iterpara) << '\n'; // } // cout << '\n'; int cstatus=GSL_CONTINUE; //Current status do { gsl_multifit_fdfsolver_iterate(solver); //Iterate one step. cstatus = norm0_rel_test(solver->dx, solver->x, 1e-7, 1e-7); //Test the exiting criteria //For debugging and monitering the iterations // for (int iterpara=0; iterpara<cnumOfPara; ++iterpara) // { // cout << gsl_vector_get(solver->x, iterpara) << '\n'; // } // cout << '\n'; //If to use other exiting criteria //gsl_multifit_gradient(solver->J,solver->f, g); //status[iterq-1]=gsl_multifit_test_gradient(g, 1e-5); // status[iterq - 1] = covar_rel_test(solver->J, solver->x, 1e-4); ++iter; //Number of iterations exceed certain limitation if (iter>maxIter) { cstatus=GSL_EMAXITER; } } while (cstatus == GSL_CONTINUE); status[iterq]=cstatus; //gsl_vector_free(g); //Estimating the error. gsl_matrix* covar=gsl_matrix_alloc(cnumOfPara, cnumOfPara); gsl_multifit_covar(solver->J, 0.0, covar); for (int iterpara=0; iterpara<cnumOfPara; ++iterpara) //Record result. { gsl_matrix_set(fittedPara, iterq, iterpara, gsl_vector_get(solver->x, iterpara) ); gsl_matrix_set(fitErr, iterq, iterpara, sqrt(gsl_matrix_get(covar, iterpara, iterpara)) ); //Not presice in log scale } gsl_matrix_free(covar); gsl_multifit_fdfsolver_free(solver); //Output to standard I/O progress+=1; cout << "Fitted q=" << qabs[iterq] << " at iter=" << iter << ", " << 100.0*progress / qsize << "% completed from thread No." << omp_get_thread_num() << ", "<< gsl_strerror(status[iterq]) << "." << '\n'; for (int iterpara=0; iterpara<cnumOfPara; ++iterpara) { cout << gsl_matrix_get(fittedPara, iterq, iterpara) << '\n'; } cout << '\n'; delete [] datafit; delete [] qList; delete [] localinipara; delete [] time; } }
double psi(double x) { return gsl_sf_psi(x); }
//------------------------------------------------------------------------------ /// Digamma function \f$ \psi^{(0)}(x) \f$ inline double psi0(const double x) { return gsl_sf_psi(x); }
int main() { typedef double T; #define SC_(x) static_cast<double>(x) # include "digamma_data.ipp" # include "digamma_root_data.ipp" # include "digamma_small_data.ipp" # include "digamma_neg_data.ipp" static const boost::array<boost::array<T, 2>, 5> digamma_bugs = {{ // Test cases from Rocco Romeo: {{ static_cast<T>(std::ldexp(1.0, -100)), SC_(-1.26765060022822940149670320537657721566490153286060651209008e30) }}, {{ static_cast<T>(-std::ldexp(1.0, -100)), SC_(1.26765060022822940149670320537542278433509846713939348790992e30) }}, {{ static_cast<T>(1), SC_(-0.577215664901532860606512090082402431042159335939923598805767) }}, {{ static_cast<T>(-1) + static_cast<T>(std::ldexp(1.0, -20)), SC_(-1.04857557721314249602848739817764518743062133735858753112190e6) }}, {{ static_cast<T>(-1) - static_cast<T>(std::ldexp(1.0, -20)), SC_(1.04857642278181269259522681939281063878220298942888100442172e6) }}, }}; static const boost::array<boost::array<T, 2>, 40> digamma_integers = { { { 1, SC_(-0.57721566490153286060651209008240243) }, { 2, SC_(0.42278433509846713939348790991759757) }, { 3, SC_(0.92278433509846713939348790991759757) }, { 4, SC_(1.2561176684318004727268212432509309) }, { 5, SC_(1.5061176684318004727268212432509309) }, { 6, SC_(1.7061176684318004727268212432509309) }, { 7, SC_(1.8727843350984671393934879099175976) }, { 8, SC_(2.0156414779556099965363450527747404) }, { 9, SC_(2.1406414779556099965363450527747404) }, { SC_(10.0), SC_(2.2517525890667211076474561638858515) }, { SC_(11.0), SC_(2.3517525890667211076474561638858515) }, { SC_(12.0), SC_(2.4426616799758120167383652547949424) }, { SC_(13.0), SC_(2.5259950133091453500716985881282758) }, { SC_(14.0), SC_(2.6029180902322222731486216650513527) }, { SC_(15.0), SC_(2.6743466616607937017200502364799241) }, { SC_(16.0), SC_(2.7410133283274603683867169031465908) }, { SC_(17.0), SC_(2.8035133283274603683867169031465908) }, { SC_(18.0), SC_(2.8623368577392250742690698443230614) }, { SC_(19.0), SC_(2.9178924132947806298246253998786169) }, { SC_(20.0), SC_(2.9705239922421490508772569788259854) }, { SC_(21.0), SC_(3.0205239922421490508772569788259854) }, { SC_(22.0), SC_(3.0681430398611966699248760264450330) }, { SC_(23.0), SC_(3.1135975853157421244703305718995784) }, { SC_(24.0), SC_(3.1570758461853073418616349197256654) }, { SC_(25.0), SC_(3.1987425128519740085283015863923321) }, { SC_(26.0), SC_(3.2387425128519740085283015863923321) }, { SC_(27.0), SC_(3.2772040513135124700667631248538705) }, { SC_(28.0), SC_(3.3142410883505495071038001618909076) }, { SC_(29.0), SC_(3.3499553740648352213895144476051933) }, { SC_(30.0), SC_(3.3844381326855248765619282407086415) }, { SC_(31.0), SC_(3.4177714660188582098952615740419749) }, { SC_(32.0), SC_(3.4500295305349872421533260901710071) }, { SC_(33.0), SC_(3.4812795305349872421533260901710071) }, { SC_(34.0), SC_(3.5115825608380175451836291204740374) }, { SC_(35.0), SC_(3.5409943255438998981248055910622727) }, { SC_(36.0), SC_(3.5695657541153284695533770196337013) }, { SC_(37.0), SC_(3.5973435318931062473311547974114791) }, { SC_(38.0), SC_(3.6243705589201332743581818244385061) }, { SC_(39.0), SC_(3.6506863483938174848844976139121903) }, { SC_(40.0), SC_(3.6763273740348431259101386395532160) } } }; static const boost::array<boost::array<T, 2>, 41> digamma_half_integers = { { { SC_(0.5), SC_(-1.9635100260214234794409763329987556) }, { SC_(1.5), SC_(0.036489973978576520559023667001244433) }, { SC_(2.5), SC_(0.70315664064524318722569033366791110) }, { SC_(3.5), SC_(1.1031566406452431872256903336679111) }, { SC_(4.5), SC_(1.3888709263595289015114046193821968) }, { SC_(5.5), SC_(1.6110931485817511237336268416044190) }, { SC_(6.5), SC_(1.7929113303999329419154450234226009) }, { SC_(7.5), SC_(1.9467574842460867880692911772687547) }, { SC_(8.5), SC_(2.0800908175794201214026245106020880) }, { SC_(9.5), SC_(2.1977378764029495331673303929550292) }, { SC_(10.5), SC_(2.3030010342976863752725935508497661) }, { SC_(11.5), SC_(2.3982391295357816133678316460878613) }, { SC_(12.5), SC_(2.4851956512749120481504403417400352) }, { SC_(13.5), SC_(2.5651956512749120481504403417400352) }, { SC_(14.5), SC_(2.6392697253489861222245144158141093) }, { SC_(15.5), SC_(2.7082352425903654325693420020210058) }, { SC_(16.5), SC_(2.7727513716226234970854710342790703) }, { SC_(17.5), SC_(2.8333574322286841031460770948851310) }, { SC_(18.5), SC_(2.8905002893715412460032199520279881) }, { SC_(19.5), SC_(2.9445543434255953000572740060820421) }, { SC_(20.5), SC_(2.9958363947076465821085560573640934) }, { SC_(21.5), SC_(3.0446168825125246308890438622421422) }, { SC_(22.5), SC_(3.0911285104195013750750903738700492) }, { SC_(23.5), SC_(3.1355729548639458195195348183144936) }, { SC_(24.5), SC_(3.1781261463533075216471943927825787) }, { SC_(25.5), SC_(3.2189424728839197665451535764560481) }, { SC_(26.5), SC_(3.2581581591584295704667222039070285) }, { SC_(27.5), SC_(3.2958940082150333440516278642843870) }, { SC_(28.5), SC_(3.3322576445786697076879915006480234) }, { SC_(29.5), SC_(3.3673453638769153217230792199462690) }, { SC_(30.5), SC_(3.4012436689616610844349436267259300) }, { SC_(31.5), SC_(3.4340305542075627237792059218078972) }, { SC_(32.5), SC_(3.4657765859535944698109519535539290) }, { SC_(33.5), SC_(3.4965458167228252390417211843231597) }, { SC_(34.5), SC_(3.5263965629914819554596316320843538) }, { SC_(35.5), SC_(3.5553820702378587670538345306350784) }, { SC_(36.5), SC_(3.5835510843223658093073556573956418) }, { SC_(37.5), SC_(3.6109483445963384120470816847929021) }, { SC_(38.5), SC_(3.6376150112630050787137483514595687) }, { SC_(39.5), SC_(3.6635890372370310527397223774335947) }, { SC_(40.5), SC_(3.6889054929332335843852919976867593) } } }; add_data(digamma_data); add_data(digamma_root_data); add_data(digamma_small_data); add_data(digamma_neg_data); add_data(digamma_bugs); add_data(digamma_integers); add_data(digamma_half_integers); unsigned data_total = data.size(); screen_data([](const std::vector<double>& v){ return boost::math::digamma(v[0]); }, [](const std::vector<double>& v){ return v[1]; }); #if defined(TEST_GSL) && !defined(COMPILER_COMPARISON_TABLES) screen_data([](const std::vector<double>& v){ return gsl_sf_psi(v[0]); }, [](const std::vector<double>& v){ return v[1]; }); #endif #if defined(TEST_RMATH) && !defined(COMPILER_COMPARISON_TABLES) screen_data([](const std::vector<double>& v){ return ::digamma(v[0]); }, [](const std::vector<double>& v){ return v[1]; }); #endif unsigned data_used = data.size(); std::string function = "digamma[br](" + boost::lexical_cast<std::string>(data_used) + "/" + boost::lexical_cast<std::string>(data_total) + " tests selected)"; std::string function_short = "digamma"; double time = exec_timed_test([](const std::vector<double>& v){ return boost::math::digamma(v[0]); }); std::cout << time << std::endl; #if !defined(COMPILER_COMPARISON_TABLES) && (defined(TEST_GSL) || defined(TEST_RMATH)) report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, boost_name()); #endif report_execution_time(time, std::string("Compiler Comparison on ") + std::string(platform_name()), function_short, compiler_name() + std::string("[br]") + boost_name()); // // Boost again, but with promotion to long double turned off: // #if !defined(COMPILER_COMPARISON_TABLES) if(sizeof(long double) != sizeof(double)) { double time = exec_timed_test([](const std::vector<double>& v){ return boost::math::digamma(v[0], boost::math::policies::make_policy(boost::math::policies::promote_double<false>())); }); std::cout << time << std::endl; #if !defined(COMPILER_COMPARISON_TABLES) && (defined(TEST_GSL) || defined(TEST_RMATH)) report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, boost_name() + "[br]promote_double<false>"); #endif report_execution_time(time, std::string("Compiler Comparison on ") + std::string(platform_name()), function_short, compiler_name() + std::string("[br]") + boost_name() + "[br]promote_double<false>"); } #endif #if defined(TEST_GSL) && !defined(COMPILER_COMPARISON_TABLES) time = exec_timed_test([](const std::vector<double>& v){ return gsl_sf_psi(v[0]); }); std::cout << time << std::endl; report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, "GSL " GSL_VERSION); #endif #if defined(TEST_RMATH) && !defined(COMPILER_COMPARISON_TABLES) time = exec_timed_test([](const std::vector<double>& v){ return ::digamma(v[0]); }); std::cout << time << std::endl; report_execution_time(time, std::string("Library Comparison with ") + std::string(compiler_name()) + std::string(" on ") + platform_name(), function, "Rmath " R_VERSION_STRING); #endif return 0; }
void update_phi_fixed(int doc_number, int time, lda_post* p, lda_seq* var, gsl_matrix* g3_matrix, gsl_matrix* g4_matrix, gsl_matrix* g5_matrix) { // Hate to do this, but I had problems allocating this data // structure. if (scaled_influence == NULL) { scaled_influence = NewScaledInfluence(FLAGS_max_number_time_points); } int i, k, n, K = p->model->ntopics, N = p->doc->nterms; double dig[p->model->ntopics]; double k_sum = 0.0; for (k = 0; k < K; k++) { double gamma_k = vget(p->gamma, k); dig[k] = gsl_sf_psi(gamma_k); k_sum += gamma_k; } double dig_sum = gsl_sf_psi(k_sum); gsl_vector_view document_weights; if (var && var->influence) { document_weights = gsl_matrix_row( var->influence->doc_weights[time], doc_number); } for (n=0; n < N; ++n) { int w = p->doc->word[n]; // We have info. about the topics. Use them! // Try two alternate approaches. We compare results of the new // algorithm with the old to make sure we're not doing anything // silly. for (k = 0; k < K; ++k) { // Find an estimate for log_phi_nk. double doc_weight = 0.0; sslm_var* topic = var->topic[k]; const double chain_variance = topic->chain_variance; // These matrices are already set up for the correct time. double g3 = mget(g3_matrix, w, k); double g4 = mget(g4_matrix, w, k); double g5 = mget(g5_matrix, w, k); double w_phi_sum = gsl_matrix_get( var->topic[k]->w_phi_sum, w, time); // Only set these variables if we are within the correct // time window. if (time < var->nseq) { doc_weight = gsl_vector_get(&document_weights.vector, k); } double term_weight; if (FLAGS_normalize_docs == "normalize") { term_weight = ((double) p->doc->count[n] / (double) p->doc->total); } else if (FLAGS_normalize_docs == "log") { term_weight = log(p->doc->count[n] + 1.0); } else if (FLAGS_normalize_docs == "log_norm") { term_weight = log(p->doc->count[n] / p->doc->total); } else if (FLAGS_normalize_docs == "identity") { term_weight = p->doc->count[n]; } else if (FLAGS_normalize_docs == "occurrence") { term_weight = ((double) p->doc->count[n] / (double) p->doc->total); } else { assert(0); } assert(var != NULL); double total, term1, term2, term3, term4; double phi_last = 0.0; // It's unnecessary to always multiply by 1/chain_variance // this deep in a loop, but it's likely not a major // bottleneck. term1 = dig[k] + mget(p->model->topics, w, k); term2 = (g3 * term_weight * doc_weight / chain_variance); term3 = (term_weight * doc_weight * g4 / chain_variance); term4 = (term_weight * term_weight * (phi_last * (doc_weight * doc_weight) - (doc_weight * doc_weight + FLAGS_sigma_l * FLAGS_sigma_l)) * g5 / chain_variance); // Note: we're ignoring term3. sgerrish: 18 July 2010: // Changing term2 to have a positive coefficient (instead of // negative) to be consistent with parallel version. // sgerrish: 23 July 2010: changing term2 back to negative, // to try to reproduce earlier results. total = term1 - term2 - term3 + term4; mset(p->log_phi, n, k, total); } // Normalize in log space. gsl_vector log_phi_row = gsl_matrix_row(p->log_phi, n).vector; gsl_vector phi_row = gsl_matrix_row(p->phi, n).vector; log_normalize(&log_phi_row); for (i = 0; i < K; i++) { vset(&phi_row, i, exp(vget(&log_phi_row, i))); } } }