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);
117template <
class T,
int N>
119 next(0),
ref(1), minOrd(minOrder), maxOrd(maxOrder), trcOrd(trcOrder) {
128template <
class T,
int N>
134template <
class T,
int N>
136 clear(minOrd, maxOrd);
140template <
class T,
int N>
151template <
class T,
int N>
154template <
class T,
int N>
158template <
class T,
int N>
160 itsRep = allocate(0, 0, EXACT);
161 itsRep->data[0] =
T(0);
165template <
class T,
int N>
172template <
class T,
int N>
174 itsRep = allocate(minOrder, maxOrder, trcOrder);
175 itsRep->clear(minOrder, maxOrder);
179template <
class T,
int N>
181 itsRep = allocate(0, 0, EXACT);
182 itsRep->data[0] = rhs;
186template <
class T,
int N>
188 itsRep = allocate(0, 0, EXACT);
189 itsRep->data[0] =
T(rhs);
193template <
class T,
int N>
196 if(itsRep->ref == 0) deallocate(itsRep);
200template <
class T,
int N>
202 if(itsRep != rhs.
itsRep) {
204 if(itsRep->ref == 0) deallocate(itsRep);
212template <
class T,
int N>
215 if(itsRep->ref == 0) deallocate(itsRep);
216 itsRep = allocate(0, 0, EXACT);
217 itsRep->data[0] =
T(rhs);
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;
230 if(index < orderStart(itsRep->minOrd) || orderEnd(itsRep->maxOrd) <= index)
return T(0);
231 return itsRep->data[index];
235template <
class T,
int N>
238 std::cerr <<
" <*** WARNING ***> from FTps<T,N>::setCoefficient(index, value):\n"
246 if(order > itsRep->trcOrd)
return;
250 if(order > itsRep->allocOrd) grow(order, EXACT);
255 else if(order > itsRep->maxOrd)
setMaxOrder(order);
256 itsRep->data[index] = value;
260template <
class T,
int N>
263 return getCoefficient(index);
267template <
class T,
int N>
270 setCoefficient(index, value);
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.");
327 if(order > globalTruncOrder)
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;
337 order = itsRep->trcOrd;
341 else if(order > itsRep->allocOrd) grow(order, EXACT);
344 if(order > itsRep->maxOrd) {
345 itsRep->maxOrd = order;
346 itsRep->clear(order, order);
349 else if(order < itsRep->minOrd) itsRep->clear(order, itsRep->minOrd - 1);
352 itsRep->minOrd = order;
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.");
363 if(order > globalTruncOrder)
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;
373 order = itsRep->trcOrd;
377 else if(order > itsRep->allocOrd) grow(order, EXACT);
380 if(order > itsRep->maxOrd) itsRep->clear(itsRep->maxOrd + 1, order);
382 else if(order < itsRep->minOrd) {
383 itsRep->minOrd = order;
384 itsRep->clear(order, order);
388 itsRep->maxOrd = 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.");
397 if(order != EXACT && order > globalTruncOrder)
399 "Cannot set truncation order beyond globalTruncOrder.");
403 if(order < itsRep->minOrd) {
404 itsRep->minOrd = order;
405 itsRep->maxOrd = order;
406 itsRep->clear(order, order);
409 else if(order < itsRep->maxOrd) itsRep->maxOrd = order;
411 else if(order != EXACT && order > itsRep->allocOrd) grow(itsRep->maxOrd, order);
414 itsRep->trcOrd = 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.");
427 globalTruncOrder = 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);
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>
546 return *
this = multiply(rhs);
550template <
class T,
int N>
552 return *
this = divide(rhs);
556template <
class T,
int N>
560 itsRep->data[0] += rhs;
565template <
class T,
int N>
569 itsRep->data[0] -= rhs;
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);
634 FTps<T, N> result(1 + f_min, maxOrder, trcOrder);
640 int ie = orderStart(maxOrder);
641 for(
int i = orderStart(f_min); i < ie; i++)
642 g[product[i]] = f[i];
649template <
class T,
int N>
655 if(itsRep->trcOrd == EXACT) {
656 if(rhs.
itsRep->trcOrd == EXACT) trcOrder = EXACT;
657 else trcOrder = itsRep->minOrd + rhs.
itsRep->trcOrd;
658 }
else if(rhs.
itsRep->trcOrd == EXACT) trcOrder = itsRep->trcOrd + rhs.
itsRep->minOrd;
659 else trcOrder =
std::min(itsRep->trcOrd + rhs.
itsRep->minOrd, itsRep->minOrd + rhs.
itsRep->trcOrd);
660 trcOrder =
std::min(trcOrder, trunc);
661 int maxOrder =
std::min(itsRep->maxOrd + rhs.
itsRep->maxOrd, trcOrder);
662 int minOrder = itsRep->minOrd + rhs.
itsRep->minOrd;
664 if(minOrder <= maxOrder) {
666 FTps<T, N> result(minOrder, maxOrder, trcOrder);
672 int first_f = orderStart(itsRep->minOrd);
673 int first_g = orderStart(rhs.
itsRep->minOrd);
675 int f_max = itsRep->maxOrd;
679 for(
int gOrd = rhs.
itsRep->minOrd; gOrd <= g_max; gOrd++) {
681 int last_f = orderEnd(
std::min(f_max, maxOrder - gOrd));
682 int last_g = orderEnd(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>
711 T b0 = itsRep->data[0];
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);
721 if(trcOrder > globalTruncOrder)
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;
742 int start_c = orderStart(mc), end_c = orderEnd(mc);
743 int start_b = orderStart(mb), end_b = orderEnd(mb);
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;
752 int je = orderEnd(m);
753 for(
int j = orderStart(m); j < je; ++j)
c[j] *= neg_c0;
760template <
class T,
int N>
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); }
787 if(c_trc > globalTruncOrder)
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));
800 if(c_min == 0)
c[0] *= b0inv;
803 if(c_trc == 0)
return result;
807 for(
int m = mi; m <= c_max; ++m) {
809 for(
int mc = c_min; mc < m; ++mc) {
811 if(mb > b_max)
continue;
812 int start_c = orderStart(mc), end_c = orderEnd(mc);
813 int start_b = orderStart(mb), end_b = orderEnd(mb);
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;
822 int je = orderEnd(m);
823 for(
int j = orderStart(m); j < je; ++j)
c[j] *= b0inv;
830template <
class T,
int N>
832 if(itsRep == rhs.
itsRep)
return true;
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>
872 if(*f != rhs)
return false;
874 }
else if(rhs !=
T(0))
return false;
876 int i = orderStart(f_min);
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>
899 int size = getSize(maxOrder);
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>
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;
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;
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;
1074template <
class T,
int N>
1079 "Transformation order, n, is negative.");
1080 else if(
n > globalTruncOrder)
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;
1110 t =
new T[getSize(
n)];
1119 int start_n = orderStart(
n), end_n = orderEnd(
n);
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));
1153 int start_l = orderStart(ord1), end_l = orderEnd(ord1);
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.");
1182 else if(nh > globalTruncOrder)
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;
1208 std::fill(result.
begin(nl), result.
end(nh),
T(0));
1213 static const T **fp;
1214 static int max_nh = -1;
1220 t =
new T[getSize(nh)];
1221 fp =
new const T*[nh+1];
1228 for(
int m = nl; m <= nh; ++m) fp[m] =
begin(m);
1231 int start_nh = orderStart(nh), end_nh = orderEnd(nh), nh1 = nh - 1, nh2 = nh - 2;
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;
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));
1275 int start_l = orderStart(ord1), end_l = orderEnd(ord1);
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) {
1288 int start_m = orderStart(m), end_m = orderEnd(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];
1317 if(g_trc != EXACT && g_trc > globalTruncOrder)
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);
1341 int start_nh = orderStart(nh), end_nh = orderEnd(nh), nh1 = nh - 1, nh2 = nh - 2;
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;
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;
1413 T *dfe = df + orderEnd(df_max);
1414 int ks = orderStart(df_min);
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);
1451 if(maxOrder > globalTruncOrder || (trcOrder != EXACT && trcOrder > globalTruncOrder))
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;
1463 int is = orderStart(f_min);
1464 int ie = orderEnd(maxOrder - 1);
1472 for(
int i = is; i < ie; ++i) {
1480template <
class T,
int N>
1487 for(
int m = 1; m <= order; ++m) {
1497 result.
itsRep->data[0] = series[order-m];
1504template <
class T,
int N>
inline
1506 if(itsRep->ref > 1) {
1510 std::copy(oldRep->
begin(), oldRep->
end(itsRep->maxOrd), itsRep->begin());
1514template <
class T,
int N>
1518 int size = getSize();
1521 std::list<int> coeffs;
1524 for (
int i = 0; i < size; ++i) {
1526 if (getCoefficient(i) != 0) {
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) {
1565 result = result.
multiply(*
this, globalTruncOrder);
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 <<
' ';
1651 if(itsRep->trcOrd == EXACT)
1654 os << itsRep->trcOrd;
1659 std::streamsize old_prec = os.
precision(14);
1660 os.setf(std::ios::scientific, std::ios::floatfield);
1663 int i = orderStart(itsRep->minOrd);
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);
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;
1703 freeList[allocOrder] = rep->
next;
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;
1738 FTpsRep<T, N> *newRep = allocate(minOrder, maxOrder, trcOrder);
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);
1750 if(itsRep->ref == 0) deallocate(itsRep);
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.";
1777 else if(maxOrder > globalTruncOrder) {
1779 message =
"The argument maxOrder exceeds globalTruncOrder.";
1780 }
else if(trcOrder != EXACT && trcOrder > 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;
1801template <
class T,
int N>
1808 if(h_trc < f_min) h_max = g_max;
1809 else if(h_trc < g_min) h_max = f_max;
1822 const T *f = lhs.
begin();
1823 const T *g = rhs.
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>
1864 if(h_trc < f_min) h_max = g_max;
1865 else if(h_trc < g_min) h_max = f_max;
1878 const T *f = lhs.
begin();
1879 const T *g = rhs.
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>
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;}
2070 h_trc =
std::min(f_trc + g_min - 2, f_min + g_trc - 2);
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.
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)
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
T::PETE_Expr_t::PETE_Return_t prod(const PETE_Expr< T > &expr)
Inform & endl(Inform &inf)
constexpr double c
The velocity of light in m/s.
bool ge(double x, double y)
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.
iterator begin()
Get iterator pointing to beginning of array.
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.
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.
FTps divide(const FTps &y, int trunc=EXACT) const
Division.
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)
void clear(int minOrder, int maxOrder)
T * begin(int order) const
A templated representation for vectors.
Internal utility class for FTps<T,N> class.
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.