double WP::loglike(const Vector &lam0_delta_weekday_weekend)const{ const Mat &exposure(suf()->exposure()); const Mat & count(suf()->count()); double lambda0 = lam0_delta_weekday_weekend[0]; Vector delta(7, 0.0); int pos = 1; VectorView(delta, 0, 6) = ConstVectorView(lam0_delta_weekday_weekend, pos, 6); delta[6] = 7.0 - sum(delta); pos += 6; Vector eta_weekday(24, 0.0); VectorView(eta_weekday, 0, 23) = ConstVectorView(lam0_delta_weekday_weekend, pos, 23); eta_weekday[23] = 24.0 - sum(eta_weekday); pos += 23; Vector eta_weekend(24, 0.0); VectorView(eta_weekend, 0, 23) = ConstVectorView(lam0_delta_weekday_weekend, pos, 23); eta_weekend[23] = 24.0 - sum(eta_weekend); double ans = 0; for(int d = 0; d < 7; ++d){ const Vec &eta( (d==Sat || d==Sun) ? eta_weekend : eta_weekday); for(int h = 0; h < 24; ++h){ double lam = lambda0 * delta[d] * eta[h] * exposure(d, h); ans += dpois(count(d, h), lam, true); } } return ans; }
Mat & AccumulatorStateVarianceMatrix::add_to(Mat &m)const { int state_dim(state_variance_matrix_->nrow()); if(m.nrow()!= state_dim+2) { report_error("wrong sizes in AccumulatorStateVarianceMatrix::add_to"); } SubMatrix RQR(m, 0, state_dim, 0, state_dim); state_variance_matrix_->add_to_submatrix(RQR); Vec ZRQR = (*state_variance_matrix_) * observation_vector_.dense(); VectorView(m.col(state_dim), 0, state_dim) += ZRQR; VectorView(m.row(state_dim), 0, state_dim) += ZRQR; m(state_dim, state_dim) += observation_vector_.dot(ZRQR) + observation_variance_; return m; }
// Args: // probs: A vector of probabilities to be evaluated. If no // derivatives are desired then probs can either match the // dimension of nu(), in which case it must sum to 1, or its // dimension must be one less, in which case its sum must be // non-negative but can't exceed 1. Element 0 is assumed to be // the function of the other elements, so that probs0 = 1 - // sum(probs). If derivatives are desired then probs.size() // must be nu().size() - 1. // gradient: The derivative of the unconstrained elements of // probs. This is only accessed if nderivs > 0. It will be // resized if needed, so that its dimension is one less than the // dimension of nu(). // Hessian: Second derivative of logp with respect to the free // elements of probs (i.e. not the first one). This matrix is // only accessed if nderiv > 1, in which case it will be resized. // nderiv: The number of derivatives desired. double DirichletModel::Logp(const Vector &probs, Vector &gradient, Matrix &Hessian, uint nderiv) const { // Because sum(p)=1, there are only p.size()-1 free elements in p. // The constraint is enforced by expressing the first element of p // as a function of the other variables. The corresponding elements // in g and h are zeroed. if (probs.size() == nu().size() && nderiv == 0) { return ddirichlet(probs, nu(), true); } else if (probs.size() + 1 != nu().size()) { report_error( "probs is the wrong size in DirichletModel::Logp. " "Its dimension should be one less than nu().size()"); } const Vector &n(nu()); double p0 = 1 - sum(probs); Vector full_probs(probs.size() + 1); full_probs[0] = p0; VectorView(full_probs, 1) = probs; double ans = ddirichlet(full_probs, n, true); if (nderiv > 0) { gradient.resize(probs.size()); for (int i = 0; i < probs.size(); ++i) { gradient[i] = (n[i + 1] - 1) / probs[i] - (n[0] - 1) / p0; if (nderiv > 1) { Hessian.resize(probs.size(), probs.size()); for (int j = 0; j < probs.size(); ++j) { Hessian(i, j) = -(n[0] - 1) / square(p0) - (i == j ? (1.0 - n[i + 1]) / square(probs[i]) : 0.0); } } } } return ans; }
VectorView MatrixPartition::view(VectorView v, int i, bool premultiply)const{ const std::vector<int> &pos(premultiply ? col_start_ : row_start_); int max = premultiply ? col_max_ : row_max_; int start = pos[i]; int stop = (i < max) ? pos[i+1] - 1 : length(v) - 1; return VectorView(v, start, stop - start + 1); }
// P is decomposed where dim(a) = 'state_dim' and dim(y) = dim(Y) = 1. // | Pa Pay PaY | // | Pya Py PyY | // | PYa PYy PY | void AccumulatorTransitionMatrix::sandwich_inplace(Spd &P)const { int state_dim = transition_matrix_->ncol(); if(P.ncol() != state_dim+2) report_multiplication_error( transition_matrix_, observation_vector_, contains_end_, fraction_in_initial_period_, P.col(0)); SubMatrix TPT(P, 0, state_dim-1, 0, state_dim-1); transition_matrix_->sandwich_inplace_submatrix(TPT); double a = 1 - fraction_in_initial_period_ * contains_end_; int b = !contains_end_; Vec zTPT = TPT * observation_vector_; double zTPTz = observation_vector_.dot(zTPT); Vec TPay = (*transition_matrix_) * VectorView(P.col(state_dim), 0, state_dim); Vec TPaY = (*transition_matrix_) * VectorView(P.col(state_dim+1), 0, state_dim); double zTPay = observation_vector_.dot(TPay); double zTPaY = observation_vector_.dot(TPaY); double Py = P(state_dim, state_dim); double PY = P(state_dim+1, state_dim+1); double PyY = P(state_dim, state_dim+1); VectorView(P.col(state_dim), 0, state_dim) = zTPT; VectorView(P.row(state_dim), 0, state_dim) = zTPT; P(state_dim, state_dim) = zTPTz; VectorView tmp(P.col(state_dim+1), 0, state_dim); tmp = a*TPay + b*TPaY; VectorView(P.row(state_dim+1), 0, state_dim) = tmp; P(state_dim+1, state_dim) = a*zTPay + b*zTPaY; P(state_dim, state_dim+1) = P(state_dim+1, state_dim); P(state_dim+1, state_dim+1) = a*a*Py + b*b*PY + 2*a*b*PyY; }
//---------------------------------------------------------------------- Mat & AccumulatorTransitionMatrix::add_to(Mat &P)const { int state_dim = transition_matrix_->nrow(); if(P.nrow() != state_dim+2 || P.ncol() != state_dim+2) { report_error("wrong sizes in AccumulatorTransitionMatrix::add_to"); } SubMatrix Pa(P, 0, state_dim-1, 0, state_dim-1); transition_matrix_->add_to_submatrix(Pa); Vec tmp = transition_matrix_->Tmult(observation_vector_.dense()); VectorView(P.row(state_dim), 0, state_dim) += tmp; double a = 1 - fraction_in_initial_period_ * contains_end_; int b = !contains_end_; P(state_dim+1, state_dim) += a; P(state_dim+1, state_dim+1) += b; return P; }
Vec RQR_Multiply(const VECTOR &v, const SparseKalmanMatrix &RQR, const SparseVector &Z, double H) { int state_dim = Z.size(); if(v.size() != state_dim + 2) { report_error("wrong sizes in RQR_Multiply"); } // Partition v = [eta, epsilon, 0] ConstVectorView eta(v, 0, state_dim); double epsilon = v[state_dim]; // Partition this Vec RQRZ = RQR * Z.dense(); double ZRQRZ_plus_H = Z.dot(RQRZ) + H; Vec ans(v.size()); VectorView(ans, 0, state_dim) = (RQR * eta).axpy(RQRZ, epsilon); ans[state_dim] = RQRZ.dot(eta) + ZRQRZ_plus_H * epsilon; return ans; }
Vec ASSR::simulate_initial_state()const { Vec ans(state_dimension()); simulate_initial_state(VectorView(ans)); return ans; }
const VectorView block(const size_t begin, const size_t length) const { assert(begin + length <= length_); return VectorView(data_ + begin, length_mem_ - begin, length); }
VectorView DM::diag() { return VectorView(diagonal_elements_); }
VectorView subvector(VEC &v, uint start, uint stop){ assert(start <=stop && start < v.size()); uint size = 1+stop-start; return VectorView(v.data()+start, size, v.stride()); }
VectorView subvector(VEC &v, uint start){ assert(start <v.size()); return VectorView(v.data()+start, v.size()-start, v.stride()); }