Theoretica
A C++ numerical and automatic mathematical library
deriv.h
Go to the documentation of this file.
1 
5 
6 #ifndef DERIVATION_THEORETICA_H
7 #define DERIVATION_THEORETICA_H
8 
9 #include "../core/function.h"
10 #include "../polynomial/polynomial.h"
11 
12 
13 namespace theoretica {
14 
15 
20  template<typename Field = real>
22 
23  if (p.coeff.size() == 0) {
24  TH_MATH_ERROR("deriv", p.coeff.size(), INVALID_ARGUMENT);
25  return polynomial<Field>({ static_cast<Field>(nan()) });
26  }
27 
28  if (p.coeff.size() == 1)
29  return polynomial<Field>({static_cast<Field>(0.0)});
30 
32  Dp.coeff.resize(p.coeff.size() - 1);
33 
34  for (unsigned int i = 1; i < p.size(); ++i)
35  Dp.coeff[i - 1] = p[i] * i;
36 
37  return Dp;
38  }
39 
40 
48  inline real deriv(const polynomial<real>& p, real x) {
49 
50  real dp = 0.0;
51 
52  for (unsigned int i = 0; i + 1 < p.size(); ++i) {
53 
54  const unsigned int pos = p.size() - i - 1;
55  dp = pos * p[pos] + x * dp;
56  }
57 
58  return dp;
59  }
60 
61 
69  template <
70  typename RealFunction = std::function<real(real)>,
71  enable_real_func<RealFunction> = true
72  >
73  inline real deriv_central(RealFunction f, real x, real h = CALCULUS_DERIV_STEP) {
74  return (f(x + h) - f(x - h)) / (2.0 * h);
75  }
76 
77 
85  template <
86  typename RealFunction = std::function<real(real)>,
87  enable_real_func<RealFunction> = true
88  >
89  inline real deriv_forward(RealFunction f, real x, real h = CALCULUS_DERIV_STEP) {
90  return (f(x + h) - f(x)) / h;
91  }
92 
93 
101  template <
102  typename RealFunction = std::function<real(real)>,
103  enable_real_func<RealFunction> = true
104  >
105  inline real deriv_backward(RealFunction f, real x, real h = CALCULUS_DERIV_STEP) {
106  return (f(x) - f(x - h)) / h;
107  }
108 
109 
117  template <
118  typename RealFunction = std::function<real(real)>,
119  enable_real_func<RealFunction> = true
120  >
121  inline real deriv_ridders2(RealFunction f, real x, real h = CALCULUS_DERIV_STEP) {
122  return (4.0 * deriv_central(f, x, h / 2.0) - deriv_central(f, x, h)) / 3.0;
123  }
124 
125 
134  template <
135  typename RealFunction = std::function<real(real)>,
136  enable_real_func<RealFunction> = true
137  >
138  inline real deriv_ridders(RealFunction f, real x, real h = 0.01, unsigned int degree = 3) {
139 
140  real A[degree][degree];
141 
142  for (unsigned int i = 0; i < degree; ++i) {
143 
144  for (unsigned int n = 0; n <= i; ++n) {
145 
146  unsigned int m = i - n;
147 
148  if(n == 0) {
149  A[n][m] = deriv_central(f, x, h / (1 << m));
150  } else {
151  real coeff = square(1 << n);
152  A[n][m] = (coeff * A[n - 1][m + 1] - A[n - 1][m]) / (coeff - 1);
153  }
154  }
155 
156  }
157 
158  return A[degree - 1][0];
159  }
160 
161 
169  template <
170  typename RealFunction = std::function<real(real)>,
171  enable_real_func<RealFunction> = true
172  >
173  inline real deriv(RealFunction f, real x, real h = CALCULUS_DERIV_STEP) {
174  return deriv_ridders2(f, x, h);
175  }
176 
177 
185  template <
186  typename RealFunction = std::function<real(real)>,
187  enable_real_func<RealFunction> = true
188  >
189  inline real deriv2(RealFunction f, real x, real h = CALCULUS_DERIV_STEP) {
190  return (f(x + h) - (2 * f(x)) + f(x - h)) / (h * h);
191  }
192 
193 }
194 
195 
196 #endif
A polynomial of arbitrary order.
Definition: polynomial.h:25
size_t size() const
Get the number of coefficients.
Definition: polynomial.h:119
#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
TH_MATH_ERROR is a macro which throws exceptions or modifies errno (depending on which compiling opti...
Definition: error.h:219
Main namespace of the library which contains all functions and objects.
Definition: algebra.h:27
double real
A real number, defined as a floating point type.
Definition: constants.h:198
real deriv_forward(RealFunction f, real x, real h=CALCULUS_DERIV_STEP)
Approximate the first derivative of a real function using the forward method.
Definition: deriv.h:89
constexpr real CALCULUS_DERIV_STEP
Default variation for derivative approximation.
Definition: constants.h:318
real deriv_ridders(RealFunction f, real x, real h=0.01, unsigned int degree=3)
Approximate the first derivative of a real function using Ridder's method of arbitrary degree.
Definition: deriv.h:138
real deriv_ridders2(RealFunction f, real x, real h=CALCULUS_DERIV_STEP)
Approximate the first derivative of a real function using Ridder's method of second degree.
Definition: deriv.h:121
real deriv_central(RealFunction f, real x, real h=CALCULUS_DERIV_STEP)
Approximate the first derivative of a real function using the central method.
Definition: deriv.h:73
real deriv2(RealFunction f, real x, real h=CALCULUS_DERIV_STEP)
Approximate the second derivative of a real function using the best available algorithm.
Definition: deriv.h:189
real deriv_backward(RealFunction f, real x, real h=CALCULUS_DERIV_STEP)
Approximate the first derivative of a real function using the backward method.
Definition: deriv.h:105
polynomial< Field > deriv(const polynomial< Field > &p)
Compute the exact derivative of a polynomial function.
Definition: deriv.h:21
dual2 square(dual2 x)
Return the square of a second order dual number.
Definition: dual2_functions.h:23
real nan()
Return a quiet NaN number in floating point representation.
Definition: error.h:54