double predcorr( double t, double I ) // Predictor Correcotr Method { double I_p, I_i1; // I_p: estimated value of current // I_i1: new value of current at next time step I_p = I + h * dydx( t, I ); // Predictor Formula I_i1 = I + 0.5 * h * ( dydx( t, I ) + dydx( t + h, I_p ) ); // Corrector Formula I_i1 = I_i1+1; return I_i1; }
double WaveformUtilities::Eccentricity_rDot(const std::vector<double>& t, const std::vector<double>& rDot, const double r0, const double Omega0, double& DeltarDot, double& DeltaPhiDot) { //// Do the fit to the model: //// rDot(t) = vbar0 + arbar0*t + Br*cos(omegar*t+phir) //// First fit to rDotDot to find phase, frequency, and amplitude std::vector<double> rDotDot = dydx(rDot, t); std::vector<double> aDotDotGuesses(3); aDotDotGuesses[0] = 0.5*(max(rDotDot)-min(rDotDot)); aDotDotGuesses[1] = Omega0; aDotDotGuesses[2] = 0.0; std::vector<double> rDotDotMinusAvg = rDotDot-avg(rDotDot); std::vector<double> TrivialSigmas(t.size(), 1.0); Eccentricity_rDotDotFit e_dd; FitNonlinear<Eccentricity_rDotDotFit> rDotDotFit(t, rDotDotMinusAvg, TrivialSigmas, aDotDotGuesses, e_dd, 1.e-8); rDotDotFit.hold(0, aDotDotGuesses[0]); rDotDotFit.hold(1, aDotDotGuesses[1]); rDotDotFit.fit(); rDotDotFit.free(1); rDotDotFit.fit(); rDotDotFit.free(0); rDotDotFit.fit(); //// Next fit to rDot to find all parameters std::vector<double> aDotGuesses(5); aDotGuesses[0] = avg(rDot); aDotGuesses[1] = avg(rDotDot); aDotGuesses[2] = rDotDotFit.a[0] / rDotDotFit.a[1]; aDotGuesses[3] = rDotDotFit.a[1]; aDotGuesses[4] = rDotDotFit.a[2]; Eccentricity_rDotFit e_d; FitNonlinear<Eccentricity_rDotFit> rDotFit(t, rDot, TrivialSigmas, aDotGuesses, e_d, 1.e-8); rDotFit.fit(); //// Adjust the parameters //double& vbar0 = rDotFit.a[0]; //double& arbar0 = rDotFit.a[1]; double& Br = rDotFit.a[2]; double& omegar = rDotFit.a[3]; double& phir = rDotFit.a[4]; DeltarDot = -Br * cos(phir); // Eq. (71) of arXiv:1012.1549 DeltaPhiDot = Br * omegar * sin(phir) / (2* r0 * Omega0); // Eq. (73) of arXiv:1012.1549 //// Return the measured eccentricity return -Br / (r0 * omegar); }
///////////////////////////////////////////////// // Epidemiological modeling and model fitting void TEpidemModel::RunModel(const TFltV& StartValV, const double& StartT, const double& StopT, const int& NSteps, TVec<TFltV>& OutValV) { TFltV ValV(StartValV), dydx(StartValV.Len()), ValV2(StartValV.Len()); OutValV.Clr(false); for (int v = 0; v < StartValV.Len(); v++) { OutValV.Add(); OutValV[v].Clr(false); OutValV[v].Add(StartValV[v]); } const double h = (StopT-StartT) / NSteps; double x = StartT; for (int k = 0; k < NSteps; k++) { GetDerivs(x, ValV, dydx); RungeKutta(ValV, dydx, x, h, ValV2); for (int v = 0; v < ValV2.Len(); v++) { double X = ValV2[v]; if (X < 0 || _isnan(X) || !_finite(X)) { X = 0; } OutValV[v].Add(X); } ValV = ValV2; x += h; } }
void TEpidemModel::RunEuler(const TFltV& StartValV, const double& StartT, const double& StopT, const int& NSteps, TVec<TFltV>& OutValV) { const double h = (StopT-StartT) / NSteps; TFltV ValV(StartValV), dydx(StartValV.Len()), ValV2(StartValV.Len()); for (int v = 0; v < StartValV.Len(); v++) { OutValV.Add(); OutValV[v].Clr(false); OutValV[v].Add(StartValV[v]); } OutValV.Add(); // x values OutValV.Last().Add(StartT); for (double x = StartT; x <= StopT; x += h) { GetDerivs(x, ValV, dydx); for (int v = 0; v < ValV.Len(); v++) { ValV[v] += h*dydx[v]; OutValV[v].Add(ValV[v]); } OutValV.Last().Add(x+h); } for (int v = 1; v < OutValV.Len(); v++) { IAssert(OutValV[v].Len()==OutValV[v-1].Len()); } }
// run the model internally with 10 times greater resolution void TEpidemModel::RunModel10(const TFltV& StartValV, const double& StartT, const double& StopT, const int& NSteps, TVec<TFltV>& OutValV) { TFltV ValV(StartValV), dydx(StartValV.Len()), ValV2(StartValV.Len()); OutValV.Clr(false); for (int v = 0; v < StartValV.Len(); v++) { OutValV.Add(); OutValV[v].Clr(false); OutValV[v].Add(StartValV[v]); } const double h = (StopT-StartT) / (10*NSteps); double x = StartT; for (int k = 0; k < 10*NSteps; k++) { GetDerivs(x, ValV, dydx); RungeKutta(ValV, dydx, x, h, ValV2); // take values at only every 10th step if (k % 10 == 0) { for (int v = 0; v < ValV2.Len(); v++) { OutValV[v].Add(ValV2[v]); } } ValV = ValV2; x += h; } }