52template<
class T,
int N>
55template <
class T,
int N>
59 friend class FTps<T, N>;
60 friend class FVps<T, N>;
63 FTpsRep(
int minOrder,
int maxOrder,
int trcOrder);
72 void clear(
int minOrder,
int maxOrder);
87 T *
end(
int order)
const
117template <
class T,
int N>
128template <
class T,
int N>
134template <
class T,
int N>
140template <
class T,
int N>
151template <
class T,
int N>
154template <
class T,
int N>
158template <
class T,
int N>
165template <
class T,
int N>
172template <
class T,
int N>
175 itsRep->clear(minOrder, maxOrder);
179template <
class T,
int N>
186template <
class T,
int N>
193template <
class T,
int N>
200template <
class T,
int N>
212template <
class T,
int N>
222template <
class T,
int N>
225 std::cerr <<
" <*** WARNING ***> from FTps<T,N>::getCoefficient(index):\n"
226 <<
" No coefficient has a negative index; returning 0." << std::endl;
231 return itsRep->data[index];
235template <
class T,
int N>
238 std::cerr <<
" <*** WARNING ***> from FTps<T,N>::setCoefficient(index, value):\n"
239 <<
" Ignoring request because index < 0." << std::endl;
246 if(order >
itsRep->trcOrd)
return;
256 itsRep->data[index] = value;
260template <
class T,
int N>
267template <
class T,
int N>
274template <
class T,
int N>
276 return itsRep->data[index];
280template <
class T,
int N>
283 return itsRep->data[index];
287template <
class T,
int N>
290 return itsRep->data[index];
294template <
class T,
int N>
298 return itsRep->data[index];
302template <
class T,
int N>
308template <
class T,
int N>
314template <
class T,
int N>
320template <
class T,
int N>
324 throw LogicalError(
"FTps<T,N>::setMinOrder(order)",
"Cannot set minimum order to EXACT.");
326 throw LogicalError(
"FTps<T,N>::setMinOrder(order)",
"Cannot set a negative minimum order.");
329 "Cannot set minimum order beyond globalTruncOrder.");
333 if(order >
itsRep->trcOrd) {
334 std::cerr <<
" <*** WARNING ***> from FTps<T,N>::setMinOrder(order):\n"
335 <<
" Cannot set minimum order above truncation order;\n"
336 <<
" raising both minimum and maximum orders to truncation order." << std::endl;
344 if(order >
itsRep->maxOrd) {
346 itsRep->clear(order, order);
349 else if(order < itsRep->minOrd)
itsRep->clear(order,
itsRep->minOrd - 1);
356template <
class T,
int N>
360 throw LogicalError(
"FTps<T,N>::setMaxOrder(order)",
"Cannot set maximum order to EXACT.");
362 throw LogicalError(
"FTps<T,N>::setMaxOrder(order)",
"Cannot set a negative maximum order.");
365 "Cannot set maximum order beyond globalTruncOrder.");
369 if(order >
itsRep->trcOrd) {
370 std::cerr <<
" <*** WARNING ***> from FTps<T,N>::setMaxOrder(order):\n"
371 <<
" Cannot set maximum order above truncation order;\n"
372 <<
" raising maximum order to truncation order." << std::endl;
382 else if(order < itsRep->minOrd) {
384 itsRep->clear(order, order);
392template <
class T,
int N>
395 if(order !=
EXACT && order < 0)
396 throw LogicalError(
"FTps<T,N>::setTruncOrder(order)",
"Cannot set a negative truncation order.");
399 "Cannot set truncation order beyond globalTruncOrder.");
403 if(order < itsRep->minOrd) {
406 itsRep->clear(order, order);
409 else if(order < itsRep->maxOrd)
itsRep->maxOrd = order;
418template <
class T,
int N>
422 throw LogicalError(
"FTps<T,N>::setGlobalTruncOrder(order)",
"Cannot make globalTruncOrder EXACT.");
424 throw LogicalError(
"FTps<T,N>::setGlobalTruncOrder(order)",
425 "Cannot set a negative global truncation order.");
432template <
class T,
int N>
438template <
class T,
int N>
444template <
class T,
int N>
450template <
class T,
int N>
453 checkOrders(
"filter(minOrder, maxOrder, trcOrder)", minOrder, maxOrder, trcOrder);
456 int myMin = std::max(minOrder,
itsRep->minOrd);
457 int myMax = std::min(maxOrder,
itsRep->maxOrd);
458 int myTrc = std::min(trcOrder,
itsRep->trcOrd);
463 myMin = std::min(minOrder, myTrc);
464 myMax = std::min(maxOrder, myTrc);
468 if(OLflag) std::copy(
begin(myMin),
end(myMax), result.
begin(myMin));
474template <
class T,
int N>
inline
476 return filter(0, trunc, trunc);
480template <
class T,
int N>
483 result[var + 1] = T(1);
488template <
class T,
int N>
498template <
class T,
int N>
507template <
class T,
int N>
516template <
class T,
int N>
522template <
class T,
int N>
527 std::transform(
begin(minOrder),
end(maxOrder), result.
begin(minOrder), std::negate<T>());
532template <
class T,
int N>
534 return *
this = *
this + rhs;
538template <
class T,
int N>
540 return *
this = *
this - rhs;
544template <
class T,
int N>
550template <
class T,
int N>
552 return *
this =
divide(rhs);
556template <
class T,
int N>
565template <
class T,
int N>
574template <
class T,
int N>
578 std::bind(std::multiplies<T>(), std::placeholders::_1, rhs));
582template <
class T,
int N>
584 if(rhs == T(0))
throw DivideError(
"FTps::operator/=()");
585 return *
this *= T(1) / rhs;
588template <
class T,
int N>
596 int minOrder = std::max(f_min, g_min);
597 int maxOrder = std::min(f_max, g_max);
599 if(minOrder <= maxOrder) {
600 FTps<T, N> result(minOrder, maxOrder, trcOrder);
601 std::transform(
begin(minOrder),
end(maxOrder), rhs.
begin(minOrder),
602 result.
begin(minOrder), std::multiplies<T>());
605 throw LogicalError(
"FTps<T,N>::scaleMonomials(rhs)",
"No overlap exists.");
609template <
class T,
int N>
616 std::cerr <<
" <*** WARNING ***> from FTps<T,N>::multiplyVariable(var, trunc):\n"
617 <<
" Result truncated out of existence; returning a zero polynomial."
624 if (trcOrder ==
EXACT) {
628 trcOrder = std::min(trcOrder, trunc);
631 int maxOrder = std::min(1 +
getMaxOrder(), trcOrder);
634 FTps<T, N> result(1 + f_min, maxOrder, trcOrder);
635 const T *f =
begin();
636 T *g = result.
begin();
642 g[product[i]] = f[i];
649template <
class T,
int N>
660 trcOrder = std::min(trcOrder, trunc);
661 int maxOrder = std::min(
itsRep->maxOrd + rhs.
itsRep->maxOrd, trcOrder);
664 if(minOrder <= maxOrder) {
666 FTps<T, N> result(minOrder, maxOrder, trcOrder);
671 T *h = result.
begin();
675 int f_max =
itsRep->maxOrd;
676 int g_max = std::min(rhs.
itsRep->maxOrd, maxOrder);
679 for(
int gOrd = rhs.
itsRep->minOrd; gOrd <= g_max; gOrd++) {
681 int last_f =
orderEnd(std::min(f_max, maxOrder - gOrd));
684 for(
int j = first_g; j < last_g; j++) {
688 for(
int i = first_f; i < last_f; i++) h[
prod[i]] += f[i] * gj;
697 std::cerr <<
" <*** WARNING ***> from FTps<T,N>::multiply(rhs, trunc):\n"
698 <<
" Result truncated out of existence; returning a zero polynomial."
701 return FTps<T, N>(trcOrder, trcOrder, trcOrder);
706template <
class T,
int N>
712 if(b0 == T(0) ||
itsRep->minOrd != 0) {
713 std::cerr <<
" <*** ERROR ***> in FTps::inverse():\n"
714 <<
" Cannot invert a polynomial with zero constant term." << std::endl;
719 int trcOrder = std::min(
itsRep->trcOrd, trunc);
720 int maxOrder = std::min(
itsRep->maxOrd, trcOrder);
722 throw LogicalError(
"FTps::inverse(trunc)",
"Truncation order exceeds globalTruncOrder!");
728 const T *b =
itsRep->data;
734 if(trcOrder == 0)
return result;
737 for(
int m = 1; m <= trcOrder; ++m) {
739 for(
int mc = 0; mc < m; ++mc) {
741 if(mb > maxOrder)
continue;
744 for(
int k = start_c; k < end_c; ++k) {
748 for(
int i = end_b; i-- > start_b;)
c[
prod[i]] += b[i] * ck;
753 for(
int j =
orderStart(m); j < je; ++j)
c[j] *= neg_c0;
760template <
class T,
int N>
774 T b0 = rhs.
itsRep->data[0];
775 if(b0 == T(0) || rhs.
itsRep->minOrd != 0) {
776 std::cerr <<
" <*** ERROR ***> in FTps::divide(rhs,trunc):\n"
777 <<
" Cannot divide by a polynomial with zero constant term." << std::endl;
785 if(b_trc ==
EXACT) c_trc = std::min(a_trc, trunc);
786 else { c_trc = std::min(a_trc, b_trc + a_min); c_trc = std::min(c_trc, trunc); }
788 throw LogicalError(
"FTps::divide(rhs,trunc)",
"Truncation order exceeds globalTruncOrder!");
789 int c_max = c_trc, c_min = a_min;
790 int ac_max_min = std::min(a_max, c_max);
796 std::copy(
begin(c_min),
end(ac_max_min), result.
begin(c_min));
797 const T *b = rhs.
itsRep->data;
800 if(c_min == 0)
c[0] *= b0inv;
803 if(c_trc == 0)
return result;
806 int mi = std::max(1, c_min);
807 for(
int m = mi; m <= c_max; ++m) {
809 for(
int mc = c_min; mc < m; ++mc) {
811 if(mb > b_max)
continue;
814 for(
int k = start_c; k < end_c; ++k) {
818 for(
int i = end_b; i-- > start_b;)
c[
prod[i]] -= b[i] * ck;
823 for(
int j =
orderStart(m); j < je; ++j)
c[j] *= b0inv;
830template <
class T,
int N>
839 int r_min = std::min(f_min, g_min), r_max = std::max(f_max, g_max);
841 const T *f =
begin();
842 const T *g = rhs.
begin();
845 if(g_min < f_max && f_min < g_max) {
846 int i = r_min, fg_max_min = std::min(f_max, g_max);
847 for(; i < g_min; i++)
if(f[i] != T(0))
return false;
848 for(; i < f_min; i++)
if(g[i] != T(0))
return false;
849 for(; i < fg_max_min; i++)
if(f[i] != g[i])
return false;
850 for(; i < f_max; i++)
if(f[i] != T(0))
return false;
851 for(; i < g_max; i++)
if(g[i] != T(0))
return false;
854 for(
int i = r_min ; i < f_max; i++)
if(f[i] != T(0))
return false;
855 for(
int i = g_min ; i < r_max; i++)
if(g[i] != T(0))
return false;
857 for(
int i = r_min; i < g_max; i++)
if(g[i] != T(0))
return false;
858 for(
int i = f_min; i < r_max; i++)
if(f[i] != T(0))
return false;
866template <
class T,
int N>
869 const T *f =
begin();
872 if(*f != rhs)
return false;
874 }
else if(rhs != T(0))
return false;
879 if(f[i] != T(0))
return false;
885template <
class T,
int N>
887 return !(*
this == rhs);
891template <
class T,
int N>
893 return !(*
this == rhs);
897template <
class T,
int N>
905 T *mon = result.
begin();
906 const T *z = rhs.
begin();
912 if(maxOrder > 0) std::copy(z, z + N, mon);
919 for(; m <= maxOrder; ++m) {
922 for(
int k = 0, k1 = N1; k < N; k++, k1--) {
925 while(mona != monx) *mon++ = zk * *mona++;
933template <
class T,
int N>
939 const T *f =
begin();
940 const T *z = rhs.
begin();
948 static T *monoms = 0;
949 static int myOrd = -1;
950 if(maxOrder > myOrd) {
951 if(monoms)
delete [] monoms;
952 monoms =
new T[
getSize(maxOrder)];
962 if(maxOrder == 0)
return result;
966 std::copy(z, z + N, mon);
970 if(minOrder <= 1)
while(mon != monx) result += *f++ * *mon++;
971 else { f += N; mon = monx; }
977 for(; m < minOrder; m++) {
980 for(
int k = 0, k1 = N1; k < N; k++, k1--) {
983 while(mona != monx) {
984 *mon++ = zk * *mona++;
990 for(; m <= maxOrder; m++) {
993 for(
int k = 0, k1 = N1; k < N; k++, k1--) {
996 while(mona != monx) {
998 result += *f++ * *mon++;
1007template <
class T,
int N>
1021template <
class T,
int N>
1026 int f_min = ordersL[0], f_max = ordersL[1], f_trc = ordersL[2];
1027 int r_min = ordersR[0], r_max = ordersR[1], r_trc = ordersR[2];
1028 int g_min = f_min * r_min, g_max = f_max * r_max, g_trc;
1029 if(f_trc ==
EXACT) {
1030 if(r_trc ==
EXACT) {g_trc = (g_max <= trunc) ?
EXACT : trunc;}
1032 if(f_max == 0) g_trc =
EXACT;
1035 if(f_min != 0) g_trc += g_min - r_min;
1036 g_trc = std::min(g_trc, trunc);
1041 g_trc = std::min((f_trc + 1) * r_min - 1, trunc);
1042 if(r_trc !=
EXACT && f_max != 0) {
1044 if(f_min != 0) t_trc += g_min - r_min;
1045 g_trc = std::min(g_trc, t_trc);
1049 std::cerr <<
" <*** WARNING ***> from FTps<T,N>::getSubstOrders(ordersL,ordersR,trunc):\n"
1050 <<
" Incomplete computation of feed-down terms.\n" << std::endl;
1052 if(f_max == 0) g_trc = 0;
1054 g_trc = std::min(f_trc, r_trc);
1055 g_trc = std::min(g_trc, trunc);
1060 g_max = std::min(g_max, g_trc);
1074template <
class T,
int N>
1079 "Transformation order, n, is negative.");
1082 "Transformation order, n, exceeds globalTruncOrder.");
1088 FTps<T, N> result(minOrder, maxOrder, trcOrder);
1089 std::copy(
begin(minOrder),
end(maxOrder), result.
begin(minOrder));
1094 std::cerr <<
" <*** WARNING ***> from FTps<T,N>::substitute(mat,n):\n"
1095 <<
" Transformation order exceeds truncation order;\n"
1096 <<
" returning polynomial unchanged." << std::endl;
1100 if(n == 0 || n < minOrder || maxOrder < n)
return result;
1107 static int max_n = -1;
1115 const T *fj =
begin(n);
1116 T *g = result.
begin();
1122 std::fill(g + start_n, g + end_n, T(0));
1125 for(
int j = start_n; j < end_n; ++j, ++fj) {
1127 if(*fj == T(0))
continue;
1133 while((*vrbl)[vi] == (*oldvrbl)[vi]) ++vi;
1140 mv = mat[(*vrbl)[0]];
1141 std::copy(mv, mv + N, t1);
1143 }
else ord = vi + 1;
1146 std::fill(t +
orderStart(ord), t + end_n, T(0));
1154 mv = mat[(*vrbl)[ord1]];
1155 for(
int k = 0; k < N; k++) {
1157 if(mvk == T(0))
continue;
1159 for(
int l = start_l; l < end_l; l++) t[
prod[l]] += mvk * t[l];
1164 for(
int i = start_n; i < end_n; i++) g[i] += *fj * t[i];
1173template <
class T,
int N>
1178 "Inconsistent transformation orders: nl > nh.");
1181 "Transformation order nl is negative.");
1184 "Transformation order nh exceeds globalTruncOrder.");
1190 FTps<T, N> result(minOrder, maxOrder, trcOrder);
1191 std::copy(
begin(minOrder),
end(maxOrder), result.
begin(minOrder));
1195 std::cerr <<
" <*** WARNING ***> from FTps<T,N>::substitute(mat,nl,nh):\n"
1196 <<
" Transformation order nh exceeds truncation order;\n"
1197 <<
" truncation order unchanged." << std::endl;
1202 if(nh == 0 || nh < minOrder || maxOrder < nl)
return result;
1206 nl = std::max(nl, minOrder);
1207 nh = std::min(nh, maxOrder);
1208 std::fill(result.
begin(nl), result.
end(nh), T(0));
1213 static const T **fp;
1214 static int max_nh = -1;
1221 fp =
new const T*[nh+1];
1228 for(
int m = nl; m <= nh; ++m) fp[m] =
begin(m);
1229 T *g = result.
begin();
1234 for(
int j = start_nh; j < end_nh; ++j) {
1239 while((*vrbl)[vk] == (*oldvrbl)[vk]) ++vk;
1242 int jl = (*vrbl)[nh1], ni = nh2;
1243 while(ni >= 0 && (*vrbl)[ni] == jl) --ni;
1245 ni = std::max(ni, nl);
1247 int n1 = std::max(nl, ni), n2 = nh;
1248 while(n1 <= n2 && *fp[n1] == 0) ++n1;
1249 while(n2 > n1 && *fp[n2] == 0) --n2;
1252 for(
int m = ni; m <= nh; ++m) ++fp[m];
1261 mv = mat[(*vrbl)[0]];
1262 std::copy(mv, mv + N, t1);
1264 }
else ord = vk + 1;
1267 std::fill(t +
orderStart(ord), t + end_nh, T(0));
1276 mv = mat[(*vrbl)[ord1]];
1277 for(
int k = 0; k < N; k++) {
1279 if(mvk == T(0))
continue;
1281 for(
int l = start_l; l < end_l; ++l) t[
prod[l]] += mvk * t[l];
1286 for(
int m = n1; m <= n2; ++m) {
1289 for(
int i = start_m; i < end_m; i++) g[i] += fj * t[i];
1292 for(
int m = ni; m <= nh; ++m) ++fp[m];
1301template <
class T,
int N>
1307template <
class T,
int N>
1314 int g_min = orders[0], g_max = orders[1], g_trc = orders[2];
1318 throw LogicalError(
"FTps::substitute(FVps rhs, int trunc)",
1319 "Truncation order exceeds globalTruncOrder!");
1322 if(g_min > g_max)
return FTps<T, N>(g_trc, g_trc, g_trc);
1326 if(f_min == 0) result[0] = *
begin();
1327 if(f_max == 0)
return result;
1330 int nl = f_min, nh = f_max;
1339 for(
int m = nl; m <= nh; ++m) fp[m] =
begin(m);
1344 for(
int j = start_nh; j < end_nh; ++j) {
1349 while((*vrbl)[vk] == (*oldvrbl)[vk]) ++vk;
1352 int jl = (*vrbl)[nh1], ni = nh2;
1353 while(ni >= 0 && (*vrbl)[ni] == jl) --ni;
1355 ni = std::max(ni, nl);
1357 int n1 = std::max(nl, ni), n2 = nh;
1358 while(n1 <= n2 && *fp[n1] == 0) ++n1;
1359 while(n2 > n1 && *fp[n2] == 0) --n2;
1362 for(
int m = ni; m <= nh; ++m) ++fp[m];
1370 t[1] = rhs[(*vrbl)[0]];
1372 }
else ord = vk + 1;
1380 t[ord] = t[ord1].multiply(rhs[(*vrbl)[ord1]], g_trc);
1384 for(
int m = n1; m <= n2; ++m) result += *fp[m] * t[m];
1386 for(
int m = ni; m <= nh; ++m) ++fp[m];
1395template <
class T,
int N>
1399 int df_min = (f_min == 0) ? f_min : f_min - 1;
1400 int df_max = (f_max == 0) ? f_max : f_max - 1;
1401 int df_trc = (f_trc == 0 || f_trc ==
EXACT) ? f_trc : f_trc - 1;
1402 if(f_min == 0 && f_min < f_max) f_min = 1;
1407 if(f_max == 0)
return result;
1411 const T *f =
begin();
1412 T *df = result.
begin();
1424 int kp = *product++;
1432template <
class T,
int N>
1435 for(
int i = 0; i < N; ++i) result[i] =
derivative(i);
1440template <
class T,
int N>
1446 int minOrder = std::min(f_min + 1, trunc);
1447 int maxOrder = std::min(f_max + 1, trunc);
1449 if(f_trc ==
EXACT) trcOrder = trunc;
1450 else trcOrder = std::min(f_trc + 1, trunc);
1452 throw LogicalError(
"FTps::integral(int var, int trunc)",
"Some order exceeds globalTruncOrder!");
1455 FTps<T, N> result(minOrder, maxOrder, trcOrder);
1458 if(f_min >= maxOrder)
return result;
1461 const T *f =
begin();
1462 T *r = result.
begin();
1472 for(
int i = is; i < ie; ++i) {
1480template <
class T,
int N>
1484 x.
itsRep->data[0] = T(0);
1487 for(
int m = 1; m <= order; ++m) {
1497 result.
itsRep->data[0] = series[order-m];
1504template <
class T,
int N>
inline
1514template <
class T,
int N>
1521 std::list<int> coeffs;
1524 for (
int i = 0; i < size; ++i) {
1527 coeffs.push_back(i);
1534template <
class T,
int N>
1538 if ( index < 0 ||
getSize() - 1 < index)
1539 throw LogicalError(
"FVps<T,N>::extractExponents(var)",
"Index out of range.");
1548 for (
int i = 0; i < N; ++i)
1549 expons[i] = mono[i];
1554template <
class T,
int N>
1558 throw LogicalError(
"FTps<T,N>::makePower(power)",
"Power is negative.");
1563 for (
int i = 1; i < power; ++i) {
1570template <
class T,
int N>
1584 throw FormatError(
"FTps::get()",
"Flag word \"Tps\" missing.");
1587 int minOrder, maxOrder, trcOrder, nVar;
1589 is >> minOrder >> maxOrder >> trunc >> nVar;
1590 if(trunc ==
"EXACT") trcOrder =
EXACT;
1591 else trcOrder = std::atoi(trunc.c_str());
1595 throw FormatError(
"FTps::get()",
"Invalid number of variables.");
1598 FTps<T, N> result(minOrder, maxOrder, trcOrder);
1610 for(
int var = 0; var < nVar; var++) {
1614 if(p < 0) done =
true;
1619 if(fail)
throw FormatError(
"FTps::get()",
"File read error");
1625 minOrder = maxOrder = order;
1627 if(order < minOrder) minOrder = order;
1628 else if(order > maxOrder) maxOrder = order;
1631 result[index] = coeff;
1636 throw FormatError(
"FTps::get()",
"minOrder incorrect in file");
1638 throw FormatError(
"FTps::get()",
"maxOrder incorrect in file");
1639 result.
itsRep->minOrd = minOrder;
1640 result.
itsRep->maxOrd = maxOrder;
1647template <
class T,
int N>
1650 os <<
"Tps " <<
itsRep->minOrd <<
' ' <<
itsRep->maxOrd <<
' ';
1655 os <<
" " << N << std::endl;
1659 std::streamsize old_prec = os.precision(14);
1660 os.setf(std::ios::scientific, std::ios::floatfield);
1666 for(; f != fe; f++, i++) {
1668 os << std::setw(24) << *f;
1669 for(
int var = 0; var < N; var++)
1675 os << std::setw(24) << T(0);
1676 for(
int var = 0; var < N; var++) os << std::setw(3) << (-1);
1680 os.precision(old_prec);
1681 os.setf(std::ios::fixed, std::ios::floatfield);
1690template <
class T,
int N>
inline
1693 checkOrders(
"FTps<T,N>::allocate(minOrder, maxOrder, trcOrder)", minOrder, maxOrder, trcOrder);
1696 int allocOrder = trcOrder ==
EXACT ? maxOrder : trcOrder;
1713 std::cerr <<
" <*** allocOrder error ***> " << allocOrder <<
" != " << rep->
allocOrd << std::endl;
1725template <
class T,
int N>
inline
1733template <
class T,
int N>
1735 int minOrder =
itsRep->minOrd;
1741 T *f =
itsRep->begin(minOrder);
1742 T *fe =
itsRep->end(std::min(
itsRep->maxOrd, maxOrder));
1743 T *g = newRep->
begin(minOrder);
1744 T *
ge = newRep->
end(maxOrder);
1745 while(f < fe) *g++ = *f++;
1746 while(g <
ge) *g++ = T(0);
1755template <
class T,
int N>
1758 result[0] =
itsRep->minOrd;
1759 result[1] =
itsRep->maxOrd;
1760 result[2] =
itsRep->trcOrd;
1761 result[3] =
itsRep->allocOrd;
1766template <
class T,
int N>
1769 std::string message;
1772 if(!(0 <= minOrder && minOrder <= maxOrder && maxOrder <= trcOrder && maxOrder <
EXACT)) {
1774 message =
"Invalid, or inconsistent, arguments.";
1779 message =
"The argument maxOrder exceeds globalTruncOrder.";
1782 message =
"The argument trcOrder has a finite value that exceeds globalTruncOrder.";
1785 std::cerr <<
"Method " << method <<
", called with arguments (";
1786 if(minOrder ==
EXACT) std::cerr <<
"EXACT,";
1787 else std::cerr << minOrder <<
",";
1788 if(maxOrder ==
EXACT) std::cerr <<
"EXACT,";
1789 else std::cerr << maxOrder <<
",";
1790 if(trcOrder ==
EXACT) std::cerr <<
"EXACT";
1791 else std::cerr << trcOrder;
1792 std::cerr <<
")." << std::endl;
1801template <
class T,
int N>
1807 int h_min = std::min(f_min, g_min), h_max = std::min(std::max(f_max, g_max), h_trc);
1808 if(h_trc < f_min) h_max = g_max;
1809 else if(h_trc < g_min) h_max = f_max;
1819 h_min = std::min(f_min, g_min);
1820 h_max = std::max(f_max, g_max);
1822 const T *f = lhs.
begin();
1823 const T *g = rhs.
begin();
1824 T *h = result.
begin();
1828 if(g_min < f_max && f_min < g_max) {
1829 int fg_max_min = std::min(f_max, g_max);
1830 for(; i < g_min; i++) h[i] = f[i];
1831 for(; i < f_min; i++) h[i] = g[i];
1832 for(; i < fg_max_min; i++) h[i] = f[i] + g[i];
1833 for(; i < f_max; i++) h[i] = f[i];
1834 for(; i < g_max; i++) h[i] = g[i];
1836 if(f_max <= g_min) {
1838 if(g_min > h_max) g_min = h_max;
1840 for(; i < f_max; i++) h[i] = f[i];
1841 for(; i < g_min; i++) h[i] = 0;
1842 for(; i < h_max; i++) h[i] = g[i];
1845 if(f_min > h_max) f_min = h_max;
1847 for(; i < g_max; i++) h[i] = g[i];
1848 for(; i < f_min; i++) h[i] = 0;
1849 for(; i < h_max; i++) h[i] = f[i];
1857template <
class T,
int N>
1863 int h_min = std::min(f_min, g_min), h_max = std::min(std::max(f_max, g_max), h_trc);
1864 if(h_trc < f_min) h_max = g_max;
1865 else if(h_trc < g_min) h_max = f_max;
1875 h_min = std::min(f_min, g_min);
1876 h_max = std::max(f_max, g_max);
1878 const T *f = lhs.
begin();
1879 const T *g = rhs.
begin();
1880 T *h = result.
begin();
1884 if(g_min < f_max && f_min < g_max) {
1885 int fg_max_min = std::min(f_max, g_max);
1886 for(; i < g_min; i++) h[i] = f[i];
1887 for(; i < f_min; i++) h[i] = -g[i];
1888 for(; i < fg_max_min; i++) h[i] = f[i] - g[i];
1889 for(; i < f_max; i++) h[i] = f[i];
1890 for(; i < g_max; i++) h[i] = -g[i];
1892 if(f_max <= g_min) {
1894 if(g_min > h_max) g_min = h_max;
1896 for(; i < f_max; i++) h[i] = f[i];
1897 for(; i < g_min; i++) h[i] = 0;
1898 for(; i < h_max; i++) h[i] = -g[i];
1901 if(f_min > h_max) f_min = h_max;
1903 for(; i < g_max; i++) h[i] = -g[i];
1904 for(; i < f_min; i++) h[i] = 0;
1905 for(; i < h_max; i++) h[i] = f[i];
1913template <
class T,
int N>
1916 return result += rhs;
1920template <
class T,
int N>
1923 return result -= rhs;
1927template <
class T,
int N>
1930 return result += lhs;
1934template <
class T,
int N>
1937 return result += lhs;
1941template <
class T,
int N>
1948template <
class T,
int N>
1954template <
class T,
int N>
1957 return result *= rhs;
1961template <
class T,
int N>
1964 return result /= rhs;
1968template <
class T,
int N>
1971 return result *= lhs;
1975template <
class T,
int N>
1981template <
class T,
int N>
1987template <
class T,
int N>
2004 const int MAX_ITER = 100;
2012 std::cerr <<
" <*** WARNING ***> from ExpMap(H,f,trunc):\n"
2013 <<
" Incomplete computation of feed-down terms.\n" << std::endl;
2020 for(
int i = 0; i < N; i += 2) {
2033 for(
int k = 1; expHf != old; ++k) {
2036 "No convergence in ExpMap(H,f)");
2042 FTps<T, N> dHk1f = dH[0].multiply(ddHkf, trunc);
2043 for(
int v = 1; v < N; ++v) {
2046 dHk1f += dH[v].multiply(ddHkf, trunc);
2049 dHkf = dHk1f / T(k);
2057template <
class T,
int N>
2063 int g_min = g.getMinOrder(), g_max = g.getMaxOrder(), g_trc = g.getTruncOrder();
2064 int h_min = std::max(f_min + g_min - 2, 0), h_max = std::max(f_max + g_max - 2, 0), h_trc;
2066 if(g_trc ==
FTps<T, N>::EXACT) {h_trc = (h_max <= trunc) ? FTps<T, N>::EXACT : trunc;}
2067 else h_trc = std::min(std::max(f_min + g_trc - 2, 0), trunc);
2068 }
else if(g_trc ==
FTps<T, N>::EXACT) h_trc = std::min(std::max(f_trc + g_min - 2, 0), trunc);
2070 h_trc = std::min(f_trc + g_min - 2, f_min + g_trc - 2);
2071 h_trc = std::min(std::max(h_trc, 0), trunc);
2073 h_max = std::min(h_max, h_trc);
2081 for(
int q = 0; q < N; q += 2) {
2091template <
class T,
int N>
2097template <
class T,
int N>
std::istream & operator>>(std::istream &is, FTps< T, N > &tps)
Extract FTps from stream [b]is[/b].
FTps< T, N > operator+(const FTps< T, N > &lhs, const FTps< T, N > &rhs)
Add.
FVps< T, N > ExpMap(const FTps< T, N > &H, int trunc)
Build the exponential series.
FTps< T, N > operator/(const FTps< T, N > &lhs, const FTps< T, N > &rhs)
Divide.
bool operator==(const T &lhs, const FTps< T, N > &rhs)
Equality.
bool operator!=(const T &lhs, const FTps< T, N > &rhs)
Inequality.
FTps< T, N > operator-(const FTps< T, N > &lhs, const FTps< T, N > &rhs)
Subtract.
const int FTps< T, N >::EXACT
FTps< T, N > operator*(const FTps< T, N > &lhs, const FTps< T, N > &rhs)
Multiply.
FTps< T, N > PoissonBracket(const FTps< T, N > &f, const FTps< T, N > &g, int trunc)
Poisson bracket.
std::ostream & operator<<(std::ostream &os, const FTps< T, N > &tps)
Insert FTps into stream [b]os[/b].
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
constexpr double c
The velocity of light in m/s.
PETE_TBTree< OpGE, Index::PETE_Expr_t, PETE_Scalar< double > > ge(const Index &idx, double x)
T::PETE_Expr_t::PETE_Return_t prod(const PETE_Expr< T > &expr)
Vector truncated power series in n variables.
Array1D< int > getSubstOrders(const FVps< T, N > &rhs, int trunc=(FTps< T, N >::EXACT)) const
Return orders {min, max, trc} of f(rhs(z)).
void setMinOrder(int order)
Set minimum order.
FVps substitute(const FMatrix< T, N, N > &M, int n) const
Substitute.
int getMaxOrder() const
Get highest order contained in any component.
void setMaxOrder(int order)
Set maximum order.
FVps derivative(int var) const
Partial derivative.
FVps filter(int minOrder, int maxOrder, int trcOrder=(FTps< T, N >::EXACT)) const
Extract given range of orders, with truncation.
int getTruncOrder() const
Get lowest truncation order in any component.
int getMinOrder() const
Get lowest order contained in any component.
iterator begin()
Get beginning of data.
A templated representation for one-dimensional arrays.
iterator begin()
Get iterator pointing to beginning of array.
A templated representation for matrices.
Truncated power series in N variables of type T.
static void deallocate(FTpsRep< T, N > *)
static const Array1D< int > & getProductArray(int index)
Index array for products of monomial "index".
FTps< T, N > makePower(int power) const
Multiply FTps with itself.
Array1D< int > getRepOrders() const
FTps substitute(const FMatrix< T, N, N > &M, int n) const
Substitute.
const T getCoefficient(int index) const
Get coefficient.
std::list< int > getListOfNonzeroCoefficients() const
Get a list containing the indexes of non-zero coefficients of a FTps.
FTps inverse(int trunc=EXACT) const
Reciprocal, 1/(*this).
FTps taylor(const Array1D< T > &series, int order) const
Taylor series.
FTps & operator/=(const FTps &y)
Divide and assign.
void setTruncOrder(int order)
Set truncation order.
std::istream & get(std::istream &is)
Read FTps on the stream [b]is[/b].
FTps & operator+=(const FTps &y)
Add and assign.
FTps()
Default constructor.
static FTps makeVarPower(int var, int power)
Make power.
FTps integral(int var, int trunc=EXACT) const
Partial integral.
int getMinOrder() const
Get minimum order.
static FTpsRep< T, N > * allocate(int minOrder, int maxOrder, int trcOrder)
FTps truncate(int trunc)
Truncate.
int getTruncOrder() const
Get truncation order.
static void checkOrders(const std::string &method, int minOrder, int maxOrder, int &trcOrder)
FTps multiply(const FTps &y, int trunc=EXACT) const
Multiplication.
std::ostream & put(std::ostream &os) const
Write FTps on the stream [b]os[/b].
const T operator[](int index) const
Get coefficient.
static const int EXACT
Representation of infinite precision.
FTps & operator-=(const FTps &y)
Subtract and assign.
FTps operator+() const
Unary plus.
static FTps makeMonomial(int index, const T &t)
Make monomial.
int getSize() const
Get total number of coefficients.
FTps & operator=(const FTps &y)
Assign.
static Array1D< T > evalMonoms(const FVector< T, N > &, int)
Evaluate monomials at point.
FTps multiplyVariable(int var, int trunc=EXACT) const
Multiply by variable [b]var[/b].
FTps derivative(int var) const
Partial derivative.
void unique()
Make representation unique.
FVps< T, N > gradient() const
Gradient.
bool operator!=(const FTps &y) const
Inequality operator.
FTps & operator*=(const FTps &y)
Multiply and assign.
T * begin() const
Return beginning of monomial array.
void setCoefficient(int index, const T &value)
Set coefficient.
static FTps makeVariable(int var)
Make variable.
static int orderEnd(int order)
Get one plus index at which [b]order[/b] ends.
static int globalTruncOrder
FTps divide(const FTps &y, int trunc=EXACT) const
Division.
static FTpsRep< T, N > * freeList[100]
T evaluate(const FVector< T, N > &) const
Evaluate FTps at point.
static void setGlobalTruncOrder(int order)
Set the global truncation order.
static const Array1D< TpsSubstitution > & getSubTable()
Return the substitution table.
int getMaxOrder() const
Get maximum order.
static int orderStart(int order)
Get index at which [b]order[/b] starts.
void setMaxOrder(int order)
Set maximum order.
T * end() const
Return end of monomial array.
Array1D< int > getSubstOrders(const FVps< T, N > &rhs, int trunc=EXACT) const
Return orders {min, max, trc} of f(rhs(z)).
static const FMonomial< N > & getExponents(int index)
Get exponents for given index.
bool operator==(const FTps &y) const
Equality operator.
static const Array1D< int > & getVariableList(int index)
List of variables contained in monomial "index".
FTps scaleMonomials(const FTps &y) const
Scale monomial coefficients by coefficients in [b]y[/b].
FTps filter(int minOrder, int maxOrder, int trcOrder=EXACT) const
Extract given range of orders, with truncation.
FArray1D< int, N > extractExponents(int index) const
Extract exponents of coefficient.
FTps operator-() const
Unary minus.
static int getIndex(const FMonomial< N > &mono)
Get Giorgilli index for monomial.
void setMinOrder(int order)
Set minimum order.
void grow(int maxOrder, int trcOrder)
Representation of the exponents for a monomial with fixed dimension.
int getOrder() const
Compute the monomial's order.
FTpsRep(int minOrder, int maxOrder, int trcOrder)
T * begin(int order) const
A templated representation for vectors.
static int orderEnd(int order)
static const FMonomial< N > & getExponents(int index)
static int getIndex(const FMonomial< N > &)
static const Array1D< TpsSubstitution > & getSubTable()
static int getOrder(int index)
static int getSize(int order)
static const Array1D< int > & getVariableList(int index)
static void setup(int order)
static int orderStart(int order)
static const Array1D< int > & getProductArray(int index)
Convergence error exception.