1 #ifndef MAD_FNormalForm_HH
2 #define MAD_FNormalForm_HH
28 template <
class T,
int,
int>
class FMatrix;
29 template <
class T,
int>
class FTps;
30 template <
class T,
int>
class FVps;
35 const double tol = 1.0e-8;
120 #include <functional>
130 freedom(0), A_Lie(), N_Lie(), lambda(), V()
136 freedom(form.freedom), A_Lie(form.A_Lie), N_Lie(form.N_Lie),
137 lambda(form.lambda), V(form.V)
143 freedom(N / 2), A_Lie(0.0),
144 N_Lie(0, 2, M_scr.getTopOrder() + 1),
147 throw LogicalError(
"FNormalForm::FNormalForm()",
"Map dimension is odd.");
159 V_inv = lu.inverse();
165 for(
int i = 0; i < N; ++i) {
166 Rot(i, i) = R_dir(i, i) = I_dir(i, i) = R_inv(i, i) = 1.0;
171 for(
int i = 0; i < 2 *
freedom; i += 2) {
191 R_dir(i, i) = R_dir(i, i + 1) = R_dir(i + 1, i) = 0.5;
192 R_dir(i + 1, i + 1) = -0.5;
193 R_inv(i, i) = R_inv(i, i + 1) = R_inv(i + 1, i) = 1.0;
194 R_inv(i + 1, i + 1) = -1.0;
202 I_dir(i, i) = I_dir(i + 1, i + 1) = 0.0;
203 I_dir(i, i + 1) = I_dir(i + 1, i) = 1.0;
213 for(
int i = 2 * freedom; i < N; i += 2) {
227 for(
int omega = 2; omega < maxOrder; omega++) {
232 for(
int i = 0; i < N; i += 2) {
233 f += temp[i+1].multiplyVariable(i) - temp[i].multiplyVariable(i + 1);
236 f /= double(omega + 1);
245 m < FTps<double, N>::getSize(omega + 1); m++) {
247 std::complex<double> factor = 1.0;
250 for(
int j = 0; j < 2 *
freedom; j += 2) {
260 factor = 1.0 / (1.0 - factor);
289 N_acc =
ExpMap(- T_omega, N_acc);
309 FMatrix < double, N / 2, N / 2 > QQ;
312 for(
int mode1 = 0; mode1 < freedom; mode1++) {
315 power1[2*mode1] = power3[2*mode1+1] = 4;
316 power2[2*mode1] = power2[2*mode1+1] = 2;
318 - (3.0 * (N_Lie.getCoefficient(power1) +
319 N_Lie.getCoefficient(power3)) +
320 N_Lie.getCoefficient(power2)) / (4.0 *
pi);
323 for(
int mode2 = mode1 + 1; mode2 < freedom; mode2++) {
325 power1[2*mode1] = power1[2*mode2] = 2;
326 power2[2*mode1+1] = power2[2*mode2] = 2;
327 power3[2*mode1] = power3[2*mode2+1] = 2;
328 power4[2*mode1+1] = power4[2*mode2+1] = 2;
329 QQ(mode1, mode2) = QQ(mode2, mode1) =
330 - (N_Lie.getCoefficient(power1) +
331 N_Lie.getCoefficient(power2) +
332 N_Lie.getCoefficient(power3) +
333 N_Lie.getCoefficient(power4)) / (4.0 *
pi);
346 for(
int j = 0; j < N; j += 2) {
354 return (a * a + b * b);
356 return (a * a - b * b);
393 for(
int i = 0; i < N;) {
398 std::fill(V.col_begin(nDim), V.col_end(nDim), 0.0);
412 for(
int j = 0; j < N; j += 2) {
413 pb += tmat(j, i) * tmat(j + 1, i + 1) - tmat(j + 1, i) * tmat(j, i + 1);
424 lambda[n_c] = tlam[i1];
425 lambda[n_c+1] = tlam[i2];
429 for(
int j = 0; j < N; j++) {
430 V(j, n_c) = tmat(j, i1) / fact;
431 V(j, n_c + 1) = tmat(j, i2) / fact;
440 for(
int i = 0; i < n_r;) {
442 for(m = i + 1; m < n_r; ++m) {
443 if(
std::abs(tlam[i] * tlam[m] - 1.0) < tol)
break;
448 "Cannot find pair of real eigenvalues.");
453 std::swap(tlam[m], tlam[i+1]);
459 for(
int j = 0; j < N; j += 2) {
460 pb += tmat(j, i) * tmat(j + 1, i + 1) - tmat(j + 1, i) * tmat(j, i + 1);
471 lambda[n_c] = tlam[i1];
472 lambda[n_c+1] = tlam[i2];
476 for(
int j = 0; j < N; ++j) {
477 V(j, n_c) = (tmat(j, i1) + tmat(j, i2)) / fact;
478 V(j, n_c + 1) = (tmat(j, i1) - tmat(j, i2)) / fact;
486 if(nDim != 2 * freedom) {
487 throw LogicalError(
"FNormalForm::orderModes()",
"Map dimension is odd.");
491 for(
int i = 0; i < nDim; i += 2) {
495 for(
int j = i; j < N; j += 2) {
496 double c =
std::abs(V(i, j) * V(i + 1, j + 1) - V(i, j + 1) * V(i + 1, j));
506 std::swap(lambda[i], lambda[k]);
507 std::swap(lambda[i+1], lambda[k+1]);
509 V.swapColumns(i + 1, k + 1);
514 double re = V(i, i) /
sqrt(V(i, i) * V(i, i) + V(i, i + 1) * V(i, i + 1));
515 double im = V(i, i + 1) /
sqrt(V(i, i) * V(i, i) + V(i, i + 1) * V(i, i + 1));
517 for(
int j = 0; j < N; j++) {
518 double real_part = re * V(j, i) + im * V(j, i + 1);
519 double imag_part = re * V(j, i + 1) - im * V(j, i);
521 V(j, i + 1) = imag_part;
527 #endif // MAD_FNormalForm_HH
int degreesOfFreedom() const
Get number of stable degrees of freedom.
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
int getTopOrder() const
Get highest order contained in any component.
col_iterator col_end(int c)
Get column iterator.
A templated representation for matrices.
FVector< std::complex< double >, N > lambda
void swapColumns(int c1, int c2)
Exchange columns.
A templated representation for vectors.
Eigenvalues and eigenvectors for a real general matrix.
Representation of the exponents for a monomial with fixed dimension.
void orderModes(FVector< std::complex< double >, N >, FMatrix< double, N, N >)
FTps< double, N > invariant(int i) const
Get invariant polynomial for mode i.
const FMatrix< double, N, N > & eigenVectors() const
Get eigenvectors of the linear part in packed form.
Tps< T > log(const Tps< T > &x)
Natural logarithm.
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
A templated representation of a LU-decomposition.
constexpr double pi
The value of .
constexpr double c
The velocity of light in m/s.
const FVector< std::complex< double >, N > & eigenValues() const
Get eigenvalues of the linear part as a complex vector.
col_iterator col_begin(int c)
Get column iterator.
const FTps< double, N > & normalisingMap() const
Get normalising map as a Lie transform.
FMatrix< double, N/2, N/2 > anharmonicity() const
Get anharmonicities as a matrix.
FVps< T, N > ExpMap(const FTps< T, N > &H, int trunc=FTps< T, N >::EXACT)
Build the exponential series.
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
FMatrix< double, N, N > packedEigenVectors() const
Get eigenvectors.
MMatrix< double > im(MMatrix< m_complex > mc)
Normal form of a truncated Taylor series map.
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.
FTps scaleMonomials(const FTps &y) const
Scale monomial coefficients by coefficients in [b]y[/b].
FMatrix< T, N, N > linearTerms() const
Extract the linear part of the map.
Tps< T > sqrt(const Tps< T > &x)
Square root.
static const FMonomial< N > & getExponents(int index)
MMatrix< double > re(MMatrix< m_complex > mc)
FMatrix< double, N, N > V
void operator=(const FNormalForm &)
const FTps< double, N > & normalForm() const
Get normal-form map as a Lie transform.
Truncated power series in N variables of type T.
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.
FVector< std::complex< double >, N > eigenValues() const
Get eigenvalues.
Vector truncated power series in n variables.
void setCoefficient(int index, const T &value)
Set coefficient.