void ImplicitNewmarkDenseMulti1D::SetInternalForceScalingFactor(double internalForceScalingFactor_) { internalForceScalingFactor = internalForceScalingFactor_; for(int dim=0; dim<r; dim++) tangentStiffnessMatrix[dim] = internalForceScalingFactor * tangentStiffnessMatrixOriginal[dim]; UpdateCoefs(); }
ImplicitNewmarkDenseMulti1D::ImplicitNewmarkDenseMulti1D(int r_, double timestep_, double * massMatrix_, double * tangentStiffnessMatrix_, double dampingMassCoef_, double dampingStiffnessCoef_, double NewmarkBeta_, double NewmarkGamma_): IntegratorBaseDense(r_, timestep_, dampingMassCoef_, dampingStiffnessCoef_), IntegratorMulti1D(r_, timestep_, massMatrix_, tangentStiffnessMatrix_, dampingMassCoef_, dampingStiffnessCoef_), ImplicitNewmarkDense(r_, timestep_, dampingMassCoef_, dampingStiffnessCoef_, 0.25, 0.5) { coef_deltaZ = (double *) malloc (sizeof(double) * r); coef_zvel = (double *) malloc (sizeof(double) * r); coef_zaccel = (double *) malloc (sizeof(double) * r); UpdateCoefs(); }
// Return the predicted value and its variance at time assuming a CAR(1) process std::pair<double, double> KalmanFilter1::Predict(double time) { double rho, var_ratio, previous_var; double ypredict_mean, ypredict_var, yprecision; unsigned int ipredict = 0; while (time > time_(ipredict)) { // find the index where time_ > time for the first time ipredict++; if (ipredict == time_.n_elem) { // time is greater than last element of time_, so do forecasting break; } } // Run the Kalman filter up to the point time_[ipredict-1] Reset(); for (int i=1; i<ipredict; i++) { Update(); } if (ipredict == 0) { // backcasting, so initialize the conditional mean and variance to the stationary values ypredict_mean = 0.0; ypredict_var = sigsqr_ / (2.0 * omega_); } else { // predict the value of the time series at time, given the earlier values double dt = time - time_[ipredict-1]; rho = exp(-dt * omega_); previous_var = var(ipredict-1) - yerr_(ipredict-1) * yerr_(ipredict-1); var_ratio = previous_var / var(ipredict-1); // initialize the conditional mean and variance ypredict_mean = rho * mean(ipredict-1) + rho * var_ratio * (y_(ipredict-1) - mean(ipredict-1)); ypredict_var = sigsqr_ / (2.0 * omega_) * (1.0 - rho * rho) + rho * rho * previous_var * (1.0 - var_ratio); } if (ipredict == time_.n_elem) { // Forecasting, so we're done: no need to run interpolation steps std::pair<double, double> ypredict(ypredict_mean, ypredict_var); return ypredict; } yprecision = 1.0 / ypredict_var; ypredict_mean *= yprecision; // Either backcasting or interpolating, so need to calculate coefficients of linear filter as a function of // the predicted time series value, then update the running conditional mean and variance of the predicted // time series value InitializeCoefs(time, ipredict, 0.0, 0.0); yprecision += yslope_ * yslope_ / var(ipredict); ypredict_mean += yslope_ * (y_(ipredict) - yconst_) / var(ipredict); for (int i=ipredict+1; i<time_.n_elem; i++) { UpdateCoefs(); yprecision += yslope_ * yslope_ / var(i); ypredict_mean += yslope_ * (y_(i) - yconst_) / var(i); } ypredict_var = 1.0 / yprecision; ypredict_mean *= ypredict_var; std::pair<double, double> ypredict(ypredict_mean, ypredict_var); return ypredict; }
// Predict the time series at the input time given the measured time series, assuming a CARMA(p,q) process std::pair<double, double> KalmanFilterp::Predict(double time) { unsigned int ipredict = 0; while (time > time_(ipredict)) { // find the index where time_ > time for the first time ipredict++; if (ipredict == time_.n_elem) { // time is greater than last element of time_, so do forecasting break; } } // Run the Kalman filter up to the point time_[ipredict-1] Reset(); for (int i=1; i<ipredict; i++) { Update(); } double ypredict_mean, ypredict_var, yprecision; if (ipredict == 0) { // backcasting, so initialize the conditional mean and variance to the stationary values ypredict_mean = 0.0; ypredict_var = std::real( arma::as_scalar(rotated_ma_coefs_ * StateVar_ * rotated_ma_coefs_.t()) ); } else { // predict the value of the time series at time, given the earlier values kalman_gain_ = PredictionVar_ * rotated_ma_coefs_.t() / var(ipredict-1); state_vector_ += kalman_gain_ * innovation_; PredictionVar_ -= var(ipredict-1) * (kalman_gain_ * kalman_gain_.t()); double dt = std::abs(time - time_(ipredict-1)); rho_ = arma::exp(omega_ * dt); state_vector_ = rho_ % state_vector_; PredictionVar_ = (rho_ * rho_.t()) % (PredictionVar_ - StateVar_) + StateVar_; // initialize the conditional mean and variance ypredict_mean = std::real( arma::as_scalar(rotated_ma_coefs_ * state_vector_) ); ypredict_var = std::real( arma::as_scalar(rotated_ma_coefs_ * PredictionVar_ * rotated_ma_coefs_.t()) ); } if (ipredict == time_.n_elem) { // Forecasting, so we're done: no need to run interpolation steps std::pair<double, double> ypredict(ypredict_mean, ypredict_var); return ypredict; } yprecision = 1.0 / ypredict_var; ypredict_mean *= yprecision; // Either backcasting or interpolating, so need to calculate coefficients of linear filter as a function of // the predicted time series value, then update the running conditional mean and variance of the predicted // time series value InitializeCoefs(time, ipredict, ypredict_mean / yprecision, ypredict_var); yprecision += yslope_ * yslope_ / var(ipredict); ypredict_mean += yslope_ * (y_(ipredict) - yconst_) / var(ipredict); for (int i=ipredict+1; i<time_.n_elem; i++) { UpdateCoefs(); yprecision += yslope_ * yslope_ / var(i); ypredict_mean += yslope_ * (y_(i) - yconst_) / var(i); } ypredict_var = 1.0 / yprecision; ypredict_mean *= ypredict_var; std::pair<double, double> ypredict(ypredict_mean, ypredict_var); return ypredict; }
void ImplicitNewmarkDenseMulti1D::SetTimestep(double timestep_) { ImplicitNewmarkDense::SetTimestep(timestep_); UpdateCoefs(); }
void ImplicitNewmarkDenseMulti1D::SetDampingStiffnessCoef(double dampingStiffnessCoef_) { dampingStiffnessCoef = dampingStiffnessCoef_; UpdateCoefs(); }
void ImplicitNewmarkDenseMulti1D::SetNewmarkGamma(double NewmarkGamma_) { NewmarkGamma = NewmarkGamma_; UpdateAlphas(); UpdateCoefs(); }