1#ifndef __JTOOLS__JPOLINT__
2#define __JTOOLS__JPOLINT__
39 template<
unsigned int N,
41 template<
class,
class>
class JCollection_t,
54 template<
unsigned int N,
class JElement_t,
template<
class,
class>
class JCollection_t,
class JDistance_t>
60 public JCollection_t<JElement_t, JDistance_t>,
61 public virtual JFunctional<typename JElement_t::abscissa_type,
62 typename JResultType<typename JElement_t::ordinate_type>::result_type>
75 typedef typename collection_type::iterator
iterator;
107 if (this->size() > 1u) {
111 if ((p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) ||
112 (p == this->end() && this->getDistance((--p)->getX(), x) > distance_type::precision)) {
115 return this->getExceptionHandler().action();
119 std::ostringstream os;
121 os << __FILE__ <<
':' << __LINE__ <<
" abscissa out of range "
122 <<
STREAM(
"?") << x <<
" <> "
123 <<
STREAM(
"?") << this->begin() ->getX() <<
' '
124 <<
STREAM(
"?") << this->rbegin()->getX();
133 const int n = std::min((
int) (N + 1), (
int) this->size());
135 for (
int i =
n/2; i != 0 && p != this->end(); --i, ++p) {}
136 for (
int i =
n ; i != 0 && p != this->begin(); --i, --p) {}
143 for (
int i = 0; i !=
n; ++p, ++i) {
145 u[i] = this->getDistance(x, p->getX());
146 v[i] = function_type::getValue(p->getY(),
pX);
149 if (fabs(u[i]) < fabs(u[
j])) {
159 for (
int m = 1; m !=
n; ++m) {
161 for (
int i = 0; i !=
n-m; ++i) {
163 const double ho = u[ i ];
164 const double hp = u[i+m];
165 const double dx = ho - hp;
183 }
else if (this->size() == 1u && this->getDistance(x, this->begin()->getX()) <= distance_type::precision) {
185 return function_type::getValue(this->begin()->getY(), ++
pX);
190 return this->getExceptionHandler().action();
194 std::ostringstream os;
196 os << __FILE__ <<
':' << __LINE__ <<
" not enough data " <<
STREAM(
"?") << x;
216 template<
class JElement_t,
template<
class,
class>
class JCollection_t,
class JDistance_t>
222 public JCollection_t<JElement_t, JDistance_t>,
223 public virtual JFunctional<typename JElement_t::abscissa_type,
224 typename JResultType<typename JElement_t::ordinate_type>::result_type>
237 typedef typename collection_type::iterator
iterator;
265 if (this->size() > 1u) {
269 if ((p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) ||
270 (p == this->end() && this->getDistance((--p)->getX(), x) > distance_type::precision)) {
273 return this->getExceptionHandler().action();
277 std::ostringstream os;
279 os << __FILE__ <<
':' << __LINE__ <<
" abscissa out of range "
280 <<
STREAM(
"?") << x <<
" <> "
281 <<
STREAM(
"?") << this->begin() ->getX() <<
' '
282 <<
STREAM(
"?") << this->rbegin()->getX();
293 if (q == this->begin() || this->getDistance(x, q->getX()) < this->getDistance(p->getX(), x))
294 return function_type::getValue(q->getY(),
pX);
296 return function_type::getValue(p->getY(),
pX);
298 }
else if (this->size() == 1u && this->getDistance(x, this->begin()->getX()) <= distance_type::precision) {
300 return function_type::getValue(this->begin()->getY(), ++
pX);
305 return this->getExceptionHandler().action();
309 std::ostringstream os;
311 os << __FILE__ <<
':' << __LINE__ <<
" not enough data " <<
STREAM(
"?") << x;
331 template<
class JElement_t,
template<
class,
class>
class JCollection_t,
class JDistance_t>
337 public JCollection_t<JElement_t, JDistance_t>,
338 public virtual JFunctional<typename JElement_t::abscissa_type,
339 typename JResultType<typename JElement_t::ordinate_type>::result_type>
352 typedef typename collection_type::iterator
iterator;
380 if (this->size() > 1u) {
384 if ((p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) ||
385 (p == this->end() && this->getDistance((--p)->getX(), x) > distance_type::precision)) {
388 return this->getExceptionHandler().action();
392 std::ostringstream os;
394 os << __FILE__ <<
':' << __LINE__ <<
" abscissa out of range "
395 <<
STREAM(
"?") << x <<
" <> "
396 <<
STREAM(
"?") << this->begin() ->getX() <<
' '
397 <<
STREAM(
"?") << this->rbegin()->getX();
408 const double dx = this->getDistance(p->getX(), q->getX());
409 const double a = this->getDistance(x, q->getX()) / dx;
410 const double b = 1.0 - a;
422 }
else if (this->size() == 1u && this->getDistance(x, this->begin()->getX()) <= distance_type::precision) {
424 return function_type::getValue(this->begin()->getY(), ++
pX);
429 return this->getExceptionHandler().action();
433 std::ostringstream os;
435 os << __FILE__ <<
':' << __LINE__ <<
" not enough data " <<
STREAM(
"?") << x;
461 template<
unsigned int N,
class JElement_t,
template<
class,
class>
class JCollection_t,
class JDistance_t>
467 public JCollection_t<JElement_t, JDistance_t>,
468 public virtual JFunctional<typename JElement_t::abscissa_type,
469 JResultPDF<typename JResultType<typename JElement_t::ordinate_type>::result_type> >
482 typedef typename collection_type::iterator
iterator;
519 if (this->size() <= 1u) {
522 return this->getExceptionHandler().action();
526 std::ostringstream os;
528 os << __FILE__ <<
':' << __LINE__ <<
" not enough data " <<
STREAM(
"?") << x;
536 if (p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) {
540 result = this->getExceptionHandler().action();
545 result.V = this->rbegin()->getIntegral();
549 std::ostringstream os;
551 os << __FILE__ <<
':' << __LINE__ <<
" abscissa out of range " <<
STREAM(
"?") << x <<
" < " <<
STREAM(
"?") << this->begin() ->getX();
558 }
else if (p == this->end() && this->getDistance((--p)->getX(), x) > distance_type::precision) {
562 result = this->getExceptionHandler().action();
566 result.v = this->rbegin()->getIntegral();
567 result.V = this->rbegin()->getIntegral();
571 std::ostringstream os;
573 os << __FILE__ <<
':' << __LINE__ <<
" abscissa out of range " <<
STREAM(
"?") << x <<
" > " <<
STREAM(
"?") << this->rbegin()->getX();
584 const int n = std::min((
int) (N + 1), (
int) this->size());
586 for (
int i =
n/2; i != 0 && p != this->end(); --i, ++p) {}
587 for (
int i =
n ; i != 0 && p != this->begin(); --i, --p) {}
596 for (
int i = 0; i !=
n; ++p, ++i) {
598 u[i] = this->getDistance(x, p->getX());
602 w[i][2] = v[i][2] = p->getIntegral();
604 if (fabs(u[i]) < fabs(u[
j])) {
613 result.V = this->rbegin()->getIntegral();
617 for (
int m = 1; m !=
n; ++m) {
619 for (
int i = 0; i !=
n-m; ++i) {
621 const double ho = u[ i ];
622 const double hp = u[i+m];
623 const double dx = ho - hp;
625 for (
int k = 0; k != 3; ++k) {
626 r[k] = (v[i+1][k] - w[i][k]) / dx;
631 v[i][1] = ho * r[1] - r[0];
632 w[i][1] = hp * r[1] - r[0];
637 if (2*(
j+1) <
n - m) {
665 if (this->getSize() > 1) {
669 this->begin()->setIntegral(V);
671 for (
iterator j = this->begin(), i =
j++;
j != this->end(); ++i, ++
j) {
678 const abscissa_type x = 0.5 * (xmax + xmin + m->getX() * (xmax - xmin));
694 template<
unsigned int N,
696 template<
class,
class>
class JCollection_t,
707 template<
unsigned int N,
class JElement_t,
template<
class,
class>
class JCollection_t,
class JDistance_t,
unsigned int M>
713 public JCollection_t<JElement_t, JDistance_t>,
719 typedef JCollection_t<JElement_t, JDistance_t> collection_type;
721 typedef typename collection_type::abscissa_type abscissa_type;
722 typedef typename collection_type::ordinate_type ordinate_type;
723 typedef typename collection_type::value_type value_type;
724 typedef typename collection_type::distance_type distance_type;
726 typedef typename collection_type::const_iterator const_iterator;
727 typedef typename collection_type::const_reverse_iterator const_reverse_iterator;
728 typedef typename collection_type::iterator iterator;
729 typedef typename collection_type::reverse_iterator reverse_iterator;
731 typedef typename JResultType<ordinate_type>::result_type data_type;
732 typedef JFunctional<abscissa_type, JResultPolynome<M, data_type> > function_type;
734 typedef typename function_type::argument_type argument_type;
735 typedef typename function_type::result_type result_type;
737 using JFunctional<>::compile;
753 result_type evaluate(const argument_type* pX) const
756 data_type v[N+1][M+1];
757 data_type w[N+1][M+1];
762 const argument_type x = *pX;
764 if (this->size() <= N) {
766 std::ostringstream os;
768 os << __FILE__ << ':' << __LINE__ << " not enough data " << STREAM("?") << x;
770 throw JFunctionalException(os.str());
773 const_iterator p = this->lower_bound(x);
775 if ((p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) ||
776 (p == this->end() && this->getDistance((--p)->getX(), x) > distance_type::precision)) {
778 std::ostringstream os;
780 os << __FILE__ << ':' << __LINE__ << " abscissa out of range "
781 << STREAM("?") << x << " <> "
782 << STREAM("?") << this->begin() ->getX() << ' '
783 << STREAM("?") << this->rbegin()->getX();
785 throw JValueOutOfRange(os.str());
791 const int n = std::min((int) (N + 1), (int) this->size());
793 for (int i = n/2; i != 0 && p != this->end(); --i, ++p) {}
794 for (int i = n ; i != 0 && p != this->begin(); --i, --p) {}
797 for (unsigned int k = 0; k != M+1; ++k) {
798 v[0][k] = JMATH::zero;
803 for (int i = 0; i != n; ++p, ++i) {
805 u[i] = this->getDistance(x, p->getX());
807 w[i][0] = v[i][0] = JFunctional<argument_type, data_type>::getValue(p->getY(), pX);
809 for (unsigned int k = 1; k != M+1; ++k) {
810 w[i][k] = v[i][k] = JMATH::zero;
813 if (fabs(u[i]) < fabs(u[j])) {
819 for (unsigned int k = 0; k != M+1; ++k) {
820 result.y[k] = v[j][k];
825 for (int m = 1; m != n; ++m) {
827 for (int i = 0; i != n-m; ++i) {
829 const double ho = u[ i ];
830 const double hp = u[i+m];
831 const double dx = ho - hp;
833 for (int k = 0; k != M+1; ++k) {
834 r[k] = (v[i+1][k] - w[i][k]) / dx;
840 for (int k = 1; k != M+1; ++k) {
841 v[i][k] = ho * r[k] - k * r[k-1];
842 w[i][k] = hp * r[k] - k * r[k-1];
846 if (2*(j+1) < n - m) {
848 for (int k = 0; k != M+1; ++k) {
849 result.y[k] += v[j+1][k];
854 for (int k = 0; k != M+1; ++k) {
855 result.y[k] += w[j][k];
869 virtual void do_compile() override
877 template<unsigned int N, class JElement_t, template<class, class> class JCollection_t, class JDistance_t, unsigned int M>
878 class JPolintFunction<N,
881 JResultPolynome<M, typename JResultType<typename JElement_t::ordinate_type>::result_type>,
883 public JPolintCollection<N,
886 JResultPolynome<M, typename JResultType<typename JElement_t::ordinate_type>::result_type>,
888 public virtual JFunctional<typename JElement_t::abscissa_type,
889 JResultPolynome<N, typename JResultType<typename JElement_t::ordinate_type>::result_type> >
893 typedef JPolintCollection<N,
896 JResultPolynome<M, typename JResultType<typename JElement_t::ordinate_type>::result_type>,
897 JDistance_t> collection_type;
899 typedef typename collection_type::abscissa_type abscissa_type;
900 typedef typename collection_type::ordinate_type ordinate_type;
901 typedef typename collection_type::value_type value_type;
902 typedef typename collection_type::distance_type distance_type;
904 typedef typename collection_type::const_iterator const_iterator;
905 typedef typename collection_type::const_reverse_iterator const_reverse_iterator;
906 typedef typename collection_type::iterator iterator;
907 typedef typename collection_type::reverse_iterator reverse_iterator;
909 typedef typename JResultType<ordinate_type>::result_type data_type;
910 typedef JFunctional<abscissa_type, JResultPolynome<M, data_type> > function_type;
912 typedef typename function_type::argument_type argument_type;
913 typedef typename function_type::result_type result_type;
914 typedef typename function_type::JExceptionHandler exceptionhandler_type;
930 virtual result_type evaluate(const argument_type* pX) const override
933 return collection_type::evaluate(pX);
935 catch(const JException& error) {
936 return this->getExceptionHandler().action(error);
945 template<unsigned int N, class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
946 class JPolintFunction<N,
949 JResultDerivative<typename JResultType<typename JElement_t::ordinate_type>::result_type>,
951 public JPolintCollection<N,
954 JResultPolynome<1, typename JResultType<typename JElement_t::ordinate_type>::result_type>,
956 public virtual JFunctional<typename JElement_t::abscissa_type,
957 JResultDerivative<typename JResultType<typename JElement_t::ordinate_type>::result_type> >
961 typedef JPolintCollection<N,
964 JResultPolynome<1, typename JResultType<typename JElement_t::ordinate_type>::result_type>,
965 JDistance_t> collection_type;
967 typedef typename collection_type::abscissa_type abscissa_type;
968 typedef typename collection_type::ordinate_type ordinate_type;
969 typedef typename collection_type::value_type value_type;
970 typedef typename collection_type::distance_type distance_type;
972 typedef typename collection_type::const_iterator const_iterator;
973 typedef typename collection_type::const_reverse_iterator const_reverse_iterator;
974 typedef typename collection_type::iterator iterator;
975 typedef typename collection_type::reverse_iterator reverse_iterator;
977 typedef typename JResultType<ordinate_type>::result_type data_type;
978 typedef JFunctional<abscissa_type, JResultDerivative<data_type> > function_type;
980 typedef typename function_type::argument_type argument_type;
981 typedef typename function_type::result_type result_type;
982 typedef typename function_type::JExceptionHandler exceptionhandler_type;
984 using JFunctional<>::compile;
1000 virtual result_type evaluate(const argument_type* pX) const override
1003 return collection_type::evaluate(pX);
1005 catch(const JException& error) {
1006 return this->getExceptionHandler().action(error);
1015 template<unsigned int N, class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
1016 class JPolintFunction<N,
1019 JResultHesse<typename JResultType<typename JElement_t::ordinate_type>::result_type>,
1021 public JPolintCollection<N,
1024 JResultPolynome<2, typename JResultType<typename JElement_t::ordinate_type>::result_type>,
1026 public virtual JFunctional<typename JElement_t::abscissa_type,
1027 JResultHesse<typename JResultType<typename JElement_t::ordinate_type>::result_type> >
1031 typedef JPolintCollection<N,
1034 JResultPolynome<2, typename JResultType<typename JElement_t::ordinate_type>::result_type>,
1035 JDistance_t> collection_type;
1037 typedef typename collection_type::abscissa_type abscissa_type;
1038 typedef typename collection_type::ordinate_type ordinate_type;
1039 typedef typename collection_type::value_type value_type;
1040 typedef typename collection_type::distance_type distance_type;
1042 typedef typename collection_type::const_iterator const_iterator;
1043 typedef typename collection_type::const_reverse_iterator const_reverse_iterator;
1044 typedef typename collection_type::iterator iterator;
1045 typedef typename collection_type::reverse_iterator reverse_iterator;
1047 typedef typename JResultType<ordinate_type>::result_type data_type;
1048 typedef JFunctional<abscissa_type, JResultHesse<data_type> > function_type;
1050 typedef typename function_type::argument_type argument_type;
1051 typedef typename function_type::result_type result_type;
1052 typedef typename function_type::JExceptionHandler exceptionhandler_type;
1054 using JFunctional<>::compile;
1070 virtual result_type evaluate(const argument_type* pX) const override
1073 return collection_type::evaluate(pX);
1075 catch(const JException& error) {
1076 return this->getExceptionHandler().action(error);
1087 template<unsigned int N,
1089 template<class, class> class JCollection_t,
1090 class JResult_t = typename JElement_t::ordinate_type,
1091 class JDistance_t = JDistance<typename JElement_t::abscissa_type> >
1092 class JPolintFunction1D :
1093 public JPolintFunction<N, JElement_t, JCollection_t, JResult_t, JDistance_t>,
1094 public JFunction1D<typename JElement_t::abscissa_type, JResult_t>
1098 typedef JCollection_t<JElement_t, JDistance_t> collection_type;
1100 typedef typename collection_type::abscissa_type abscissa_type;
1101 typedef typename collection_type::ordinate_type ordinate_type;
1102 typedef typename collection_type::value_type value_type;
1103 typedef typename collection_type::distance_type distance_type;
1105 typedef typename collection_type::const_iterator const_iterator;
1106 typedef typename collection_type::const_reverse_iterator const_reverse_iterator;
1107 typedef typename collection_type::iterator iterator;
1108 typedef typename collection_type::reverse_iterator reverse_iterator;
1110 typedef JFunction1D<abscissa_type, JResult_t> function_type;
1112 typedef typename function_type::argument_type argument_type;
1113 typedef typename function_type::result_type result_type;
1114 typedef typename function_type::JExceptionHandler exceptionhandler_type;
1130 template<class JAbscissa_t, class JOrdinate_t>
1133 template<template<class, class, class> class JMap_t>
1134 struct JMapCollection;
1140 template<unsigned int N,
1143 template<class, class, class> class JMap_t,
1145 class JDistance_t = JDistance<JKey_t> >
1147 public JPolintFunction<N,
1148 JElement2D<JKey_t, JValue_t>,
1149 JMapCollection<JMap_t>::template collection_type,
1152 public JFunction<typename JElement2D<JKey_t, JValue_t>::abscissa_type, JResult_t>
1156 typedef JElement2D<JKey_t, JValue_t> element_type;
1157 typedef JPolintFunction<N,
1159 JMapCollection<JMap_t>::template collection_type,
1161 JDistance_t> JPolintFunction_t;
1163 typedef typename JPolintFunction_t::abscissa_type abscissa_type;
1164 typedef typename JPolintFunction_t::ordinate_type ordinate_type;
1165 typedef typename JPolintFunction_t::value_type value_type;
1166 typedef typename JPolintFunction_t::distance_type distance_type;
1168 typedef typename JPolintFunction_t::const_iterator const_iterator;
1169 typedef typename JPolintFunction_t::const_reverse_iterator const_reverse_iterator;
1170 typedef typename JPolintFunction_t::iterator iterator;
1171 typedef typename JPolintFunction_t::reverse_iterator reverse_iterator;
1173 typedef typename JPolintFunction_t::argument_type argument_type;
1174 typedef typename JPolintFunction_t::result_type result_type;
1175 typedef typename JPolintFunction_t::JExceptionHandler exceptionhandler_type;
1195 template<unsigned int N,
1197 template<class, class> class JCollection_t,
1200 inline typename JElement_t::ordinate_type
1201 integrate(const JPolintFunction1D<N, JElement_t, JCollection_t, JResult_t, JDistance_t>& input,
1202 typename JMappable<JElement_t>::map_type& output)
1204 return integrate(input, output, JLANG::JBool<N == 0 || N == 1>());
1219 template<unsigned int N,
1221 template<class, class> class JCollection_t,
1224 inline typename JElement_t::ordinate_type
1225 integrate(const JPolintFunction1D<N, JElement_t, JCollection_t, JResult_t, JDistance_t>& input,
1226 typename JMappable<JElement_t>::map_type& output,
1227 const JLANG::JBool<false>& option)
1229 typedef typename JElement_t::abscissa_type abscissa_type;
1230 typedef typename JElement_t::ordinate_type ordinate_type;
1231 typedef typename JPolintFunction1D<N, JElement_t, JCollection_t, JResult_t, JDistance_t>::const_iterator const_iterator;
1233 ordinate_type V(JMATH::zero);
1235 if (input.getSize() > 1) {
1237 output.put(input.begin()->getX(), V);
1239 const JGaussLegendre engine(N);
1241 for (const_iterator j = input.begin(), i = j++; j != input.end(); ++i, ++j) {
1243 const abscissa_type xmin = i->getX();
1244 const abscissa_type xmax = j->getX();
1246 for (JGaussLegendre::const_iterator m = engine.begin(); m != engine.end(); ++m) {
1248 const abscissa_type x = 0.5 * (xmax + xmin + m->getX() * (xmax - xmin));
1249 const ordinate_type v = 0.5 * (xmax - xmin) * m->getY() * get_value(input(x));
1254 output.put(xmax, V);
1272 template<class JElement_t,
1273 template<class, class> class JCollection_t,
1276 inline typename JElement_t::ordinate_type
1277 integrate(const JPolintFunction1D<0, JElement_t, JCollection_t, JResult_t, JDistance_t>& input,
1278 typename JMappable<JElement_t>::map_type& output,
1279 const JLANG::JBool<true>& option)
1281 typedef typename JElement_t::ordinate_type ordinate_type;
1282 typedef typename JPolintFunction1D<0, JElement_t, JCollection_t, JResult_t, JDistance_t>::const_iterator const_iterator;
1284 ordinate_type V(JMATH::zero);
1286 if (input.getSize() > 1) {
1288 output.put(input.begin()->getX(), V);
1290 for (const_iterator j = input.begin(), i = j++; j != input.end(); ++i, ++j) {
1292 V += input.getDistance(i->getX(), j->getX()) * j->getY();
1294 output.put(j->getX(), V);
1312 template<class JElement_t,
1313 template<class, class> class JCollection_t,
1316 inline typename JElement_t::ordinate_type
1317 integrate(const JPolintFunction1D<1, JElement_t, JCollection_t, JResult_t, JDistance_t>& input,
1318 typename JMappable<JElement_t>::map_type& output,
1319 const JLANG::JBool<true>& option)
1321 typedef typename JElement_t::ordinate_type ordinate_type;
1322 typedef typename JPolintFunction1D<1, JElement_t, JCollection_t, JResult_t, JDistance_t>::const_iterator const_iterator;
1324 ordinate_type V(JMATH::zero);
1326 if (input.getSize() > 1) {
1328 output.put(input.begin()->getX(), V);
1330 for (const_iterator j = input.begin(), i = j++; j != input.end(); ++i, ++j) {
1332 V += 0.5 * input.getDistance(i->getX(), j->getX()) * (i->getY() + j->getY());
1334 output.put(j->getX(), V);
The elements in a collection are sorted according to their abscissa values and a given distance opera...
Auxiliary classes for numerical integration.
This include file containes various data structures that can be used as specific return types for the...
Exception for a functional operation.
Exception for numerical precision error.
Exception for accessing a value in a collection that is outside of its range.
static const JZero zero
Function object to assign zero value.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Generation of compiler error.
Auxiliary data structure for handling std::ostream.