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