Jpp test-rotations-old
the software that should make you happy
Loading...
Searching...
No Matches
JHermiteSpline.hh
Go to the documentation of this file.
1#ifndef __JTOOLS__JHERMITESPLINE__
2#define __JTOOLS__JHERMITESPLINE__
3
4#include <utility>
5#include <sstream>
6#include <cmath>
7
8#include "JMath/JZero.hh"
9#include "JLang/JException.hh"
10#include "JLang/JClass.hh"
12#include "JTools/JFunctional.hh"
13#include "JTools/JDistance.hh"
14#include "JTools/JResult.hh"
17#include "JTools/JElement.hh"
18
19
20/**
21 * \author mdejong
22 */
23
24namespace JTOOLS {}
25namespace JPP { using namespace JTOOLS; }
26
27namespace JTOOLS {
28
29 using JLANG::JNoValue;
33
34
35 /**
36 * Template base class spline interpolations.
37 *
38 * This class implements the JFunctional interface.
39 *
40 * Note that the data structure of the elements in the collection should have the additional methods:
41 * <pre>
42 * ordinate_type getU() const;
43 * void setU(ordinate_type u);
44 * </pre>
45 * to get and set the derivatives, respectively.
46 *
47 * Note that -by default- the compilation is for a monotonous interpolation.
48 */
49 template<class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
51 public JCollection_t<JElement_t, JDistance_t>,
52 public virtual JFunctional<>
53 {
54 public:
55
56 typedef JCollection_t<JElement_t, JDistance_t> collection_type;
57
58 typedef typename collection_type::abscissa_type abscissa_type;
59 typedef typename collection_type::ordinate_type ordinate_type;
60 typedef typename collection_type::value_type value_type;
61 typedef typename collection_type::distance_type distance_type;
62
63 typedef typename collection_type::const_iterator const_iterator;
64 typedef typename collection_type::const_reverse_iterator const_reverse_iterator;
65 typedef typename collection_type::iterator iterator;
66 typedef typename collection_type::reverse_iterator reverse_iterator;
67
69
70
71 /**
72 * Determination of derivatives.
73 *
74 * \param monotone monotone
75 */
76 void compile(const bool monotone)
77 {
78 using namespace std;
79
80 if (this->size() >= 2u) {
81
82 {
83 iterator j = this->begin(), i = j++;
84
85 i->setU((j->getY() - i->getY()) / this->getDistance(i->getX(), j->getX()));
86 }
87
88 {
89 reverse_iterator j = this->rbegin(), i = j++;
90
91 i->setU((j->getY() - i->getY()) / this->getDistance(i->getX(), j->getX()));
92 }
93
94 for (iterator k = this->begin(), i = k++, j = k++; k != this->end(); ++i, ++j, ++k) {
95 j->setU(0.5 * ((j->getY() - i->getY()) / this->getDistance(i->getX(), j->getX()) +
96 (k->getY() - j->getY()) / this->getDistance(j->getX(), k->getX())));
97 }
98
99 if (monotone) {
100
101 for (iterator j = this->begin(), i = j++; j != this->end(); ++i, ++j) {
102 if (i->getY() == j->getY()) {
103 j->setU(JMATH::zero);
104 }
105 }
106
107 for (iterator j = this->begin(), i = j++; j != this->end(); ++i, ++j) {
108
109 const ordinate_type u = (j->getY() - i->getY()) / this->getDistance(i->getX(), j->getX());
110 const ordinate_type w = (i->getU()*i->getU() + j->getU()*j->getU());
111
112 if (w > 9.0*u*u) {
113
114 const ordinate_type v = 3.0*u/sqrt(w);
115
116 i->setU(v*i->getU());
117 j->setU(v*j->getU());
118 }
119 }
120 }
121 }
122 }
123
124
125 protected:
126
127 static abscissa_type h00 (abscissa_type t) { return (1.0 + 2*t) * (1.0 - t) * (1.0 - t); }
128 static abscissa_type h10 (abscissa_type t) { return t * (1.0 - t) * (1.0 - t); }
129 static abscissa_type h01 (abscissa_type t) { return t * t * (3.0 - 2*t); }
130 static abscissa_type h11 (abscissa_type t) { return t * t * (t - 1.0); }
131
132 static abscissa_type h00p(abscissa_type t) { return 6 * t * (t - 1.0); }
133 static abscissa_type h10p(abscissa_type t) { return t * (3*t - 4.0) + 1.0; }
134 static abscissa_type h01p(abscissa_type t) { return 6 * t * (1.0 -t); }
135 static abscissa_type h11p(abscissa_type t) { return t * (3*t - 2.0); }
136
137 static abscissa_type H00 (abscissa_type t) { return t * (t * t * (0.5*t - 1.0) + 1.0); }
138 static abscissa_type H10 (abscissa_type t) { return t * t * (t * (0.25*t - 2.0/3.0) + 0.5); }
139 static abscissa_type H01 (abscissa_type t) { return t * t * t * (1.0 - 0.5*t); }
140 static abscissa_type H11 (abscissa_type t) { return t * t * t * (0.25*t - 1.0/3.0); }
141
142
143 /**
144 * Default constructor.
145 */
148
149
150 /**
151 * Determination of derivatives.
152 */
153 virtual void do_compile() override
154 {
155 compile(true);
156 }
157 };
158
159
160 /**
161 * Template definition for functional collection with spline interpolation.
162 */
163 template<class JElement_t,
164 template<class, class> class JCollection_t,
165 class JResult_t,
166 class JDistance_t>
168
169
170 /**
171 * Template specialisation for functional collection with spline interpolation.
172 */
173 template<class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
174 class JHermiteSplineFunction<JElement_t,
175 JCollection_t,
176 typename JResultType<typename JElement_t::ordinate_type>::result_type,
177 JDistance_t> :
178 public JHermiteSplineCollection<JElement_t, JCollection_t, JDistance_t>,
179 public virtual JFunctional<typename JElement_t::abscissa_type,
180 typename JResultType<typename JElement_t::ordinate_type>::result_type>
181 {
182 public:
183
185
190
195
198
202
203
204 /**
205 * Default constructor.
206 */
209
210
211 /**
212 * Recursive interpolation method implementation.
213 *
214 * \param pX pointer to abscissa values
215 * \return function value
216 */
217 virtual result_type evaluate(const argument_type* pX) const override
218 {
219 const argument_type x = *pX;
220
221 if (this->size() <= 1u) {
222
223 try {
224 return this->getExceptionHandler().action();
225 }
226 catch (const JException& error) {
227
228 std::ostringstream os;
229
230 os << __FILE__ << ':' << __LINE__ << " not enough data " << STREAM("?") << x;
231
232 throw JFunctionalException(os.str());
233 }
234 }
235
236 const_iterator p = this->lower_bound(x);
237
238 if ((p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) ||
239 (p == this->end() && this->getDistance((--p)->getX(), x) > distance_type::precision)) {
240
241 try {
242 return this->getExceptionHandler().action();
243 }
244 catch (const JException& error) {
245
246 std::ostringstream os;
247
248 os << __FILE__ << ':' << __LINE__ << " abscissa out of range "
249 << STREAM("?") << x << " <> "
250 << STREAM("?") << this->begin() ->getX() << ' '
251 << STREAM("?") << this->rbegin()->getX();
252
253 throw JValueOutOfRange(os.str());
254 }
255 }
256
257 const_iterator q = p--;
258
259 const double dx = this->getDistance(p->getX(), q->getX());
260 const double t = this->getDistance(p->getX(), x) / dx;
261
262 return h00(t)*p->getY() + h10(t)*p->getU()*dx + h01(t)*q->getY() + h11(t)*q->getU()*dx;
263 }
264
265 protected:
266
267 using collection_type::h00;
268 using collection_type::h10;
269 using collection_type::h01;
270 using collection_type::h11;
271 };
272
273
274 /**
275 * Template specialisation for spline interpolation method with returning JResultDerivative data structure.
276 */
277 template<class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
278 class JHermiteSplineFunction<JElement_t,
279 JCollection_t,
280 JResultDerivative<typename JResultType<typename JElement_t::ordinate_type>::result_type>,
281 JDistance_t> :
282 public JHermiteSplineCollection<JElement_t, JCollection_t, JDistance_t>,
283 public virtual JFunctional<typename JElement_t::abscissa_type,
284 JResultDerivative<typename JResultType<typename JElement_t::ordinate_type>::result_type> >
285 {
286 public:
287
289
294
299
302
306
307
308 /**
309 * Default constructor.
310 */
313
314
315 /**
316 * Recursive interpolation method implementation.
317 *
318 * \param pX pointer to abscissa values
319 * \return function value
320 */
321 virtual result_type evaluate(const argument_type* pX) const override
322 {
324
325 const argument_type x = *pX;
326
327 if (this->size() <= 1u) {
328
329 try {
330 return this->getExceptionHandler().action();
331 }
332 catch (const JException& error) {
333
334 std::ostringstream os;
335
336 os << __FILE__ << ':' << __LINE__ << " not enough data " << STREAM("?") << x;
337
338 throw JFunctionalException(os.str());
339 }
340 }
341
342 const_iterator p = this->lower_bound(x);
343
344
345 if ((p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) ||
346 (p == this->end() && this->getDistance((--p)->getX(), x) > distance_type::precision)) {
347
348 try {
349 return this->getExceptionHandler().action();
350 }
351 catch (const JException& error) {
352
353 std::ostringstream os;
354
355 os << __FILE__ << ':' << __LINE__ << " abscissa out of range "
356 << STREAM("?") << x << " <> "
357 << STREAM("?") << this->begin() ->getX() << ' '
358 << STREAM("?") << this->rbegin()->getX();
359
360 throw JValueOutOfRange(os.str());
361 }
362 }
363
364 const_iterator q = p--;
365
366 const double dx = this->getDistance(p->getX(), q->getX());
367 const double t = this->getDistance(p->getX(), x) / dx;
368
369 result.f = h00 (t)*p->getY() + h10 (t)*p->getU()*dx + h01 (t)*q->getY() + h11 (t)*q->getU()*dx;
370 result.fp = h00p(t)*p->getY()/dx + h10p(t)*p->getU() + h01p(t)*q->getY()/dx + h11p(t)*q->getU();
371
372 return result;
373 }
374
375
376 protected:
377
378 using collection_type::h00;
379 using collection_type::h10;
380 using collection_type::h01;
381 using collection_type::h11;
382
383 using collection_type::h00p;
384 using collection_type::h10p;
385 using collection_type::h01p;
386 using collection_type::h11p;
387 };
388
389
390 /**
391 * Template specialisation for spline interpolation method with returning JResultPDF data structure.
392 *
393 * Note that the data structure of the elements in the collection should have the additional methods:
394 * <pre>
395 * ordinate_type getIntegral() const;
396 * void setIntegral(ordinate_type v);
397 * </pre>
398 * to get and set the integral values, respectively.
399 */
400 template<class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
401 class JHermiteSplineFunction<JElement_t,
402 JCollection_t,
403 JResultPDF<typename JResultType<typename JElement_t::ordinate_type>::result_type>,
404 JDistance_t> :
405 public JHermiteSplineCollection<JElement_t, JCollection_t, JDistance_t>,
406 public virtual JFunctional<typename JElement_t::abscissa_type,
407 JResultPDF<typename JResultType<typename JElement_t::ordinate_type>::result_type> >
408 {
409 public:
410
412
417
422
425
429
430
431 /**
432 * Default constructor.
433 */
436
437
438 /**
439 * Recursive interpolation method implementation.
440 *
441 * \param pX pointer to abscissa values
442 * \return function value
443 */
444 virtual result_type evaluate(const argument_type* pX) const override
445 {
447
448 const argument_type x = *pX;
449
450 if (this->size() <= 1u) {
451
452 try {
453 return this->getExceptionHandler().action();
454 }
455 catch (const JException& error) {
456
457 std::ostringstream os;
458
459 os << __FILE__ << ':' << __LINE__ << " not enough data " << STREAM("?") << x;
460
461 throw JFunctionalException(os.str());
462 }
463 }
464
465 const_iterator p = this->lower_bound(x);
466
467 if (p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) {
468
469 try {
470
471 result = this->getExceptionHandler().action();
472
473 // overwrite integral values
474
475 result.v = 0;
476 result.V = this->rbegin()->getIntegral();
477
478 } catch(const JException& error) {
479
480 std::ostringstream os;
481
482 os << __FILE__ << ':' << __LINE__ << " abscissa out of range " << STREAM("?") << x << " < " << STREAM("?") << this->begin() ->getX();
483
484 throw JValueOutOfRange(os.str());
485 }
486
487 return result;
488
489 } else if (p == this->end() && this->getDistance((--p)->getX(), x) > distance_type::precision) {
490
491 try {
492
493 result = this->getExceptionHandler().action();
494
495 // overwrite integral values
496
497 result.v = this->rbegin()->getIntegral();
498 result.V = this->rbegin()->getIntegral();
499
500 } catch(const JException& error) {
501
502 std::ostringstream os;
503
504 os << __FILE__ << ':' << __LINE__ << " abscissa out of range " << STREAM("?") << x << " > " << STREAM("?") << this->rbegin()->getX();
505
506 throw JValueOutOfRange(os.str());
507 }
508
509 return result;
510 }
511
512 const_iterator q = p--;
513
514 const double dx = this->getDistance(p->getX(), q->getX());
515 const double t = this->getDistance(p->getX(), x) / dx;
516
517 result.f = h00 (t)*p->getY() + h10 (t)*p->getU()*dx + h01 (t)*q->getY() + h11 (t)*q->getU()*dx;
518 result.fp = h00p(t)*p->getY()/dx + h10p(t)*p->getU() + h01p(t)*q->getY()/dx + h11p(t)*q->getU();
519 result.v = (p->getIntegral() +
520 (H00 (t)*p->getY() + H10 (t)*p->getU()*dx + H01 (t)*q->getY() + H11 (t)*q->getU()*dx)*dx);
521 result.V = this->rbegin()->getIntegral();
522
523 return result;
524 }
525
526
527 protected:
528
529 using collection_type::h00;
530 using collection_type::h10;
531 using collection_type::h01;
532 using collection_type::h11;
533
534 using collection_type::h00p;
535 using collection_type::h10p;
536 using collection_type::h01p;
537 using collection_type::h11p;
538
539 using collection_type::H00;
540 using collection_type::H10;
541 using collection_type::H01;
542 using collection_type::H11;
543
544 /**
545 * Determination of derivatives.
546 */
547 virtual void do_compile() override
548 {
549 if (!this->empty()) {
550
551 collection_type::do_compile();
552
553 this->begin()->setIntegral(JMATH::zero);
554
555 for (iterator j = this->begin(), i = j++; j != this->end(); ++i, ++j) {
556
557 const double dx = this->getDistance(i->getX(), j->getX());
558 const ordinate_type y = i->getY() + j->getY();
559 const ordinate_type z = i->getU() - j->getU();
560
561 const ordinate_type v = dx * 0.50 * y;
562 const ordinate_type w = dx * 1.00 * z*dx/12.0;
563
564 j->setIntegral(i->getIntegral() + v + w);
565 }
566 }
567 }
568 };
569
570
571 /**
572 * Template class for spline interpolation in 1D
573 *
574 * This class implements the JFunction1D interface.
575 */
576 template<class JElement_t,
577 template<class, class> class JCollection_t,
578 class JResult_t = typename JElement_t::ordinate_type,
611
612
613 /**
614 * Functional map with spline interpolation.
615 */
616 template<class JKey_t,
617 class JValue_t,
618 template<class, class, class> class JMap_t,
619 class JResult_t,
620 class JDistance_t = JDistance<JKey_t> >
622 public JMap_t<JKey_t, JValue_t, JDistance_t>,
623 public JFunction<JKey_t, JResult_t>
624 {
625 public:
626
627 typedef JMap_t<JKey_t, JValue_t, JDistance_t> collection_type;
629
630 typedef typename collection_type::abscissa_type abscissa_type;
631 typedef typename collection_type::ordinate_type ordinate_type;
632 typedef typename collection_type::value_type value_type;
633 typedef typename collection_type::distance_type distance_type;
634
635 typedef typename collection_type::const_iterator const_iterator;
636 typedef typename collection_type::const_reverse_iterator const_reverse_iterator;
637 typedef typename collection_type::iterator iterator;
638 typedef typename collection_type::reverse_iterator reverse_iterator;
639
643
648
649
650 /**
651 * Default constructor.
652 */
655
656
657 /**
658 * Recursive interpolation method implementation.
659 *
660 * \param pX pointer to abscissa values
661 * \return function value
662 */
663 virtual result_type evaluate(const argument_type* pX) const override
664 {
665 const argument_type x = *pX;
666
667 ++pX; // next argument value
668
669 const_iterator p = this->begin();
670
671 for (typename JHermiteSplineFunction1D_t::iterator q = buffer.begin(); q != buffer.end(); ++q, ++p) {
673 }
674
675 buffer.compile();
676
677 return buffer(x);
678 }
679
680
681 private:
682 /**
683 * Function compilation.
684 */
685 virtual void do_compile() override
686 {
687 buffer.clear();
688
689 for (iterator i = this->begin(); i != this->end(); ++i) {
690 buffer.put(i->getX(), data_type());
691 }
692 }
693
694
696 };
697
698
699 /**
700 * Conversion of data points to integral values.
701 *
702 * The integration includes the use of 2nd derivatives of the data points of the input spline interpolating function.
703 *
704 * \param input collection
705 * \param output mappable collection
706 * \return integral
707 */
708 template<class JElement_t,
709 template<class, class> class JCollection_t,
710 class JResult_t,
711 class JDistance_t>
712 inline typename JElement_t::ordinate_type
714 typename JMappable<JElement_t>::map_type& output)
715 {
716 typedef typename JElement_t::ordinate_type ordinate_type;
718
719 ordinate_type V(JMATH::zero);
720
721 if (input.getSize() > 1) {
722
723 output.put(input.begin()->getX(), V);
724
725 for (const_iterator j = input.begin(), i = j++; j != input.end(); ++i, ++j) {
726
727 const double dx = input.getDistance(i->getX(), j->getX());
728 const ordinate_type y = i->getY() + j->getY();
729 const ordinate_type z = i->getU() - j->getU();
730
731 const ordinate_type v = dx * 0.50 * y;
732 const ordinate_type w = dx * 1.00 * z*dx/12.0;
733
734 V += v + w;
735
736 output.put(j->getX(), V);
737 }
738 }
739
740 return V;
741 }
742
743
744 /**
745 * Conversion of data points to integral values.
746 *
747 * The integration directly uses the integral values of the input spline interpolating function.
748 *
749 * \param input collection
750 * \param output mappable collection
751 * \return integral
752 */
753 template<class JElement_t,
754 template<class, class> class JCollection_t,
755 class JDistance_t>
756 inline typename JElement_t::ordinate_type
757 integrate(const JHermiteSplineFunction1D<JElement_t, JCollection_t, JResultPDF<typename JElement_t::ordinate_type>, JDistance_t>& input,
758 typename JMappable<JElement_t>::map_type& output)
759 {
760 typedef typename JElement_t::ordinate_type ordinate_type;
761 typedef JResultPDF<ordinate_type> result_type;
763
764 if (input.getSize() > 1) {
765
766 for (const_iterator i = input.begin(); i != input.end(); ++i) {
767 output.put(i->getX(), i->getIntegral());
768 }
769
770 return input.rbegin()->getIntegral();
771 }
772
773 return JMATH::zero;
774 }
775}
776
777#endif
The elements in a collection are sorted according to their abscissa values and a given distance opera...
Exceptions.
This include file containes various data structures that can be used as specific return types for the...
Definition of zero value for any class.
Exception for division by zero.
General exception.
Definition JException.hh:24
Exception for a functional operation.
Exception for missing value.
Exception for accessing a value in a collection that is outside of its range.
Template definition of function object interface.
JArgument_t argument_type
static result_type getValue(const JFunctional &function, const argument_type *pX)
Recursive function value evaluation.
Template base class spline interpolations.
collection_type::abscissa_type abscissa_type
static abscissa_type h01(abscissa_type t)
static abscissa_type h00p(abscissa_type t)
collection_type::value_type value_type
static abscissa_type h11p(abscissa_type t)
collection_type::iterator iterator
collection_type::reverse_iterator reverse_iterator
JHermiteSplineCollection()
Default constructor.
static abscissa_type h10p(abscissa_type t)
static abscissa_type h00(abscissa_type t)
JCollection_t< JElement_t, JDistance_t > collection_type
static abscissa_type h01p(abscissa_type t)
static abscissa_type H00(abscissa_type t)
static abscissa_type h11(abscissa_type t)
collection_type::ordinate_type ordinate_type
collection_type::distance_type distance_type
collection_type::const_iterator const_iterator
virtual void do_compile() override
Determination of derivatives.
static abscissa_type H01(abscissa_type t)
void compile(const bool monotone)
Determination of derivatives.
static abscissa_type H10(abscissa_type t)
static abscissa_type H11(abscissa_type t)
collection_type::const_reverse_iterator const_reverse_iterator
static abscissa_type h10(abscissa_type t)
Template class for spline interpolation in 1D.
collection_type::reverse_iterator reverse_iterator
JFunction1D< abscissa_type, JResult_t > function_type
collection_type::const_iterator const_iterator
collection_type::value_type value_type
function_type::result_type result_type
collection_type::const_reverse_iterator const_reverse_iterator
collection_type::ordinate_type ordinate_type
function_type::JExceptionHandler exceptionhandler_type
collection_type::abscissa_type abscissa_type
JHermiteSplineCollection< JElement_t, JCollection_t, JDistance_t > collection_type
collection_type::iterator iterator
function_type::argument_type argument_type
JHermiteSplineFunction1D()
Default contructor.
collection_type::distance_type distance_type
virtual result_type evaluate(const argument_type *pX) const override
Recursive interpolation method implementation.
Template definition for functional collection with spline interpolation.
Functional map with spline interpolation.
JResultType< ordinate_type >::result_type data_type
collection_type::const_reverse_iterator const_reverse_iterator
JHermiteSplineMap()
Default constructor.
collection_type::iterator iterator
JHermiteSplineFunction1D< JSplineElement2D< argument_type, data_type >, JMapCollection< JMap_t >::template collection_type, result_type > JHermiteSplineFunction1D_t
JHermiteSplineFunction1D_t buffer
virtual result_type evaluate(const argument_type *pX) const override
Recursive interpolation method implementation.
collection_type::abscissa_type abscissa_type
function_type::argument_type argument_type
JFunction< JKey_t, JResult_t > function_type
collection_type::reverse_iterator reverse_iterator
collection_type::distance_type distance_type
virtual void do_compile() override
Function compilation.
collection_type::const_iterator const_iterator
collection_type::ordinate_type ordinate_type
collection_type::value_type value_type
JMap_t< JKey_t, JValue_t, JDistance_t > collection_type
function_type::result_type result_type
function_type::JExceptionHandler exceptionhandler_type
static const JZero zero
Function object to assign zero value.
Definition JZero.hh:105
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary classes and methods for multi-dimensional interpolations and histograms.
return result
Definition JPolint.hh:862
JElement_t::ordinate_type integrate(const JCollection< JElement_t, JDistance_t > &input, typename JMappable< JElement_t >::map_type &output)
Conversion of data points to integral values.
int j
Definition JPolint.hh:801
Template class for distance evaluation.
Definition JDistance.hh:24
Template definition of function object interface in one dimension.
functional_type::result_type result_type
functional_type::argument_type argument_type
Template definition of function object interface in multidimensions.
functional_type::result_type result_type
functional_type::argument_type argument_type
functional_type::JExceptionHandler JExceptionHandler
Exception handler for functional object.
Template class to define the corresponding JCollection for a given template JMap.
Definition JSpline.hh:773
Template interface definition for associative collection of elements.
void put(typename JClass< key_type > ::argument_type key, typename JClass< mapped_type >::argument_type value)
Put pair-wise element (key,value) into collection.
Data structure for result including value and first derivative of function.
Definition JResult.hh:45
Data structure for result including value, first derivative and integrals of function.
Definition JResult.hh:339
Auxiliary class to evaluate result type.
Auxiliary data structure for handling std::ostream.