1 #ifndef CLASSIC_FTps_CC
2 #define CLASSIC_FTps_CC
52 template<
class T,
int N>
55 template <
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);
117 template <
class T,
int N>
119 next(0),
ref(1), minOrd(minOrder), maxOrd(maxOrder), trcOrd(trcOrder) {
128 template <
class T,
int N>
134 template <
class T,
int N>
136 clear(minOrd, maxOrd);
140 template <
class T,
int N>
151 template <
class T,
int N>
154 template <
class T,
int N>
158 template <
class T,
int N>
160 itsRep = allocate(0, 0, EXACT);
161 itsRep->data[0] =
T(0);
165 template <
class T,
int N>
172 template <
class T,
int N>
174 itsRep = allocate(minOrder, maxOrder, trcOrder);
175 itsRep->clear(minOrder, maxOrder);
179 template <
class T,
int N>
181 itsRep = allocate(0, 0, EXACT);
182 itsRep->data[0] = rhs;
186 template <
class T,
int N>
188 itsRep = allocate(0, 0, EXACT);
189 itsRep->data[0] =
T(rhs);
193 template <
class T,
int N>
196 if(itsRep->ref == 0) deallocate(itsRep);
200 template <
class T,
int N>
202 if(itsRep != rhs.
itsRep) {
204 if(itsRep->ref == 0) deallocate(itsRep);
212 template <
class T,
int N>
215 if(itsRep->ref == 0) deallocate(itsRep);
216 itsRep = allocate(0, 0, EXACT);
217 itsRep->data[0] =
T(rhs);
222 template <
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];
235 template <
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;
260 template <
class T,
int N>
263 return getCoefficient(index);
267 template <
class T,
int N>
270 setCoefficient(index, value);
274 template <
class T,
int N>
276 return itsRep->data[index];
280 template <
class T,
int N>
283 return itsRep->data[index];
287 template <
class T,
int N>
290 return itsRep->data[index];
294 template <
class T,
int N>
298 return itsRep->data[index];
302 template <
class T,
int N>
308 template <
class T,
int N>
314 template <
class T,
int N>
320 template <
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;
356 template <
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;
392 template <
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;
418 template <
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;
432 template <
class T,
int N>
438 template <
class T,
int N>
444 template <
class T,
int N>
450 template <
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));
474 template <
class T,
int N>
inline
476 return filter(0, trunc, trunc);
480 template <
class T,
int N>
483 result[var + 1] =
T(1);
488 template <
class T,
int N>
498 template <
class T,
int N>
507 template <
class T,
int N>
516 template <
class T,
int N>
522 template <
class T,
int N>
527 std::transform(
begin(minOrder),
end(maxOrder), result.
begin(minOrder), std::negate<T>());
532 template <
class T,
int N>
534 return *
this = *
this + rhs;
538 template <
class T,
int N>
540 return *
this = *
this - rhs;
544 template <
class T,
int N>
546 return *
this = multiply(rhs);
550 template <
class T,
int N>
552 return *
this = divide(rhs);
556 template <
class T,
int N>
560 itsRep->data[0] += rhs;
565 template <
class T,
int N>
569 itsRep->data[0] -= rhs;
574 template <
class T,
int N>
578 std::bind(std::multiplies<T>(), std::placeholders::_1, rhs));
582 template <
class T,
int N>
584 if(rhs ==
T(0))
throw DivideError(
"FTps::operator/=()");
585 return *
this *=
T(1) / rhs;
588 template <
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.");
609 template <
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];
649 template <
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);
706 template <
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;
760 template <
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;
830 template <
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;
866 template <
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;
885 template <
class T,
int N>
887 return !(*
this == rhs);
891 template <
class T,
int N>
893 return !(*
this == rhs);
897 template <
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++;
933 template <
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++;
1007 template <
class T,
int N>
1021 template <
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;
1048 #ifdef DEBUG_FTps_CC
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;
1074 template <
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));
1093 #ifdef DEBUG_FTps_CC
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];
1173 template <
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));
1194 #ifdef DEBUG_FTps_CC
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];
1301 template <
class T,
int N>
1307 template <
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];
1395 template <
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++;
1432 template <
class T,
int N>
1435 for(
int i = 0; i < N; ++i) result[i] =
derivative(i);
1440 template <
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) {
1480 template <
class T,
int N>
1487 for(
int m = 1; m <= order; ++m) {
1497 result.
itsRep->data[0] = series[order-m];
1504 template <
class T,
int N>
inline
1506 if(itsRep->ref > 1) {
1510 std::copy(oldRep->
begin(), oldRep->
end(itsRep->maxOrd), itsRep->begin());
1514 template <
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);
1534 template <
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];
1554 template <
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);
1570 template <
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;
1647 template <
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);
1690 template <
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;
1711 #ifdef DEBUG_FTps_CC
1713 std::cerr <<
" <*** allocOrder error ***> " << allocOrder <<
" != " << rep->
allocOrd <<
std::endl;
1725 template <
class T,
int N>
inline
1733 template <
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);
1755 template <
class T,
int N>
1758 result[0] = itsRep->minOrd;
1759 result[1] = itsRep->maxOrd;
1760 result[2] = itsRep->trcOrd;
1761 result[3] = itsRep->allocOrd;
1766 template <
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;
1801 template <
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];
1857 template <
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];
1913 template <
class T,
int N>
1916 return result += rhs;
1920 template <
class T,
int N>
1923 return result -= rhs;
1927 template <
class T,
int N>
1930 return result += lhs;
1934 template <
class T,
int N>
1937 return result += lhs;
1941 template <
class T,
int N>
1948 template <
class T,
int N>
1954 template <
class T,
int N>
1957 return result *= rhs;
1961 template <
class T,
int N>
1964 return result /= rhs;
1968 template <
class T,
int N>
1971 return result *= lhs;
1975 template <
class T,
int N>
1981 template <
class T,
int N>
1987 template <
class T,
int N>
2004 const int MAX_ITER = 100;
2011 #ifdef DEBUG_FTps_CC
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);
2057 template <
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) {
2091 template <
class T,
int N>
2097 template <
class T,
int N>
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
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].
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)
Divide.
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)
Multiply.
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)
Subtract.
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.
T * begin() const
Return beginning of monomial array.
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 * end() const
Return end 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.
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.
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.