OPAL (Object Oriented Parallel Accelerator Library) 2022.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
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>
100{}
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 */
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 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.
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
888template <class T, int N>
890 return substitute(mat, getMinOrder(), getMaxOrder());
891}
892
893
894template <class T, int N>
895FVps<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.
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
1020template <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
1033template <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
1056template <class T, int N>
1057std::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
1077template <class T, int N>
1078std::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
1088template <class T, int N>
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
1096template <class T, int N>
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
1104template <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
1112template <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
1120template <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
1128template <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
1136template <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
1147template <class T, int N>
1149 FVps<T, N> result;
1150 for(int i = 0; i < N; ++i) result[i] = lhs[i] * rhs;
1151 return result;
1152}
1153
1154
1155template <class T, int N>
1157 FVps<T, N> result;
1158 for(int i = 0; i < N; ++i) result[i] = lhs * rhs[i];
1159 return result;
1160}
1161
1162
1163template <class T, int N>
1164FVps<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
1171template <class T, int N>
1172FVps<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
1178template <class T, int N>
1180 return rhs.substituteInto(lhs);
1181}
1182
1183
1184template <class T, int N>
1186 FVps<T, N> result;
1187 for(int i = 0; i < N; ++i) result[i] = lhs[i] / rhs;
1188 return result;
1189}
1190
1191
1192template <class T, int N>
1193FVps<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
1200template <class T, int N> FVps<T, N>
1201ExpMap(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
1265template <class T, int N> FVps<T, N>
1266PoissonBracket(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
1274template <class T, int N>
1275std::istream &operator>>(std::istream &is, FVps<T, N> &vps) {
1276 return vps.get(is);
1277}
1278
1279
1280template <class T, int N>
1281std::ostream &operator<<(std::ostream &os, const FVps<T, N> &vps) {
1282 return vps.put(os);
1283}
1284
1285#endif // CLASSIC_FVps_CC
FVps< T, N > operator/(const FVps< T, N > &lhs, const FTps< T, N > &rhs)
Divide.
Definition: FVps.hpp:1185
FVector< T, N > operator*(const FVps< T, N > &lhs, const FVector< T, N > &rhs)
Multiply.
Definition: FVps.hpp:1137
FVps< T, N > operator-(const FVps< T, N > &lhs, const FVps< T, N > &rhs)
Subtract.
Definition: FVps.hpp:1097
FVps< T, N > operator+(const FVps< T, N > &lhs, const FVps< T, N > &rhs)
Add.
Definition: FVps.hpp:1089
std::istream & operator>>(std::istream &is, FVps< T, N > &vps)
Extract FVps from stream [b]is[/b].
Definition: FVps.hpp:1275
std::ostream & operator<<(std::ostream &os, const FVps< T, N > &vps)
Insert FVps to stream [b]os[/b].
Definition: FVps.hpp:1281
FVps< T, N > PoissonBracket(const FTps< T, N > &x, const FVps< T, N > &y, int trunc)
Poisson bracket.
Definition: FVps.hpp:1266
FVps< T, N > ExpMap(const FTps< T, N > &H, const FVps< T, N > &map, int trunc)
Build the exponential series.
Definition: FVps.hpp:1201
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
@ SIZE
Definition: IndexMap.cpp:174
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:84
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 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
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
std::string::iterator iterator
Definition: MSLang.h:16
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:1078
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:1021
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:1034
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:1057
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
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
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 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.
Definition: TransportMap.h:39
Range error.
Definition: CLRangeError.h:33
Convergence error exception.
Domain error exception.
Definition: DomainError.h:32
Format error exception.
Definition: FormatError.h:32
Logical error exception.
Definition: LogicalError.h:33
Singular matrix exception.