finitediff.cpp
1 
2 #include <symengine/add.h>
3 #include <symengine/mul.h>
4 #include <symengine/constants.h>
5 #include <symengine/finitediff.h>
6 
7 namespace SymEngine
8 {
9 
10 vec_basic generate_fdiff_weights_vector(const vec_basic &grid,
11  const unsigned max_deriv,
12  const RCP<const Basic> around)
13 {
14  // Parameters
15  // ----------
16  // grid: grid point locations
17  // max_deriv: highest derivative.
18  // around: location where approximations are to be accurate
19  //
20  // Returns
21  // -------
22  // weights[grid_index, deriv_order]: weights of order 0 to max_deriv (column
23  // major order)
24  //
25  // References
26  // ----------
27  // Generation of Finite Difference Formulas on Arbitrarily Spaced Grids
28  // Bengt Fornberg, Mathematics of compuation, 51, 184, 1988, 699-706
29  //
30  const unsigned len_g = numeric_cast<unsigned>(grid.size());
31  const unsigned len_w = len_g * (max_deriv + 1);
32  RCP<const Basic> c1, c4, c5;
33  c1 = one;
34  c4 = sub(grid[0], around);
35  vec_basic weights(len_w);
36  weights[0] = one;
37  for (unsigned idx = 1; idx < len_w; ++idx)
38  weights[idx] = zero; // clear weights
39  for (unsigned i = 1; i < len_g; ++i) {
40  const int mn = (i < max_deriv) ? i : max_deriv; // min(i, max_deriv)
41  RCP<const Basic> c2 = one;
42  c5 = c4;
43  c4 = sub(grid[i], around);
44  for (unsigned j = 0; j < i; ++j) {
45  const RCP<const Basic> c3 = sub(grid[i], grid[j]);
46  c2 = mul(c2, c3);
47  if (j == i - 1) {
48  for (int k = mn; k >= 1; --k) {
49  weights[i + k * len_g]
50  = div(mul(c1, sub(mul(integer(k),
51  weights[i - 1 + (k - 1) * len_g]),
52  mul(c5, weights[i - 1 + k * len_g]))),
53  c2);
54  }
55  weights[i]
56  = mul(minus_one, div(mul(c1, mul(c5, weights[i - 1])), c2));
57  }
58  for (int k = mn; k >= 1; --k) {
59  weights[j + k * len_g]
60  = div(sub(mul(c4, weights[j + k * len_g]),
61  mul(integer(k), weights[j + (k - 1) * len_g])),
62  c3);
63  }
64  weights[j] = div(mul(c4, weights[j]), c3);
65  }
66  c1 = c2;
67  }
68  return weights;
69 }
70 } // namespace SymEngine
Classes and functions relating to the binary operation of addition.
Main namespace for SymEngine package.
Definition: add.cpp:19
std::enable_if< std::is_integral< T >::value, RCP< const Integer > >::type integer(T i)
Definition: integer.h:197
RCP< const Basic > mul(const RCP< const Basic > &a, const RCP< const Basic > &b)
Multiplication.
Definition: mul.cpp:352
RCP< const Basic > sub(const RCP< const Basic > &a, const RCP< const Basic > &b)
Substracts b from a.
Definition: add.cpp:495
RCP< const Basic > div(const RCP< const Basic > &a, const RCP< const Basic > &b)
Division.
Definition: mul.cpp:431