1 #ifndef CLASSIC_FTps_CC
2 #define CLASSIC_FTps_CC
52 template<
class T,
int N>
55 template <
class T,
int 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"
239 <<
" Ignoring request because index < 0." <<
std::endl;
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);
635 const T *f = begin();
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;
841 const T *f = 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;
866 template <
class T,
int N>
869 const T *f = begin();
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>
939 const T *f = 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++;
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)];
1115 const T *fj = begin(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;
1411 const T *f = begin();
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;
1461 const T *f = begin();
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)");
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>
2098 std::ostream &operator<<(std::ostream &os, const FTps<T, N> &tps) {
2102 #endif // CLASSIC_FTps_CC
static const Array1D< int > & getProductArray(int index)
Matrix< T > operator+(const Matrix< T > &, const Matrix< T > &)
Matrix addition.
FTps operator+() const
Unary plus.
static void checkOrders(const std::string &method, int minOrder, int maxOrder, int &trcOrder)
Array1D< int > getRepOrders() const
Matrix< T > operator/(const Matrix< T > &, const T &)
Matrix divided by scalar.
FTps truncate(int trunc)
Truncate.
void setMinOrder(int order)
Set minimum order.
FVps derivative(int var) const
Partial derivative.
int getMaxOrder() const
Get maximum order.
static const Array1D< TpsSubstitution > & getSubTable()
bool operator!=(const FTps &y) const
Inequality operator.
Array1D< int > getSubstOrders(const FVps< T, N > &rhs, int trunc=EXACT) const
Return orders {min, max, trc} of f(rhs(z)).
FTpsRep(int minOrder, int maxOrder, int trcOrder)
A templated representation for vectors.
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
int getMinOrder() const
Get minimum order.
FTps & operator+=(const FTps &y)
Add and assign.
Representation of the exponents for a monomial with fixed dimension.
static int orderStart(int order)
static void setup(int order)
Matrix< T > operator*(const Matrix< T > &, const Matrix< T > &)
Matrix multiply.
static const Array1D< int > & getVariableList(int index)
iterator begin()
Get iterator pointing to beginning of array.
FTps< T, N > makePower(int power) const
Multiply FTps with itself.
std::list< int > getListOfNonzeroCoefficients() const
Get a list containing the indexes of non-zero coefficients of a FTps.
static FTps makeMonomial(int index, const T &t)
Make monomial.
Array1D< int > getSubstOrders(const FVps< T, N > &rhs, int trunc=(FTps< T, N >::EXACT)) const
Return orders {min, max, trc} of f(rhs(z)).
static int orderEnd(int order)
void setMaxOrder(int order)
Set maximum order.
PETE_TBTree< OpGE, Index::PETE_Expr_t, PETE_Scalar< double > > ge(const Index &idx, double x)
FTps multiplyVariable(int var, int trunc=EXACT) const
Multiply by variable [b]var[/b].
FTps multiply(const FTps &y, int trunc=EXACT) const
Multiplication.
static int orderStart(int order)
Get index at which [b]order[/b] starts.
FTps divide(const FTps &y, int trunc=EXACT) const
Division.
static int getSize(int order)
Tps< T > PoissonBracket(const Tps< T > &x, const Tps< T > &y)
Poisson bracket.
int getTruncOrder() const
Get lowest truncation order in any component.
FTps()
Default constructor.
iterator begin()
Get beginning of data.
static const Array1D< int > & getVariableList(int index)
List of variables contained in monomial "index".
static const Array1D< int > & getProductArray(int index)
Index array for products of monomial "index".
std::istream & get(std::istream &is)
Read FTps on the stream [b]is[/b].
FVps< T, N > gradient() const
Gradient.
int getSize() const
Get total number of coefficients.
const T operator[](int index) const
Get coefficient.
Internal utility class for FTps<T,N> class.
constexpr double c
The velocity of light in m/s.
void setMaxOrder(int order)
Set maximum order.
bool operator==(const FTps &y) const
Equality operator.
Convergence error exception.
void unique()
Make representation unique.
static int getOrder(int index)
FVps< T, N > ExpMap(const FTps< T, N > &H, int trunc=FTps< T, N >::EXACT)
Build the exponential series.
FTps & operator-=(const FTps &y)
Subtract and assign.
const T getCoefficient(int index) const
Get coefficient.
int getTruncOrder() const
Get truncation order.
static int getIndex(const FMonomial< N > &)
FTps & operator=(const FTps &y)
Assign.
FTps substitute(const FMatrix< T, N, N > &M, int n) const
Substitute.
static Array1D< T > evalMonoms(const FVector< T, N > &, int)
Evaluate monomials at point.
FVps filter(int minOrder, int maxOrder, int trcOrder=(FTps< T, N >::EXACT)) const
Extract given range of orders, with truncation.
T evaluate(const FVector< T, N > &) const
Evaluate FTps at point.
FTps scaleMonomials(const FTps &y) const
Scale monomial coefficients by coefficients in [b]y[/b].
std::ostream & put(std::ostream &os) const
Write FTps on the stream [b]os[/b].
FArray1D< int, N > extractExponents(int index) const
Extract exponents of coefficient.
T * end() const
Return end of monomial array.
static void deallocate(FTpsRep< T, N > *)
FTps derivative(int var) const
Partial derivative.
static const FMonomial< N > & getExponents(int index)
FTps taylor(const Array1D< T > &series, int order) const
Taylor series.
bool operator!=(const Offset &off1, const Offset &off2)
int getMaxOrder() const
Get highest order contained in any component.
FTps filter(int minOrder, int maxOrder, int trcOrder=EXACT) const
Extract given range of orders, with truncation.
int getOrder() const
Compute the monomial's order.
void grow(int maxOrder, int trcOrder)
FTps inverse(int trunc=EXACT) const
Reciprocal, 1/(*this).
FTps operator-() const
Unary minus.
static const FMonomial< N > & getExponents(int index)
Get exponents for given index.
FTps & operator/=(const FTps &y)
Divide and assign.
static void setGlobalTruncOrder(int order)
Set the global truncation order.
static FTps makeVarPower(int var, int power)
Make power.
void setMinOrder(int order)
Set minimum order.
T::PETE_Expr_t::PETE_Return_t prod(const PETE_Expr< T > &expr)
FTps integral(int var, int trunc=EXACT) const
Partial integral.
static int orderEnd(int order)
Get one plus index at which [b]order[/b] ends.
void setTruncOrder(int order)
Set truncation order.
Truncated power series in N variables of type T.
Matrix< T > operator-(const Matrix< T > &, const Matrix< T > &)
Matrix subtraction.
FVps substitute(const FMatrix< T, N, N > &M, int n) const
Substitute.
static int getIndex(const FMonomial< N > &mono)
Get Giorgilli index for monomial.
int getMinOrder() const
Get lowest order contained in any component.
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
static const Array1D< TpsSubstitution > & getSubTable()
Return the substitution table.
Vector truncated power series in n variables.
static FTps makeVariable(int var)
Make variable.
static FTpsRep< T, N > * allocate(int minOrder, int maxOrder, int trcOrder)
std::istream & operator>>(std::istream &, LieMap< T > &x)
Extract LieMap<T> from stream.
T * begin(int order) const
void setCoefficient(int index, const T &value)
Set coefficient.
Inform & endl(Inform &inf)
T * begin() const
Return beginning of monomial array.
bool operator==(const TwoPolynomial &left, const TwoPolynomial &right)
FTps & operator*=(const FTps &y)
Multiply and assign.