//--------------------------------------------------------------------------- SpdMatrix Marginal::forecast_precision() const { const Selector &observed(model_->observed_status(time_index())); DiagonalMatrix observation_precision = model_->observation_variance(time_index()).inv(); const SparseKalmanMatrix *observation_coefficients( model_->observation_coefficients(time_index(), observed)); SpdMatrix variance; if (previous()) { variance = previous()->state_variance(); } else { variance = model_->initial_state_variance(); } // 'inner' is I + P * Z' Hinv Z Matrix inner = variance * observation_coefficients->inner( observation_precision.diag()); inner.diag() += 1.0; SpdMatrix outer = inner.solve(variance); SpdMatrix ans = observation_precision.sandwich( observation_coefficients->sandwich(outer)); ans *= -1; ans.diag() += observation_precision.diag(); return ans; }
//--------------------------------------------------------------------------- SpdMatrix Marginal::direct_forecast_precision() const { SpdMatrix variance; if (previous()) { variance = previous()->state_variance(); } else { variance = model_->initial_state_variance(); } const Selector &observed(model_->observed_status(time_index())); SpdMatrix ans = model_->observation_coefficients( time_index(), observed)->sandwich(variance); ans.diag() += model_->observation_variance(time_index()).diag(); return ans.inv(); }
// When dimensions are small the updates are trivial, and careful // optimization is not necessary. void Marginal::low_dimensional_update( const Vector &observation, const Selector &observed, const SparseKalmanMatrix &transition, const SparseKalmanMatrix &observation_coefficient_subset) { set_prediction_error( observed.select(observation) - observation_coefficient_subset * state_mean()); SpdMatrix forecast_variance = observed.select_square(model_->observation_variance(time_index())) + observation_coefficient_subset.sandwich(state_variance()); SpdMatrix forecast_precision = forecast_variance.inv(); set_forecast_precision_log_determinant(forecast_precision.logdet()); set_scaled_prediction_error(forecast_precision * prediction_error()); set_kalman_gain(transition * state_variance() * observation_coefficient_subset.Tmult(forecast_precision)); }
// Effects: // 4 things are set. // 1) prediction_error // 2) scaled_prediction_error // 3) forecast_precision_log_determinant // 4) kalman_gain void Marginal::high_dimensional_update( const Vector &observation, const Selector &observed, const SparseKalmanMatrix &transition, const SparseKalmanMatrix &observation_coefficient_subset) { Vector observed_subset = observed.select(observation); set_prediction_error(observed_subset - observation_coefficient_subset * state_mean()); // At this point the Kalman recursions compute the forecast precision Finv // and its log determinant. However, we can get rid of the forecast // precision matrix, and replace it with the scaled error = Finv * // prediction_error. // // To evaluate the normal likelihood, we need the quadratic form: // error * Finv * error == error.dot(scaled_error). // We also need the log determinant of Finv. // // The forecast_precision can be computed using a version of the binomial // inverse theorem: // // (A + UBV).inv = // A.inv - A.inv * U * (I + B * V * Ainv * U).inv * B * V * Ainv. // // When applied to F = H + Z P Z' the theorem gives // // Finv = Hinv - Hinv * Z * (I + P Z' Hinv Z).inv * P * Z' * Hinv // // This helps because H is diagonal. The only matrix that needs to be // inverted is (I + PZ'HinvZ), which is a state x state matrix. // // We don't compute Finv directly, we compute Finv * prediction_error. // observation_precision refers to the precision of the observed subset. DiagonalMatrix observation_precision(observed.select( 1.0 / model_->observation_variance(time_index()).diag())); // Set inner_matrix to I + P * Z' * Hinv * Z SpdMatrix ZTZ = observation_coefficient_subset.inner( observation_precision.diag()); // Note: the product of two SPD matrices need not be symmetric. Matrix inner_matrix = state_variance() * ZTZ; inner_matrix.diag() += 1.0; LU inner_lu(inner_matrix); // inner_inv_P is inner.inv() * state_variance. This matrix need not be // symmetric. Matrix inner_inv_P = inner_lu.solve(state_variance()); Matrix HinvZ = observation_precision * observation_coefficient_subset.dense(); set_scaled_prediction_error( observation_precision * prediction_error() - HinvZ * inner_inv_P * HinvZ.Tmult(prediction_error())); // The log determinant of F.inverse is the negative log of det(H + ZPZ'). // That determinant can be computed using the "matrix determinant lemma," // which says det(A + UV') = det(I + V' * A.inv * U) * det(A) // // https://en.wikipedia.org/wiki/Matrix_determinant_lemma#Generalization // // With F = H + ZPZ', and setting A = H, U = Z, V' = PZ'. // Then det(F) = det(I + PZ' * Hinv * Z) * det(H) set_forecast_precision_log_determinant( observation_precision.logdet() - inner_lu.logdet()); // The Kalman gain is: K = T * P * Z' * Finv. // Substituting the expression for Finv from above gives // // K = T * P * Z' * // (Hinv - Hinv * Z * (I + P Z' Hinv Z).inv * P * Z' * Hinv) Matrix ZtHinv = HinvZ.transpose(); set_kalman_gain(transition * state_variance() * (ZtHinv - ZTZ * inner_inv_P * ZtHinv)); }
bool SqliteObject::deleteDay(const boost::gregorian::date &d) { //std::cout << boost::gregorian::to_simple_string(d) << std::endl; boost::gregorian::greg_day gd = d.day(); std::stringstream ssd; ssd << gd.as_number(); std::string d_day = ssd.str(); boost::gregorian::greg_month gm = d.month(); std::stringstream ssm; ssm << gm.as_number(); std::string d_month = ssm.str(); //std::cout << " " << d_month << " " << d_day << std::endl; // What are the timeindex values to delete std::stringstream cmd1; cmd1 << "select TimeIndex from Time where month=" << d_month << " and day=" << d_day; execute(cmd1.str()); std::vector<int> time_index(0); for(size_t r=0; r<m_results->data.size(); ++r){ time_index.push_back(atoi(m_results->data[r][0].c_str())); } // What are the ReportExtendedData records associated with the timeindex values from ReportData to delete std::stringstream cmd3; std::vector<int> RVEDV_index(0); for(size_t s=0; s<time_index.size(); ++s){ cmd3 << "select ReportExtendedDataIndex from reportExtendedData inner join reportData on reportExtendedData.ReportDataIndex=reportData.ReportDataIndex where reportData.timeindex =" << time_index[s]; execute(cmd3.str()); cmd3.str(std::string()); //clear out the string for(size_t r=0; r<m_results->data.size(); ++r){ RVEDV_index.push_back(atoi(m_results->data[r][0].c_str())); } } execute("begin"); std::stringstream cmd2; // reportData for(size_t r=0; r<time_index.size(); ++r){ cmd2.str(std::string()); //clear out the string cmd2 << "delete from reportData where TimeIndex = " << time_index[r]; execute(cmd2.str()); //std::cout << cmd2.str() << std::endl; //print(); } // reportExtendedData for(size_t r=0; r<RVEDV_index.size(); ++r){ //std::stringstream cmd2; cmd2.str(std::string()); //clear out the string cmd2 << "delete from reportExtendedData where ReportExtendedDataIndex = " << RVEDV_index[r]; execute(cmd2.str()); //std::cout << cmd2.str() << std::endl; //print(); } // Time for(size_t r=0; r<time_index.size(); ++r){ //std::stringstream cmd2; cmd2.str(std::string()); //clear out the string cmd2 << "delete from Time where TimeIndex = " << time_index[r]; execute(cmd2.str()); //std::cout << cmd2.str() << std::endl; //print(); } execute("commit"); return true; }
bool SqliteObject::removeDesignDay() { // What are the timeindex values to delete std::stringstream cmd1; cmd1 << "select TimeIndex from Time where time.daytype = 'WinterDesignDay' "; cmd1 << "or time.daytype = 'SummerDesignDay' or time.daytype = 'customday1' or time.daytype = 'customday2'"; execute(cmd1.str()); std::vector<int> time_index(0); for(size_t r=0; r<m_results->data.size(); ++r){ time_index.push_back(atoi(m_results->data[r][0].c_str())); } // What are the ReportExtendedDataIndexes associated with the timeindex values from ReportData to delete std::stringstream cmd3; std::vector<int> RVEDV_index(0); for(size_t s=0; s<time_index.size(); ++s){ cmd3 << "select ReportExtendedDataIndex from reportdata where timeindex =" << time_index[s] << " and ReportExtendedDataIndex != 'NULL'"; execute(cmd3.str()); for(size_t r=0; r<m_results->data.size(); ++r){ RVEDV_index.push_back(atoi(m_results->data[r][0].c_str())); } cmd3.str(std::string()); //clear out the string } execute("begin"); std::stringstream cmd2; // reportVariableData for(size_t r=0; r<time_index.size(); ++r){ //std::stringstream cmd2; cmd2.str(std::string()); //clear out the string cmd2 << "delete from reportData where TimeIndex = " << time_index[r]; execute(cmd2.str()); //std::cout << cmd2.str() << std::endl; //print(); } // reportVariableExtendedData for(size_t r=0; r<RVEDV_index.size(); ++r){ //std::stringstream cmd2; cmd2.str(std::string()); //clear out the string cmd2 << "delete from reportExtendedData where ReportExtendedDataIndex = " << RVEDV_index[r]; execute(cmd2.str()); //std::cout << cmd2.str() << std::endl; //print(); } // Time for(size_t r=0; r<time_index.size(); ++r){ std::stringstream cmd2; cmd2.str(std::string()); //clear out the string cmd2 << "delete from Time where TimeIndex = " << time_index[r]; execute(cmd2.str()); //std::cout << cmd2.str() << std::endl; //print(); } execute("commit"); return true; }
void ParamEdit::FormulaCompiledForExpression(DatabaseQuery *q) { DatabaseQuery::CompileFormula& cf = q->compile_formula; bool ok = cf.ok; if (ok == false) { m_error = true; m_error_string = wxString::Format(_("Invalid expression %s"), cf.error); } free(cf.formula); free(cf.error); delete q; if (!ok) { return; } DefinedParam* param = new DefinedParam(m_draws_ctrl->GetCurrentDrawInfo()->GetBasePrefix(), L"TEMPORARY:SEARCH:EXPRESSION", L"", GetFormula(), 0, TParam::LUA_AV, -1); param->CreateParam(); std::vector<DefinedParam*> dpv = std::vector<DefinedParam*>(1, param); m_cfg_mgr->SubstituteOrAddDefinedParams(dpv); DefinedDrawInfo* ddi = new DefinedDrawInfo(L"", L"", wxColour(), 0, 1, TDraw::NONE, L"", param, m_cfg_mgr->GetDefinedDrawsSets()); q = new DatabaseQuery(); q->type = DatabaseQuery::SEARCH_DATA; q->draw_info = ddi; q->param = param->GetIPKParam(); q->draw_no = -1; q->search_data.end = -1; q->search_data.period_type = m_draws_ctrl->GetPeriod(); q->search_data.search_condition = new non_zero_search_condition; wxDateTime t = m_current_search_date.IsValid() ? m_current_search_date.GetTicks() : m_draws_ctrl->GetCurrentTime(); DTime dt(m_draws_ctrl->GetPeriod(), t); dt.AdjustToPeriod(); TimeIndex time_index(m_draws_ctrl->GetPeriod()); switch (m_search_direction) { case SEARCHING_LEFT: q->search_data.start = (dt - time_index.GetTimeRes() - time_index.GetDateRes()).GetTime().GetTicks(); q->search_data.direction = -1; break; case SEARCHING_RIGHT: q->search_data.start = (dt + time_index.GetTimeRes() + time_index.GetDateRes()).GetTime().GetTicks(); q->search_data.direction = 1; break; case NOT_SEARCHING: assert(false); break; } QueryDatabase(q); }