1 #ifndef CLASSIC_DragtFinnMap_HH
2 #define CLASSIC_DragtFinnMap_HH
30 template <
class T,
int N>
class FVector;
31 template <
class T,
int N>
class FVps;
32 template <
class T,
int N>
class LinearMap;
176 inline const double *
begin(
int)
const;
180 inline double *
begin(
int);
184 inline const double *
end(
int)
const;
188 inline double *
end(
int);
227 std::ostream &operator<<(std::ostream &, const DragtFinnMap<N> &);
251 itsMatrix(rhs.itsMatrix), itsGenerators(rhs.itsGenerators)
258 itsMatrix(), itsGenerators() {
259 for(
int i = 0; i < 2 * N; ++i)
itsMatrix(i, i) = 1.0;
266 itsMatrix(), itsGenerators(0, order, order) {
267 for(
int i = 0; i < 2 * N; ++i)
itsMatrix(i, i) = 1.0;
289 itsMatrix(rhs.linearTerms()), itsGenerators() {
290 for(
int i = 0; i < N; ++i) {
301 itsMatrix(rhs.linearTerms()), itsGenerators() {
302 for(
int i = 0; i < N; ++i) {
312 int maxOrder = getOrder();
316 for(
int i = maxOrder; i >= 3; --i) {
318 theMap =
ExpMap(tps, theMap);
324 for(
int i = 0; i < N; ++i) {
325 xlate[2*i][0] = -gen[2*i+2];
326 xlate[2*i+1][0] = gen[2*i+1];
330 return theMap.
filter(0, maxOrder < 2 ? 1 : maxOrder - 1);
341 for(
int i = 0; i < N; ++i) {
342 theMap[2*i+0][0] = - f_1[2*i+2];
343 theMap[2*i+1][0] = f_1[2*i+1];
353 if(H.
filter(1, 1) == 0.0) {
355 *
this = factorize(H);
373 for(
int epsilonRank = 1; epsilonRank <= order - 3; ++epsilonRank) {
374 int top = order - epsilonRank;
378 for(
int ord = 3; ord <= top; ++ord) {
412 if(itsGenerators.getMaxOrder() < order) {
414 std::copy(itsGenerators.begin(), itsGenerators.end(), temp.
begin());
415 itsGenerators = temp;
420 std::copy(gen.
begin(), gen.
end(), begin(order));
427 static const double tol = 1.0e-12;
446 modes = orderModes(V, mu);
454 for(
int i = 0; i < 2 * N; i += 2) {
458 R_dir(i + 1, i + 1) = 1.0;
460 R_inv(i + 1, i + 1) = 1.0;
462 I_dir(i + 1, i + 1) = 1.0;
464 Rot(i, i + 1) = M(i, i + 1);
465 Rot(i + 1, i) = M(i + 1, i);
466 Rot(i + 1, i + 1) = 1.0;
469 R_dir(i, i + 1) = + 0.5;
470 R_dir(i + 1, i) = + 0.5;
471 R_dir(i + 1, i + 1) = - 0.5;
473 R_inv(i, i + 1) = + 1.0;
474 R_inv(i + 1, i) = + 1.0;
475 R_inv(i + 1, i + 1) = - 1.0;
484 Rot(i + 1, i + 1) = +
c;
485 I_dir(i, i + 1) = 1.0;
486 I_dir(i + 1, i) = 1.0;
492 Rot(i, i + 1) = - sh;
493 Rot(i + 1, i) = - sh;
494 Rot(i + 1, i + 1) = + ch;
496 I_dir(i + 1, i + 1) = 1.0;
510 for(
int omega = 3; omega <= maxOrder; omega++) {
517 for(
int m = f.getBottomIndex(); m < f.getTopIndex(); m++) {
519 std::complex<double> factor = 0.0;
522 for(
int j = 0; j < 2 * modes; j += 2) {
524 factor += double(index[j]) * mu[j] + double(index[j+1]) * mu[j+1];
529 factor = 1.0 / factor;
534 pi[m] =
std::pow(- 1.0, (count + 1) / 2);
543 N_scr = N_scr.
transform(- F_omega, maxOrder);
686 return itsGenerators;
693 return itsGenerators;
702 if(itsGenerators.getMaxOrder() >= order) {
703 std::copy(begin(order), end(order), gen.
begin());
705 std::fill(gen.
begin(), gen.
end(), 0.0);
715 return itsGenerators.getMaxOrder();
734 int order = getOrder();
760 itsGenerators += gen;
767 itsGenerators -= gen;
777 if(itsGenerators.getMaxOrder() < order) {
779 std::copy(itsGenerators.begin(), itsGenerators.end(), temp.
begin());
780 itsGenerators = temp;
785 std::transform(begin(order), end(order), gen.
begin(),
786 begin(order), std::plus<double>());
797 if(itsGenerators.getMaxOrder() < order) {
799 std::copy(itsGenerators.begin(), itsGenerators.end(), temp.
begin());
800 itsGenerators = temp;
805 std::transform(begin(order), end(order), gen.
begin(),
806 begin(order), std::minus<double>());
816 return catenateZero(rhs);
836 static const int itmax = 10;
837 static const double tol = 1.0e-16;
840 for(
int iter = 1; iter <= itmax; ++iter) {
842 trackOrbit(fp1, map);
859 static const int itmax = 10;
860 static const double tol = 1.0e-16;
863 for(
int iter = 1; iter <= itmax; ++iter) {
865 trackOrbit(fp1, map);
873 FMatrix < double, 2 * N - 2, 2 * N - 2 > MM;
875 for(
int i = 0; i < 2 * N - 2; ++i) {
876 for(
int j = 0; j < 2 * N - 2; ++j) {
883 lu.backSubstitute(X);
884 for(
int i = 0; i < 2 * N - 2; ++i) {
895 FMatrix < double, 2 * N - 2, 2 * N - 2 > B;
896 FVector < double, 2 * N - 2 > C;
899 for(
int i = 0; i < 2 * N - 2; ++i) {
900 for(
int j = 0; j < 2 * N - 2; ++j) {
905 C[i] = - A(i, 2 * N - 1);
909 lu.backSubstitute(C);
913 for(
int i = 0; i < N - 1; ++i) {
914 T(2 * i, 2 * N - 1) = C[2*i];
915 T(2 * i + 1, 2 * N - 1) = C[2*i+1];
916 T(2 * N - 2, 2 * i) = C[2*i+1];
917 T(2 * N - 2, 2 * i + 1) = - C[2*i];
927 for(
int order = 2; order <= getOrder(); ++order) {
930 for(
int i = 0; i < 2 * N - 2; ++i) {
931 for(
int j = 0; j < 2 * N - 2; ++j) {
943 lu.backSubstitute(C);
948 for(
int i = 0; i < 2 * N - 2; ++i) {
973 for(
int i = 0; i < N; ++i) {
974 g_1[2*i+1] = f_1[2*i+1] + orbit[2*i+1];
975 g_1[2*i+2] = f_1[2*i+2] - orbit[2*i];
987 if(getOrder() >= 3) {
996 if(getOrder() >= 4) {
1012 hM = (((hM * (1. / 4.) + 1.) * hM * (1. / 3.) + 1.) * hM * (1. / 2.) + 1.) * hM + 1.;
1016 for(
int i = 0; i < N; ++i) {
1017 orbit[2*i] = - h_1[2*i+2];
1018 orbit[2*i+1] = h_1[2*i+1];
1033 for(
int order = 1; order <= topOrder; ++order) {
1035 int pbOrder = order;
1037 for(
int power = 1; power <= topOrder; ++power) {
1038 pbOrder += gOrder - 2;
1039 if(pbOrder <= 0 || pbOrder > topOrder)
break;
1091 itsGenerators.
filter(2, itsGenerators.getMaxOrder()).substitute(g_inv)
1092 + itsGenerators.
filter(1, 1);
1102 h += pb_f3_g3 / 2.0;
1109 h += pb_f4_g3 - pb_f3_f3_g3 / 6.0 - pb_g3_f3_g3 / 3.0;
1133 for(
int i = 0; i < N; ++i) {
1136 return factorBerzForestIrwin(HH);
1140 return factorDouglas(HH);
1150 for(
int j = 0; j < 2 * N; ++j) {
1151 for(
int i = 0; i < 2 * N; ++i) {
1152 B(i, j) = (A(i, j) - C(i, j) / 12.0) / 2.0;
1153 C(i, j) = - B(i, j);
1156 B(j, j) = B(j, j) + 1.0;
1157 C(j, j) = C(j, j) + 1.0;
1173 unsigned gior_min = 2 * N + 1;
1174 for(
unsigned i = 0, ig = gior_min ; i < N ; ++i) {
1175 M(2 * i + 1, 2 * i) = 2.0 * f_2[ig++];
1176 for(
unsigned j = 2 * i + 1 ; j < 2 * N ; ++j) {
1177 M(2 * i + 1, j) = f_2[ig];
1178 M(j + 1 - 2 * (j % 2), 2 * i) = (1 - 2 * (
static_cast<int>(j) % 2)) * f_2[ig++];
1180 M(2 * i, 2 * i + 1) = -2.0 * f_2[ig++];
1181 for(
unsigned j = 2 * i + 2 ; j < 2 * N ; ++j) {
1182 M(2 * i, j) = -f_2[ig];
1183 M(j + 1 - 2 * (j % 2), 2 * i + 1) = (1 - 2 * (
static_cast<int>(j) % 2)) * f_2[ig++];
1217 for(
int i = 1; i <= 5; ++i) {
1229 for(
int i = 1; i <= 4; ++i) {
1290 k_1 -= (pb_131 - pb_221) / 6.0;
1291 k_2 -= (pb_231 - 2.0 * pb_321) / 12.0;
1292 k_3 -= (pb_232 - pb_331) / 6.0;
1293 k_4 -= pb_332 / 12.0;
1361 static const double tol = 1.0e-12;
1369 for(
int i = 0; i < 2 * N;) {
1374 for(
int j = 0; j < 2 * N; ++j) V(j, nDim) = 0.0;
1375 V(nDim, nDim) = 1.0;
1381 for(
int j = 0; j < 2 * N; ++j) tmat(j, n_r) = tmat(j, i);
1385 }
else if (i + 1 < 2 * N) {
1388 mu[n_c+1] = tmu[i+1];
1392 for(
int j = 0; j < 2 * N; j += 2) {
1393 pb += tmat(j, i) * tmat(j + 1, i + 1) - tmat(j + 1, i) * tmat(j, i + 1);
1397 for(
int j = 0; j < 2 * N; j++) {
1398 V(j, n_c) = tmat(j, i) * fact;
1399 V(j, n_c + 1) = tmat(j, i + 1) * fact;
1408 for(
int i = 0; i < n_r;) {
1410 for(; m < n_r && m < 2 * N; ++m) {
1411 if(
std::abs(tmu[i] + tmu[m]) < tol)
break;
1416 "Cannot find pair of real eigenvalues.");
1421 std::swap(tmu[m], tmu[i+1]);
1434 mu[n_c+1] = tmu[i1];
1438 for(
int j = 0; j < 2 * N; j += 2) {
1439 pb += tmat(j, i1) * tmat(j + 1, i2) - tmat(j + 1, i1) * tmat(j, i2);
1444 double fact2 = (pb > 0.0) ? (- fact1) : fact1;
1445 for(
int j = 0; j < 2 * N; ++j) {
1446 V(j, n_c) = tmat(j, i1) * fact1 + tmat(j, i2) * fact2;
1447 V(j, n_c + 1) = tmat(j, i1) * fact1 - tmat(j, i2) * fact2;
1455 int modes = nDim / 2;
1456 for(
int i = 0; i < nDim; i += 2) {
1460 for(
int j = i; j < 2 * N; j += 2) {
1461 double c =
std::abs(V(i, j) * V(i + 1, j + 1) - V(i, j + 1) * V(i + 1, j));
1470 std::swap(mu[i], mu[k]);
1471 std::swap(mu[i+1], mu[k+1]);
1482 std::ostream &operator<<(std::ostream &os, const DragtFinnMap<N> &map) {
1484 std::streamsize old_prec = os.precision(14);
1485 os.setf(std::ios::floatfield, std::ios::scientific);
1493 os.setf(std::ios::floatfield, std::ios::fixed);
1497 #endif // CLASSIC_DragtFinnMap_HH
void fp1(BareField< T, 1U > &field, bool docomm=true)
T sum() const
Return sum of series.
static int orderModes(FMatrix< double, 2 *N, 2 *N > &, FVector< std::complex< double >, 2 *N > &)
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
DragtFinnMap catenateZero(const DragtFinnMap &) const
int getMaxOrder() const
Get maximum order.
void swapColumns(int c1, int c2)
Exchange columns.
A templated representation for vectors.
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Tps< T > sin(const Tps< T > &x)
Sine.
FLieGenerator< U, N > transform(const FMatrix< U, 2 *N, 2 *N > &) const
Substitute matrix in Lie generator.
Eigenvalues and eigenvectors for a real general matrix.
Representation of the exponents for a monomial with fixed dimension.
FLieGenerator scale(const FLieGenerator &) const
Scale monomial-wise.
static DragtFinnMap factorSimple(const FTps< double, 2 *N > &H)
const FMatrix< double, 2 *N, 2 *N > & getMatrix() const
Return the matrix representing the linear transform.
void operator-=(const FTps< double, 2 *N > &)
Subtract from set of generators.
void assign(const BareField< T, Dim > &a, RHS b, OP op, ExprTag< true >)
static DragtFinnMap factorize(const FTps< double, 2 *N > &H)
DragtFinnMap catenate(const DragtFinnMap &) const
Substitute (concatenate) with another map in beam order.
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
Tps< T > cosh(const Tps< T > &x)
Hyperbolic cosine.
FLieGenerator derivative(int var) const
Partial derivative.
static void move_g_1(DragtFinnMap &f, DragtFinnMap &g)
static DragtFinnMap factorBerzForestIrwin(const FTps< double, 2 *N > &H)
void assign(const FMatrix< double, 2 *N, 2 *N > &)
Assign the matrix representing the linear transform.
static int getSize(int order)
Tps< T > PoissonBracket(const Tps< T > &x, const Tps< T > &y)
Poisson bracket.
const FTps< double, 2 *N > & getGenerators() const
Return the complete set of generators.
A templated representation of a LU-decomposition.
const double * end(int) const
Linear map with values of type [b]T[/b] in [b]N[/b] variables.
const DragtFinnMap & operator=(const DragtFinnMap &)
constexpr double c
The velocity of light in m/s.
void removeDispersion(DragtFinnMap &dm, DragtFinnMap &map)
Split map into dispersion map and non-dispersive part.
DragtFinnMap reverse() const
Compute inverse factorisation of map.
void unique()
Make representation unique.
int getOrder() const
Return order of this generator.
void backSubstitute(FVector< T, N > &B) const
Back substitution.
FVps< T, N > ExpMap(const FTps< T, N > &H, int trunc=FTps< T, N >::EXACT)
Build the exponential series.
DragtFinnMap transform(const FLieGenerator< double, N > &g, int topOrder)
Build the terminating exponential series.
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
FMatrix< double, N, N > packedEigenVectors() const
Get eigenvectors.
bool isZero() const
Test for zero.
FTps substitute(const FMatrix< T, N, N > &M, int n) const
Substitute.
FVps filter(int minOrder, int maxOrder, int trcOrder=(FTps< T, N >::EXACT)) const
Extract given range of orders, with truncation.
static FMatrix< double, 2 *N, 2 *N > makeMatrix(const FLieGenerator< double, N > &f_2)
Tps< T > sqrt(const Tps< T > &x)
Square root.
A representation for a homogeneous polynomial, used as a Lie generator.
static const FMonomial< N > & getExponents(int index)
const FLieGenerator< double, N > getGenerator(int) const
Return the generator for a selected order.
DragtFinnMap inverse() const
Compute inverse map.
static FMatrix< double, 2 *N, 2 *N > exponentiate(const FMatrix< double, 2 *N, 2 *N > &)
FTps filter(int minOrder, int maxOrder, int trcOrder=EXACT) const
Extract given range of orders, with truncation.
void operator+=(const FTps< double, 2 *N > &)
Add to set of generators.
FTps< double, 2 *N > itsGenerators
DragtFinnMap conjugate(const DragtFinnMap &) const
Conjugate with another map.
void staticFixedPoint(FVector< double, 2 *N > &fp, DragtFinnMap &map)
Compute static fixed point.
Tps< T > cos(const Tps< T > &x)
Cosine.
T * begin()
Get pointer to beginning of generator.
T euclidean_norm(const Vector< T > &)
Euclidean norm.
DragtFinnMap()
Construct identity map.
A representation for a Taylor series in one variable,.
FMatrix< T, N, N > inverse() const
Get inverse.
void dynamicFixedPoint(FVector< double, 2 *N > &fp, DragtFinnMap &map)
Compute dynamic fixed point.
A Lie algebraic map, factored according to Dragt and Finn.
T * end()
Get pointer past end of generator.
static DragtFinnMap factorDouglas(const FTps< double, 2 *N > &H)
const double * begin(int) const
FVps substitute(const FMatrix< T, N, N > &M, int n) const
Substitute.
FLieGenerator< T, N > imag(const FLieGenerator< std::complex< T >, N > &)
Take imaginary part of a complex generator.
FMatrix< double, 2 *N, 2 *N > itsMatrix
int getOrder() const
Return the order of the generators.
FVector< std::complex< double >, N > eigenValues() const
Get eigenvalues.
Tps< T > sinh(const Tps< T > &x)
Hyperbolic sine.
Vector truncated power series in n variables.
void trackOrbit(FVector< double, 2 *N > &orbit, DragtFinnMap &map)
Track an orbit through the map.
Inform & endl(Inform &inf)
T * begin() const
Return beginning of monomial array.