OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
FVps.hpp
Go to the documentation of this file.
1 #ifndef CLASSIC_FVps_CC
2 #define CLASSIC_FVps_CC
3 
4 // ------------------------------------------------------------------------
5 // $RCSfile: FVps.cpp,v $
6 // ------------------------------------------------------------------------
7 // $Revision: 1.2.2.8 $
8 // ------------------------------------------------------------------------
9 // Copyright: see Copyright.readme
10 // ------------------------------------------------------------------------
11 //
12 // Template Class: FVps<T,N>
13 // Vector of power series with dimension N and N variables.
14 //
15 // ------------------------------------------------------------------------
16 // Class category: FixedAlgebra
17 // ------------------------------------------------------------------------
18 //
19 // $Date: 2004/11/18 22:18:06 $
20 // $Author: jsberg $
21 //
22 // ------------------------------------------------------------------------
23 
24 //#define DEBUG_FVps_CC
25 
26 #include "FixedAlgebra/FLUMatrix.h"
27 #include "FixedAlgebra/FMatrix.h"
28 #include "FixedAlgebra/FTps.h"
29 #include "FixedAlgebra/FTpsData.h"
30 #include "FixedAlgebra/FVector.h"
31 #include "FixedAlgebra/LinearMap.h"
34 #include "Utilities/DomainError.h"
35 #include "Utilities/FormatError.h"
36 #include "Utilities/LogicalError.h"
37 #include "Utilities/CLRangeError.h"
38 #include <iostream>
39 #include <iterator>
40 #include <list>
41 
42 // Template class FVps<T,N>
43 // ------------------------------------------------------------------------
44 
45 template <class T, int N>
47  identity();
48 }
49 
50 
51 template <class T, int N>
53  for(int i = 0; i < N; ++i) data[i] = rhs.data[i];
54 }
55 
56 
57 template <class T, int N>
59  identity();
60  for(int i = 0; i < N; ++i) {
61  if(rhs[i][0] != T(0)) data[i].setMinOrder(0);
62  for(int j = 0; j <= N; ++j) data[i][j] = rhs[i][j];
63  }
64 }
65 
66 
67 template <class T, int N>
69  static const int SIZE = FTpsData<N>::getSize(2);
70  for(int i = 0; i < N; ++i) {
71  data[i] = FTps<T, N>(0, 2, 2);
72  for(int j = 0; j < SIZE; ++j) data[i][j] = rhs[i][j];
73  }
74 }
75 
76 
77 template <class T, int N>
78 FVps<T, N>::FVps(int minOrder, int maxOrder, int trcOrder) {
79  for(int i = 0; i < N; ++i)
80  data[i] = FTps<T, N>(minOrder, maxOrder, trcOrder);
81 }
82 
83 
84 template <class T, int N>
86  identity();
87  for(int i = 0; i < N; ++i)
88  for(int j = 0; j < N; j++) data[i][j+1] = x(i, j);
89 }
90 
91 
92 template <class T, int N>
94  for(int i = 0; i < N; i++) data[i] = FTps<T, N>(x[i]);
95 }
96 
97 
98 template <class T, int N>
100 {}
101 
102 
103 template <class T, int N>
105  if(&rhs != this) for(int i = 0; i < N; ++i) data[i] = rhs.data[i];
106  return *this;
107 }
108 
109 
110 template <class T, int N>
112  for(int i = 0; i < N; ++i) data[i] = FTps<T, N>::makeVariable(i);
113 }
114 
115 
116 template <class T, int N>
118  for(int i = 0; i < N; ++i) data[i] = T(0);
119 }
120 
121 
122 template <class T, int N>
123 const FTps<T, N> &FVps<T, N>::getComponent(int index) const {
124  if(index < 0 || index >= N)
125  throw CLRangeError("FVps::getComponent()", "Index out of range.");
126 
127  return data[index];
128 }
129 
130 
131 template <class T, int N>
132 void FVps<T, N>::setComponent(int index, const FTps<T, N> &value) {
133  if(index < 0 || index >= N)
134  throw CLRangeError("FVps::setComponent()", "Index out of range.");
135 
136  data[index] = value;
137 }
138 
139 
140 template <class T, int N> inline
141 const FTps<T, N> &FVps<T, N>::operator[](int index) const {
142  return data[index];
143 }
144 
145 
146 template <class T, int N> inline
148  return data[index];
149 }
150 
151 
152 template <class T, int N>
154  return N;
155 }
156 
157 
158 template <class T, int N>
160  return N;
161 }
162 
163 
164 template <class T, int N>
166  const FTps<T, N> *p = data + N - 1;
167  int minOrder = p->getMinOrder();
168 
169  while(p-- > data) minOrder = std::min(minOrder, p->getMinOrder());
170  return minOrder;
171 }
172 
173 
174 template <class T, int N>
175 void FVps<T, N>::setMinOrder(int order) {
176  for(int i = 0; i < N; ++i) data[i].setMinOrder(order);
177 }
178 
179 
180 template <class T, int N>
182  const FTps<T, N> *p = data + N;
183  int maxOrder = 0;
184 
185  while(p-- > data) maxOrder = std::max(maxOrder, p->getMaxOrder());
186  return maxOrder;
187 }
188 
189 
190 template <class T, int N>
191 void FVps<T, N>::setMaxOrder(int order) {
192  for(int i = 0; i < N; ++i) data[i].setMaxOrder(order);
193 }
194 
195 
196 template <class T, int N>
198  const FTps<T, N> *p = data + N;
199  int topOrder = 0;
200 
201  while(p-- > data) topOrder = std::max(topOrder, p->getMaxOrder());
202  return topOrder;
203 }
204 
205 
206 template <class T, int N>
208  const FTps<T, N> *p = data + N - 1;
209  int trcOrder = p->getTruncOrder();
210 
211  while(p-- > data) trcOrder = std::min(trcOrder, p->getTruncOrder());
212  return trcOrder;
213 }
214 
215 
216 template <class T, int N>
217 void FVps<T, N>::setTruncOrder(int order) {
218  for(int i = 0; i < N; ++i) data[i].setTruncOrder(order);
219 }
220 
221 
222 template <class T, int N>
223 FVps<T, N> FVps<T, N>::filter(int minOrder, int maxOrder, int trcOrder) const {
224  // Default: trunc = FTps<T,N>::EXACT
225 
227  for(int i = 0; i < N; i++)
228  result[i] = data[i].filter(minOrder, maxOrder, trcOrder);
229  return result;
230 }
231 
232 
233 template <class T, int N>
235  return filter(0, trunc, trunc);
236 }
237 
238 
239 template <class T, int N>
241  return *this;
242 }
243 
244 
245 template <class T, int N>
248  for(int i = 0; i < N; i++) result[i] = - data[i];
249  return result;
250 }
251 
252 
253 template <class T, int N>
255  for(int i = 0; i < N; i++) data[i] += rhs[i];
256  return *this;
257 }
258 
259 
260 template <class T, int N>
262  for(int i = 0; i < N; i++) data[i] -= rhs[i];
263  return *this;
264 }
265 
266 
267 template <class T, int N>
269  for(int i = 0; i < N; i++) data[i] += rhs[i];
270  return *this;
271 }
272 
273 
274 template <class T, int N>
276  for(int i = 0; i < N; i++) data[i] -= rhs[i];
277  return *this;
278 }
279 
280 
281 template <class T, int N>
283  for(int i = 0; i < N; i++) data[i] *= rhs;
284  return *this;
285 }
286 
287 template <class T, int N>
290  // go through variables (N) and compute truncated power series for them
291  for(int i = 0; i < N; ++i) {
292  // get truncated power series for variable i
293  FTps<T, N> tps = this->getComponent(i);
294 
295  // initialize tps of result
296  FTps<T, N> r = 0.0;
297  // fake order --> gets updated inside this function
298  r.setMinOrder(1);
299 
300  /* get coefficients and exponents of their monomials and multiply
301  * truncated power series of rhs with appropriate power and coefficient
302  */
303  std::list<int> coeffs = tps.getListOfNonzeroCoefficients();
304 
305  for(std::list<int>::iterator it = coeffs.begin(); it != coeffs.end(); ++it) {
306 
307  FArray1D<int, N> expons = tps.extractExponents(*it);
308 
309  // represents the monomial --> is polynomial due to multiplication of each variable's polynomial
310  FTps<T, N> mono = 1.0;
311 
312  for(int j = 0; j < N; ++j) {
313 
314  if (expons[j] != 0) {
315  // multiply each variable of the monomial of appropriate power, i.e. build monomial
316  FTps<T, N> tmp = rhs.getComponent(j);
317  mono = mono.multiply(tmp.makePower(expons[j]), FTps<T, N>::getGlobalTruncOrder());
318  }
319  }
320  // multiply truncated power series with appropriate coefficient
321  mono *= tps.getCoefficient(*it);
322 
323  /* sum up all polynomials that build the FTps of the result map for that variable,
324  * make sure that the minimum order is correct.
325  */
327  r += mono;
328  }
329  // computation of Tps of variable i finished
330  result.setComponent(i,r);
331  }
332 
333  return result;
334 }
335 
336 
337 template <class T, int N>
339  FTps<T, N> t = rhs.inverse();
340  for(int i = 0; i < N; i++) data[i] *= t;
341  return *this;
342 }
343 
344 
345 template <class T, int N>
347  for(int i = 0; i < N; i++) data[i] *= rhs;
348  return *this;
349 }
350 
351 
352 template <class T, int N>
354  for(int i = 0; i < N; i++) data[i] /= rhs;
355  return *this;
356 }
357 
358 
359 template <class T, int N>
360 FVps<T, N> FVps<T, N>::inverse(int trunc) const {
361  // Default: trunc = FTps<T,N>::EXACT
362 
363  // Get orders.
364  int minOrder = getMinOrder(), maxOrder = getMaxOrder(), trcOrder = getTruncOrder();
365  maxOrder = std::min(maxOrder, trunc);
366  trcOrder = std::min(trcOrder, trunc);
367 
368  // Check sanity.
369  if(maxOrder < minOrder) {
370  std::cerr << " <*** ERROR ***> in FVps::inverse():\n";
371  throw LogicalError("FVps<T,N>::inverse()", "Map truncated to a zero map.");
372  }
373 
374  // Exceptions for non-invertible maps.
375  if(minOrder > 1) {
376  std::cerr << " <*** ERROR ***> in FVps::inverse():\n"
377  << " Cannot invert a purely nonlinear map." << std::endl;
378  throw DomainError("FVps<T,N>::inverse()");
379  } else if(minOrder == 1) {
380  if(maxOrder > 1 && trcOrder == FTps<T, N>::EXACT) {
381  std::cerr << " <*** ERROR ***> in FVps::inverse():\n"
382  << " Cannot invert an EXACT nonlinear map." << std::endl;
383  throw DomainError("FVps<T,N>::inverse()");
384  }
385  } else { // minOrder == 0
386  if(maxOrder == 0) {
387  std::cerr << " <*** ERROR ***> in FVps::inverse():\n"
388  << " Cannot invert a constant map." << std::endl;
389  throw DomainError("FVps<T,N>::inverse()");
390  }
391  if(maxOrder > 1) {
392  std::cerr << " <*** ERROR ***> in FVps::inverse():\n"
393  << " Cannot invert a nonlinear map containing a constant term." << std::endl;
394  throw DomainError("FVps<T,N>::inverse()");
395  }
396  if(trcOrder != FTps<T, N>::EXACT) {
397  std::cerr << " <*** ERROR ***> in FVps::inverse():\n"
398  << " Cannot invert a map with both constant and linear terms unless it is EXACT."
399  << std::endl;
400  throw DomainError("FVps<T,N>::inverse()");
401  }
402  }
403 
404  // Invert linear part.
405  FMatrix<T, N, N> t1inv;
406  FVps<T, N> r1;
407  try {
408  FLUMatrix<T, N> lu(linearTerms());
409  t1inv = lu.inverse();
410  r1 = FVps<T, N>(t1inv);
411  } catch(SingularMatrixError &smx) {
412  std::cerr << " <*** ERROR ***> in FVps::inverse():\n"
413  << " Cannot invert a map having a singular linear part." << std::endl;
414  throw DomainError("FVps<T,N>::inverse()");
415  }
416 
417  // Return linear case.
418  if(maxOrder == 1) {
419  if(minOrder == 0) r1 -= t1inv * constantTerm();
420  r1.setTruncOrder(trcOrder);
421  return r1;
422  }
423 
424  // General case (minOrder == 1, maxOrder > 1, trcOrder != EXACT).
425  // Inverse map computed order by order using the relations
426  // intitial R = R_1 = T_1^{-1};
427  // iterate R = R_1 o (I - T_{2..m} o R) trcOrder
428  FVps<T, N> id;
429  FVps<T, N> result = r1;
430  FVps<T, N> T2n = filter(2, maxOrder, trcOrder);
431  for(int m = 2; m <= trcOrder; ++m) {
432  FVps<T, N> tr = T2n.substitute(result, m);
433  result = t1inv * (id - tr);
434  }
435 
436  return result;
437 }
438 
439 
440 template <class T, int N>
442  // Default: trunc = FTps<T,N>::EXACT
443 
444  // Get orders.
445  int minOrder = getMinOrder(), maxOrder = getMaxOrder(), trcOrder = getTruncOrder();
446  maxOrder = std::min(maxOrder, trunc);
447  trcOrder = std::min(trcOrder, trunc);
448 
449  // Check sanity.
450  if(maxOrder < minOrder) {
451  std::cerr << " <*** ERROR ***> in FVps::inverse():\n";
452  throw LogicalError("FVps<T,N>::inverse()", "Map truncated to a zero map.");
453  }
454 
455  // Exceptions for non-invertible maps.
456  if(minOrder > 1) {
457  std::cerr << " <*** ERROR ***> in FVps::inverse():\n"
458  << " Cannot invert a purely nonlinear map." << std::endl;
459  throw DomainError("FVps<T,N>::inverse()");
460  } else if(minOrder == 1) {
461  if(maxOrder > 1 && trcOrder == FTps<T, N>::EXACT) {
462  std::cerr << " <*** ERROR ***> in FVps::inverse():\n"
463  << " Cannot invert an EXACT nonlinear map." << std::endl;
464  throw DomainError("FVps<T,N>::inverse()");
465  }
466  } else { // minOrder == 0
467  if(maxOrder == 0) {
468  std::cerr << " <*** ERROR ***> in FVps::inverse():\n"
469  << " Cannot invert a constant map." << std::endl;
470  throw DomainError("FVps<T,N>::inverse()");
471  }
472  if(maxOrder > 1) {
473  std::cerr << " <*** ERROR ***> in FVps::inverse():\n"
474  << " Cannot invert a nonlinear map containing a constant term." << std::endl;
475  throw DomainError("FVps<T,N>::inverse()");
476  }
477  if(trcOrder != FTps<T, N>::EXACT) {
478  std::cerr << " <*** ERROR ***> in FVps::inverse():\n"
479  << " Cannot invert a map with both constant and linear terms unless it is EXACT."
480  << std::endl;
481  throw DomainError("FVps<T,N>::inverse()");
482  }
483  }
484 
485  // Invert linear part.
486  FMatrix<T, N, N> t1inv;
487  FVps<T, N> r1;
488  try {
489  FLUMatrix<T, N> lu(linearTerms());
490  t1inv = lu.inverse();
491  r1 = FVps<T, N>(t1inv);
492  } catch(SingularMatrixError &smx) {
493  std::cerr << " <*** ERROR ***> in FVps::inverse():\n"
494  << " Cannot invert a map having a singular linear part." << std::endl;
495  throw DomainError("FVps<T,N>::inverse()");
496  }
497 
498  // Return linear case.
499  if(maxOrder == 1) {
500  if(minOrder == 0) r1 -= t1inv * constantTerm();
501  r1.setTruncOrder(trcOrder);
502  return r1;
503  }
504 
505  // General case (minOrder == 1, maxOrder > 1, trcOrder != EXACT).
506  // Inverse map computed order by order using the relations
507  // intitial R = R_1 = T_1^{-1};
508  // iterate R = R_1 o (I - T_{2..m} o R) trcOrder
509  FVps<T, N> id;
510  FVps<T, N> result = r1;
511  FVps<T, N> T2n = filter(2, maxOrder, trcOrder);
512  for(int m = 2; m <= trcOrder; ++m) {
513  FVps<T, N> tr = T2n.substitute(result, m);
514  result = t1inv * (id - tr);
515  tr = substitute(result, m);
516  result += t1inv * (id - tr);
517  }
518 
519  return result;
520 }
521 
522 
523 template <class T, int N>
526  for(int i = 0; i < N; i++) result[i] = data[i].derivative(var);
527  return result;
528 }
529 
530 
531 template <class T, int N>
534  for(int i = 0; i < N; i++) result[i] = data[i].integral(var);
535  return result;
536 }
537 
538 
539 template <class T, int N>
542  for(int i = 0; i < N; i++) {
543  if(data[i].getMinOrder() == 0) result[i] = data[i][0];
544  else result[i] = T(0);
545  }
546  return result;
547 }
548 
549 
550 template <class T, int N>
552  // Evaluate each component.
554  for(int v = N; v-- > 0;)
555  result[v] = (*this)[v].evaluate(P);
556  return result;
557 }
558 
559 
560 template <class T, int N>
563  for(int i = 0; i < N; i++)
564  for(int j = 0; j < N; j++) result(i, j) = data[i][j+1];
565  return result;
566 }
567 
568 
569 template <class T, int N>
571  // Evaluate monomials.
572  int maxOrder = getMaxOrder();
573  if(maxOrder) --maxOrder;
574  Array1D<T> monoms = FTps<T, N>::evalMonoms(P, maxOrder);
575  T *m = monoms.begin();
576 
578  for(int i = 0; i < N; ++i) {
579  for(int j = 0; j < N; ++j) {
580  FTps<T, N> gzij = data[i].derivative(j);
581  int ks = FTps<T, N>::orderStart(gzij.getMinOrder());
582  int ke = FTps<T, N>::orderEnd(gzij.getMaxOrder());
583  T *dk = gzij.begin() + ks, *mk = m + ks, *mke = m + ke;
584  T rij = T(0);
585  while(mk != mke) rij += *dk++ * *mk++;
586  result(i, j) = rij;
587  }
588  }
589  return result;
590 }
591 
592 
593 template <class T, int N>
594 Array1D<int> FVps<T, N>::getSubstOrders(const FVps<T, N> &rhs, int trunc) const {
595  // Defaul: trunc = EXACT
596 
597  // Get orders.
598  Array1D<int> ordersL(3), ordersR(3);
599  ordersL[0] = getMinOrder(), ordersL[1] = getMaxOrder(), ordersL[2] = getTruncOrder();
600  ordersR[0] = rhs.getMinOrder(), ordersR[1] = rhs.getMaxOrder(), ordersR[2] = rhs.getTruncOrder();
601 
602  Array1D<int> result = FTps<T, N>::getSubstOrders(ordersL, ordersR, trunc);
603  return result;
604 }
605 
606 
607 template <class T, int N>
609  // Check sanity.
610  if(n < 0)
611  throw LogicalError("FVps<T,N>::substitute(mat,n)",
612  "Transformation order, n, is negative.");
613  else if(n > FTps<T, N>::getGlobalTruncOrder())
614  throw LogicalError("FVps<T,N>::substitute(mat,n)",
615  "Transformation order, n, exceeds globalTruncOrder.");
616 
617  // Get orders; if necessary, make LHS have uniform min, max, and trc orders.
618  FVps<T, N> f = *this;
619  int minOrder = getMinOrder(), maxOrder = getMaxOrder(), trcOrder = getTruncOrder();
620  for(int k = N; k-- > 0;) {
621  if(f[k].getMinOrder() != minOrder) f[k].setMinOrder(minOrder);
622  if(f[k].getMaxOrder() != maxOrder) f[k].setMaxOrder(maxOrder);
623  if(f[k].getTruncOrder() != trcOrder) f[k].setTruncOrder(trcOrder);
624  }
625 
626  //Allocate result.
627  FVps<T, N> result(minOrder, maxOrder, trcOrder);
628  for(int k = N; k-- > 0;)
629  std::copy(f[k].begin(minOrder), f[k].end(maxOrder), result[k].begin(minOrder));
630 
631  // Return trivial cases.
632  if(n > trcOrder) {
633 #ifdef DEBUG_FVps_CC
634  std::cerr << " <*** WARNING ***> from FTps<T,N>::substitute(mat,n):\n"
635  << " Transformation order exceeds truncation order;\n"
636  << " returning map unchanged." << std::endl;
637 #endif
638  return result;
639  }
640  if(n == 0 || n < minOrder || maxOrder < n) return result;
641 
642  // Allocate working array; use static
643  // local memory to avoid fragmentation.
644  static T *t = 0;
645  static int max_n = -1;
646  if(n > max_n) {
647  if(t) delete [] t;
648  t = new T[FTps<T, N>::getSize(n)];
649  max_n = n;
650  }
651 
652  // Initialisations.
653  T *t1 = t + 1;
654  const T *fj[N];
655  T *g[N];
656  const Array1D<int> *oldvrbl = 0;
657  int start_n = FTps<T, N>::orderStart(n), end_n = FTps<T, N>::orderEnd(n);
658  for(int k = N; k-- > 0;) {
659  fj[k] = f[k].begin(n);
660  g[k] = result[k].begin();
661  std::fill(g[k] + start_n, g[k] + end_n, T(0));
662  }
663 
664  // Loop over order n monomials.
665  for(int j = start_n; j < end_n; ++j) {
666  // Skip monomials with coefficient zero.
667  bool zeroQ = true;
668  for(int k = N; k-- > 0;)
669  if(*fj[k] != T(0)) zeroQ = false;
670  if(zeroQ) {
671  for(int k = N; k-- > 0;) ++fj[k];
672  continue;
673  }
674 
675  // Get current monomial's variable list; compare with old variable list.
676  const Array1D<int> *vrbl = &FTpsData<N>::getVariableList(j);
677  int vi = 0;
678  if(oldvrbl)
679  while((*vrbl)[vi] == (*oldvrbl)[vi]) ++vi;
680 
681  const T *mv;
682  int ord;
683  // If vi = 0, we must start at the beginning; otherwise,
684  // we may re-use the first vi orders stored in t.
685  if(vi == 0) {
686  mv = mat[(*vrbl)[0]];
687  std::copy(mv, mv + N, t1);
688  ord = 2;
689  } else ord = vi + 1;
690 
691  // In working array t, clear orders we can't use.
692  std::fill(t + FTps<T, N>::orderStart(ord), t + end_n, T(0));
693  // Build the remainder.
694  while(ord <= n) {
695  // Build next order part of transformed monomial by multiplying
696  // the part that is one order lower by the transformed version
697  // of the next variable in the variable list.
698  int ord1 = ord - 1;
699  int start_l = FTps<T, N>::orderStart(ord1), end_l = FTps<T, N>::orderEnd(ord1);
700  mv = mat[(*vrbl)[ord1]]; // transformed version of next variable
701  for(int k = 0; k < N; k++) {
702  T mvk = mv[k];
703  if(mvk == T(0)) continue;
705  for(int l = start_l; l < end_l; l++) t[prod[l]] += mvk * t[l];
706  }
707  ++ord;
708  }
709  //Increment g[k] by fj[k] * transformed monomial.
710  for(int k = N; k-- > 0;) {
711  T *gk = g[k];
712  T fjk = *fj[k];
713  if(fjk != T(0))
714  for(int i = start_n; i < end_n; i++) gk[i] += fjk * t[i];
715  }
716  // Save variable list for comparison with the next one.
717  oldvrbl = vrbl;
718 
719  // Increment array of monomial pointers.
720  for(int k = N; k-- > 0;) ++fj[k];
721  }
722 
723  return result;
724 }
725 
726 
727 template <class T, int N>
728 FVps<T, N> FVps<T, N>::substitute(const FMatrix<T, N, N> &mat, int nl, int nh) const {
729  // Check sanity.
730  if(nl > nh)
731  throw LogicalError("FVps<T,N>::substitute(mat,nl,nh)",
732  "Inconsistent transformation orders: nl > nh.");
733  if(nl < 0)
734  throw LogicalError("FVps<T,N>::substitute(mat,nl,nh)",
735  "Transformation order nl is negative.");
736  else if(nh > FTps<T, N>::getGlobalTruncOrder())
737  throw LogicalError("FVps<T,N>::substitute(mat,nl,nh)",
738  "Transformation order nh exceeds globalTruncOrder.");
739 
740  // Get orders; if necessary, make LHS have uniform min, max, and trc orders..
741  FVps<T, N> f = *this;
742  int minOrder = getMinOrder(), maxOrder = getMaxOrder(), trcOrder = getTruncOrder();
743  for(int k = N; k-- > 0;) {
744  if(f[k].getMinOrder() != minOrder) f[k].setMinOrder(minOrder);
745  if(f[k].getMaxOrder() != maxOrder) f[k].setMaxOrder(maxOrder);
746  if(f[k].getTruncOrder() != trcOrder) f[k].setTruncOrder(trcOrder);
747  }
748 
749  //Allocate result.
750  FVps<T, N> result(minOrder, maxOrder, trcOrder);
751  for(int k = N; k-- > 0;)
752  std::copy(f[k].begin(minOrder), f[k].end(maxOrder), result[k].begin(minOrder));
753 
754  if(nh > trcOrder) {
755 #ifdef DEBUG_FVps_CC
756  std::cerr << " <*** WARNING ***> from FVps<T,N>::substitute(mat,nl,nh):\n"
757  << " Transformation order nh exceeds truncation order;\n"
758  << " truncation order unchanged." << std::endl;
759 #endif
760  }
761 
762  // Return trivial cases.
763  if(nh == 0 || nh < minOrder || maxOrder < nl) return result;
764 
765  // Set and clear actual range of orders to transform.
766  if(nl == 0) nl = 1;
767  nl = std::max(nl, minOrder);
768  nh = std::min(nh, maxOrder);
769  for(int k = N; k-- > 0;)
770  std::fill(result[k].begin(nl), result[k].end(nh), T(0));
771 
772  // Allocate working arrays; use static
773  // local memory to avoid fragmentation.
774  static T *t = 0;
775  static int max_nh = -1;
776  if(nh > max_nh) {
777  if(t) delete [] t;
778  t = new T[FTps<T, N>::getSize(nh)];
779  max_nh = nh;
780  }
781  T *t1 = t + 1;
782 
783  // Initialisations.
784  // Array element fp[k][m] points to the next order m monomial
785  // to transform in k-th component.
786  const T *fp[N][nh+1];
787  T *g[N];
788  for(int k = N; k-- > 0;) {
789  for(int m = nl; m <= nh; ++m) fp[k][m] = f[k].begin(m);
790  g[k] = result[k].begin();
791  }
792  const Array1D<int> *oldvrbl = 0;
793  int start_nh = FTps<T, N>::orderStart(nh), end_nh = FTps<T, N>::orderEnd(nh);
794  int nh1 = nh - 1, nh2 = nh - 2;
795 
796  // Loop over order nh monomials; construct lower orders along the way.
797  for(int j = start_nh; j < end_nh; ++j) {
798  // Get current monomial's variable list; compare with old variable list.
799  const Array1D<int> *vrbl = &FTpsData<N>::getVariableList(j);
800  int vk = 0;
801  if(oldvrbl)
802  while((*vrbl)[vk] == (*oldvrbl)[vk]) ++vk;
803 
804  // Determine which monomial pointers we shall need to increment.
805  int jl = (*vrbl)[nh1], ni = nh2;
806  while(ni >= 0 && (*vrbl)[ni] == jl) --ni;
807  ni += 2;
808  ni = std::max(ni, nl);
809  // Determine which monomials contribute this round.
810  int n1 = std::max(nl, ni), n2 = nh;
811  while(n1 <= n2) {
812  bool zeroQ = true;
813  for(int k = N; k-- > 0;) {
814  if(*fp[k][n1] != T(0)) {
815  zeroQ = false;
816  break;
817  }
818  }
819  if(zeroQ) ++n1;
820  else break;
821  }
822  while(n2 > n1) {
823  bool zeroQ = true;
824  for(int k = N; k-- > 0;) {
825  if(*fp[k][n2] != T(0)) {
826  zeroQ = false;
827  break;
828  }
829  }
830  if(zeroQ) --n2;
831  else break;
832  }
833  // Skip if all monomials have coefficient zero.
834  if(n1 > n2) {
835  for(int k = N; k-- > 0;)
836  for(int m = ni; m <= nh; ++m) ++fp[k][m];
837  continue;
838  }
839 
840  const T *mv;
841  int ord;
842  // If vk = 0, we must start at the beginning; otherwise,
843  // we may keep the first vk orders stored in t.
844  if(vk == 0) {
845  mv = mat[(*vrbl)[0]];
846  std::copy(mv, mv + N, t1);
847  ord = 2;
848  } else ord = vk + 1;
849 
850  // In working array t, clear orders we can't use.
851  std::fill(t + FTps<T, N>::orderStart(ord), t + end_nh, T(0));
852 
853  // Build the remainder.
854  while(ord <= nh) {
855  // Build next order part of transformed monomial by multiplying
856  // the part that is one order lower by the transformed version
857  // of the next variable in the variable list.
858  int ord1 = ord - 1;
859  int start_l = FTps<T, N>::orderStart(ord1), end_l = FTps<T, N>::orderEnd(ord1);
860  mv = mat[(*vrbl)[ord1]]; // transformed version of next variable
861  for(int k = 0; k < N; k++) {
862  T mvk = mv[k];
863  if(mvk == T(0)) continue;
865  for(int l = start_l; l < end_l; ++l) t[prod[l]] += mvk * t[l];
866  }
867  ++ord;
868  }
869  // Increment g[k] by f[k][j] * transformed monomial.
870  // and increment pointers in fp[][].
871  for(int k = N; k-- > 0;) {
872  for(int m = n1; m <= n2; ++m) {
873  const T fkj = *fp[k][m];
874  int start_m = FTps<T, N>::orderStart(m), end_m = FTps<T, N>::orderEnd(m);
875  for(int i = start_m; i < end_m; i++) g[k][i] += fkj * t[i];
876  }
877  for(int m = ni; m <= nh; ++m) ++fp[k][m];
878  }
879 
880  // Save variable list for comparison with the next one.
881  oldvrbl = vrbl;
882  }
883 
884  return result;
885 }
886 
887 
888 template <class T, int N>
890  return substitute(mat, getMinOrder(), getMaxOrder());
891 }
892 
893 
894 template <class T, int N>
895 FVps<T, N> FVps<T, N>::substitute(const FVps<T, N> &rhs, int trunc) const {
896  // Default: trunc = FTps<T,N>::EXACT
897 
898  // Get orders; if necessary, make LHS have uniform min, max, and trc orders..
899  FVps<T, N> f = *this;
900  int f_min = getMinOrder(), f_max = getMaxOrder(), f_trc = getTruncOrder();
901  Array1D<int> orders = getSubstOrders(rhs, trunc);
902  int g_min = orders[0], g_max = orders[1], g_trc = orders[2];
903  for(int k = N; k-- > 0;) {
904  if(f[k].getMinOrder() != f_min) f[k].setMinOrder(f_min);
905  if(f[k].getMaxOrder() != f_max) f[k].setMaxOrder(f_max);
906  if(f[k].getTruncOrder() != f_trc) f[k].setTruncOrder(f_trc);
907  }
908 
909  // Make sure we don't trip over globalTruncOrder.
910  if(g_trc != FTps<T, N>::EXACT && g_trc > FTps<T, N>::getGlobalTruncOrder())
911  throw LogicalError("FVps::substitute(FVps rhs, int trunc)",
912  "Truncation order exceeds globalTruncOrder!");
913 
914  // Return trivial case.
915  if(g_min > g_max) return FVps<T, N>(g_trc, g_trc, g_trc);
916 
917  //Allocate result.
918  FVps<T, N> result(g_min, g_max, g_trc);
919  if(f_min == 0)
920  for(int k = N; k-- > 0;) result[k][0] = *f[k].begin();
921  if(f_max == 0) return result;
922 
923  // Set actual range of orders to transform
924  int nl = f_min, nh = f_max;
925  if(nl == 0) nl = 1;
926 
927  // Allocate working arrays.
928  const T *fp[N][nh+1];
929  Array1D< FTps<T, N> > t(nh + 1);
930 
931  // Initialisations.
932  // Array element fp[k][m] points to the next order m monomial
933  // to transform in the k-th component.
934  for(int k = N; k-- > 0;)
935  for(int m = nl; m <= nh; ++m) fp[k][m] = f[k].begin(m);
936  const Array1D<int> *oldvrbl = 0;
937  int start_nh = FTps<T, N>::orderStart(nh), end_nh = FTps<T, N>::orderEnd(nh);
938  int nh1 = nh - 1, nh2 = nh - 2;
939 
940  // Loop over order nh monomials; construct lower orders along the way.
941  for(int j = start_nh; j < end_nh; ++j) {
942  // Get current monomial's variable list; compare with old variable list.
943  const Array1D<int> *vrbl = &FTpsData<N>::getVariableList(j);
944  int vk = 0;
945  if(oldvrbl)
946  while((*vrbl)[vk] == (*oldvrbl)[vk]) ++vk;
947 
948  // Determine which monomial pointers we shall need to increment.
949  int jl = (*vrbl)[nh1], ni = nh2;
950  while(ni >= 0 && (*vrbl)[ni] == jl) --ni;
951  ni += 2;
952  ni = std::max(ni, nl);
953  // Determine which monomials contribute this round.
954  int n1 = std::max(nl, ni), n2 = nh;
955  while(n1 <= n2) {
956  bool zeroQ = true;
957  for(int k = N; k-- > 0;) {
958  if(*fp[k][n1] != T(0)) {
959  zeroQ = false;
960  break;
961  }
962  }
963  if(zeroQ) ++n1;
964  else break;
965  }
966  while(n2 > n1) {
967  bool zeroQ = true;
968  for(int k = N; k-- > 0;) {
969  if(*fp[k][n2] != T(0)) {
970  zeroQ = false;
971  break;
972  }
973  }
974  if(zeroQ) --n2;
975  else break;
976  }
977  // Skip if all monomials have coefficient zero.
978  if(n1 > n2) {
979  for(int k = N; k-- > 0;)
980  for(int m = ni; m <= nh; ++m) ++fp[k][m];
981  continue;
982  }
983 
984  // If vk = 0, we must start at the beginning; otherwise,
985  // we may keep the first vk orders stored in t.
986  int ord;
987  if(vk == 0) {
988  t[1] = rhs[(*vrbl)[0]];
989  ord = 2;
990  } else ord = vk + 1;
991 
992  // Build the remainder.
993  while(ord <= nh) {
994  // Build next order part of transformed monomial by multiplying
995  // the part that is one order lower by the transformed version
996  // of the next variable in the variable list.
997  int ord1 = ord - 1;
998  t[ord] = t[ord1].multiply(rhs[(*vrbl)[ord1]], g_trc);
999  ++ord;
1000  }
1001 
1002  // Increment result by f[k][j] * transformed monomial,
1003  // and increment pointers in fp[].
1004  for(int k = N; k-- > 0;) {
1005  const T **fpk = fp[k];
1006  for(int m = n1; m <= n2; ++m) result[k] += *fpk[m] * t[m];
1007  for(int m = ni; m <= nh; ++m) ++fpk[m];
1008  //for (int m = n1; m <= n2; ++m) result[k] += *fpk[m] * t[m];
1009  //for (int m = ni; m <= nh; ++m) ++fpk[m];
1010  }
1011 
1012  // Save variable list for comparison with the next one.
1013  oldvrbl = vrbl;
1014  }
1015 
1016  return result;
1017 }
1018 
1019 
1020 template <class T, int N>
1023 
1024  for(int i = 0; i < N; ++i) {
1025  FTps<T, N> sum = lhs(i, 0) * data[0];
1026  for(int j = 1; j < N; ++j) sum += lhs(i, j) * data[j];
1027  result[i] = sum;
1028  }
1029 
1030  return result;
1031 }
1032 
1033 template <class T, int N>
1035 
1036  // function does not handle negative powers
1037  if ( std::any_of(power.begin(), power.end(), [&](int p) { return p < 0; }) )
1038  throw LogicalError("FVps<T,N>::getFTps(power)", "Negative power.");
1039 
1040  // initial Tps
1041  FTps<T, N> result = 1.0;
1042 
1043  // go through variables and multiply its power to "result"
1044  for (int i = 0; i < N; ++i) {
1045  // get polynomial
1046  FTps<T, N> rhs = getComponent(i);
1047 
1048  // multiply polynomials
1049  for (int j = 0; j < power[i]; ++j)
1050  result = result.multiply(rhs, FTps<T, N>::getGlobalTruncOrder()); // make sure that no global trunc exceeding
1051  }
1052 
1053  return result;/*.truncate(FTps<T, N>::getGlobalTruncOrder());*/
1054 }
1055 
1056 template <class T, int N>
1057 std::istream &FVps<T, N>::get(std::istream &is) {
1058  is.flags(std::ios::skipws);
1059  char head[4];
1060  (is >> std::ws).get(head, 4);
1061 
1062  if(strcmp(head, "FVps") != 0)
1063  throw FormatError("FVps::get()", "Flag word \"FVps\" missing.");
1064 
1065  int nDim;
1066  is >> nDim;
1067  if(nDim != N) throw FormatError("FVps::get()", "Invalid FVps dimension");
1068 
1069  // Read into temporary for exception safety.
1071  for(int i = 0; i < N; i++) is >> result.data[i];
1072  *this = result;
1073  return is;
1074 }
1075 
1076 
1077 template <class T, int N>
1078 std::ostream &FVps<T, N>::put(std::ostream &os) const {
1079  os << "FVps " << N << std::endl;
1080  for(int i = 0; i < N; i++) os << data[i];
1081  return os;
1082 }
1083 
1084 
1085 // Global Operators on FVps<T,N>
1086 // ------------------------------------------------------------------------
1087 
1088 template <class T, int N>
1089 FVps<T, N> operator+(const FVps<T, N> &lhs, const FVps<T, N> &rhs) {
1091  for(int i = 0; i < N; ++i) result[i] = lhs[i] + rhs[i];
1092  return result;
1093 }
1094 
1095 
1096 template <class T, int N>
1097 FVps<T, N> operator-(const FVps<T, N> &lhs, const FVps<T, N> &rhs) {
1099  for(int i = 0; i < N; ++i) result[i] = lhs[i] - rhs[i];
1100  return result;
1101 }
1102 
1103 
1104 template <class T, int N>
1107  for(int i = 0; i < N; ++i) result[i] = lhs[i] + rhs[i];
1108  return result;
1109 }
1110 
1111 
1112 template <class T, int N>
1115  for(int i = 0; i < N; ++i) result[i] = lhs[i] - rhs[i];
1116  return result;
1117 }
1118 
1119 
1120 template <class T, int N>
1123  for(int i = 0; i < N; ++i) result[i] = lhs[i] + rhs[i];
1124  return result;
1125 }
1126 
1127 
1128 template <class T, int N>
1131  for(int i = 0; i < N; ++i) result[i] = lhs[i] - rhs[i];
1132  return result;
1133 }
1134 
1135 
1136 template <class T, int N>
1139  for (int i = 0; i < N; ++i) {
1140  FTps<T, N> tps = lhs.getComponent(i);
1141  result[i] = tps.evaluate(rhs);
1142  }
1143  return result;
1144 }
1145 
1146 
1147 template <class T, int N>
1148 FVps<T, N> operator*(const FVps<T, N> &lhs, const FTps<T, N> &rhs) {
1150  for(int i = 0; i < N; ++i) result[i] = lhs[i] * rhs;
1151  return result;
1152 }
1153 
1154 
1155 template <class T, int N>
1156 FVps<T, N> operator*(const FTps<T, N> &lhs, const FVps<T, N> &rhs) {
1158  for(int i = 0; i < N; ++i) result[i] = lhs * rhs[i];
1159  return result;
1160 }
1161 
1162 
1163 template <class T, int N>
1164 FVps<T, N> operator*(const FVps<T, N> &lhs, const T &rhs) {
1166  for(int i = 0; i < N; ++i) result[i] = lhs[i] * rhs;
1167  return result;
1168 }
1169 
1170 
1171 template <class T, int N>
1172 FVps<T, N> operator*(const T &lhs, const FVps<T, N> &rhs) {
1174  for(int i = 0; i < N; ++i) result[i] = lhs * rhs[i];
1175  return result;
1176 }
1177 
1178 template <class T, int N>
1180  return rhs.substituteInto(lhs);
1181 }
1182 
1183 
1184 template <class T, int N>
1185 FVps<T, N> operator/(const FVps<T, N> &lhs, const FTps<T, N> &rhs) {
1187  for(int i = 0; i < N; ++i) result[i] = lhs[i] / rhs;
1188  return result;
1189 }
1190 
1191 
1192 template <class T, int N>
1193 FVps<T, N> operator/(const FVps<T, N> &lhs, const T &rhs) {
1195  for(int i = 0; i < N; ++i) result[i] = lhs[i] / rhs;
1196  return result;
1197 }
1198 
1199 
1200 template <class T, int N> FVps<T, N>
1201 ExpMap(const FTps<T, N> &H, const FVps<T, N> &map, int trunc) {
1202  //std::cerr << "==> In ExpMap(H,map,trunc)" << std::endl;
1203  // Default: trunc = FTps<T,N>::EXACT
1204 
1205  // Limit number of iterations.
1206  const int MAX_ITER = 400;
1207 
1208  // We really ought to throw an exception if H contains linear terms and is not exact,
1209  // but we're just going to complain!!
1210  bool FD = false;
1211  if(H.getTruncOrder() != FTps<T, N>::EXACT && H.getMinOrder() < 2) {
1212  FD = true;
1213 #ifdef DEBUG_FVps_CC
1214  std::cerr << " <*** WARNING ***> from ExpMap(H,map,trunc):\n"
1215  << " Incomplete computation of feed-down terms.\n" << std::endl;
1216 #endif
1217  }
1218  int fd_trc = std::min(H.getTruncOrder() - 1, map.getTruncOrder());
1219 
1220  // Construct dH = grad(H).J, s.t. :H:f = dH.grad(f).
1221  FVps<T, N> dH;
1222  for(int i = 0; i < N; i += 2) {
1223  dH[i] = - H.derivative(i + 1);
1224  dH[i+1] = H.derivative(i);
1225  }
1226 
1227  // Allocate result.
1228  FVps<T, N> expHmap;
1229 
1230  // Apply exp(:H:) to each component of map.
1231  for(int var = 0; var < N; var++) {
1232  // Initialize variables.
1233  FTps<T, N> expHf = map[var];
1234  FTps<T, N> dHkf = map[var];
1235  FTps<T, N> old = T(0);
1236  // Compute series; quit loop if we added nothing last time through.
1237  for(int k = 1; expHf != old; ++k) {
1238  if(k > MAX_ITER) {
1239  std::cerr << " present error:\n" << expHf - old << std::endl;
1240  throw ConvergenceError("ExpMap(const FTps<T,N> &H, const FVps<T,N> &map)",
1241  "No convergence in ExpMap(H,map)");
1242  }
1243  // Don't initialize dHk1f to 0, as that sets minOrder to 0!
1244  old = expHf;
1245  FTps<T, N> ddHkf = dHkf.derivative(0);
1246  if(FD) ddHkf.setTruncOrder(fd_trc);
1247  FTps<T, N> dHk1f = dH[0].multiply(ddHkf, trunc);
1248  for(int v = 1; v < N; ++v) {
1249  FTps<T, N> ddHkf = dHkf.derivative(v);
1250  if(FD) ddHkf.setTruncOrder(fd_trc);
1251  dHk1f += dH[v].multiply(ddHkf, trunc);
1252  //dHk1f += dH[v].multiply(dHkf.derivative(v),trunc);
1253  }
1254  dHkf = dHk1f / T(k); // :H:^{k}/(k!)
1255  expHf += dHkf;
1256  }
1257  expHmap[var] = expHf;
1258  }
1259 
1260  //std::cerr << "==> Leaving ExpMap(H,map,trunc)" << std::endl;
1261  return expHmap;
1262 }
1263 
1264 
1265 template <class T, int N> FVps<T, N>
1266 PoissonBracket(const FTps<T, N> &x, const FVps<T, N> &y, int trunc) {
1267  FVps<T, N> z;
1268  for(int v = 0; v < N; ++v)
1269  z[v] = PoissonBracket(x, y[v], trunc);
1270  return z;
1271 }
1272 
1273 
1274 template <class T, int N>
1275 std::istream &operator>>(std::istream &is, FVps<T, N> &vps) {
1276  return vps.get(is);
1277 }
1278 
1279 
1280 template <class T, int N>
1281 std::ostream &operator<<(std::ostream &os, const FVps<T, N> &vps) {
1282  return vps.put(os);
1283 }
1284 
1285 #endif // CLASSIC_FVps_CC
A templated representation for vectors.
Definition: FTps.h:34
Singular matrix exception.
~FVps()
Definition: FVps.hpp:99
T evaluate(const FVector< T, N > &) const
Evaluate FTps at point.
Definition: FTps.hpp:934
void setMinOrder(int order)
Set minimum order.
Definition: FVps.hpp:175
Linear map with values of type [b]T[/b] in [b]N[/b] variables.
Definition: FVps.h:30
and give any other recipients of the Program a copy of this License along with the Program You may charge a fee for the physical act of transferring a copy
Definition: LICENSE:87
FVps inverse(int trunc=(FTps< T, N >::EXACT)) const
Inverse.
Definition: FVps.hpp:360
void setComponent(int, const FTps< T, N > &)
Set component.
Definition: FVps.hpp:132
int getVariables() const
Get number of variables.
Definition: FVps.hpp:159
FVps operator*(const FVps< T, N > &rhs) const
Multiply.
Definition: FVps.hpp:288
and that you know you can do these things To protect your we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights These restrictions translate to certain responsibilities for you if you distribute copies of the or if you modify it For if you distribute copies of such a whether gratis or for a you must give the recipients all the rights that you have You must make sure that receive or can get the source code And you must show them these terms so they know their rights We protect your rights with two distribute and or modify the software for each author s protection and we want to make certain that everyone understands that there is no warranty for this free software If the software is modified by someone else and passed we want its recipients to know that what they have is not the so that any problems introduced by others will not reflect on the original authors reputations any free program is threatened constantly by software patents We wish to avoid the danger that redistributors of a free program will individually obtain patent in effect making the program proprietary To prevent we have made it clear that any patent must be licensed for everyone s free use or not licensed at all The precise terms and conditions for distribution and modification follow GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR DISTRIBUTION AND MODIFICATION This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License The refers to any such program or and a work based on the Program means either the Program or any derivative work under copyright a work containing the Program or a portion of it
Definition: LICENSE:43
FVps truncate(int trunc)
Truncate.
Definition: FVps.hpp:234
Array1D< int > getSubstOrders(const FVps< T, N > &rhs, int trunc=EXACT) const
Return orders {min, max, trc} of f(rhs(z)).
Definition: FTps.hpp:1008
void setTruncOrder(int order)
Set truncation order.
Definition: FTps.hpp:393
Truncated power series in N variables of type T.
Definition: FLieGenerator.h:29
FVps operator-() const
Unary minus.
Definition: FVps.hpp:246
const FVps & operator=(const FVps &)
Definition: FVps.hpp:104
FVps filter(int minOrder, int maxOrder, int trcOrder=(FTps< T, N >::EXACT)) const
Extract given range of orders, with truncation.
Definition: FVps.hpp:223
Matrix< T > operator-(const Matrix< T > &, const Matrix< T > &)
Matrix subtraction.
Definition: Matrix.h:283
FVps & operator*=(const FTps< T, N > &rhs)
Multiply and assign.
Definition: FVps.hpp:282
const FTps< T, N > & operator[](int) const
Get Component.
Definition: FVps.hpp:141
T * begin() const
Return beginning of monomial array.
Definition: FTps.h:118
FVps & operator-=(const FVps &rhs)
Subtract and assign.
Definition: FVps.hpp:261
FTps multiply(const FTps &y, int trunc=EXACT) const
Multiplication.
Definition: FTps.hpp:650
static int getGlobalTruncOrder()
Return the global truncation order.
Definition: FTps.h:191
std::list< int > getListOfNonzeroCoefficients() const
Get a list containing the indexes of non-zero coefficients of a FTps.
Definition: FTps.hpp:1515
A templated representation of a LU-decomposition.
Definition: FLUMatrix.h:42
const T getCoefficient(int index) const
Get coefficient.
Definition: FTps.hpp:223
Matrix< T > operator*(const Matrix< T > &, const Matrix< T > &)
Matrix multiply.
Definition: Matrix.h:298
int getTruncOrder() const
Get truncation order.
Definition: FTps.h:183
clearpage the user may choose between constant or variable radius This model includes fringe fields begin
Definition: multipole_t.tex:6
static Array1D< T > evalMonoms(const FVector< T, N > &, int)
Evaluate monomials at point.
Definition: FTps.hpp:898
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
Transport map with values of type [b]T[/b] in [b]N[/b] variables.
Definition: FVps.h:31
FTps inverse(int trunc=EXACT) const
Reciprocal, 1/(*this).
Definition: FTps.hpp:707
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:76
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:84
Domain error exception.
Definition: DomainError.h:32
static int orderStart(int order)
Get index at which [b]order[/b] starts.
Definition: FTps.h:143
FVps integral(int var) const
Partial integral.
Definition: FVps.hpp:532
std::string::iterator iterator
Definition: MSLang.h:15
FVps derivative(int var) const
Partial derivative.
Definition: FVps.hpp:524
Format error exception.
Definition: FormatError.h:32
int getMaxOrder() const
Get highest order contained in any component.
Definition: FVps.hpp:181
void setMinOrder(int order)
Set minimum order.
Definition: FTps.hpp:321
Convergence error exception.
FVps substitute(const FMatrix< T, N, N > &M, int n) const
Substitute.
Definition: FVps.hpp:608
FVps< T, N > ExpMap(const FTps< T, N > &H, int trunc=FTps< T, N >::EXACT)
Build the exponential series.
Definition: FTps.hpp:1994
T::PETE_Expr_t::PETE_Return_t sum(const PETE_Expr< T > &expr)
Definition: PETE.h:1111
int getMinOrder() const
Get minimum order.
Definition: FTps.h:165
static int getSize(int order)
Definition: FTpsData.h:187
int getMinOrder() const
Get lowest order contained in any component.
Definition: FVps.hpp:165
T::PETE_Expr_t::PETE_Return_t prod(const PETE_Expr< T > &expr)
Definition: PETE.h:1121
FVps & operator+=(const FVps &rhs)
Add and assign.
Definition: FVps.hpp:254
iterator begin()
Get beginning of data.
Definition: Array1D.h:204
iterator end()
Get iterator pointing past end of array.
Definition: FArray1D.h:198
Matrix< T > operator+(const Matrix< T > &, const Matrix< T > &)
Matrix addition.
Definition: Matrix.h:276
FTps< T, N > makePower(int power) const
Multiply FTps with itself.
Definition: FTps.hpp:1555
FMatrix< T, N, N > linearTerms() const
Extract the linear part of the map.
Definition: FVps.hpp:561
Array1D< int > getSubstOrders(const FVps< T, N > &rhs, int trunc=(FTps< T, N >::EXACT)) const
Return orders {min, max, trc} of f(rhs(z)).
Definition: FVps.hpp:594
int getSize() const
Get total number of coefficients.
Definition: FTps.h:136
FVps operator+() const
Unary plus.
Definition: FVps.hpp:240
FTps< T, N > data[N]
Definition: FVps.h:247
void setTruncOrder(int order)
Set truncation order for all components.
Definition: FVps.hpp:217
Vector truncated power series in n variables.
Definition: Component.h:34
const FTps< T, N > & getComponent(int n) const
Get component.
Definition: FVps.hpp:123
int getTopOrder() const
Get highest order contained in any component.
Definition: FVps.hpp:197
FVps myInverse(int trunc=(FTps< T, N >::EXACT)) const
Inverse.
Definition: FVps.hpp:441
FMatrix< T, N, N > inverse() const
Get inverse.
Definition: FLUMatrix.h:236
void zero()
Set to zero.
Definition: FVps.hpp:117
float result
Definition: test.py:2
FTps derivative(int var) const
Partial derivative.
Definition: FTps.hpp:1396
One-dimensional array.
Definition: Array1D.h:36
static const Array1D< int > & getVariableList(int index)
Definition: FTpsData.h:244
std::istream & get(std::istream &is)
Get a FVps from stream [b]is[/b].
Definition: FVps.hpp:1057
int getTruncOrder() const
Get lowest truncation order in any component.
Definition: FVps.hpp:207
FArray1D< int, N > extractExponents(int index) const
Extract exponents of coefficient.
Definition: FTps.hpp:1535
b mention the algorithm in the References section The appropriate citation is
Definition: README.TXT:103
FVps()
Definition: FVps.hpp:46
FVps & operator/=(const FTps< T, N > &rhs)
Divide and assign.
Definition: FVps.hpp:338
FLieGenerator< T, N > PoissonBracket(const FLieGenerator< T, N > &, const FLieGenerator< T, N > &)
Poisson bracket of two Lie generators.
int getMaxOrder() const
Get maximum order.
Definition: FTps.h:174
std::istream & operator>>(std::istream &, Tps< T > &x)
Extract from stream.
Definition: Tps.h:376
void identity()
Set to identity.
Definition: FVps.hpp:111
int getDimension() const
Get dimension.
Definition: FVps.hpp:153
static int orderEnd(int order)
Get one plus index at which [b]order[/b] ends.
Definition: FTps.h:147
void setMaxOrder(int order)
Set maximum order.
Definition: FVps.hpp:191
Logical error exception.
Definition: LogicalError.h:33
Matrix< T > operator/(const Matrix< T > &, const T &)
Matrix divided by scalar.
Definition: Matrix.h:330
Range error.
Definition: CLRangeError.h:33
FVector< T, N > constantTerm() const
Extract the constant part of the map.
Definition: FVps.hpp:540
FTps< T, N > getFTps(const FArray1D< int, N > &power) const
Get a FTps that is a combination of the polynomials of FVps.
Definition: FVps.hpp:1034
static const Array1D< int > & getProductArray(int index)
Definition: FTpsData.h:237
end
Definition: multipole_t.tex:9
FVps substituteInto(const FMatrix< T, N, N > &lhs) const
Substitute map into matrix.
Definition: FVps.hpp:1021
iterator begin()
Get iterator pointing to beginning of array.
Definition: FArray1D.h:192
std::ostream & put(std::ostream &os) const
Put a FVps to stream [b]os[/b].
Definition: FVps.hpp:1078