Jpp 21.0.0-rc.1-88-g0130508c4
the software that should make you happy
Loading...
Searching...
No Matches
JMathlib.hh
Go to the documentation of this file.
1#ifndef __JMATH__JMATHLIB__
2#define __JMATH__JMATHLIB__
3
4#include <cstddef>
5#include <cmath>
6#include <array>
7#include <utility>
8#include <memory>
9
10
11/**
12 * \file
13 * Functional algebra.
14 *
15 * \author mdejong
16 */
17
18namespace JMATH {}
19namespace JPP { using namespace JMATH; }
20
21namespace JMATH {
22
23
24 /**
25 * Type definition for list of parameters.
26 *
27 * The template argument refers to the function that could be fitted to some data.\n
28 * The parameters of the function should be data members of type <tt>double</tt>.
29 */
30 template<class JF1_t, size_t N>
32
33
34 /**
35 * Auxiliary method to join parameter and list of parameters.
36 *
37 * \param parameters parameter list
38 * \param ls indices of parameter list
39 * \param parameter parameter
40 * \return parameter list
41 */
42 template<typename U, typename V, typename W, size_t ...i>
43 constexpr parameter_list<U, sizeof...(i) + 1> join(const parameter_list<V, sizeof...(i)>& parameters,
44 const std::index_sequence<i...>& ls,
45 double W::* parameter)
46 {
47 return {parameters[i]..., parameter};
48 };
49
50
51 /**
52 * Join parameter and list of parameters.
53 *
54 * \param parameters parameter list
55 * \param parameter parameter
56 * \return parameter list
57 */
58 template<typename U, typename V, size_t N, typename W>
60 double W::* parameter)
61 {
62 return join<U>(parameters, std::make_index_sequence<N>{}, parameter);
63 }
64
65
66 /**
67 * Auxiliary method to join two parameter lists.
68 *
69 * \param v first parameter list
70 * \param lv indices of first parameter list
71 * \param w second parameter list
72 * \param lw indices of second parameter list
73 * \return parameter list
74 */
75 template<typename U, typename V, typename W, size_t ...iv, size_t ...iw>
76 constexpr parameter_list<U, sizeof...(iv) + sizeof...(iw)> join(const parameter_list<V, sizeof...(iv)>& v,
77 const std::index_sequence<iv...>& lv,
78 const parameter_list<W, sizeof...(iw)>& w,
79 const std::index_sequence<iw...>& lw)
80 {
81 return {v[iv]..., w[iw]... };
82 };
83
84
85 /**
86 * Join two parameter lists.
87 *
88 * \param v first parameter list
89 * \param w second parameter list
90 * \return parameter list
91 */
92 template<typename U, typename V, size_t NV, typename W, size_t NW>
94 const parameter_list<W, NW>& w)
95 {
96 return join<U>(v, std::make_index_sequence<NV>{},
97 w, std::make_index_sequence<NW>{});
98 }
99
100
101 /**
102 * Auxiliary method to convert parameter list.
103 *
104 * \param parameters parameter list
105 * \param ls indices of parameter list
106 * \return parameter list
107 */
108 template<typename U, typename V, size_t ...i>
109 constexpr parameter_list<U, sizeof...(i)> convert(const parameter_list<V, sizeof...(i)>& parameters,
110 const std::index_sequence<i...>& ls)
111 {
112 return {parameters[i]...};
113 };
114
115
116 /**
117 * Convert parameter list.
118 *
119 * \param parameters parameter list
120 * \return parameter list
121 */
122 template<typename U, typename V, size_t N>
124 {
125 return convert<U>(parameters, std::make_index_sequence<N>{});
126 }
127
128
129 /**
130 * Get number of parameters.
131 *
132 * \return number of parameters
133 */
134 template<class JF1_t>
135 constexpr size_t getNumberOfParameters()
136 {
137 return JF1_t::parameters.size();
138 }
139
140
141 /**
142 * Set values of all parameters.
143 *
144 * \param f1 pointer to function
145 * \param values pointer to list of values
146 */
147 template<class JF1_t>
148 inline void setParameters(JF1_t* f1, const double* values)
149 {
150 if (f1 != NULL && values != NULL) {
151 for (size_t i = 0; i != getNumberOfParameters<JF1_t>(); ++i) {
152 (*f1)[i] = values[i];
153 }
154 }
155 }
156
157
158 /**
159 * Auxiliary base class for mathematical operations on parameters of function.
160 */
161 template<class JF1_t>
162 struct JCalculus
163 {
164 /**
165 * Negate function.
166 *
167 * \return this function
168 */
169 JF1_t& negate()
170 {
171 for (const auto& i : JF1_t::parameters) {
172 static_cast<JF1_t&>(*this).*i = -(static_cast<JF1_t&>(*this).*i);
173 }
174
175 return static_cast<JF1_t&>(*this);
176 }
177
178
179 /**
180 * Add function.
181 *
182 * \param f1 function
183 * \return this function
184 */
185 JF1_t& add(const JF1_t& f1)
186 {
187 for (const auto& i : JF1_t::parameters) {
188 static_cast<JF1_t&>(*this).*i += f1.*i;
189 }
190
191 return static_cast<JF1_t&>(*this);
192 }
193
194
195 /**
196 * Subtract function.
197 *
198 * \param f1 function
199 * \return this function
200 */
201 JF1_t& sub(const JF1_t& f1)
202 {
203 for (const auto& i : JF1_t::parameters) {
204 static_cast<JF1_t&>(*this).*i -= f1.*i;
205 }
206
207 return static_cast<JF1_t&>(*this);
208 }
209
210
211 /**
212 * Scale function.
213 *
214 * \param factor factor
215 * \return this function
216 */
217 JF1_t& mul(const double factor)
218 {
219 for (const auto& i : JF1_t::parameters) {
220 static_cast<JF1_t&>(*this).*i *= factor;
221 }
222
223 return static_cast<JF1_t&>(*this);
224 }
225
226
227 /**
228 * Scale function.
229 *
230 * \param factor factor
231 * \return this function
232 */
233 JF1_t& div(const double factor)
234 {
235 for (const auto& i : JF1_t::parameters) {
236 static_cast<JF1_t&>(*this).*i /= factor;
237 }
238
239 return static_cast<JF1_t&>(*this);
240 }
241
242
243 /**
244 * Add function.
245 *
246 * \param function this function
247 * \param value value
248 * \return this function
249 */
250 friend JF1_t& operator+=(JF1_t& function, const JF1_t& value)
251 {
252 return function.add(value);
253 }
254
255
256 /**
257 * Subtract function.
258 *
259 * \param function this function
260 * \param value value
261 * \return this function
262 */
263 friend JF1_t& operator-=(JF1_t& function, const JF1_t& value)
264 {
265 return function.sub(value);
266 }
267
268
269 /**
270 * Scale function.
271 *
272 * \param function this function
273 * \param factor factor
274 * \return this function
275 */
276 friend JF1_t& operator*=(JF1_t& function, const double factor)
277 {
278 return function.mul(factor);
279 }
280
281
282 /**
283 * Scale function.
284 *
285 * \param function this function
286 * \param factor factor
287 * \return this function
288 */
289 friend JF1_t& operator/=(JF1_t& function, const double factor)
290 {
291 return function.div(factor);
292 }
293 };
294
295
296 template<class JF1_t>
297 struct JNegate; // forward declaration for negation of function.
298
299 template<class JF1_t, class JF2_t = double>
300 struct JAdd; // forward declaration for addition of fuction.
301
302 template<class JF1_t, class JF2_t = double>
303 struct JSub; // forward declaration for subtraction of fuction.
304
305 template<class JF1_t, class JF2_t = double>
306 struct JMul; // forward declaration for multiplication of fuction.
307
308 template<class JF1_t, class JF2_t = double>
309 struct JDiv; // forward declaration for division of fuction.
310
311 template<class JF1_t = void>
312 struct JFn; // forward declaration for fixed power of function.
313
314 template<class JF1_t = void>
315 struct JPf; // forward declaration for pointer to function.
316
317
318 /**
319 * Auxiliary base class for mathematical operations on functions.
320 */
321 template<class JF1_t>
322 struct JMathlib {
323 /**
324 * Function value.
325 *
326 * \param args abscissa value(s)
327 * \return function value
328 */
329 template<class ...Args>
330 double operator()(const Args& ...args) const
331 {
332 return static_cast<const JF1_t&>(*this).getValue(args...);
333 }
334
335
336 /**
337 * Affirm operator.
338 *
339 * \param function this function
340 * \return result function
341 */
342 friend const JF1_t& operator+(const JF1_t& function)
343 {
344 return function;
345 }
346
347
348 /**
349 * Negate operator.
350 *
351 * \param function this function
352 * \return result function
353 */
354 friend JNegate<JF1_t> operator-(const JF1_t& function)
355 {
356 return JNegate<JF1_t>(function);
357 }
358
359
360 /**
361 * Addition of constant value.
362 *
363 * \param f1 function
364 * \param value value
365 * \return result function
366 */
367 friend JAdd<JF1_t> operator+(const JF1_t& f1, const double value)
368 {
369 return JAdd<JF1_t>(f1, value);
370 }
371
372
373 /**
374 * Addition of constant value.
375 *
376 * \param value value
377 * \param f1 function
378 * \return result function
379 */
380 friend JAdd<JF1_t> operator+(const double value, const JF1_t& f1)
381 {
382 return JAdd<JF1_t>(f1, value);
383 }
384
385
386 /**
387 * Subtraction of constant value.
388 *
389 * \param f1 function
390 * \param value value
391 * \return result function
392 */
393 friend JSub<JF1_t> operator-(const JF1_t& f1, const double value)
394 {
395 return JSub<JF1_t>(f1, value);
396 }
397
398
399 /**
400 * Subtraction of constant value.
401 *
402 * \param f1 function
403 * \param value value
404 * \return result function
405 */
406 friend JAdd< JNegate<JF1_t> > operator-(const double value, const JF1_t& f1)
407 {
408 return JAdd< JNegate<JF1_t> >(JNegate<JF1_t>(f1), value);
409 }
410
411
412 /**
413 * Multiplication of constant value.
414 *
415 * \param f1 function
416 * \param value value
417 * \return result function
418 */
419 friend JMul<JF1_t> operator*(const JF1_t& f1, const double value)
420 {
421 return JMul<JF1_t>(f1, value);
422 }
423
424
425 /**
426 * Multiplication of constant value.
427 *
428 * \param value value
429 * \param f1 function
430 * \return result function
431 */
432 friend JMul<JF1_t> operator*(const double value, const JF1_t& f1)
433 {
434 return JMul<JF1_t>(f1, value);
435 }
436
437
438 /**
439 * Division of constant value.
440 *
441 * \param f1 function
442 * \param value value
443 * \return result function
444 */
445 friend JDiv<JF1_t> operator/(const JF1_t& f1, const double value)
446 {
447 return JDiv<JF1_t>(f1, value);
448 }
449
450
451 /**
452 * Addition of two functions.
453 *
454 * \param f1 first function
455 * \param f2 second function
456 * \return result function
457 */
458 template<class JF2_t>
459 friend JAdd<JF1_t, JF2_t> operator+(const JF1_t& f1, const JF2_t& f2)
460 {
461 return JAdd<JF1_t, JF2_t>(f1, f2);
462 }
463
464
465 /**
466 * Subtraction of two functions.
467 *
468 * \param f1 first function
469 * \param f2 second function
470 * \return result function
471 */
472 template<class JF2_t>
473 friend JSub<JF1_t, JF2_t> operator-(const JF1_t& f1, const JF2_t& f2)
474 {
475 return JSub<JF1_t, JF2_t>(f1, f2);
476 }
477
478
479 /**
480 * Multiplication of two functions.
481 *
482 * \param f1 first function
483 * \param f2 second function
484 * \return result function
485 */
486 template<class JF2_t>
487 friend JMul<JF1_t, JF2_t> operator*(const JF1_t& f1, const JF2_t& f2)
488 {
489 return JMul<JF1_t, JF2_t>(f1, f2);
490 }
491
492
493 /**
494 * Division of two functions.
495 *
496 * \param f1 first function
497 * \param f2 second function
498 * \return result function
499 */
500 template<class JF2_t>
501 friend JDiv<JF1_t, JF2_t> operator/(const JF1_t& f1, const JF2_t& f2)
502 {
503 return JDiv<JF1_t, JF2_t>(f1, f2);
504 }
505
506
507 /**
508 * Power-of operator.
509 *
510 * \param f1 function
511 * \param N power
512 * \return result function
513 */
514 friend JFn<JF1_t> operator^(const JF1_t& f1, int N)
515 {
516 return JFn<JF1_t>(f1, N);
517 }
518
519
520 /**
521 * Address-of operator.
522 *
523 * \param f1 function
524 * \return result function
525 */
526 friend JPf<JF1_t> operator&(const JF1_t& f1)
527 {
528 return JPf<JF1_t>(std::addressof(f1));
529 }
530
531
532 /**
533 * Get value of parameter at given index.
534 *
535 * \param i index
536 * \return value
537 */
538 double operator[](const size_t i) const
539 {
540 return static_cast<const JF1_t&>(*this).*JF1_t::parameters[i];
541 }
542
543
544 /**
545 * Get value of parameter at given index.
546 *
547 * \param i index
548 * \return value
549 */
550 double& operator[](const size_t i)
551 {
552 return static_cast<JF1_t&>(*this).*JF1_t::parameters[i];
553 }
554 };
555
556
557 /**
558 * Negate of function.
559 */
560 template<class JF1_t>
561 struct JNegate :
562 public JMathlib< JNegate<JF1_t> >,
563 public JF1_t
564 {
565 using JMathlib< JNegate<JF1_t> >::operator();
566 using JMathlib< JNegate<JF1_t> >::operator[];
567
568
569 /**
570 * Default constructor.
571 */
573 {}
574
575
576 /**
577 * Constructor.
578 *
579 * \param f1 function
580 */
581 JNegate(const JF1_t& f1) :
582 JF1_t(f1)
583 {}
584
585
586 /**
587 * Function value.
588 *
589 * \param args abscissa value(s)
590 * \return function value
591 */
592 template<class ...Args>
593 double getValue(const Args& ...args) const
594 {
595 return -static_cast<const JF1_t&>(*this).getValue(args...);
596 }
597
598
599 /**
600 * Derivative value.
601 *
602 * \param x abscissa value
603 * \return derivative value
604 */
605 double getDerivative(const double x) const
606 {
607 return -static_cast<const JF1_t&>(*this).getDerivative(x);
608 }
609
610
611 /**
612 * Get gradient.
613 *
614 * \param args abscissa value(s)
615 * \return gradient
616 */
617 template<class ...Args>
618 JNegate getGradient(const Args& ...args) const
619 {
620 JNegate gradient;
621
622 static_cast<JF1_t&>(gradient) = static_cast<const JF1_t&>(*this).getGradient(args...);
623 static_cast<JF1_t&>(gradient).negate();
624
625 return gradient;
626 }
627 };
628
629
630 /**
631 * Addition of constant value.
632 */
633 template<class JF1_t>
634 struct JAdd<JF1_t, double> :
635 public JMathlib< JAdd<JF1_t, double> >,
636 public JF1_t
637 {
638 using JMathlib< JAdd<JF1_t, double> >::operator();
639 using JMathlib< JAdd<JF1_t, double> >::operator[];
640
641
642 /**
643 * Default constructor.
644 */
646 {}
647
648
649 /**
650 * Constructor.
651 *
652 * \param f1 function
653 * \param value value
654 */
655 JAdd(const JF1_t& f1, const double value) :
656 JF1_t(f1),
657 value(value)
658 {}
659
660
661 /**
662 * Function value.
663 *
664 * \param args abscissa value(s)
665 * \return function value
666 */
667 template<class ...Args>
668 double getValue(const Args& ...args) const
669 {
670 return static_cast<const JF1_t&>(*this).getValue(args...) + value;
671 }
672
673
674 /**
675 * Derivative value.
676 *
677 * \param x abscissa value
678 * \return derivative value
679 */
680 double getDerivative(const double x) const
681 {
682 return static_cast<const JF1_t&>(*this).getDerivative(x);
683 }
684
685
686 /**
687 * Get gradient.
688 *
689 * \param args abscissa value(s)
690 * \return gradient
691 */
692 template<class ...Args>
693 JAdd getGradient(const Args& ...args) const
694 {
695 JAdd gradient;
696
697 static_cast<JF1_t&>(gradient) = static_cast<const JF1_t&>(*this).getGradient(args...);
698
699 return gradient;
700 }
701
702 private:
703 double value;
704 };
705
706
707 /**
708 * Subtraction of constant value.
709 */
710 template<class JF1_t>
711 struct JSub<JF1_t, double> :
712 public JMathlib< JSub<JF1_t, double> >,
713 public JF1_t
714 {
715 using JMathlib< JSub<JF1_t, double> >::operator();
716 using JMathlib< JSub<JF1_t, double> >::operator[];
717
718
719 /**
720 * Default constructor.
721 */
723 {}
724
725
726 /**
727 * Constructor.
728 *
729 * \param f1 function
730 * \param value value
731 */
732 JSub(const JF1_t& f1, const double value) :
733 JF1_t(f1),
734 value(value)
735 {}
736
737
738 /**
739 * Function value.
740 *
741 * \param args abscissa value(s)
742 * \return function value
743 */
744 template<class ...Args>
745 double getValue(const Args& ...args) const
746 {
747 return static_cast<const JF1_t&>(*this).getValue(args...) - value;
748 }
749
750
751 /**
752 * Derivative value.
753 *
754 * \param x abscissa value
755 * \return derivative value
756 */
757 double getDerivative(const double x) const
758 {
759 return static_cast<const JF1_t&>(*this).getDerivative(x);
760 }
761
762
763 /**
764 * Get gradient.
765 *
766 * \param args abscissa value(s)
767 * \return gradient
768 */
769 template<class ...Args>
770 JSub getGradient(const Args& ...args) const
771 {
772 JSub gradient;
773
774 static_cast<JF1_t&>(gradient) = static_cast<const JF1_t&>(*this).getGradient(args...);
775
776 return gradient;
777 }
778
779 private:
780 double value;
781 };
782
783
784 /**
785 * Multiplication of constant value.
786 */
787 template<class JF1_t>
788 struct JMul<JF1_t, double> :
789 public JMathlib< JMul<JF1_t, double> >,
790 public JF1_t
791 {
792 using JMathlib< JMul<JF1_t, double> >::operator();
793 using JMathlib< JMul<JF1_t, double> >::operator[];
794
795
796 /**
797 * Default constructor.
798 */
800 {}
801
802
803 /**
804 * Constructor.
805 *
806 * \param f1 function
807 * \param value value
808 */
809 JMul(const JF1_t& f1, const double value) :
810 JF1_t(f1),
811 value(value)
812 {}
813
814
815 /**
816 * Function value.
817 *
818 * \param args abscissa value(s)
819 * \return function value
820 */
821 template<class ...Args>
822 double getValue(const Args& ...args) const
823 {
824 return static_cast<const JF1_t&>(*this).getValue(args...) * value;
825 }
826
827
828 /**
829 * Derivative value.
830 *
831 * \param x abscissa value
832 * \return derivative value
833 */
834 double getDerivative(const double x) const
835 {
836 return static_cast<const JF1_t&>(*this).getDerivative(x) * value;
837 }
838
839
840 /**
841 * Get gradient.
842 *
843 * \param args abscissa value(s)
844 * \return gradient
845 */
846 template<class ...Args>
847 JMul getGradient(const Args& ...args) const
848 {
849 JMul gradient;
850
851 static_cast<JF1_t&>(gradient) = static_cast<const JF1_t&>(*this).getGradient(args...);
852 static_cast<JF1_t&>(gradient) *= value;
853
854 return gradient;
855 }
856
857 private:
858 double value;
859 };
860
861
862 /**
863 * Division of constant value.
864 */
865 template<class JF1_t>
866 struct JDiv<JF1_t, double> :
867 public JMathlib< JDiv<JF1_t, double> >,
868 public JF1_t
869 {
870 using JMathlib< JDiv<JF1_t, double> >::operator();
871 using JMathlib< JDiv<JF1_t, double> >::operator[];
872
873
874 /**
875 * Default constructor.
876 */
878 {}
879
880
881 /**
882 * Constructor.
883 *
884 * \param f1 function
885 * \param value value
886 */
887 JDiv(const JF1_t& f1, const double value) :
888 JF1_t(f1),
889 value(value)
890 {}
891
892
893 /**
894 * Function value.
895 *
896 * \param args abscissa value(s)
897 * \return function value
898 */
899 template<class ...Args>
900 double getValue(const Args& ...args) const
901 {
902 return static_cast<const JF1_t&>(*this).getValue(args...) / value;
903 }
904
905
906 /**
907 * Derivative value.
908 *
909 * \param x abscissa value
910 * \return derivative value
911 */
912 double getDerivative(const double x) const
913 {
914 return static_cast<const JF1_t&>(*this).getDerivative(x) / value;
915 }
916
917
918 /**
919 * Get gradient.
920 *
921 * \param args abscissa value(s)
922 * \return gradient
923 */
924 template<class ...Args>
925 JDiv getGradient(const Args& ...args) const
926 {
927 JDiv gradient;
928
929 static_cast<JF1_t&>(gradient) = static_cast<const JF1_t&>(*this).getGradient(args...);
930 static_cast<JF1_t&>(gradient) /= value;
931
932 return gradient;
933 }
934
935 private:
936 double value;
937 };
938
939
940 /**
941 * Auxiliary data structure for pair of functions.
942 */
943 template<class JF1_t, class JF2_t,
944 bool v1 = JF1_t::parameters.size() == 0 && !std::is_base_of<JPf<>, JF1_t>::value && !std::is_base_of<JFn<>, JF1_t>::value, // true -> virtual base class
945 bool v2 = JF2_t::parameters.size() == 0 && !std::is_base_of<JPf<>, JF2_t>::value && !std::is_base_of<JFn<>, JF2_t>::value> // true -> virtual base class
946 struct JPair :
947 public JF1_t,
948 public JF2_t
949 {
950 /**
951 * Default constructor.
952 */
954 {}
955
956
957 /**
958 * Constructor.
959 *
960 * \param f1 first function
961 * \param f2 second function
962 */
963 JPair(const JF1_t& f1, const JF2_t& f2) :
964 JF1_t(f1),
965 JF2_t(f2)
966 {}
967
968 static constexpr parameter_list<JPair, JF1_t::parameters.size() + JF2_t::parameters.size()> parameters = join<JPair>(JF1_t::parameters, JF2_t::parameters);
969 };
970
971
972 /**
973 * Template specialisation for pair of functions.
974 */
975 template<class JF1_t, class JF2_t>
976 struct JPair<JF1_t, JF2_t, false, true> :
977 public virtual JF2_t,
978 public JF1_t
979 {
980 /**
981 * Default constructor.
982 */
984 {}
985
986
987 /**
988 * Constructor.
989 *
990 * \param f1 first function
991 * \param f2 second function
992 */
993 JPair(const JF1_t& f1, const JF2_t& f2) :
994 JF1_t(f1)
995 {}
996
997 static constexpr parameter_list<JPair, JF1_t::parameters.size()> parameters = convert<JPair>(JF1_t::parameters);
998 };
999
1000
1001 /**
1002 * Template specialisation for pair of functions.
1003 */
1004 template<class JF1_t, class JF2_t>
1005 struct JPair<JF1_t, JF2_t, true, false> :
1006 public virtual JF1_t,
1007 public JF2_t
1008 {
1009 /**
1010 * Default constructor.
1011 */
1013 {}
1014
1015
1016 /**
1017 * Constructor.
1018 *
1019 * \param f1 first function
1020 * \param f2 second function
1021 */
1022 JPair(const JF1_t& f1, const JF2_t& f2) :
1023 JF2_t(f2)
1024 {}
1025
1026 static constexpr parameter_list<JPair, JF2_t::parameters.size()> parameters = convert<JPair>(JF2_t::parameters);
1027 };
1028
1029
1030 /**
1031 * Template specialisation for pair of functions.
1032 */
1033 template<class JF1_t, class JF2_t>
1034 struct JPair<JF1_t, JF2_t, true, true> :
1035 public virtual JF1_t,
1036 public virtual JF2_t
1037 {
1038 /**
1039 * Default constructor.
1040 */
1042 {}
1043
1044
1045 /**
1046 * Constructor.
1047 *
1048 * \param f1 first function
1049 * \param f2 second function
1050 */
1051 JPair(const JF1_t& f1, const JF2_t& f2)
1052 {}
1053
1055 };
1056
1057
1058 /**
1059 * Auxiliary data structure for pair of functions.
1060 */
1061 template<class JF1_t, class JF2_t>
1062 struct JPair_t :
1063 public JPair<JF1_t, JF2_t>,
1064 public JCalculus< JPair_t<JF1_t, JF2_t> >
1065 {
1071
1072
1073 /**
1074 * Default constructor.
1075 */
1077 {}
1078
1079
1080 /**
1081 * Constructor.
1082 *
1083 * \param f1 first function
1084 * \param f2 second function
1085 */
1086 JPair_t(const JF1_t& f1, const JF2_t& f2) :
1087 JPair<JF1_t, JF2_t>(f1, f2)
1088 {}
1089 };
1090
1091
1092 /**
1093 * Addition of two functions.
1094 */
1095 template<class JF1_t, class JF2_t>
1096 struct JAdd :
1097 public JMathlib< JAdd<JF1_t, JF2_t> >,
1098 public JPair_t<JF1_t, JF2_t>
1099 {
1100 using JMathlib< JAdd<JF1_t, JF2_t> >::operator();
1101 using JMathlib< JAdd<JF1_t, JF2_t> >::operator[];
1102
1103
1104 /**
1105 * Default constructor.
1106 */
1108 {}
1109
1110
1111 /**
1112 * Constructor.
1113 *
1114 * \param f1 first function
1115 * \param f2 second function
1116 */
1117 JAdd(const JF1_t& f1, const JF2_t& f2) :
1118 JPair_t<JF1_t, JF2_t>(f1, f2)
1119 {}
1120
1121
1122 /**
1123 * Function value.
1124 *
1125 * \param args abscissa value(s)
1126 * \return function value
1127 */
1128 template<class ...Args>
1129 double getValue(const Args& ...args) const
1130 {
1131 return (static_cast<const JF1_t&>(*this).getValue(args...) +
1132 static_cast<const JF2_t&>(*this).getValue(args...));
1133 }
1134
1135
1136 /**
1137 * Derivative value.
1138 *
1139 * \param x abscissa value
1140 * \return derivative value
1141 */
1142 double getDerivative(const double x) const
1143 {
1144 return (static_cast<const JF1_t&>(*this).getDerivative(x) +
1145 static_cast<const JF2_t&>(*this).getDerivative(x));
1146 }
1147
1148
1149 /**
1150 * Get gradient.
1151 *
1152 * \param args abscissa value(s)
1153 * \return gradient
1154 */
1155 template<class ...Args>
1156 JAdd getGradient(const Args& ...args) const
1157 {
1158 JAdd gradient;
1159
1160 static_cast<JF1_t&>(gradient) = static_cast<const JF1_t&>(*this).getGradient(args...);
1161 static_cast<JF2_t&>(gradient) = static_cast<const JF2_t&>(*this).getGradient(args...);
1162
1163 return gradient;
1164 }
1165 };
1166
1167
1168 /**
1169 * Subtraction of two functions.
1170 */
1171 template<class JF1_t, class JF2_t>
1172 struct JSub :
1173 public JMathlib< JSub<JF1_t, JF2_t> >,
1174 public JPair_t<JF1_t, JF2_t>
1175 {
1176 using JMathlib< JSub<JF1_t, JF2_t> >::operator();
1177 using JMathlib< JSub<JF1_t, JF2_t> >::operator[];
1178
1179
1180 /**
1181 * Default constructor.
1182 */
1184 {}
1185
1186
1187 /**
1188 * Constructor.
1189 *
1190 * \param f1 first function
1191 * \param f2 second function
1192 */
1193 JSub(const JF1_t& f1, const JF2_t& f2) :
1194 JPair_t<JF1_t, JF2_t>(f1, f2)
1195 {}
1196
1197
1198 /**
1199 * Function value.
1200 *
1201 * \param args abscissa value(s)
1202 * \return function value
1203 */
1204 template<class ...Args>
1205 double getValue(const Args& ...args) const
1206 {
1207 return (static_cast<const JF1_t&>(*this).getValue(args...) -
1208 static_cast<const JF2_t&>(*this).getValue(args...));
1209 }
1210
1211
1212 /**
1213 * Derivative value.
1214 *
1215 * \param x abscissa value
1216 * \return derivative value
1217 */
1218 double getDerivative(const double x) const
1219 {
1220 return (static_cast<const JF1_t&>(*this).getDerivative(x) -
1221 static_cast<const JF2_t&>(*this).getDerivative(x));
1222 }
1223
1224
1225 /**
1226 * Get gradient.
1227 *
1228 * \param args abscissa value(s)
1229 * \return gradient
1230 */
1231 template<class ...Args>
1232 JSub getGradient(const Args& ...args) const
1233 {
1234 JSub gradient;
1235
1236 static_cast<JF1_t&>(gradient) = static_cast<const JF1_t&>(*this).getGradient(args...);
1237 static_cast<JF2_t&>(gradient) = static_cast<const JF2_t&>(*this).getGradient(args...);
1238 static_cast<JF2_t&>(gradient).negate();
1239
1240 return gradient;
1241 }
1242 };
1243
1244
1245 /**
1246 * Multiplication of two functions.
1247 */
1248 template<class JF1_t, class JF2_t>
1249 struct JMul :
1250 public JMathlib< JMul<JF1_t, JF2_t> >,
1251 public JPair_t<JF1_t, JF2_t>
1252 {
1253 using JMathlib< JMul<JF1_t, JF2_t> >::operator();
1254 using JMathlib< JMul<JF1_t, JF2_t> >::operator[];
1255
1256
1257 /**
1258 * Default constructor.
1259 */
1261 {}
1262
1263
1264 /**
1265 * Constructor.
1266 *
1267 * \param f1 first function
1268 * \param f2 second function
1269 */
1270 JMul(const JF1_t& f1, const JF2_t& f2) :
1271 JPair_t<JF1_t, JF2_t>(f1, f2)
1272 {}
1273
1274
1275 /**
1276 * Function value.
1277 *
1278 * \param args abscissa value(s)
1279 * \return function value
1280 */
1281 template<class ...Args>
1282 double getValue(const Args& ...args) const
1283 {
1284 return (static_cast<const JF1_t&>(*this).getValue(args...) *
1285 static_cast<const JF2_t&>(*this).getValue(args...));
1286 }
1287
1288
1289 /**
1290 * Derivative value.
1291 *
1292 * \param x abscissa value
1293 * \return derivative value
1294 */
1295 double getDerivative(const double x) const
1296 {
1297 return (static_cast<const JF1_t&>(*this).getDerivative(x) * static_cast<const JF2_t&>(*this).getValue(x) +
1298 static_cast<const JF1_t&>(*this).getValue(x) * static_cast<const JF2_t&>(*this).getDerivative(x));
1299 }
1300
1301
1302 /**
1303 * Get gradient.
1304 *
1305 * \param args abscissa value(s)
1306 * \return gradient
1307 */
1308 template<class ...Args>
1309 JMul getGradient(const Args& ...args) const
1310 {
1311 JMul gradient;
1312
1313 static_cast<JF1_t&>(gradient) = static_cast<const JF1_t&>(*this).getGradient(args...);
1314 static_cast<JF1_t&>(gradient) *= static_cast<const JF2_t&>(*this).getValue(args...);
1315 static_cast<JF2_t&>(gradient) = static_cast<const JF2_t&>(*this).getGradient(args...);
1316 static_cast<JF2_t&>(gradient) *= static_cast<const JF1_t&>(*this).getValue(args...);
1317
1318 return gradient;
1319 }
1320 };
1321
1322
1323 /**
1324 * Division of two functions.
1325 */
1326 template<class JF1_t, class JF2_t>
1327 struct JDiv :
1328 public JMathlib< JDiv<JF1_t, JF2_t> >,
1329 public JPair_t<JF1_t, JF2_t>
1330 {
1331 using JMathlib< JDiv<JF1_t, JF2_t> >::operator();
1332 using JMathlib< JDiv<JF1_t, JF2_t> >::operator[];
1333
1334
1335 /**
1336 * Default constructor.
1337 */
1339 {}
1340
1341
1342 /**
1343 * Constructor.
1344 *
1345 * \param f1 first function
1346 * \param f2 second function
1347 */
1348 JDiv(const JF1_t& f1, const JF2_t& f2) :
1349 JPair_t<JF1_t, JF2_t>(f1, f2)
1350 {}
1351
1352
1353 /**
1354 * Function value.
1355 *
1356 * \param args abscissa value(s)
1357 * \return function value
1358 */
1359 template<class ...Args>
1360 double getValue(const Args& ...args) const
1361 {
1362 return (static_cast<const JF1_t&>(*this).getValue(args...) /
1363 static_cast<const JF2_t&>(*this).getValue(args...));
1364 }
1365
1366
1367 /**
1368 * Derivative value.
1369 *
1370 * \param x abscissa value
1371 * \return derivative value
1372 */
1373 double getDerivative(const double x) const
1374 {
1375 const double v = static_cast<const JF1_t&>(*this).getValue(x);
1376 const double w = static_cast<const JF2_t&>(*this).getValue(x);
1377
1378 return (static_cast<const JF1_t&>(*this).getDerivative(x) * w -
1379 v * static_cast<const JF2_t&>(*this).getDerivative(x)) / (w*w);
1380 }
1381
1382
1383 /**
1384 * Get gradient.
1385 *
1386 * \param args abscissa value(s)
1387 * \return gradient
1388 */
1389 template<class ...Args>
1390 JDiv getGradient(const Args& ...args) const
1391 {
1392 JDiv gradient;
1393
1394 const double v = static_cast<const JF1_t&>(*this).getValue(args...);
1395 const double w = static_cast<const JF2_t&>(*this).getValue(args...);
1396
1397 static_cast<JF1_t&>(gradient) = static_cast<const JF1_t&>(*this).getGradient(args...);
1398 static_cast<JF1_t&>(gradient) *= 1.0/w;
1399 static_cast<JF2_t&>(gradient) = static_cast<const JF2_t&>(*this).getGradient(args...);
1400 static_cast<JF2_t&>(gradient) *= -v/(w*w);
1401
1402 return gradient;
1403 }
1404 };
1405
1406
1407 /**
1408 * Auxiliary base class for fixed power of function.
1409 */
1410 template<>
1411 struct JFn<void>
1412 {};
1413
1414 /**
1415 * Fixed power of function.
1416 */
1417 template<class JF1_t>
1418 struct JFn :
1419 public JFn<>,
1420 public JMathlib < JFn<JF1_t> >,
1421 public JF1_t
1422 {
1423 using JMathlib< JFn<JF1_t> >::operator();
1424 using JMathlib< JFn<JF1_t> >::operator[];
1425
1426
1427 /**
1428 * Default constructor.
1429 */
1431 JF1_t(),
1432 N(1)
1433 {}
1434
1435
1436 /**
1437 * Constructor.
1438 *
1439 * \param f1 first function
1440 * \param N power
1441 */
1442 JFn(const JF1_t& f1, const int N) :
1443 JF1_t(f1),
1444 N(N)
1445 {}
1446
1447
1448 /**
1449 * Function value.
1450 *
1451 * \param args abscissa value(s)
1452 * \return function value
1453 */
1454 template<class ...Args>
1455 double getValue(const Args& ...args) const
1456 {
1457 const double u = static_cast<const JF1_t&>(*this).getValue(args...);
1458
1459 return pow(u, N);
1460 }
1461
1462
1463 /**
1464 * Derivative value.
1465 *
1466 * \param x abscissa value
1467 * \return derivative value
1468 */
1469 double getDerivative(const double x) const
1470 {
1471 const double u = static_cast<const JF1_t&>(*this).getValue(x);
1472 const double v = static_cast<const JF1_t&>(*this).getDerivative(x);
1473
1474 return N * pow(u, N - 1) * v;
1475 }
1476
1477
1478 /**
1479 * Get gradient.
1480 *
1481 * \param args abscissa value(s)
1482 * \return gradient
1483 */
1484 template<class ...Args>
1485 JFn getGradient(const Args& ...args) const
1486 {
1487 JFn gradient;
1488
1489 const double u = static_cast<const JF1_t&>(*this).getValue(args...);
1490 const double w = N * pow(u, N - 1);
1491
1492 static_cast<JF1_t&>(gradient) = static_cast<const JF1_t&>(*this).getGradient(args...);
1493 static_cast<JF1_t&>(gradient) *= w;
1494
1495 return gradient;
1496 }
1497
1498 private:
1499 int N;
1500 };
1501
1502
1503 /**
1504 * x.
1505 */
1506 struct JX :
1507 public JMathlib < JX >,
1508 public JCalculus< JX >
1509 {
1510 /**
1511 * Default constructor.
1512 */
1514 {}
1515
1516
1517 /**
1518 * Function value.
1519 *
1520 * \param x abscissa value
1521 * \return function value
1522 */
1523 double getValue(const double x) const
1524 {
1525 return x;
1526 }
1527
1528
1529 /**
1530 * Derivative value.
1531 *
1532 * \param x abscissa value
1533 * \return derivative value
1534 */
1535 double getDerivative(const double x) const
1536 {
1537 return 1.0;
1538 }
1539
1540
1541 /**
1542 * Get gradient.
1543 *
1544 * \param x abscissa value
1545 * \return gradient
1546 */
1547 JX getGradient(const double x) const
1548 {
1549 JX gradient;
1550
1551 return gradient;
1552 }
1553
1555 };
1556
1557
1558 static const JX X; //! Function object for x;
1559
1560
1561 /**
1562 * Fixed power of x.
1563 */
1564 template<int N>
1565 struct JXn :
1566 public JMathlib < JXn<N> >,
1567 public JCalculus< JXn<N> >
1568 {
1569 /**
1570 * Default constructor.
1571 */
1573 {}
1574
1575
1576 /**
1577 * Function value.
1578 *
1579 * \param x abscissa value
1580 * \return function value
1581 */
1582 double getValue(const double x) const
1583 {
1584 return pow(x, N);
1585 }
1586
1587
1588 /**
1589 * Derivative value.
1590 *
1591 * \param x abscissa value
1592 * \return derivative value
1593 */
1594 double getDerivative(const double x) const
1595 {
1596 return N * pow(x, N - 1);
1597 }
1598
1599
1600 /**
1601 * Get gradient.
1602 *
1603 * \param x abscissa value
1604 * \return gradient
1605 */
1606 JXn getGradient(const double x) const
1607 {
1608 JXn gradient;
1609
1610 return gradient;
1611 }
1612
1614 };
1615
1616
1617 template<>
1618 struct JXn<0>; //! Invalidate x^0.
1619 static const JXn<2> X2; //! Function object for x^2;
1620 static const JXn<3> X3; //! Function object for x^3;
1621 static const JXn<4> X4; //! Function object for x^4;
1622 static const JXn<5> X5; //! Function object for x^5;
1623
1624
1625 /**
1626 * Auxiliary base class for pointer to function.
1627 */
1628 template<>
1629 struct JPf<void>
1630 {};
1631
1632 /**
1633 * Pointer to function.
1634 */
1635 template<class JF1_t>
1636 struct JPf :
1637 public JPf<>,
1638 public JMathlib < JPf<JF1_t> >,
1639 public JCalculus< JPf<JF1_t> >
1640 {
1641 using JMathlib< JPf<JF1_t> >::operator();
1642 using JMathlib< JPf<JF1_t> >::operator[];
1643
1644
1645 /**
1646 * Default constructor.
1647 */
1649 f1(NULL)
1650 {}
1651
1652
1653 /**
1654 * Constructor.
1655 *
1656 * \param f1 pointer to function
1657 */
1658 JPf(const JF1_t* f1) :
1659 f1(f1)
1660 {}
1661
1662
1663 /**
1664 * Function value.
1665 *
1666 * \param args abscissa value(s)
1667 * \return function value
1668 */
1669 template<class ...Args>
1670 double getValue(const Args& ...args) const
1671 {
1672 return f1->getValue(args...);
1673 }
1674
1675
1676 /**
1677 * Derivative value.
1678 *
1679 * \param x abscissa value
1680 * \return derivative value
1681 */
1682 double getDerivative(const double x) const
1683 {
1684 return f1->getDerivative(x);
1685 }
1686
1687
1688 /**
1689 * Get gradient.
1690 *
1691 * \param args abscissa value(s)
1692 * \return gradient
1693 */
1694 template<class ...Args>
1695 JPf getGradient(const Args& ...args) const
1696 {
1697 JPf gradient;
1698
1699 return gradient;
1700 }
1701
1703
1704 private:
1705 const JF1_t* f1;
1706 };
1707
1708
1709 /**
1710 * Recursive template class for polynomial function.
1711 */
1712 template<int ID_t, size_t N>
1713 struct JPolynome :
1714 public JMathlib < JPolynome<ID_t, N> >,
1715 public JCalculus< JPolynome<ID_t, N> >,
1716 public JPolynome<ID_t, N - 1>
1717 {
1718 static const int ID = ID_t;
1719
1720 static const size_t NUMBER_OF_DEGREES = N;
1721
1727 using JMathlib < JPolynome<ID_t, N> >::operator();
1728 using JMathlib < JPolynome<ID_t, N> >::operator[];
1729
1730
1731 /**
1732 * Default constructor.
1733 */
1735 a(0.0)
1736 {}
1737
1738
1739 /**
1740 * Constructor.
1741 *
1742 * \param args list of values
1743 */
1744 template<class ...Args>
1745 JPolynome(const Args& ...args) :
1746 JPolynome()
1747 {
1748 set(args...);
1749 }
1750
1751
1752 /**
1753 * Constructor.
1754 *
1755 * \param args list of values
1756 */
1758 JPolynome()
1759 {
1760 for (size_t i = 0; i <= N; ++i) {
1761 (*this)[i] = std::data(args)[i];
1762 }
1763 }
1764
1765
1766 /**
1767 * Function value.
1768 *
1769 * \param x abscissa value
1770 * \return function value
1771 */
1772 double getValue(const double x) const
1773 {
1774 return a * pow(x,N) + static_cast<const JPolynome<ID_t, N - 1>&>(*this).getValue(x);
1775 }
1776
1777
1778 /**
1779 * Derivative value.
1780 *
1781 * \param x abscissa value
1782 * \return derivative value
1783 */
1784 double getDerivative(const double x) const
1785 {
1786 return N * a * pow(x,N-1) + static_cast<const JPolynome<ID_t, N - 1>&>(*this).getDerivative(x);
1787 }
1788
1789
1790 /**
1791 * Get gradient.
1792 *
1793 * \param x abscissa value
1794 * \return gradient
1795 */
1796 JPolynome getGradient(const double x) const
1797 {
1798 JPolynome gradient;
1799
1800 gradient.a = pow(x,N);
1801
1802 static_cast<JPolynome<ID_t, N - 1>&>(gradient) = static_cast<const JPolynome<ID_t, N - 1>&>(*this).getGradient(x);
1803
1804 return gradient;
1805 }
1806
1807 double a; //!< a[N]
1808
1810
1811 protected:
1812 /**
1813 * Recursive method for setting values.
1814 *
1815 * \param x first value
1816 * \param args remaining values
1817 */
1818 template<class ...Args>
1819 void set(const double x, const Args& ...args)
1820 {
1821 a = x;
1822
1824 }
1825 };
1826
1827
1828 /**
1829 * Termination class for polynomial function.
1830 * This function consititutes a constant term and is thereby multi-dimensional by nature.
1831 */
1832 template<int ID_t>
1833 struct JPolynome<ID_t, 0> :
1834 public JMathlib < JPolynome<ID_t, 0> >,
1835 public JCalculus< JPolynome<ID_t, 0> >
1836 {
1837 static const int ID = ID_t;
1838
1839 static const size_t NUMBER_OF_DEGREES = 0;
1840
1841
1842 /**
1843 * Default constructor.
1844 */
1846 a(0.0)
1847 {}
1848
1849
1850 /**
1851 * Constructor.
1852 *
1853 * \param a value
1854 */
1855 JPolynome(const double a) :
1856 a(a)
1857 {}
1858
1859
1860 /**
1861 * Constructor.
1862 *
1863 * \param args list of values
1864 */
1866 JPolynome()
1867 {
1868 a = std::data(args)[0];
1869 }
1870
1871
1872 /**
1873 * Function value.
1874 *
1875 * \return function value
1876 */
1877 double getValue(...) const
1878 {
1879 return a;
1880 }
1881
1882
1883 /**
1884 * Derivative value.
1885 *
1886 * \return derivative value
1887 */
1888 double getDerivative(...) const
1889 {
1890 return 0.0;
1891 }
1892
1893
1894 /**
1895 * Get gradient.
1896 *
1897 * \return gradient
1898 */
1900 {
1901 JPolynome gradient;
1902
1903 gradient.a = 1.0;
1904
1905 return gradient;
1906 }
1907
1908 double a; //!< a[0]
1909
1911
1912 protected:
1913 /**
1914 * Recursive method for setting values.
1915 *
1916 * \param x value
1917 */
1918 void set(const double x)
1919 {
1920 a = x;
1921 }
1922 };
1923
1924
1925 template<int ID_t>
1926 using JP0 = JPolynome<ID_t, 0>; //!< shorthand for 0th degree polynome
1927
1928 template<int ID_t>
1929 using P0 = JP0<ID_t>; //!< shorthand for constant term
1930
1931 template<int ID_t>
1932 using JP1 = JPolynome<ID_t, 1>; //!< shorthand for 1st degree polynome
1933
1934 template<int ID_t>
1935 using JP2 = JPolynome<ID_t, 2>; //!< shorthand for 2nd degree polynome
1936
1937 template<int ID_t>
1938 using JP3 = JPolynome<ID_t, 3>; //!< shorthand for 3rd degree polynome
1939
1940
1941 /**
1942 * Gauss function.
1943 */
1944 template<int ID_t, bool normalised = false>
1945 struct JGauss :
1946 public JMathlib < JGauss<ID_t> >,
1947 public JCalculus< JGauss<ID_t> >
1948 {
1949 static const int ID = ID_t;
1950
1951
1952 /**
1953 * Default constructor.
1954 */
1956 center(0.0),
1957 sigma (0.0)
1958 {}
1959
1960
1961 /**
1962 * Constructor.
1963 *
1964 * \param center center
1965 * \param sigma sigma
1966 */
1967 JGauss(const double center,
1968 const double sigma) :
1969 center(center),
1970 sigma (sigma)
1971 {}
1972
1973
1974 /**
1975 * Function value.
1976 *
1977 * \param x abscissa value
1978 * \return function value
1979 */
1980 double getValue(const double x) const
1981 {
1982 const double u = (x - center) / sigma;
1983
1984 return get(u);
1985 }
1986
1987
1988 /**
1989 * Derivative value.
1990 *
1991 * \param x abscissa value
1992 * \return derivative value
1993 */
1994 double getDerivative(const double x) const
1995 {
1996 const double w = 1.0 / sigma;
1997 const double u = (x - center) / sigma;
1998
1999 return get(u) * -u * w;
2000 }
2001
2002
2003 /**
2004 * Get gradient.
2005 *
2006 * \param x abscissa value
2007 * \return gradient
2008 */
2009 JGauss getGradient(const double x) const
2010 {
2012
2013 const double w = 1.0 / sigma;
2014 const double u = (x - center) * w;
2015 const double f0 = get(u);
2016
2017 gradient.center = f0 * u * w; // d(f)/d(center)
2018 gradient.sigma = f0 * u * u * w; // d(f)/d(sigma)
2019
2020 return gradient;
2021 }
2022
2023 double center; //!< center
2024 double sigma; //!< sigma
2025
2027
2028 private:
2029 /**
2030 * Get ordinate value.
2031 *
2032 * \param u abscissa value
2033 * \return ordinate value
2034 */
2035 inline double get(const double u) const
2036 {
2037 return exp(-0.5*u*u);
2038 }
2039 };
2040
2041
2042 /**
2043 * Gauss function.
2044 */
2045 template<int ID_t>
2046 struct JGauss<ID_t, true> :
2047 public JMathlib < JGauss<ID_t, true> >,
2048 public JCalculus< JGauss<ID_t, true> >
2049 {
2050 static const int ID = ID_t;
2051
2052
2053 /**
2054 * Default constructor.
2055 */
2057 center(0.0),
2058 sigma (0.0)
2059 {}
2060
2061
2062 /**
2063 * Constructor.
2064 *
2065 * \param center center
2066 * \param sigma sigma
2067 */
2068 JGauss(const double center,
2069 const double sigma) :
2070 center(center),
2071 sigma (sigma)
2072 {}
2073
2074
2075 /**
2076 * Function value.
2077 *
2078 * \param x abscissa value
2079 * \return function value
2080 */
2081 double getValue(const double x) const
2082 {
2083 const double u = (x - center) / sigma;
2084
2085 return get(u);
2086 }
2087
2088
2089 /**
2090 * Derivative value.
2091 *
2092 * \param x abscissa value
2093 * \return derivative value
2094 */
2095 double getDerivative(const double x) const
2096 {
2097 const double w = 1.0 / sigma;
2098 const double u = (x - center) / sigma;
2099
2100 return get(u) * -u * w;
2101 }
2102
2103
2104 /**
2105 * Get gradient.
2106 *
2107 * \param x abscissa value
2108 * \return gradient
2109 */
2110 JGauss getGradient(const double x) const
2111 {
2113
2114 const double w = 1.0 / sigma;
2115 const double u = (x - center) * w;
2116 const double f0 = get(u);
2117
2118 gradient.center = f0 * (u) * w; // d(f)/d(center)
2119 gradient.sigma = f0 * (u + 1.0) * (u - 1.0) * w; // d(f)/d(sigma)
2120
2121 return gradient;
2122 }
2123
2124 double center; //!< center
2125 double sigma; //!< sigma
2126
2128
2129 private:
2130 /**
2131 * Get ordinate value.
2132 *
2133 * \param u abscissa value
2134 * \return ordinate value
2135 */
2136 inline double get(const double u) const
2137 {
2138 static const double W = 1.0 / sqrt(2.0 * acos(-1.0));
2139
2140 return exp(-0.5*u*u) * W / sigma;
2141 }
2142 };
2143
2144
2145 /**
2146 * Power of function.
2147 */
2148 template<int ID_t, class JF1_t = JX>
2149 struct JPow :
2150 public JMathlib < JPow<ID_t, JF1_t> >,
2151 public JF1_t
2152 {
2153 static const int ID = ID_t;
2154
2155 using JMathlib< JPow<ID_t, JF1_t> >::operator();
2156 using JMathlib< JPow<ID_t, JF1_t> >::operator[];
2157
2158
2159 /**
2160 * Default constructor.
2161 */
2163 JF1_t(),
2164 alpha(0.0)
2165 {}
2166
2167
2168 /**
2169 * Constructor.
2170 *
2171 * \param alpha value
2172 */
2173 JPow(const double alpha) :
2174 JF1_t(),
2175 alpha(alpha)
2176 {}
2177
2178
2179 /**
2180 * Constructor.
2181 *
2182 * \param f1 function
2183 * \param alpha value
2184 */
2185 JPow(const JF1_t& f1, const double alpha) :
2186 JF1_t(f1),
2187 alpha(alpha)
2188 {}
2189
2190
2191 /**
2192 * Function value.
2193 *
2194 * \param x abscissa value
2195 * \return function value
2196 */
2197 double getValue(const double x) const
2198 {
2199 const double u = static_cast<const JF1_t&>(*this).getValue(x);
2200
2201 return pow(u, alpha);
2202 }
2203
2204
2205 /**
2206 * Derivative value.
2207 *
2208 * \param x abscissa value
2209 * \return derivative value
2210 */
2211 double getDerivative(const double x) const
2212 {
2213 const double u = static_cast<const JF1_t&>(*this).getValue(x);
2214 const double v = static_cast<const JF1_t&>(*this).getDerivative(x);
2215
2216 return alpha * pow(u, alpha - 1) * v;
2217 }
2218
2219
2220 /**
2221 * Get gradient.
2222 *
2223 * \param x abscissa value
2224 * \return gradient
2225 */
2226 JPow getGradient(const double x) const
2227 {
2228 JPow gradient;
2229
2230 const double u = static_cast<const JF1_t&>(*this).getValue(x);
2231 const double w = pow(u, alpha);
2232
2233 gradient.alpha = w * log(u);
2234
2235 static_cast<JF1_t&>(gradient) = static_cast<const JF1_t&>(*this).getGradient(x);
2236 static_cast<JF1_t&>(gradient) *= alpha * w / u;
2237
2238 return gradient;
2239 }
2240
2241 double alpha; //!< f(x)^alpha
2242
2244 };
2245
2246
2247 /**
2248 * Power of function.
2249 *
2250 * \param f1 function
2251 * \param alpha alpha
2252 * \return result
2253 */
2254 template<class JF1_t>
2255 JPow<JF1_t::ID, JF1_t> Pow(const JF1_t& f1, const double alpha)
2256 {
2257 return JPow<JF1_t::ID, JF1_t>(f1, alpha);
2258 }
2259
2260
2261 /**
2262 * Square root of function.
2263 */
2264 template<class JF1_t = JX>
2265 struct JSqrt :
2266 public JMathlib < JSqrt<JF1_t> >,
2267 public JF1_t
2268 {
2269 using JMathlib< JSqrt<JF1_t> >::operator();
2270 using JMathlib< JSqrt<JF1_t> >::operator[];
2271
2272
2273 /**
2274 * Default constructor.
2275 */
2277 JF1_t()
2278 {}
2279
2280
2281 /**
2282 * Constructor.
2283 *
2284 * \param f1 function
2285 */
2286 JSqrt(const JF1_t& f1) :
2287 JF1_t(f1)
2288 {}
2289
2290
2291 /**
2292 * Function value.
2293 *
2294 * \param x abscissa value
2295 * \return function value
2296 */
2297 double getValue(const double x) const
2298 {
2299 const double u = static_cast<const JF1_t&>(*this).getValue(x);
2300
2301 return sqrt(u);
2302 }
2303
2304
2305 /**
2306 * Derivative value.
2307 *
2308 * \param x abscissa value
2309 * \return derivative value
2310 */
2311 double getDerivative(const double x) const
2312 {
2313 const double u = static_cast<const JF1_t&>(*this).getValue(x);
2314 const double v = static_cast<const JF1_t&>(*this).getDerivative(x);
2315
2316 return 0.5 * v / sqrt(u);
2317 }
2318
2319
2320 /**
2321 * Get gradient.
2322 *
2323 * \param x abscissa value
2324 * \return gradient
2325 */
2326 JSqrt getGradient(const double x) const
2327 {
2328 JSqrt gradient;
2329
2330 const double u = static_cast<const JF1_t&>(*this).getValue(x);
2331
2332 static_cast<JF1_t&>(gradient) = static_cast<const JF1_t&>(*this).getGradient(x);
2333 static_cast<JF1_t&>(gradient) *= 0.5 / sqrt(u);
2334
2335 return gradient;
2336 }
2337 };
2338
2339
2340 /**
2341 * Square root of function.
2342 *
2343 * \param f1 function
2344 * \return result
2345 */
2346 template<class JF1_t>
2347 JSqrt<JF1_t> Sqrt(const JF1_t& f1)
2348 {
2349 return JSqrt<JF1_t>(f1);
2350 }
2351
2352
2353 /**
2354 * Sine of function.
2355 */
2356 template<class JF1_t = JX>
2357 struct JSin :
2358 public JMathlib < JSin<JF1_t> >,
2359 public JF1_t
2360 {
2361 using JMathlib< JSin<JF1_t> >::operator();
2362 using JMathlib< JSin<JF1_t> >::operator[];
2363
2364
2365 /**
2366 * Default constructor.
2367 */
2369 JF1_t()
2370 {}
2371
2372
2373 /**
2374 * Constructor.
2375 *
2376 * \param f1 function
2377 */
2378 JSin(const JF1_t& f1) :
2379 JF1_t(f1)
2380 {}
2381
2382
2383 /**
2384 * Function value.
2385 *
2386 * \param x abscissa value
2387 * \return function value
2388 */
2389 double getValue(const double x) const
2390 {
2391 const double u = static_cast<const JF1_t&>(*this).getValue(x);
2392
2393 return sin(u);
2394 }
2395
2396
2397 /**
2398 * Derivative value.
2399 *
2400 * \param x abscissa value
2401 * \return derivative value
2402 */
2403 double getDerivative(const double x) const
2404 {
2405 const double u = static_cast<const JF1_t&>(*this).getValue(x);
2406 const double v = static_cast<const JF1_t&>(*this).getDerivative(x);
2407
2408 return v * cos(u);
2409 }
2410
2411
2412 /**
2413 * Get gradient.
2414 *
2415 * \param x abscissa value
2416 * \return gradient
2417 */
2418 JSin getGradient(const double x) const
2419 {
2420 JSin gradient;
2421
2422 const double u = static_cast<const JF1_t&>(*this).getValue(x);
2423
2424 static_cast<JF1_t&>(gradient) = static_cast<const JF1_t&>(*this).getGradient(x);
2425 static_cast<JF1_t&>(gradient) *= cos(u);
2426
2427 return gradient;
2428 }
2429 };
2430
2431
2432 /**
2433 * Sine of function.
2434 *
2435 * \param f1 function
2436 * \return result
2437 */
2438 template<class JF1_t>
2439 JSin<JF1_t> Sin(const JF1_t& f1)
2440 {
2441 return JSin<JF1_t>(f1);
2442 }
2443
2444
2445 /**
2446 * Cosine of function.
2447 */
2448 template<class JF1_t = JX>
2449 struct JCos :
2450 public JMathlib < JCos<JF1_t> >,
2451 public JF1_t
2452 {
2453 using JMathlib< JCos<JF1_t> >::operator();
2454 using JMathlib< JCos<JF1_t> >::operator[];
2455
2456
2457 /**
2458 * Default constructor.
2459 */
2461 JF1_t()
2462 {}
2463
2464
2465 /**
2466 * Constructor.
2467 *
2468 * \param f1 function
2469 */
2470 JCos(const JF1_t& f1) :
2471 JF1_t(f1)
2472 {}
2473
2474
2475 /**
2476 * Function value.
2477 *
2478 * \param x abscissa value
2479 * \return function value
2480 */
2481 double getValue(const double x) const
2482 {
2483 const double u = static_cast<const JF1_t&>(*this).getValue(x);
2484
2485 return cos(u);
2486 }
2487
2488
2489 /**
2490 * Derivative value.
2491 *
2492 * \param x abscissa value
2493 * \return derivative value
2494 */
2495 double getDerivative(const double x) const
2496 {
2497 const double u = static_cast<const JF1_t&>(*this).getValue(x);
2498 const double v = static_cast<const JF1_t&>(*this).getDerivative(x);
2499
2500 return v * -sin(u);
2501 }
2502
2503
2504 /**
2505 * Get gradient.
2506 *
2507 * \param x abscissa value
2508 * \return gradient
2509 */
2510 JCos getGradient(const double x) const
2511 {
2512 JCos gradient;
2513
2514 const double u = static_cast<const JF1_t&>(*this).getValue(x);
2515
2516 static_cast<JF1_t&>(gradient) = static_cast<const JF1_t&>(*this).getGradient(x);
2517 static_cast<JF1_t&>(gradient) *= -sin(u);
2518
2519 return gradient;
2520 }
2521 };
2522
2523
2524 /**
2525 * Cosine of function.
2526 *
2527 * \param f1 function
2528 * \return result
2529 */
2530 template<class JF1_t>
2531 JCos<JF1_t> Cos(const JF1_t& f1)
2532 {
2533 return JCos<JF1_t>(f1);
2534 }
2535
2536
2537 /**
2538 * Exponent of function.
2539 */
2540 template<class JF1_t = JX>
2541 struct JExp :
2542 public JMathlib< JExp<JF1_t> >,
2543 public JF1_t
2544 {
2545 using JMathlib< JExp<JF1_t> >::operator();
2546 using JMathlib< JExp<JF1_t> >::operator[];
2547
2548
2549 /**
2550 * Default constructor.
2551 */
2553 JF1_t()
2554 {}
2555
2556
2557 /**
2558 * Constructor.
2559 *
2560 * \param f1 function
2561 */
2562 JExp(const JF1_t& f1) :
2563 JF1_t(f1)
2564 {}
2565
2566
2567 /**
2568 * Function value.
2569 *
2570 * \param x abscissa value
2571 * \return function value
2572 */
2573 double getValue(const double x) const
2574 {
2575 return exp(static_cast<const JF1_t&>(*this).getValue(x));
2576 }
2577
2578
2579 /**
2580 * Derivative value.
2581 *
2582 * \param x abscissa value
2583 * \return derivative value
2584 */
2585 double getDerivative(const double x) const
2586 {
2587 return static_cast<const JF1_t&>(*this).getDerivative(x) * getValue(x);
2588 }
2589
2590
2591 /**
2592 * Get gradient.
2593 *
2594 * \param x abscissa value
2595 * \return gradient
2596 */
2597 JExp getGradient(const double x) const
2598 {
2599 JExp gradient;
2600
2601 gradient = static_cast<const JF1_t&>(*this).getGradient(x);
2602 gradient *= getValue(x);
2603
2604 return gradient;
2605 }
2606 };
2607
2608
2609 /**
2610 * Exponent of zero degree polynomial function.
2611 */
2612 template<int ID_t>
2613 struct JExp< JPolynome<ID_t, 0> > :
2614 public JMathlib< JExp< JPolynome<ID_t, 0> > >,
2615 public JPolynome<ID_t, 0>
2616 {
2617 using JMathlib< JExp< JPolynome<ID_t, 0> > >::operator();
2618 using JMathlib< JExp< JPolynome<ID_t, 0> > >::operator[];
2619
2620
2621 /**
2622 * Default constructor.
2623 */
2625 JPolynome<ID_t, 0>()
2626 {}
2627
2628
2629 /**
2630 * Constructor.
2631 *
2632 * \param f1 function
2633 */
2635 JPolynome<ID_t, 0>(f1)
2636 {}
2637
2638
2639 /**
2640 * Function value.
2641 *
2642 * \return function value
2643 */
2644 double getValue(...) const
2645 {
2646 return exp(static_cast<const JPolynome<ID_t, 0>&>(*this).getValue());
2647 }
2648
2649
2650 /**
2651 * Derivative value.
2652 *
2653 * \return derivative value
2654 */
2655 double getDerivative(...) const
2656 {
2657 return static_cast<const JPolynome<ID_t, 0>&>(*this).getDerivative() * getValue();
2658 }
2659
2660
2661 /**
2662 * Get gradient.
2663 *
2664 * \return gradient
2665 */
2667 {
2668 JExp gradient;
2669
2670 gradient = static_cast<const JPolynome<ID_t, 0>&>(*this).getGradient();
2671 gradient *= getValue();
2672
2673 return gradient;
2674 }
2675 };
2676
2677
2678 /**
2679 * Exponent of function.
2680 *
2681 * \param f1 function
2682 * \return result
2683 */
2684 template<class JF1_t>
2685 JExp<JF1_t> Exp(const JF1_t& f1)
2686 {
2687 return JExp<JF1_t>(f1);
2688 }
2689
2690
2691 /**
2692 * Logarithm of function.
2693 */
2694 template<class JF1_t = JX>
2695 struct JLog :
2696 public JMathlib< JLog<JF1_t> >,
2697 public JF1_t
2698 {
2699 using JMathlib< JLog<JF1_t> >::operator();
2700 using JMathlib< JLog<JF1_t> >::operator[];
2701
2702
2703 /**
2704 * Default constructor.
2705 */
2707 JF1_t()
2708 {}
2709
2710
2711 /**
2712 * Constructor.
2713 *
2714 * \param f1 function
2715 */
2716 JLog(const JF1_t& f1) :
2717 JF1_t(f1)
2718 {}
2719
2720
2721 /**
2722 * Function value.
2723 *
2724 * \param x abscissa value
2725 * \return function value
2726 */
2727 double getValue(const double x) const
2728 {
2729 return log(static_cast<const JF1_t&>(*this).getValue(x));
2730 }
2731
2732
2733 /**
2734 * Derivative value.
2735 *
2736 * \param x abscissa value
2737 * \return derivative value
2738 */
2739 double getDerivative(const double x) const
2740 {
2741 return static_cast<const JF1_t&>(*this).getDerivative(x) / static_cast<const JF1_t&>(*this).getValue(x);
2742 }
2743
2744
2745 /**
2746 * Get gradient.
2747 *
2748 * \param x abscissa value
2749 * \return gradient
2750 */
2751 JLog getGradient(const double x) const
2752 {
2753 JLog gradient;
2754
2755 gradient = static_cast<const JF1_t&>(*this).getGradient(x);
2756 gradient /= (static_cast<const JF1_t&>(*this).getValue(x));
2757
2758 return gradient;
2759 }
2760 };
2761
2762
2763 /**
2764 * Logarithm of function.
2765 *
2766 * \param f1 function
2767 * \return result
2768 */
2769 template<class JF1_t>
2770 JLog<JF1_t> Log(const JF1_t& f1)
2771 {
2772 return JLog<JF1_t>(f1);
2773 }
2774}
2775
2776#endif
constexpr size_t getNumberOfParameters()
Get number of parameters.
Definition JMathlib.hh:135
void setParameters(JF1_t *f1, const double *values)
Set values of all parameters.
Definition JMathlib.hh:148
JPow< JF1_t::ID, JF1_t > Pow(const JF1_t &f1, const double alpha)
Power of function.
Definition JMathlib.hh:2255
static const JXn< 5 > X5
Function object for x^4;.
Definition JMathlib.hh:1622
JSqrt< JF1_t > Sqrt(const JF1_t &f1)
Square root of function.
Definition JMathlib.hh:2347
JExp< JF1_t > Exp(const JF1_t &f1)
Exponent of function.
Definition JMathlib.hh:2685
static const JXn< 3 > X3
Function object for x^2;.
Definition JMathlib.hh:1620
T pow(const T &x, const double y)
Power .
Definition JMath.hh:97
static const JXn< 4 > X4
Function object for x^3;.
Definition JMathlib.hh:1621
JCos< JF1_t > Cos(const JF1_t &f1)
Cosine of function.
Definition JMathlib.hh:2531
constexpr parameter_list< U, sizeof...(i)> convert(const parameter_list< V, sizeof...(i)> &parameters, const std::index_sequence< i... > &ls)
Auxiliary method to convert parameter list.
Definition JMathlib.hh:109
constexpr parameter_list< U, sizeof...(i)+1 > join(const parameter_list< V, sizeof...(i)> &parameters, const std::index_sequence< i... > &ls, double W::*parameter)
Auxiliary method to join parameter and list of parameters.
Definition JMathlib.hh:43
static const JXn< 2 > X2
Invalidate x^0.
Definition JMathlib.hh:1619
static const JX X
Definition JMathlib.hh:1558
JSin< JF1_t > Sin(const JF1_t &f1)
Sine of function.
Definition JMathlib.hh:2439
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Definition log.hh:13
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:680
JAdd getGradient(const Args &...args) const
Get gradient.
Definition JMathlib.hh:693
JAdd()
Default constructor.
Definition JMathlib.hh:645
JAdd(const JF1_t &f1, const double value)
Constructor.
Definition JMathlib.hh:655
double getValue(const Args &...args) const
Function value.
Definition JMathlib.hh:668
Addition of two functions.
Definition JMathlib.hh:1099
JAdd getGradient(const Args &...args) const
Get gradient.
Definition JMathlib.hh:1156
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:1142
JAdd()
Default constructor.
Definition JMathlib.hh:1107
double getValue(const Args &...args) const
Function value.
Definition JMathlib.hh:1129
JAdd(const JF1_t &f1, const JF2_t &f2)
Constructor.
Definition JMathlib.hh:1117
Auxiliary base class for mathematical operations on parameters of function.
Definition JMathlib.hh:163
JF1_t & div(const double factor)
Scale function.
Definition JMathlib.hh:233
JF1_t & mul(const double factor)
Scale function.
Definition JMathlib.hh:217
JF1_t & add(const JF1_t &f1)
Add function.
Definition JMathlib.hh:185
friend JF1_t & operator+=(JF1_t &function, const JF1_t &value)
Add function.
Definition JMathlib.hh:250
friend JF1_t & operator/=(JF1_t &function, const double factor)
Scale function.
Definition JMathlib.hh:289
friend JF1_t & operator*=(JF1_t &function, const double factor)
Scale function.
Definition JMathlib.hh:276
JF1_t & sub(const JF1_t &f1)
Subtract function.
Definition JMathlib.hh:201
JF1_t & negate()
Negate function.
Definition JMathlib.hh:169
friend JF1_t & operator-=(JF1_t &function, const JF1_t &value)
Subtract function.
Definition JMathlib.hh:263
Cosine of function.
Definition JMathlib.hh:2452
JCos(const JF1_t &f1)
Constructor.
Definition JMathlib.hh:2470
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:2495
JCos getGradient(const double x) const
Get gradient.
Definition JMathlib.hh:2510
double getValue(const double x) const
Function value.
Definition JMathlib.hh:2481
JCos()
Default constructor.
Definition JMathlib.hh:2460
JDiv(const JF1_t &f1, const double value)
Constructor.
Definition JMathlib.hh:887
double getValue(const Args &...args) const
Function value.
Definition JMathlib.hh:900
JDiv getGradient(const Args &...args) const
Get gradient.
Definition JMathlib.hh:925
JDiv()
Default constructor.
Definition JMathlib.hh:877
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:912
Division of two functions.
Definition JMathlib.hh:1330
double getValue(const Args &...args) const
Function value.
Definition JMathlib.hh:1360
JDiv getGradient(const Args &...args) const
Get gradient.
Definition JMathlib.hh:1390
JDiv()
Default constructor.
Definition JMathlib.hh:1338
JDiv(const JF1_t &f1, const JF2_t &f2)
Constructor.
Definition JMathlib.hh:1348
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:1373
double getDerivative(...) const
Derivative value.
Definition JMathlib.hh:2655
double getValue(...) const
Function value.
Definition JMathlib.hh:2644
JExp(const JPolynome< ID_t, 0 > &f1)
Constructor.
Definition JMathlib.hh:2634
JExp getGradient(...) const
Get gradient.
Definition JMathlib.hh:2666
Exponent of function.
Definition JMathlib.hh:2544
JExp()
Default constructor.
Definition JMathlib.hh:2552
JExp getGradient(const double x) const
Get gradient.
Definition JMathlib.hh:2597
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:2585
double getValue(const double x) const
Function value.
Definition JMathlib.hh:2573
JExp(const JF1_t &f1)
Constructor.
Definition JMathlib.hh:2562
Fixed power of function.
Definition JMathlib.hh:1422
JFn()
Default constructor.
Definition JMathlib.hh:1430
JFn(const JF1_t &f1, const int N)
Constructor.
Definition JMathlib.hh:1442
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:1469
JFn getGradient(const Args &...args) const
Get gradient.
Definition JMathlib.hh:1485
double getValue(const Args &...args) const
Function value.
Definition JMathlib.hh:1455
JGauss(const double center, const double sigma)
Constructor.
Definition JMathlib.hh:2068
JGauss getGradient(const double x) const
Get gradient.
Definition JMathlib.hh:2110
JGauss()
Default constructor.
Definition JMathlib.hh:2056
double getValue(const double x) const
Function value.
Definition JMathlib.hh:2081
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:2095
double get(const double u) const
Get ordinate value.
Definition JMathlib.hh:2136
Gauss function object.
Definition JMathlib.hh:1948
double sigma
sigma
Definition JMathlib.hh:2024
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:1994
JGauss()
Default constructor.
Definition JMathlib.hh:1955
double center
center
Definition JMathlib.hh:2023
static constexpr parameter_list< JGauss, 2 > parameters
Definition JMathlib.hh:2026
double getValue(const double x) const
Function value.
Definition JMathlib.hh:1980
JGauss_t gradient
Definition JGauss.hh:289
JGauss getGradient(const double x) const
Get gradient.
Definition JMathlib.hh:2009
double get(const double u) const
Get ordinate value.
Definition JGauss.hh:284
JGauss(const double center, const double sigma)
Constructor.
Definition JMathlib.hh:1967
Logarithm of function.
Definition JMathlib.hh:2698
double getValue(const double x) const
Function value.
Definition JMathlib.hh:2727
JLog getGradient(const double x) const
Get gradient.
Definition JMathlib.hh:2751
JLog()
Default constructor.
Definition JMathlib.hh:2706
JLog(const JF1_t &f1)
Constructor.
Definition JMathlib.hh:2716
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:2739
Auxiliary base class for mathematical operations on functions.
Definition JMathlib.hh:322
friend JMul< JF1_t, JF2_t > operator*(const JF1_t &f1, const JF2_t &f2)
Multiplication of two functions.
Definition JMathlib.hh:487
friend JDiv< JF1_t, JF2_t > operator/(const JF1_t &f1, const JF2_t &f2)
Division of two functions.
Definition JMathlib.hh:501
friend JAdd< JNegate< JF1_t > > operator-(const double value, const JF1_t &f1)
Subtraction of constant value.
Definition JMathlib.hh:406
friend JFn< JF1_t > operator^(const JF1_t &f1, int N)
Power-of operator.
Definition JMathlib.hh:514
double operator[](const size_t i) const
Get value of parameter at given index.
Definition JMathlib.hh:538
double & operator[](const size_t i)
Get value of parameter at given index.
Definition JMathlib.hh:550
friend JAdd< JF1_t > operator+(const double value, const JF1_t &f1)
Addition of constant value.
Definition JMathlib.hh:380
friend JSub< JF1_t > operator-(const JF1_t &f1, const double value)
Subtraction of constant value.
Definition JMathlib.hh:393
friend const JF1_t & operator+(const JF1_t &function)
Affirm operator.
Definition JMathlib.hh:342
friend JMul< JF1_t > operator*(const double value, const JF1_t &f1)
Multiplication of constant value.
Definition JMathlib.hh:432
friend JSub< JF1_t, JF2_t > operator-(const JF1_t &f1, const JF2_t &f2)
Subtraction of two functions.
Definition JMathlib.hh:473
friend JDiv< JF1_t > operator/(const JF1_t &f1, const double value)
Division of constant value.
Definition JMathlib.hh:445
double operator()(const Args &...args) const
Function value.
Definition JMathlib.hh:330
friend JAdd< JF1_t > operator+(const JF1_t &f1, const double value)
Addition of constant value.
Definition JMathlib.hh:367
friend JPf< JF1_t > operator&(const JF1_t &f1)
Address-of operator.
Definition JMathlib.hh:526
friend JNegate< JF1_t > operator-(const JF1_t &function)
Negate operator.
Definition JMathlib.hh:354
friend JAdd< JF1_t, JF2_t > operator+(const JF1_t &f1, const JF2_t &f2)
Addition of two functions.
Definition JMathlib.hh:459
friend JMul< JF1_t > operator*(const JF1_t &f1, const double value)
Multiplication of constant value.
Definition JMathlib.hh:419
double getValue(const Args &...args) const
Function value.
Definition JMathlib.hh:822
JMul(const JF1_t &f1, const double value)
Constructor.
Definition JMathlib.hh:809
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:834
JMul getGradient(const Args &...args) const
Get gradient.
Definition JMathlib.hh:847
JMul()
Default constructor.
Definition JMathlib.hh:799
Multiplication of two functions.
Definition JMathlib.hh:1252
double getValue(const Args &...args) const
Function value.
Definition JMathlib.hh:1282
JMul()
Default constructor.
Definition JMathlib.hh:1260
JMul(const JF1_t &f1, const JF2_t &f2)
Constructor.
Definition JMathlib.hh:1270
JMul getGradient(const Args &...args) const
Get gradient.
Definition JMathlib.hh:1309
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:1295
Negate of function.
Definition JMathlib.hh:564
double getValue(const Args &...args) const
Function value.
Definition JMathlib.hh:593
JNegate()
Default constructor.
Definition JMathlib.hh:572
JNegate(const JF1_t &f1)
Constructor.
Definition JMathlib.hh:581
JNegate getGradient(const Args &...args) const
Get gradient.
Definition JMathlib.hh:618
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:605
JPair(const JF1_t &f1, const JF2_t &f2)
Constructor.
Definition JMathlib.hh:993
JPair(const JF1_t &f1, const JF2_t &f2)
Constructor.
Definition JMathlib.hh:1022
JPair(const JF1_t &f1, const JF2_t &f2)
Constructor.
Definition JMathlib.hh:1051
Auxiliary data structure for pair of functions.
Definition JMathlib.hh:1065
JPair_t()
Default constructor.
Definition JMathlib.hh:1076
JPair_t(const JF1_t &f1, const JF2_t &f2)
Constructor.
Definition JMathlib.hh:1086
Auxiliary data structure for pair of functions.
Definition JMathlib.hh:949
static constexpr parameter_list< JPair, JF1_t::parameters.size()+JF2_t::parameters.size()> parameters
Definition JMathlib.hh:968
JPair(const JF1_t &f1, const JF2_t &f2)
Constructor.
Definition JMathlib.hh:963
JPair()
Default constructor.
Definition JMathlib.hh:953
Pointer to function.
Definition JMathlib.hh:1640
const JF1_t * f1
Definition JMathlib.hh:1705
JPf getGradient(const Args &...args) const
Get gradient.
Definition JMathlib.hh:1695
JPf()
Default constructor.
Definition JMathlib.hh:1648
JPf(const JF1_t *f1)
Constructor.
Definition JMathlib.hh:1658
double getValue(const Args &...args) const
Function value.
Definition JMathlib.hh:1670
static constexpr parameter_list< JPf, 0 > parameters
Definition JMathlib.hh:1702
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:1682
Termination class for polynomial function.
Definition JMathlib.hh:1836
JPolynome getGradient(...) const
Get gradient.
Definition JMathlib.hh:1899
double getValue(...) const
Function value.
Definition JMathlib.hh:1877
double getDerivative(...) const
Derivative value.
Definition JMathlib.hh:1888
JPolynome()
Default constructor.
Definition JMathlib.hh:1845
void set(const double x)
Recursive method for setting values.
Definition JMathlib.hh:1918
JPolynome(const std::array< double, 1 > &args)
Constructor.
Definition JMathlib.hh:1865
JPolynome(const double a)
Constructor.
Definition JMathlib.hh:1855
JPolynome_t & mul(const double factor)
Scale polynome.
Definition JPolynome.hh:113
JPolynome_t & sub(const JPolynome_t &polynome)
Subtract polynome.
Definition JPolynome.hh:93
JPolynome_t & add(const JPolynome_t &polynome)
Add polynome.
Definition JPolynome.hh:73
Recursive template class for polynomial function.
Definition JPolynome.hh:165
static const size_t NUMBER_OF_DEGREES
Definition JMathlib.hh:1720
JPolynome()
Default constructor.
Definition JMathlib.hh:1734
JPolynome(const Args &...args)
Constructor.
Definition JMathlib.hh:1745
double getValue(const double x) const
Function value.
Definition JMathlib.hh:1772
void set(const double x, const Args &...args)
Recursive method for setting values.
Definition JMathlib.hh:1819
JPolynome(const std::array< double, N+1 > &args)
Constructor.
Definition JMathlib.hh:1757
JPolynome getGradient(const double x) const
Get gradient.
Definition JMathlib.hh:1796
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:1784
static constexpr parameter_list< JPolynome, N+1 > parameters
Definition JMathlib.hh:1809
Power of function.
Definition JMathlib.hh:2152
double getValue(const double x) const
Function value.
Definition JMathlib.hh:2197
JPow(const JF1_t &f1, const double alpha)
Constructor.
Definition JMathlib.hh:2185
double alpha
f(x)^alpha
Definition JMathlib.hh:2241
JPow getGradient(const double x) const
Get gradient.
Definition JMathlib.hh:2226
static constexpr parameter_list< JPow, 1 > parameters
Definition JMathlib.hh:2243
JPow(const double alpha)
Constructor.
Definition JMathlib.hh:2173
JPow()
Default constructor.
Definition JMathlib.hh:2162
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:2211
Sine of function.
Definition JMathlib.hh:2360
JSin()
Default constructor.
Definition JMathlib.hh:2368
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:2403
double getValue(const double x) const
Function value.
Definition JMathlib.hh:2389
JSin getGradient(const double x) const
Get gradient.
Definition JMathlib.hh:2418
JSin(const JF1_t &f1)
Constructor.
Definition JMathlib.hh:2378
Square root of function.
Definition JMathlib.hh:2268
JSqrt()
Default constructor.
Definition JMathlib.hh:2276
double getValue(const double x) const
Function value.
Definition JMathlib.hh:2297
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:2311
JSqrt getGradient(const double x) const
Get gradient.
Definition JMathlib.hh:2326
JSqrt(const JF1_t &f1)
Constructor.
Definition JMathlib.hh:2286
double getValue(const Args &...args) const
Function value.
Definition JMathlib.hh:745
JSub getGradient(const Args &...args) const
Get gradient.
Definition JMathlib.hh:770
JSub()
Default constructor.
Definition JMathlib.hh:722
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:757
JSub(const JF1_t &f1, const double value)
Constructor.
Definition JMathlib.hh:732
Subtraction of two functions.
Definition JMathlib.hh:1175
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:1218
double getValue(const Args &...args) const
Function value.
Definition JMathlib.hh:1205
JSub getGradient(const Args &...args) const
Get gradient.
Definition JMathlib.hh:1232
JSub()
Default constructor.
Definition JMathlib.hh:1183
JSub(const JF1_t &f1, const JF2_t &f2)
Constructor.
Definition JMathlib.hh:1193
double getValue(const double x) const
Function value.
Definition JMathlib.hh:1523
JX getGradient(const double x) const
Get gradient.
Definition JMathlib.hh:1547
JX()
Default constructor.
Definition JMathlib.hh:1513
static constexpr parameter_list< JX, 0 > parameters
Definition JMathlib.hh:1554
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:1535
Function object for x;.
Definition JMathlib.hh:1568
double getValue(const double x) const
Function value.
Definition JMathlib.hh:1582
double getDerivative(const double x) const
Derivative value.
Definition JMathlib.hh:1594
JXn()
Default constructor.
Definition JMathlib.hh:1572
JXn getGradient(const double x) const
Get gradient.
Definition JMathlib.hh:1606
static constexpr parameter_list< JXn, 0 > parameters
Definition JMathlib.hh:1613