OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
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 
226  FVps<T, N> result;
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>
247  FVps<T, N> result;
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>
289  FVps<T, N> result;
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>
525  FVps<T, N> result;
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>
533  FVps<T, N> result;
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>
541  FVector<T, N> result;
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.
553  FVector<T, N> result;
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>
562  FMatrix<T, N, N> result;
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 
577  FMatrix<T, N, N> result;
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>
1022  FVps<T, N> result;
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.
1070  FVps<T, N> result;
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) {
1090  FVps<T, N> result;
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) {
1098  FVps<T, N> result;
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>
1106  FVps<T, N> result;
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>
1114  FVps<T, N> result;
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>
1122  FVps<T, N> result;
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>
1130  FVps<T, N> result;
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>
1138  FVector<T, N> result;
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) {
1149  FVps<T, N> result;
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) {
1157  FVps<T, N> result;
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) {
1165  FVps<T, N> result;
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) {
1173  FVps<T, N> result;
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) {
1186  FVps<T, N> result;
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) {
1194  FVps<T, N> result;
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
static const Array1D< int > & getProductArray(int index)
Definition: FTpsData.h:239
Matrix< T > operator+(const Matrix< T > &, const Matrix< T > &)
Matrix addition.
Definition: Matrix.h:275
FVps operator*(const FVps< T, N > &rhs) const
Multiply.
Definition: FVps.hpp:288
FVps truncate(int trunc)
Truncate.
Definition: FVps.hpp:234
const FVps & operator=(const FVps &)
Definition: FVps.hpp:104
Matrix< T > operator/(const Matrix< T > &, const T &)
Matrix divided by scalar.
Definition: Matrix.h:329
FVps()
Definition: FVps.hpp:46
int getTopOrder() const
Get highest order contained in any component.
Definition: FVps.hpp:197
void identity()
Set to identity.
Definition: FVps.hpp:111
void setMinOrder(int order)
Set minimum order.
Definition: FTps.hpp:321
FVps derivative(int var) const
Partial derivative.
Definition: FVps.hpp:524
int getMaxOrder() const
Get maximum order.
Definition: FTps.h:174
Definition: rbendmap.h:8
Transport map with values of type [b]T[/b] in [b]N[/b] variables.
Definition: Mapper.h:33
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
A templated representation for vectors.
Definition: PartBunchBase.h:26
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:123
int getMinOrder() const
Get minimum order.
Definition: FTps.h:165
const FTps< T, N > & operator[](int) const
Get Component.
Definition: FVps.hpp:141
FVps myInverse(int trunc=(FTps< T, N >::EXACT)) const
Inverse.
Definition: FVps.hpp:441
Matrix< T > operator*(const Matrix< T > &, const Matrix< T > &)
Matrix multiply.
Definition: Matrix.h:297
FVps & operator*=(const FTps< T, N > &rhs)
Multiply and assign.
Definition: FVps.hpp:282
std::ostream & put(std::ostream &os) const
Put a FVps to stream [b]os[/b].
Definition: FVps.hpp:1078
static const Array1D< int > & getVariableList(int index)
Definition: FTpsData.h:246
const FTps< T, N > & getComponent(int n) const
Get component.
Definition: FVps.hpp:123
iterator begin()
Get iterator pointing to beginning of array.
Definition: FArray1D.h:192
FTps< T, N > makePower(int power) const
Multiply FTps with itself.
Definition: FTps.hpp:1555
std::list< int > getListOfNonzeroCoefficients() const
Get a list containing the indexes of non-zero coefficients of a FTps.
Definition: FTps.hpp:1515
FTps< T, N > data[N]
Definition: FVps.h:247
T::PETE_Expr_t::PETE_Return_t sum(const PETE_Expr< T > &expr)
Definition: PETE.h:1213
FVps substituteInto(const FMatrix< T, N, N > &lhs) const
Substitute map into matrix.
Definition: FVps.hpp:1021
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
FVps & operator/=(const FTps< T, N > &rhs)
Divide and assign.
Definition: FVps.hpp:338
Singular matrix exception.
void setTruncOrder(int order)
Set truncation order for all components.
Definition: FVps.hpp:217
void setMaxOrder(int order)
Set maximum order.
Definition: FVps.hpp:191
FVps integral(int var) const
Partial integral.
Definition: FVps.hpp:532
FTps multiply(const FTps &y, int trunc=EXACT) const
Multiplication.
Definition: FTps.hpp:650
static int orderStart(int order)
Get index at which [b]order[/b] starts.
Definition: FTps.h:143
static int getSize(int order)
Definition: FTpsData.h:189
Tps< T > PoissonBracket(const Tps< T > &x, const Tps< T > &y)
Poisson bracket.
Definition: LieMap.h:154
int getTruncOrder() const
Get lowest truncation order in any component.
Definition: FVps.hpp:207
A templated representation of a LU-decomposition.
Definition: FLUMatrix.h:42
iterator begin()
Get beginning of data.
Definition: Array1D.h:204
FVector< T, N > constantTerm() const
Extract the constant part of the map.
Definition: FVps.hpp:540
int getSize() const
Get total number of coefficients.
Definition: FTps.h:136
Linear map with values of type [b]T[/b] in [b]N[/b] variables.
~FVps()
Definition: FVps.hpp:99
Convergence error exception.
FVps inverse(int trunc=(FTps< T, N >::EXACT)) const
Inverse.
Definition: FVps.hpp:360
iterator end()
Get iterator pointing past end of array.
Definition: FArray1D.h:198
FVps< T, N > ExpMap(const FTps< T, N > &H, int trunc=FTps< T, N >::EXACT)
Build the exponential series.
Definition: FTps.hpp:1994
const T getCoefficient(int index) const
Get coefficient.
Definition: FTps.hpp:223
int getTruncOrder() const
Get truncation order.
Definition: FTps.h:183
static Array1D< T > evalMonoms(const FVector< T, N > &, int)
Evaluate monomials at point.
Definition: FTps.hpp:898
FVps filter(int minOrder, int maxOrder, int trcOrder=(FTps< T, N >::EXACT)) const
Extract given range of orders, with truncation.
Definition: FVps.hpp:223
T evaluate(const FVector< T, N > &) const
Evaluate FTps at point.
Definition: FTps.hpp:934
FMatrix< T, N, N > linearTerms() const
Extract the linear part of the map.
Definition: FVps.hpp:561
FArray1D< int, N > extractExponents(int index) const
Extract exponents of coefficient.
Definition: FTps.hpp:1535
FTps derivative(int var) const
Partial derivative.
Definition: FTps.hpp:1396
int getVariables() const
Get number of variables.
Definition: FVps.hpp:159
static int getGlobalTruncOrder()
Return the global truncation order.
Definition: FTps.h:191
int getMaxOrder() const
Get highest order contained in any component.
Definition: FVps.hpp:181
Domain error exception.
Definition: DomainError.h:32
FTps inverse(int trunc=EXACT) const
Reciprocal, 1/(*this).
Definition: FTps.hpp:707
FVps operator-() const
Unary minus.
Definition: FVps.hpp:246
Range error.
Definition: CLRangeError.h:33
void zero()
Set to zero.
Definition: FVps.hpp:117
int getDimension() const
Get dimension.
Definition: FVps.hpp:153
void setMinOrder(int order)
Set minimum order.
Definition: FVps.hpp:175
T::PETE_Expr_t::PETE_Return_t prod(const PETE_Expr< T > &expr)
Definition: PETE.h:1243
std::istream & get(std::istream &is)
Get a FVps from stream [b]is[/b].
Definition: FVps.hpp:1057
FMatrix< T, N, N > inverse() const
Get inverse.
Definition: FLUMatrix.h:236
Format error exception.
Definition: FormatError.h:32
const double ke
One-dimensional array.
Definition: Array1D.h:36
static int orderEnd(int order)
Get one plus index at which [b]order[/b] ends.
Definition: FTps.h:147
FVps & operator+=(const FVps &rhs)
Add and assign.
Definition: FVps.hpp:254
void setTruncOrder(int order)
Set truncation order.
Definition: FTps.hpp:393
std::string::iterator iterator
Definition: MSLang.h:16
Truncated power series in N variables of type T.
Matrix< T > operator-(const Matrix< T > &, const Matrix< T > &)
Matrix subtraction.
Definition: Matrix.h:282
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
FVps substitute(const FMatrix< T, N, N > &M, int n) const
Substitute.
Definition: FVps.hpp:608
FVps operator+() const
Unary plus.
Definition: FVps.hpp:240
int getMinOrder() const
Get lowest order contained in any component.
Definition: FVps.hpp:165
Logical error exception.
Definition: LogicalError.h:33
void setComponent(int, const FTps< T, N > &)
Set component.
Definition: FVps.hpp:132
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:95
Vector truncated power series in n variables.
std::istream & operator>>(std::istream &, LieMap< T > &x)
Extract LieMap&lt;T&gt; from stream.
Definition: LieMap.h:231
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
FVps & operator-=(const FVps &rhs)
Subtract and assign.
Definition: FVps.hpp:261
T * begin() const
Return beginning of monomial array.
Definition: FTps.h:118