void testEigenMap() { Vector_t theta; theta.setZero(4 * 5); for (int i = 0; i < theta.size(); ++i) theta(i) = i; std::cout << theta << std::endl; Eigen::Map<Matrix_t> Theta(theta.data(), 4, 5); // reshape std::cout << Theta << std::endl; Vector_t theta2(Eigen::Map<Vector_t>(Theta.data(), 5 * 4)); std::cout << theta2 << std::endl; }
void forwardMap(double q[2], double qdot[2], double t, double x[2], double v[2]) { // maps from (q, qdot) -> (x(t), v(t)) (forward in time) // to go backward, let t -> -t // first step: find auxiliary variables // eta0 is between 0 and pi but extends to between 0 and 2pi based on the sign of the initial r-velocity double eta0 = etaZero(q,qdot); if (qdot[0]<0.0) { eta0 = 2.0 * M_PI - eta0; } // etabase is between 0 and pi double etabase = eta(q,qdot,t, eta0); double omega3 = Omega3(q,qdot); double omega2 = Omega2(q,qdot); double J2 = Lmag(q,qdot); double ham = H(q,qdot); double e = eccentricity(q, qdot); double c = c_aux(q, qdot); // compute number of pis to add for correct branch (theta2 and theta3 must increase continuously) double Tr = 2.0 * M_PI / omega3; double tperi = (theta3(0.0, q, qdot) - theta3(eta0,q, qdot))/omega3; double tapo = (theta3(M_PI, q, qdot) - theta3(eta0,q, qdot))/omega3; // both these should be larger than 0 (time of *next* pericenter and apocenter) while (tperi<0) { tperi += Tr; } while (tapo<0) { tapo += Tr; } // calculate number of half-periods (no. of peri- or apocenter passages) int nstar = ((int) floor((t - GSL_MIN(tapo, tperi))/(Tr/2.0))) + 1; // get r double base = (1.0 + c/B_ISO * (1.0 - e * cos(etabase))); x[0] = B_ISO * sqrt(base * base - 1.0); // get phi double tan1 = atan(sqrt((1.0 + e)/(1.0 - e)) * tan(etabase/2.0)) + M_PI * floor((etabase+M_PI)/(2.0 * M_PI)); double tan2 = (atan(sqrt((1.0 + e + 2.0 * B_ISO / c)/(1.0 - e + 2.0 * B_ISO / c)) * tan(etabase/2.0)) + M_PI * floor((etabase+M_PI)/(2.0 * M_PI)))/sqrt(1 + 4.0 * M_PI * B_ISO / (J2 * J2)); double th20 = theta2(eta0, q[1], q, qdot); double th3 = theta3(etabase, q, qdot); // fprintf(stdout, "%lg %lg %lg %lg\n", t, tan1, tan2,th3); x[1] = th20 + omega2 * t - omega2/omega3 * th3 + tan1 + tan2; // conservation of angular momentum gives phidot v[1] = J2 / (x[0] * x[0]); // conservation of energy gives magnitude of rdot v[0] = M_SQRT2 * sqrt(ham - J2 * J2 / (2.0 * x[0] * x[0]) - Phi(x[0])); // figure out the sign - if it started heading toward pericenter // and has gone thru an even number of half-periods since then, vr<0 // likewise if it started heading toward apo and has gone thru an odd nm // of half-periods, vr<0 if((GSL_IS_EVEN(nstar) && (tperi<tapo)) || (GSL_IS_ODD(nstar) && (tapo<tperi))) v[0] *= -1.0; }