void bi::cov(const ExpGaussianPdf<V1, M1>& q, M2 Sigma) { /* pre-condition */ BI_ASSERT(Sigma.size1() == q.size()); BI_ASSERT(Sigma.size2() == q.size()); Sigma = q.cov(); }
void bi::marginalise(const ExpGaussianPdf<V1, M1>& p1, const ExpGaussianPdf<V2,M2>& p2, const M3 C, const ExpGaussianPdf<V4, M4>& q2, ExpGaussianPdf<V5,M5>& p3) { /* pre-conditions */ BI_ASSERT(q2.size() == p2.size()); BI_ASSERT(p3.size() == p1.size()); BI_ASSERT(C.size1() == p1.size() && C.size2() == p2.size()); typename sim_temp_vector<V1>::type z2(p2.size()); typename sim_temp_matrix<M1>::type K(p1.size(), p2.size()); typename sim_temp_matrix<M1>::type A1(p2.size(), p2.size()); typename sim_temp_matrix<M1>::type A2(p2.size(), p2.size()); /** * Compute gain matrix: * * \f[\mathcal{K} = C_{\mathbf{x}_1,\mathbf{x}_2}\Sigma_2^{-1}\,.\f] */ symm(1.0, p2.prec(), C, 0.0, K, 'R', 'U'); /** * Then result is given by \f$\mathcal{N}(\boldsymbol{\mu}', * \Sigma')\f$, where: * * \f[\boldsymbol{\mu}' = \boldsymbol{\mu}_1 + * \mathcal{K}(\boldsymbol{\mu}_3 - \boldsymbol{\mu}_2)\,,\f] */ z2 = q2.mean(); axpy(-1.0, p2.mean(), z2); p3.mean() = p1.mean(); gemv(1.0, K, z2, 1.0, p3.mean()); /** * and: * * \f{eqnarray*} * \Sigma' &=& \Sigma_1 + \mathcal{K}(\Sigma_3 - * \Sigma_2)\mathcal{K}^T \\ * &=& \Sigma_1 + \mathcal{K}\Sigma_3\mathcal{K}^T - * \mathcal{K}\Sigma_2\mathcal{K}^T\,. * \f} */ p3.cov() = p1.cov(); A1 = K; trmm(1.0, q2.std(), A1, 'R', 'U', 'T'); syrk(1.0, A1, 1.0, p3.cov(), 'U'); A2 = K; trmm(1.0, p2.std(), A2, 'R', 'U', 'T'); syrk(-1.0, A2, 1.0, p3.cov(), 'U'); /* make sure correct log-variables set */ p3.setLogs(p2.getLogs()); p3.init(); // redo precalculations }
void bi::mean(const M1 X, const V1 w, V2 mu) { /* pre-conditions */ BI_ASSERT(X.size2() == mu.size()); BI_ASSERT(X.size1() == w.size()); typedef typename V1::value_type T; T Wt = sum_reduce(w); gemv(1.0/Wt, X, w, 0.0, mu, 'T'); }
inline void bi::mean(const InverseGammaPdf& q, V1 mu) { /* pre-condition */ BI_ASSERT(mu.size() == q.size()); BI_ASSERT(q.shape() > 1.0); real alpha = q.shape(); real beta = q.scale(); set_elements(mu, alpha*std::pow(beta, 2)); }
void bi::cov(const M1 X, const V1 mu, M2 Sigma) { /* pre-conditions */ BI_ASSERT(X.size2() == mu.size()); BI_ASSERT(Sigma.size1() == mu.size() && Sigma.size2() == mu.size()); const int N = X.size1(); typename sim_temp_matrix<M2>::type Y(X.size1(), X.size2()); Y = X; sub_rows(Y, mu); syrk(1.0/(N - 1.0), Y, 0.0, Sigma, 'U', 'T'); }
void bi::cov(const GammaPdf& q, M1 Sigma) { /* pre-condition */ BI_ASSERT(Sigma.size1() == q.size()); BI_ASSERT(Sigma.size2() == q.size()); real alpha = q.shape(); real beta = q.scale(); real sigma = alpha*std::pow(beta, 2); Sigma.clear(); set_elements(diagonal(Sigma), sigma); }
void bi::var(const M1 X, const V1 mu, V2 sigma) { /* pre-conditions */ BI_ASSERT(X.size2() == mu.size()); BI_ASSERT(sigma.size() == mu.size()); const int N = X.size1(); typename sim_temp_matrix<M1>::type Z(X.size2(), X.size1()); Z = X; sub_rows(Z, mu); dot_columns(Z, sigma); scal(1.0/(N - 1.0), sigma); }
void bi::cov(const InverseGammaPdf& q, M1 Sigma) { /* pre-condition */ BI_ASSERT(Sigma.size1() == q.size()); BI_ASSERT(Sigma.size2() == q.size()); BI_ASSERT(q.shape() > 2.0); real alpha = q.shape(); real beta = q.scale(); real sigma = std::pow(beta, 2)/(std::pow(alpha - 1.0, 2)*(alpha - 2.0)); Sigma.clear(); set_elements(diagonal(Sigma), sigma); }
void bi::cross(const M1 X, const M2 Y, const V1 muX, const V2 muY, M3 SigmaXY) { /* pre-conditions */ BI_ASSERT(X.size2() == muX.size()); BI_ASSERT(Y.size2() == muY.size()); BI_ASSERT(X.size1() == Y.size1()); BI_ASSERT(SigmaXY.size1() == muX.size() && SigmaXY.size2() == muY.size()); const int N = X.size1(); gemm(1.0/(N - 1.0), X, Y, 0.0, SigmaXY, 'T', 'N'); ger(-N/(N - 1.0), muX, muY, SigmaXY); }
void bi::cov(const UniformPdf<V1>& q, M1 Sigma) { /* pre-condition */ BI_ASSERT(Sigma.size1() == q.size()); BI_ASSERT(Sigma.size2() == q.size()); temp_host_vector<real>::type diff(q.size()); diff = q.upper(); sub_elements(diff, q.lower(), diff); sq_elements(diff, diff); Sigma.clear(); axpy(1.0/12.0, diff, diagonal(Sigma)); }
void bi::mean(const UniformPdf<V1>& q, V2 mu) { /* pre-condition */ BI_ASSERT(q.size() == mu.size()); axpy(0.5, q.lower(), mu, true); axpy(0.5, q.upper(), mu); }
bi::Resampler::Resampler(const double essRel) : essRel(essRel), maxLogWeight(0.0) { /* pre-condition */ BI_ASSERT(essRel >= 0.0 && essRel <= 1.0); // }
void bi::condition(const ExpGaussianPdf<V1, M1>& p1, const ExpGaussianPdf<V2, M2>& p2, const M3 C, const V3 x2, ExpGaussianPdf<V4, M4>& p3) { /* pre-condition */ BI_ASSERT(x2.size() == p2.size()); BI_ASSERT(p3.size() == p1.size()); BI_ASSERT(C.size1() == p1.size() && C.size2() == p2.size()); typename sim_temp_vector<V1>::type z2(p2.size()); typename sim_temp_matrix<M1>::type K(p1.size(), p2.size()); /** * Compute gain matrix: * * \f[\mathcal{K} = C_{\mathbf{x}_1,\mathbf{x}_2}\Sigma_2^{-1}\,.\f] */ symm(1.0, p2.prec(), C, 0.0, K, 'R', 'U'); /** * Then result is given by \f$\mathcal{N}(\boldsymbol{\mu}', * \Sigma')\f$, where: * * \f[\boldsymbol{\mu}' = \boldsymbol{\mu}_1 + \mathcal{K}(\mathbf{x}_2 - * \boldsymbol{\mu}_2)\,,\f] */ z2 = x2; log_vector(z2, p2.getLogs()); axpy(-1.0, p2.mean(), z2); p3.mean() = p1.mean(); gemv(1.0, K, z2, 1.0, p3.mean()); /** * and: * * \f{eqnarray*} * \Sigma' &=& \Sigma_1 - \mathcal{K}C_{\mathbf{x}_1,\mathbf{x}_2}^T \\ * &=& \Sigma_1 - C_{\mathbf{x}_1,\mathbf{x}_2}\Sigma_2^{-1} * C_{\mathbf{x}_1,\mathbf{x}_2}^T\,.\f} */ K = C; trsm(1.0, p2.std(), K, 'R', 'U'); p3.cov() = p1.cov(); syrk(-1.0, K, 1.0, p3.cov(), 'U'); /* update log-variables and precalculations */ p3.setLogs(p1.getLogs()); p3.init(); }
void h_ode_set_safe(const real safein) { /* pre-condition */ BI_ASSERT(safein > BI_REAL(0.001) && safein < BI_REAL(1.0)); h_safe = safein; h_safe1 = BI_REAL(1.0) / safein; h_logsafe = bi::log(safein); }
inline T1 bi::inverse_gamma(R& rng, const T1 alpha, const T1 beta) { /* pre-condition */ BI_ASSERT(alpha > static_cast<T1>(0.0) && beta > static_cast<T1>(0.0)); const T1 x = rng.gamma(alpha, static_cast<T1>(1.0)/beta); return static_cast<T1>(1.0)/x; }
void h_ode_set_beta(const real betain) { /* pre-condition */ BI_ASSERT(betain >= 0.0 && betain <= BI_REAL(0.2)); h_beta = betain; h_expo1 = BI_REAL(0.2) - betain*BI_REAL(0.75); h_expo = BI_REAL(0.5)*(BI_REAL(0.2) - betain*BI_REAL(0.75)); }
inline T1 bi::beta(R& rng, const T1 alpha, const T1 beta) { /* pre-condition */ BI_ASSERT(alpha > static_cast<T1>(0.0) && beta > static_cast<T1>(0.0)); const T1 x = rng.gamma(alpha, static_cast<T1>(1.0)); const T1 y = rng.gamma(beta, static_cast<T1>(1.0)); return x / (x + y); }
inline void bi::mean(const GammaPdf& q, V1 mu) { /* pre-condition */ BI_ASSERT(mu.size() == q.size()); real alpha = q.shape(); real beta = q.scale(); set_elements(mu, alpha*beta); }
void bi::mean(const M1 X, V1 mu) { /* pre-condition */ BI_ASSERT(X.size2() == mu.size()); const int N = X.size1(); typename sim_temp_vector<V1>::type w(N); set_elements(w, 1.0); gemv(1.0/N, X, w, 0.0, mu, 'T'); }
void bi::cov(const M1 X, const V1 w, const V2 mu, M2 Sigma) { /* pre-conditions */ BI_ASSERT(X.size2() == mu.size()); BI_ASSERT(X.size1() == w.size()); BI_ASSERT(Sigma.size1() == mu.size() && Sigma.size2() == mu.size()); typedef typename V1::value_type T; typename sim_temp_matrix<M2>::type Y(X.size1(), X.size2()); typename sim_temp_matrix<M2>::type Z(X.size1(), X.size2()); typename sim_temp_vector<V2>::type v(w.size()); T Wt = sum_reduce(w); Y = X; sub_rows(Y, mu); sqrt_elements(w, v); gdmm(1.0, v, Y, 0.0, Z); syrk(1.0/Wt, Z, 0.0, Sigma, 'U', 'T'); // alternative weight: 1.0/(Wt - W2t/Wt) }
void bi::distance(const M1 X, const real h, M2 D) { /* pre-conditions */ BI_ASSERT(D.size1() == D.size2()); BI_ASSERT(D.size1() == X.size1()); BI_ASSERT(!M2::on_device); typedef typename M1::value_type T1; FastGaussianKernel K(X.size2(), h); typename temp_host_vector<T1>::type d(X.size2()); int i, j; for (j = 0; j < D.size2(); ++j) { for (i = 0; i <= j; ++i) { d = row(X, i); axpy(-1.0, row(X, j), d); D(i, j) = K(dot(d)); } } }
void bi::hist(const V1 x, const V2 w, V3 c, V4 h) { /* pre-condition */ BI_ASSERT(x.size() == w.size()); BI_ASSERT(c.size() == h.size()); BI_ASSERT(!V3::on_device); BI_ASSERT(!V4::on_device); typedef typename V1::value_type T1; typedef typename V2::value_type T2; const int P = x.size(); const int B = c.size(); T1 mx, mn; int i, j; typename temp_host_vector<T1>::type xSorted(P); typename temp_host_vector<T2>::type wSorted(P); xSorted = x; wSorted = w; bi::sort_by_key(xSorted, wSorted); mn = xSorted[0]; mx = xSorted[xSorted.size() - 1]; /* compute bin right edges */ for (j = 0; j < B; ++j) { c[j] = mn + (j + 1)*(mx - mn)/B; } /* compute bin heights */ h.clear(); for (i = 0, j = 0; i < P; ++i) { if (xSorted[i] >= c[j] && j < B - 1) { ++j; } h[j] += wSorted[i]; } /* compute bin centres */ for (j = B - 1; j > 0; --j) { c[j] = 0.5*(c[j - 1] + c[j]); } c[0] = 0.5*(mn + c[0]); }
void bi::var(const M1 X, const V1 w, const V2 mu, V3 sigma) { /* pre-conditions */ BI_ASSERT(X.size2() == mu.size()); BI_ASSERT(X.size1() == w.size()); BI_ASSERT(sigma.size() == mu.size()); typedef typename V1::value_type T1; typename sim_temp_matrix<M1>::type Z(X.size1(), X.size2()); typename sim_temp_matrix<M1>::type Y(X.size1(), X.size2()); typename sim_temp_vector<V2>::type v(w.size()); T1 Wt = sum_reduce(w); Z = X; sub_rows(Z, mu); sqrt_elements(w, v); gdmm(1.0, v, Z, 0.0, Y); dot_columns(Y, sigma); divscal_elements(sigma, Wt, sigma); // alternative weight: 1.0/(Wt - W2t/Wt) }
void bi::Cache::resize(const int size) { /* pre-condition */ BI_ASSERT(size >= 0); int oldSize = this->size(); valids.resize(size, true); // true is to preserve contents here dirties.resize(size, true); if (size > oldSize) { set_elements(subrange(valids, oldSize, size - oldSize), false); set_elements(subrange(dirties, oldSize, size - oldSize), false); } }
void bi::InputNetCDFBuffer::readTime(int ncVar, const long start, size_t* const len, real* const t) { /* pre-condition */ BI_ASSERT(start >= 0); BI_ASSERT(len != NULL); BI_ASSERT(t != NULL); std::vector<size_t> offsets(2), counts(2); std::vector<int> dimids = nc_inq_vardimid(ncid, ncVar); real tnxt; int j = 0; size_t T; if (nsDim >= 0 && dimids[j] == nsDim) { /* optional ns dimension */ offsets[j] = ns; counts[j] = 1; ++j; } BI_ASSERT(j < static_cast<int>(dimids.size())); T = nc_inq_dimlen(ncid, dimids[j]); offsets[j] = start; counts[j] = 1; //++j; // not here, need to hold ref to last offset /* may be multiple records with same time, keep reading until time changes */ *len = 0; *t = 0.0; tnxt = 0.0; while (*t == tnxt && offsets[j] < T) { nc_get_vara(ncid, ncVar, offsets, counts, &tnxt); if (*len == 0) { *t = tnxt; } if (tnxt == *t) { ++offsets[j]; ++(*len); } } }
T1 bi::truncated_gaussian(R& rng, const T1 lower, const T1 upper, const T1 mu, const T1 sigma) { /* pre-conditions */ BI_ASSERT(upper >= lower); T1 u; if (upper == lower) { u = upper; } else do { u = rng.gaussian(mu, sigma); } while (u < lower || u > upper); return u; }
void bi::inverse_gamma_log_densities(const M1 Z, const T1 alpha, const T1 beta, V1 p, const bool clear) { /* pre-condition */ BI_ASSERT(Z.size1() == p.size()); op_elements(vec(Z), vec(Z), inverse_gamma_log_density_functor<T1>(alpha, beta)); if (clear) { sum_columns(Z, p); } else { typename sim_temp_vector<V1>::type p1(p.size()); sum_columns(Z, p1); add_elements(p, p1, p); } }
void bi::standardise(const ExpGaussianPdf<V1,M1>& p, M2 X) { /* pre-condition */ BI_ASSERT(p.size() == X.size2()); typename sim_temp_vector<M2>::type mu(X.size2()); log_columns(X, p.getLogs()); mean(X, mu); sub_rows(X, mu); trsm(1.0, p.std(), X, 'R', 'U'); add_rows(X, mu); sub_rows(X, p.mean()); exp_columns(X, p.getLogs()); }
void bi::gaussian_log_densities(const M1 Z, const T1 logZ, V1 p, const bool clear) { /* pre-condition */ BI_ASSERT(Z.size1() == p.size()); typedef typename V1::value_type T2; if (clear) { dot_rows(Z, p); op_elements(p, p, gaussian_log_density_functor<T2>(logZ)); } else { typename sim_temp_vector<V1>::type p1(p.size()); dot_rows(Z, p1); op_elements(p1, p, p, gaussian_log_density_update_functor<T2>(logZ)); } }
void bi::MultinomialResamplerHost::ancestors(Random& rng, const V1 lws, V2 as, MultinomialPrecompute<ON_HOST>& pre) throw (ParticleFilterDegeneratedException) { typedef typename V1::value_type T1; const int P = as.size(); const int lwsSize = lws.size(); T1 lW; /* weights */ if (pre.W > 0) { lW = bi::log(pre.W); #pragma omp parallel { int Q = P/bi_omp_max_threads; int start = bi_omp_tid*Q + bi::min(bi_omp_tid, P % bi_omp_max_threads); // min() handles leftovers if (bi_omp_tid < P % bi_omp_max_threads) { ++Q; // pick up a leftover } int i, j = lwsSize; T1 lMax = 0.0, lu; for (i = Q; i > 0; --i) { lMax += bi::log(rng.uniform<T1>())/i; lu = lW + lMax; while (j > 0 && lu < bi::log(pre.Ws(j - 1))) { --j; } if (pre.sort) { as(start + i - 1) = pre.ps(j); } else { as(start + i - 1) = j; } } } } else { throw ParticleFilterDegeneratedException(); } /* post-condition */ BI_ASSERT(max_reduce(as) < lws.size()); }