OPAL (Object Oriented Parallel Accelerator Library) 2024.2
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
28#include "FixedAlgebra/FTps.h"
38#include <iostream>
39#include <iterator>
40#include <list>
41
42// Template class FVps<T,N>
43// ------------------------------------------------------------------------
44
45template <class T, int N>
47 identity();
48}
49
50
51template <class T, int N>
53 for(int i = 0; i < N; ++i) data[i] = rhs.data[i];
54}
55
56
57template <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
67template <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
77template <class T, int N>
78FVps<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
84template <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
92template <class T, int N>
94 for(int i = 0; i < N; i++) data[i] = FTps<T, N>(x[i]);
95}
96
97
98template <class T, int N>
101
102
103template <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
110template <class T, int N>
112 for(int i = 0; i < N; ++i) data[i] = FTps<T, N>::makeVariable(i);
113}
114
115
116template <class T, int N>
118 for(int i = 0; i < N; ++i) data[i] = T(0);
119}
120
121
122template <class T, int N>
123const 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
131template <class T, int N>
132void 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
140template <class T, int N> inline
141const FTps<T, N> &FVps<T, N>::operator[](int index) const {
142 return data[index];
143}
144
145
146template <class T, int N> inline
148 return data[index];
149}
150
151
152template <class T, int N>
154 return N;
155}
156
157
158template <class T, int N>
160 return N;
161}
162
163
164template <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
174template <class T, int N>
175void FVps<T, N>::setMinOrder(int order) {
176 for(int i = 0; i < N; ++i) data[i].setMinOrder(order);
177}
178
179
180template <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
190template <class T, int N>
191void FVps<T, N>::setMaxOrder(int order) {
192 for(int i = 0; i < N; ++i) data[i].setMaxOrder(order);
193}
194
195
196template <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
206template <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
216template <class T, int N>
218 for(int i = 0; i < N; ++i) data[i].setTruncOrder(order);
219}
220
221
222template <class T, int N>
223FVps<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
233template <class T, int N>
235 return filter(0, trunc, trunc);
236}
237
238
239template <class T, int N>
241 return *this;
242}
243
244
245template <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
253template <class T, int N>
255 for(int i = 0; i < N; i++) data[i] += rhs[i];
256 return *this;
257}
258
259
260template <class T, int N>
262 for(int i = 0; i < N; i++) data[i] -= rhs[i];
263 return *this;
264}
265
266
267template <class T, int N>
269 for(int i = 0; i < N; i++) data[i] += rhs[i];
270 return *this;
271}
272
273
274template <class T, int N>
276 for(int i = 0; i < N; i++) data[i] -= rhs[i];
277 return *this;
278}
279
280
281template <class T, int N>
283 for(int i = 0; i < N; i++) data[i] *= rhs;
284 return *this;
285}
286
287template <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 */
326 r.setMinOrder(std::min(r.getMinOrder(), mono.getMinOrder()));
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
337template <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
345template <class T, int N>
347 for(int i = 0; i < N; i++) data[i] *= rhs;
348 return *this;
349}
350
351
352template <class T, int N>
354 for(int i = 0; i < N; i++) data[i] /= rhs;
355 return *this;
356}
357
358
359template <class T, int N>
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
440template <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
523template <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
531template <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
539template <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
550template <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
560template <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
569template <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
593template <class T, int N>
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
607template <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.");
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.
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
727template <class T, int N>
728FVps<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 std::vector<std::vector<const T*>> fp(N, std::vector<const T*>(nh+1));
787 std::vector<T*> g(N);
788 for(int k = N; k-- > 0;) {
789 for(int m = nl; m <= nh; ++m) {
790 fp[k][m] = f[k].begin(m);
791 }
792 g[k] = result[k].begin();
793 }
794 const Array1D<int> *oldvrbl = 0;
795 int start_nh = FTps<T, N>::orderStart(nh);
796 int end_nh = FTps<T, N>::orderEnd(nh);
797 int nh1 = nh - 1, nh2 = nh - 2;
798
799 // Loop over order nh monomials; construct lower orders along the way.
800 for(int j = start_nh; j < end_nh; ++j) {
801 // Get current monomial's variable list; compare with old variable list.
803 int vk = 0;
804 if(oldvrbl)
805 while((*vrbl)[vk] == (*oldvrbl)[vk]) ++vk;
806
807 // Determine which monomial pointers we shall need to increment.
808 int jl = (*vrbl)[nh1], ni = nh2;
809 while(ni >= 0 && (*vrbl)[ni] == jl) --ni;
810 ni += 2;
811 ni = std::max(ni, nl);
812 // Determine which monomials contribute this round.
813 int n1 = std::max(nl, ni), n2 = nh;
814 while(n1 <= n2) {
815 bool zeroQ = true;
816 for(int k = N; k-- > 0;) {
817 if(*fp[k][n1] != T(0)) {
818 zeroQ = false;
819 break;
820 }
821 }
822 if(zeroQ) ++n1;
823 else break;
824 }
825 while(n2 > n1) {
826 bool zeroQ = true;
827 for(int k = N; k-- > 0;) {
828 if(*fp[k][n2] != T(0)) {
829 zeroQ = false;
830 break;
831 }
832 }
833 if(zeroQ) --n2;
834 else break;
835 }
836 // Skip if all monomials have coefficient zero.
837 if(n1 > n2) {
838 for(int k = N; k-- > 0;)
839 for(int m = ni; m <= nh; ++m) ++fp[k][m];
840 continue;
841 }
842
843 const T *mv;
844 int ord;
845 // If vk = 0, we must start at the beginning; otherwise,
846 // we may keep the first vk orders stored in t.
847 if(vk == 0) {
848 mv = mat[(*vrbl)[0]];
849 std::copy(mv, mv + N, t1);
850 ord = 2;
851 } else ord = vk + 1;
852
853 // In working array t, clear orders we can't use.
854 std::fill(t + FTps<T, N>::orderStart(ord), t + end_nh, T(0));
855
856 // Build the remainder.
857 while(ord <= nh) {
858 // Build next order part of transformed monomial by multiplying
859 // the part that is one order lower by the transformed version
860 // of the next variable in the variable list.
861 int ord1 = ord - 1;
862 int start_l = FTps<T, N>::orderStart(ord1), end_l = FTps<T, N>::orderEnd(ord1);
863 mv = mat[(*vrbl)[ord1]]; // transformed version of next variable
864 for(int k = 0; k < N; k++) {
865 T mvk = mv[k];
866 if(mvk == T(0)) continue;
868 for(int l = start_l; l < end_l; ++l) t[prod[l]] += mvk * t[l];
869 }
870 ++ord;
871 }
872 // Increment g[k] by f[k][j] * transformed monomial.
873 // and increment pointers in fp[][].
874 for(int k = N; k-- > 0;) {
875 for(int m = n1; m <= n2; ++m) {
876 const T fkj = *fp[k][m];
877 int start_m = FTps<T, N>::orderStart(m), end_m = FTps<T, N>::orderEnd(m);
878 for(int i = start_m; i < end_m; i++) g[k][i] += fkj * t[i];
879 }
880 for(int m = ni; m <= nh; ++m) ++fp[k][m];
881 }
882
883 // Save variable list for comparison with the next one.
884 oldvrbl = vrbl;
885 }
886
887 return result;
888}
889
890
891template <class T, int N>
893 return substitute(mat, getMinOrder(), getMaxOrder());
894}
895
896
897template <class T, int N>
898FVps<T, N> FVps<T, N>::substitute(const FVps<T, N> &rhs, int trunc) const {
899 // Default: trunc = FTps<T,N>::EXACT
900
901 // Get orders; if necessary, make LHS have uniform min, max, and trc orders..
902 FVps<T, N> f = *this;
903 int f_min = getMinOrder(), f_max = getMaxOrder(), f_trc = getTruncOrder();
904 Array1D<int> orders = getSubstOrders(rhs, trunc);
905 int g_min = orders[0], g_max = orders[1], g_trc = orders[2];
906 for(int k = N; k-- > 0;) {
907 if(f[k].getMinOrder() != f_min) f[k].setMinOrder(f_min);
908 if(f[k].getMaxOrder() != f_max) f[k].setMaxOrder(f_max);
909 if(f[k].getTruncOrder() != f_trc) f[k].setTruncOrder(f_trc);
910 }
911
912 // Make sure we don't trip over globalTruncOrder.
913 if(g_trc != FTps<T, N>::EXACT && g_trc > FTps<T, N>::getGlobalTruncOrder())
914 throw LogicalError("FVps::substitute(FVps rhs, int trunc)",
915 "Truncation order exceeds globalTruncOrder!");
916
917 // Return trivial case.
918 if(g_min > g_max) return FVps<T, N>(g_trc, g_trc, g_trc);
919
920 //Allocate result.
921 FVps<T, N> result(g_min, g_max, g_trc);
922 if(f_min == 0)
923 for(int k = N; k-- > 0;) result[k][0] = *f[k].begin();
924 if(f_max == 0) return result;
925
926 // Set actual range of orders to transform
927 int nl = f_min, nh = f_max;
928 if(nl == 0) nl = 1;
929
930 // Allocate working arrays.
931 std::vector<std::vector<const T*>> fp(N, std::vector<const T*>(nh+1));
932 Array1D< FTps<T, N> > t(nh + 1);
933
934 // Initialisations.
935 // Array element fp[k][m] points to the next order m monomial
936 // to transform in the k-th component.
937 for(int k = N; k-- > 0;) {
938 for(int m = nl; m <= nh; ++m) {
939 fp[k][m] = f[k].begin(m);
940 }
941 }
942 const Array1D<int> *oldvrbl = 0;
943 int start_nh = FTps<T, N>::orderStart(nh), end_nh = FTps<T, N>::orderEnd(nh);
944 int nh1 = nh - 1, nh2 = nh - 2;
945
946 // Loop over order nh monomials; construct lower orders along the way.
947 for(int j = start_nh; j < end_nh; ++j) {
948 // Get current monomial's variable list; compare with old variable list.
950 int vk = 0;
951 if(oldvrbl)
952 while((*vrbl)[vk] == (*oldvrbl)[vk]) ++vk;
953
954 // Determine which monomial pointers we shall need to increment.
955 int jl = (*vrbl)[nh1], ni = nh2;
956 while(ni >= 0 && (*vrbl)[ni] == jl) --ni;
957 ni += 2;
958 ni = std::max(ni, nl);
959 // Determine which monomials contribute this round.
960 int n1 = std::max(nl, ni), n2 = nh;
961 while(n1 <= n2) {
962 bool zeroQ = true;
963 for(int k = N; k-- > 0;) {
964 if(*fp[k][n1] != T(0)) {
965 zeroQ = false;
966 break;
967 }
968 }
969 if(zeroQ) ++n1;
970 else break;
971 }
972 while(n2 > n1) {
973 bool zeroQ = true;
974 for(int k = N; k-- > 0;) {
975 if(*fp[k][n2] != T(0)) {
976 zeroQ = false;
977 break;
978 }
979 }
980 if(zeroQ) --n2;
981 else break;
982 }
983 // Skip if all monomials have coefficient zero.
984 if(n1 > n2) {
985 for(int k = N; k-- > 0;)
986 for(int m = ni; m <= nh; ++m) ++fp[k][m];
987 continue;
988 }
989
990 // If vk = 0, we must start at the beginning; otherwise,
991 // we may keep the first vk orders stored in t.
992 int ord;
993 if(vk == 0) {
994 t[1] = rhs[(*vrbl)[0]];
995 ord = 2;
996 } else ord = vk + 1;
997
998 // Build the remainder.
999 while(ord <= nh) {
1000 // Build next order part of transformed monomial by multiplying
1001 // the part that is one order lower by the transformed version
1002 // of the next variable in the variable list.
1003 int ord1 = ord - 1;
1004 t[ord] = t[ord1].multiply(rhs[(*vrbl)[ord1]], g_trc);
1005 ++ord;
1006 }
1007
1008 // Increment result by f[k][j] * transformed monomial,
1009 // and increment pointers in fp[].
1010 for(int k = N; k-- > 0;) {
1011 const T **fpk = fp[k];
1012 for(int m = n1; m <= n2; ++m) result[k] += *fpk[m] * t[m];
1013 for(int m = ni; m <= nh; ++m) ++fpk[m];
1014 //for (int m = n1; m <= n2; ++m) result[k] += *fpk[m] * t[m];
1015 //for (int m = ni; m <= nh; ++m) ++fpk[m];
1016 }
1017
1018 // Save variable list for comparison with the next one.
1019 oldvrbl = vrbl;
1020 }
1021
1022 return result;
1023}
1024
1025
1026template <class T, int N>
1028 FVps<T, N> result;
1029
1030 for(int i = 0; i < N; ++i) {
1031 FTps<T, N> sum = lhs(i, 0) * data[0];
1032 for(int j = 1; j < N; ++j) sum += lhs(i, j) * data[j];
1033 result[i] = sum;
1034 }
1035
1036 return result;
1037}
1038
1039template <class T, int N>
1041
1042 // function does not handle negative powers
1043 if ( std::any_of(power.begin(), power.end(), [&](int p) { return p < 0; }) )
1044 throw LogicalError("FVps<T,N>::getFTps(power)", "Negative power.");
1045
1046 // initial Tps
1047 FTps<T, N> result = 1.0;
1048
1049 // go through variables and multiply its power to "result"
1050 for (int i = 0; i < N; ++i) {
1051 // get polynomial
1052 FTps<T, N> rhs = getComponent(i);
1053
1054 // multiply polynomials
1055 for (int j = 0; j < power[i]; ++j)
1056 result = result.multiply(rhs, FTps<T, N>::getGlobalTruncOrder()); // make sure that no global trunc exceeding
1057 }
1058
1059 return result;/*.truncate(FTps<T, N>::getGlobalTruncOrder());*/
1060}
1061
1062template <class T, int N>
1063std::istream &FVps<T, N>::get(std::istream &is) {
1064 is.flags(std::ios::skipws);
1065 char head[4];
1066 (is >> std::ws).get(head, 4);
1067
1068 if(strcmp(head, "FVps") != 0)
1069 throw FormatError("FVps::get()", "Flag word \"FVps\" missing.");
1070
1071 int nDim;
1072 is >> nDim;
1073 if(nDim != N) throw FormatError("FVps::get()", "Invalid FVps dimension");
1074
1075 // Read into temporary for exception safety.
1076 FVps<T, N> result;
1077 for(int i = 0; i < N; i++) is >> result.data[i];
1078 *this = result;
1079 return is;
1080}
1081
1082
1083template <class T, int N>
1084std::ostream &FVps<T, N>::put(std::ostream &os) const {
1085 os << "FVps " << N << std::endl;
1086 for(int i = 0; i < N; i++) os << data[i];
1087 return os;
1088}
1089
1090
1091// Global Operators on FVps<T,N>
1092// ------------------------------------------------------------------------
1093
1094template <class T, int N>
1096 FVps<T, N> result;
1097 for(int i = 0; i < N; ++i) result[i] = lhs[i] + rhs[i];
1098 return result;
1099}
1100
1101
1102template <class T, int N>
1104 FVps<T, N> result;
1105 for(int i = 0; i < N; ++i) result[i] = lhs[i] - rhs[i];
1106 return result;
1107}
1108
1109
1110template <class T, int N>
1112 FVps<T, N> result;
1113 for(int i = 0; i < N; ++i) result[i] = lhs[i] + rhs[i];
1114 return result;
1115}
1116
1117
1118template <class T, int N>
1120 FVps<T, N> result;
1121 for(int i = 0; i < N; ++i) result[i] = lhs[i] - rhs[i];
1122 return result;
1123}
1124
1125
1126template <class T, int N>
1128 FVps<T, N> result;
1129 for(int i = 0; i < N; ++i) result[i] = lhs[i] + rhs[i];
1130 return result;
1131}
1132
1133
1134template <class T, int N>
1136 FVps<T, N> result;
1137 for(int i = 0; i < N; ++i) result[i] = lhs[i] - rhs[i];
1138 return result;
1139}
1140
1141
1142template <class T, int N>
1144 FVector<T, N> result;
1145 for (int i = 0; i < N; ++i) {
1146 FTps<T, N> tps = lhs.getComponent(i);
1147 result[i] = tps.evaluate(rhs);
1148 }
1149 return result;
1150}
1151
1152
1153template <class T, int N>
1155 FVps<T, N> result;
1156 for(int i = 0; i < N; ++i) result[i] = lhs[i] * rhs;
1157 return result;
1158}
1159
1160
1161template <class T, int N>
1163 FVps<T, N> result;
1164 for(int i = 0; i < N; ++i) result[i] = lhs * rhs[i];
1165 return result;
1166}
1167
1168
1169template <class T, int N>
1170FVps<T, N> operator*(const FVps<T, N> &lhs, const T &rhs) {
1171 FVps<T, N> result;
1172 for(int i = 0; i < N; ++i) result[i] = lhs[i] * rhs;
1173 return result;
1174}
1175
1176
1177template <class T, int N>
1178FVps<T, N> operator*(const T &lhs, const FVps<T, N> &rhs) {
1179 FVps<T, N> result;
1180 for(int i = 0; i < N; ++i) result[i] = lhs * rhs[i];
1181 return result;
1182}
1183
1184template <class T, int N>
1186 return rhs.substituteInto(lhs);
1187}
1188
1189
1190template <class T, int N>
1192 FVps<T, N> result;
1193 for(int i = 0; i < N; ++i) result[i] = lhs[i] / rhs;
1194 return result;
1195}
1196
1197
1198template <class T, int N>
1199FVps<T, N> operator/(const FVps<T, N> &lhs, const T &rhs) {
1200 FVps<T, N> result;
1201 for(int i = 0; i < N; ++i) result[i] = lhs[i] / rhs;
1202 return result;
1203}
1204
1205
1206template <class T, int N> FVps<T, N>
1207ExpMap(const FTps<T, N> &H, const FVps<T, N> &map, int trunc) {
1208 //std::cerr << "==> In ExpMap(H,map,trunc)" << std::endl;
1209 // Default: trunc = FTps<T,N>::EXACT
1210
1211 // Limit number of iterations.
1212 const int MAX_ITER = 400;
1213
1214 // We really ought to throw an exception if H contains linear terms and is not exact,
1215 // but we're just going to complain!!
1216 bool FD = false;
1217 if(H.getTruncOrder() != FTps<T, N>::EXACT && H.getMinOrder() < 2) {
1218 FD = true;
1219#ifdef DEBUG_FVps_CC
1220 std::cerr << " <*** WARNING ***> from ExpMap(H,map,trunc):\n"
1221 << " Incomplete computation of feed-down terms.\n" << std::endl;
1222#endif
1223 }
1224 int fd_trc = std::min(H.getTruncOrder() - 1, map.getTruncOrder());
1225
1226 // Construct dH = grad(H).J, s.t. :H:f = dH.grad(f).
1227 FVps<T, N> dH;
1228 for(int i = 0; i < N; i += 2) {
1229 dH[i] = - H.derivative(i + 1);
1230 dH[i+1] = H.derivative(i);
1231 }
1232
1233 // Allocate result.
1234 FVps<T, N> expHmap;
1235
1236 // Apply exp(:H:) to each component of map.
1237 for(int var = 0; var < N; var++) {
1238 // Initialize variables.
1239 FTps<T, N> expHf = map[var];
1240 FTps<T, N> dHkf = map[var];
1241 FTps<T, N> old = T(0);
1242 // Compute series; quit loop if we added nothing last time through.
1243 for(int k = 1; expHf != old; ++k) {
1244 if(k > MAX_ITER) {
1245 std::cerr << " present error:\n" << expHf - old << std::endl;
1246 throw ConvergenceError("ExpMap(const FTps<T,N> &H, const FVps<T,N> &map)",
1247 "No convergence in ExpMap(H,map)");
1248 }
1249 // Don't initialize dHk1f to 0, as that sets minOrder to 0!
1250 old = expHf;
1251 FTps<T, N> ddHkf = dHkf.derivative(0);
1252 if(FD) ddHkf.setTruncOrder(fd_trc);
1253 FTps<T, N> dHk1f = dH[0].multiply(ddHkf, trunc);
1254 for(int v = 1; v < N; ++v) {
1255 FTps<T, N> ddHkf = dHkf.derivative(v);
1256 if(FD) ddHkf.setTruncOrder(fd_trc);
1257 dHk1f += dH[v].multiply(ddHkf, trunc);
1258 //dHk1f += dH[v].multiply(dHkf.derivative(v),trunc);
1259 }
1260 dHkf = dHk1f / T(k); // :H:^{k}/(k!)
1261 expHf += dHkf;
1262 }
1263 expHmap[var] = expHf;
1264 }
1265
1266 //std::cerr << "==> Leaving ExpMap(H,map,trunc)" << std::endl;
1267 return expHmap;
1268}
1269
1270
1271template <class T, int N> FVps<T, N>
1272PoissonBracket(const FTps<T, N> &x, const FVps<T, N> &y, int trunc) {
1273 FVps<T, N> z;
1274 for(int v = 0; v < N; ++v)
1275 z[v] = PoissonBracket(x, y[v], trunc);
1276 return z;
1277}
1278
1279
1280template <class T, int N>
1281std::istream &operator>>(std::istream &is, FVps<T, N> &vps) {
1282 return vps.get(is);
1283}
1284
1285
1286template <class T, int N>
1287std::ostream &operator<<(std::ostream &os, const FVps<T, N> &vps) {
1288 return vps.put(os);
1289}
1290
1291#endif // CLASSIC_FVps_CC
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
FVps< T, N > operator/(const FVps< T, N > &lhs, const FTps< T, N > &rhs)
Divide.
Definition FVps.hpp:1191
FVector< T, N > operator*(const FVps< T, N > &lhs, const FVector< T, N > &rhs)
Multiply.
Definition FVps.hpp:1143
FVps< T, N > operator-(const FVps< T, N > &lhs, const FVps< T, N > &rhs)
Subtract.
Definition FVps.hpp:1103
FVps< T, N > operator+(const FVps< T, N > &lhs, const FVps< T, N > &rhs)
Add.
Definition FVps.hpp:1095
std::istream & operator>>(std::istream &is, FVps< T, N > &vps)
Extract FVps from stream [b]is[/b].
Definition FVps.hpp:1281
std::ostream & operator<<(std::ostream &os, const FVps< T, N > &vps)
Insert FVps to stream [b]os[/b].
Definition FVps.hpp:1287
FVps< T, N > PoissonBracket(const FTps< T, N > &x, const FVps< T, N > &y, int trunc)
Poisson bracket.
Definition FVps.hpp:1272
FVps< T, N > ExpMap(const FTps< T, N > &H, const FVps< T, N > &map, int trunc)
Build the exponential series.
Definition FVps.hpp:1207
@ SIZE
Definition IndexMap.cpp:178
T::PETE_Expr_t::PETE_Return_t sum(const PETE_Expr< T > &expr)
Definition PETE.h:1111
T::PETE_Expr_t::PETE_Return_t prod(const PETE_Expr< T > &expr)
Definition PETE.h:1121
Vector truncated power series in n variables.
Definition FVps.h:39
FVps integral(int var) const
Partial integral.
Definition FVps.hpp:532
const FVps & operator=(const FVps &)
Definition FVps.hpp:104
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
FTps< T, N > data[N]
Definition FVps.h:247
void setComponent(int, const FTps< T, N > &)
Set component.
Definition FVps.hpp:132
FVps & operator*=(const FTps< T, N > &rhs)
Multiply and assign.
Definition FVps.hpp:282
void setMinOrder(int order)
Set minimum order.
Definition FVps.hpp:175
std::ostream & put(std::ostream &os) const
Put a FVps to stream [b]os[/b].
Definition FVps.hpp:1084
void setTruncOrder(int order)
Set truncation order for all components.
Definition FVps.hpp:217
FVector< T, N > constantTerm() const
Extract the constant part of the map.
Definition FVps.hpp:540
int getTopOrder() const
Get highest order contained in any component.
Definition FVps.hpp:197
FVps substituteInto(const FMatrix< T, N, N > &lhs) const
Substitute map into matrix.
Definition FVps.hpp:1027
FVps substitute(const FMatrix< T, N, N > &M, int n) const
Substitute.
Definition FVps.hpp:608
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:1040
void zero()
Set to zero.
Definition FVps.hpp:117
int getMaxOrder() const
Get highest order contained in any component.
Definition FVps.hpp:181
FVps operator+() const
Unary plus.
Definition FVps.hpp:240
FVps myInverse(int trunc=(FTps< T, N >::EXACT)) const
Inverse.
Definition FVps.hpp:441
int getVariables() const
Get number of variables.
Definition FVps.hpp:159
FVps & operator+=(const FVps &rhs)
Add and assign.
Definition FVps.hpp:254
FVps truncate(int trunc)
Truncate.
Definition FVps.hpp:234
~FVps()
Definition FVps.hpp:99
void setMaxOrder(int order)
Set maximum order.
Definition FVps.hpp:191
FVps operator*(const FVps< T, N > &rhs) const
Multiply.
Definition FVps.hpp:288
FVps derivative(int var) const
Partial derivative.
Definition FVps.hpp:524
FVps & operator/=(const FTps< T, N > &rhs)
Divide and assign.
Definition FVps.hpp:338
const FTps< T, N > & getComponent(int n) const
Get component.
Definition FVps.hpp:123
FVps filter(int minOrder, int maxOrder, int trcOrder=(FTps< T, N >::EXACT)) const
Extract given range of orders, with truncation.
Definition FVps.hpp:223
void identity()
Set to identity.
Definition FVps.hpp:111
int getDimension() const
Get dimension.
Definition FVps.hpp:153
std::istream & get(std::istream &is)
Get a FVps from stream [b]is[/b].
Definition FVps.hpp:1063
FVps()
Definition FVps.hpp:46
FVps & operator-=(const FVps &rhs)
Subtract and assign.
Definition FVps.hpp:261
int getTruncOrder() const
Get lowest truncation order in any component.
Definition FVps.hpp:207
FVps inverse(int trunc=(FTps< T, N >::EXACT)) const
Inverse.
Definition FVps.hpp:360
int getMinOrder() const
Get lowest order contained in any component.
Definition FVps.hpp:165
const FTps< T, N > & operator[](int) const
Get Component.
Definition FVps.hpp:141
FMatrix< T, N, N > linearTerms() const
Extract the linear part of the map.
Definition FVps.hpp:561
FVps operator-() const
Unary minus.
Definition FVps.hpp:246
One-dimensional array.
Definition Array1D.h:36
iterator begin()
Get beginning of data.
Definition Array1D.h:204
A templated representation for one-dimensional arrays.
Definition FArray1D.h:39
iterator end()
Get iterator pointing past end of array.
Definition FArray1D.h:198
iterator begin()
Get iterator pointing to beginning of array.
Definition FArray1D.h:192
A templated representation for matrices.
Definition FMatrix.h:39
Truncated power series in N variables of type T.
Definition FTps.h:45
FTps< T, N > makePower(int power) const
Multiply FTps with itself.
Definition FTps.hpp:1555
const T getCoefficient(int index) const
Get coefficient.
Definition FTps.hpp:223
std::list< int > getListOfNonzeroCoefficients() const
Get a list containing the indexes of non-zero coefficients of a FTps.
Definition FTps.hpp:1515
FTps inverse(int trunc=EXACT) const
Reciprocal, 1/(*this).
Definition FTps.hpp:707
void setTruncOrder(int order)
Set truncation order.
Definition FTps.hpp:393
int getMinOrder() const
Get minimum order.
Definition FTps.h:165
int getTruncOrder() const
Get truncation order.
Definition FTps.h:183
FTps multiply(const FTps &y, int trunc=EXACT) const
Multiplication.
Definition FTps.hpp:650
int getSize() const
Get total number of coefficients.
Definition FTps.h:136
static Array1D< T > evalMonoms(const FVector< T, N > &, int)
Evaluate monomials at point.
Definition FTps.hpp:898
FTps derivative(int var) const
Partial derivative.
Definition FTps.hpp:1396
T * begin() const
Return beginning of monomial array.
Definition FTps.h:118
static int getGlobalTruncOrder()
Return the global truncation order.
Definition FTps.h:191
static int orderEnd(int order)
Get one plus index at which [b]order[/b] ends.
Definition FTps.h:147
T evaluate(const FVector< T, N > &) const
Evaluate FTps at point.
Definition FTps.hpp:934
int getMaxOrder() const
Get maximum order.
Definition FTps.h:174
static int orderStart(int order)
Get index at which [b]order[/b] starts.
Definition FTps.h:143
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
FArray1D< int, N > extractExponents(int index) const
Extract exponents of coefficient.
Definition FTps.hpp:1535
void setMinOrder(int order)
Set minimum order.
Definition FTps.hpp:321
A templated representation of a LU-decomposition.
Definition FLUMatrix.h:42
FMatrix< T, N, N > inverse() const
Get inverse.
Definition FLUMatrix.h:236
A templated representation for vectors.
Definition FVector.h:38
static int getSize(int order)
Definition FTpsData.h:187
static const Array1D< int > & getVariableList(int index)
Definition FTpsData.h:244
static const Array1D< int > & getProductArray(int index)
Definition FTpsData.h:237
Linear map with values of type [b]T[/b] in [b]N[/b] variables.
Definition LinearMap.h:38
Transport map with values of type [b]T[/b] in [b]N[/b] variables.
Range error.
Convergence error exception.
Domain error exception.
Definition DomainError.h:32
Format error exception.
Definition FormatError.h:32
Logical error exception.
Singular matrix exception.