1#ifndef CLASSIC_FLieGenerator_CC
2#define CLASSIC_FLieGenerator_CC
36template <
class T,
int N>
40 bottomIndex(getBottomIndex(order)),
41 topIndex(getTopIndex(order)),
42 itsCoeffs(getSize(order)) {
47template <
class T,
int N>
51 bottomIndex(getBottomIndex(order)),
52 topIndex(getTopIndex(order)),
53 itsCoeffs(getSize(order)) {
62template <
class T,
int N>
73template <
class T,
int N>
76 itsOrder(rhs.itsOrder),
77 bottomIndex(rhs.bottomIndex),
78 topIndex(rhs.topIndex),
79 itsCoeffs(rhs.itsCoeffs)
83template <
class T,
int N>
89template <
class T,
int N>
100template<
class T,
int N>
inline
103 return itsCoeffs.begin();
107template<
class T,
int N>
inline
110 return itsCoeffs.begin();
114template<
class T,
int N>
inline
116 return itsCoeffs.end();
120template<
class T,
int N>
inline
123 return itsCoeffs.end();
127template<
class T,
int N>
inline
129 return itsCoeffs[i-bottomIndex];
133template<
class T,
int N>
inline
135 return itsCoeffs[i-bottomIndex];
139template<
class T,
int N>
145 std::transform(itsCoeffs.begin(), itsCoeffs.end(),
146 result.
itsCoeffs.begin(), std::negate<T>());
151template<
class T,
int N>
156 std::transform(itsCoeffs.begin(), itsCoeffs.end(), itsCoeffs.begin(),
157 std::bind(std::multiplies<T>(), std::placeholders::_1, val));
163template<
class T,
int N>
168 std::transform(itsCoeffs.begin(), itsCoeffs.end(), itsCoeffs.begin(),
169 std::bind(std::divides<T>(), std::placeholders::_1, val));
175template<
class T,
int N>
179 std::transform(itsCoeffs.begin(), itsCoeffs.end(), rhs.
itsCoeffs.begin(),
180 itsCoeffs.begin(), std::plus<T>());
181 }
else if(isZero()) {
183 }
else if(! rhs.
isZero()) {
184 throw SizeError(
"operator+=(FLieGenerator)",
"Inconsistent orders.");
191template<
class T,
int N>
195 std::transform(itsCoeffs.begin(), itsCoeffs.end(), rhs.
itsCoeffs.begin(),
196 itsCoeffs.begin(), std::minus<T>());
197 }
else if(isZero()) {
199 }
else if(! rhs.
isZero()) {
200 throw SizeError(
"operator+=(FLieGenerator)",
"Inconsistent orders.");
207template <
class T,
int N>
210 std::fill(itsCoeffs.begin(), itsCoeffs.end(),
T(0));
214template <
class T,
int N>
232template <
class T,
int N>
235 if(itsOrder < 0)
return true;
237 for(
const T *i = itsCoeffs.begin(); i != itsCoeffs.end(); ++i) {
238 if(*i !=
T(0))
return false;
245template <
class T,
int N>
249 std::transform(itsCoeffs.begin(), itsCoeffs.end(), rhs.
itsCoeffs.begin(),
250 result.
itsCoeffs.begin(), std::multiplies<T>());
255template <
class T,
int N>
template <
class U>
258 int order = getOrder();
264 U *tt = temp.
begin();
267 for(
int next = 1; next < table.
size();) {
269 int bot1 = getBottomIndex(s.
order);
270 int top1 = getTopIndex(s.
order);
271 for(
int i = bot1; i < top1; ++i) tt[i] = U(0);
274 for(
int v = 0; v < 2 * N; ++v) {
278 int bot2 = getBottomIndex(s.
order - 1);
279 int top2 = getTopIndex(s.
order - 1);
280 for(
int k = bot2; k < top2; ++k) {
281 tt[
prod[k]] +=
c * tt[k];
286 if(s.
order < order) {
288 }
else if(s.
order == order) {
289 T coeff = (*this)[s.
index];
291 for(
int k = bot1; k < top1; ++k) {
292 trans[k] += coeff * tt[k];
305template <
class T,
int N>
312template <
class T,
int N>
319template <
class T,
int N>
326template <
class T,
int N>
333template <
class T,
int N>
340template <
class T,
int N>
350template <
class T,
int N>
358template <
class T,
int N>
366template <
class T,
int N>
374template <
class T,
int N>
382template <
class T,
int N>
397 for(
int i1 = bot1; i1 < top1; ++i1) {
401 for(
int i2 = bot2; i2 < top2; ++i2) {
402 z[p[i2]] += f * y[i2];
412template <
class T,
int N>
420template <
class T,
int N>
425 const std::complex<T> *i2 = x.begin();
427 while(i1 != z.
end()) {
435template <
class T,
int N>
440 const std::complex<T> *i2 = x.begin();
442 while(i1 != z.
end()) {
450template <
class T,
int N>
454 std::complex<T> *i1 = z.
begin();
457 while(i1 != z.
end()) {
458 *i1++ = std::complex<T>(*i2++,
T(0));
477 int bot_f = (top_f * ord_f) / (2 * N + ord_f);
478 int bot_g = (top_g * ord_g) / (2 * N + ord_g);
485 for(
int ind_1 = bot_f; ind_1 < top_f; ++ind_1) {
489 for(
int ind_g = bot_g; ind_g < top_g; ++ind_g) {
493 for(
int var = 0; var < 2 * N; var += 2) {
495 int ind_h = prod_f[ind_g];
498 double f_q = ff[prod_f[var+1]] *
T(exp_f[var] + 1);
499 double g_p = gg[prod_g[var+2]] *
T(exp_g[var+1] + 1);
500 double f_p = ff[prod_f[var+2]] *
T(exp_f[var+1] + 1);
501 double g_q = gg[prod_g[var+1]] *
T(exp_g[var] + 1);
504 hh[ind_h] += (f_q * g_p - f_p * g_q);
514template <
class T,
int N>
516 os <<
"Tps" << std::setw(4) << gen.
getOrder() << std::setw(4)
518 std::streamsize old_prec = os.
precision(14);
519 os.setf(std::ios::scientific, std::ios::floatfield);
523 os << std::setw(24) << gen[i];
526 for(
int var = 0; var < 2 * N; var++) {
527 os << std::setw(3) << index[var];
534 os << std::setw(24) <<
T(0);
536 for(
int var = 0; var < 2 * N; var++) {
537 os << std::setw(3) << (-1);
541 os.
setf(std::ios::fixed, std::ios::floatfield);
542 os.precision(old_prec);
FLieGenerator< T, N > operator*(const FLieGenerator< T, N > &x, const T &y)
Multiply by scalar.
FLieGenerator< T, N > PoissonBracket(const FLieGenerator< T, N > &f, const FLieGenerator< T, N > &g)
Poisson bracket of two Lie generators.
FLieGenerator< T, N > operator/(const FLieGenerator< T, N > &x, const T &y)
Divide by scalar.
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &x)
Take real part of a complex generator.
FLieGenerator< T, N > operator-(const FLieGenerator< T, N > &x, const FLieGenerator< T, N > &y)
Subtract.
std::ostream & operator<<(std::ostream &os, const FLieGenerator< T, N > &gen)
Output.
FLieGenerator< T, N > operator+(const FLieGenerator< T, N > &x, const FLieGenerator< T, N > &y)
Add.
FLieGenerator< std::complex< T >, N > toComplex(const FLieGenerator< T, N > &x)
Convert real generator to complex.
FLieGenerator< T, N > imag(const FLieGenerator< std::complex< T >, N > &x)
Take imaginary part of a complex generator.
T::PETE_Expr_t::PETE_Return_t prod(const PETE_Expr< T > &expr)
Inform & endl(Inform &inf)
constexpr double c
The velocity of light in m/s.
iterator begin()
Get beginning of data.
int size() const
Get array size.
A templated representation for matrices.
Truncated power series in N variables of type T.
T * begin() const
Return beginning of monomial array.
int getMaxOrder() const
Get maximum order.
A representation for a homogeneous polynomial, used as a Lie generator.
void clear()
Clear all coefficients.
int getBottomIndex() const
Return bottom index of this generator.
FLieGenerator & operator*=(const T &)
Multiply by scalar and assign.
const FLieGenerator & operator=(const FLieGenerator &)
FLieGenerator & operator-=(const FLieGenerator &)
Subtract vector and assign.
T * begin()
Get pointer to beginning of generator.
FLieGenerator & operator+=(const FLieGenerator &)
Add vector and assign.
static int getSize(int order)
T & operator[](int n)
Get element.
FLieGenerator & operator/=(const T &)
Divide by scalar and assign.
FLieGenerator derivative(int var) const
Partial derivative.
int getOrder() const
Return order of this generator.
bool isZero() const
Test for zero.
FLieGenerator scale(const FLieGenerator &) const
Scale monomial-wise.
FLieGenerator operator-() const
Change sign of generator.
T * end()
Get pointer past end of generator.
FLieGenerator< U, N > transform(const FMatrix< U, 2 *N, 2 *N > &) const
Substitute matrix in Lie generator.
int getTopIndex() const
Return top index of this generator.
Representation of the exponents for a monomial with fixed dimension.
Internal utility class for FTps<T,N> class.
static const FMonomial< N > & getExponents(int index)
static const Array1D< TpsSubstitution > & getSubTable()
static int getSize(int order)
static const Array1D< int > & getProductArray(int index)
FmtFlags_t setf(FmtFlags_t setbits, FmtFlags_t field)