blob: 22d49849be21db08a88cd441042897286cbbf70f [file] [log] [blame]
Austin Schuh173a1592018-12-19 16:20:54 +11001#ifndef FRC971_CONTROL_LOOPS_FIXED_QUADRATURE_H_
2#define FRC971_CONTROL_LOOPS_FIXED_QUADRATURE_H_
3
Austin Schuha935a082023-02-20 21:45:54 -08004#include <Eigen/Dense>
Austin Schuh173a1592018-12-19 16:20:54 +11005#include <array>
6
7namespace frc971 {
8namespace control_loops {
9
10// Implements Gaussian Quadrature integration (5th order). fn is the function to
11// integrate. It must take 1 argument of type T. The integration is between a
12// and b.
Austin Schuha935a082023-02-20 21:45:54 -080013template <typename T, typename F>
14double GaussianQuadrature5(const F &fn, T a, T b) {
Austin Schuh173a1592018-12-19 16:20:54 +110015 // Pulled from Python.
16 // numpy.set_printoptions(precision=20)
17 // scipy.special.p_roots(5)
18 const ::std::array<double, 5> x{{
19 -9.06179845938663630633e-01, -5.38469310105682885670e-01,
20 3.24607628916367383789e-17, 5.38469310105683218737e-01,
21 9.06179845938663408589e-01}};
22
23 const ::std::array<double, 5> w{{
24 0.23692688505618844652, 0.4786286704993669705, 0.56888888888888811124,
25 0.47862867049936674846, 0.23692688505618875183}};
26
27 double answer = 0.0;
28 for (int i = 0; i < 5; ++i) {
29 const double y = (b - a) * (x[i] + 1) / 2.0 + a;
30 answer += (b - a) / 2.0 * w[i] * fn(y);
31 }
32 return answer;
33}
34
Austin Schuha935a082023-02-20 21:45:54 -080035template <size_t N, typename F>
36Eigen::Matrix<double, N, 1> MatrixGaussianQuadrature5(const F &fn, double a,
37 double b) {
38 // Pulled from Python.
39 // numpy.set_printoptions(precision=20)
40 // scipy.special.p_roots(5)
41 const ::std::array<double, 5> x{{
42 -9.06179845938663630633e-01, -5.38469310105682885670e-01,
43 3.24607628916367383789e-17, 5.38469310105683218737e-01,
44 9.06179845938663408589e-01}};
45
46 const ::std::array<double, 5> w{{
47 0.23692688505618844652, 0.4786286704993669705, 0.56888888888888811124,
48 0.47862867049936674846, 0.23692688505618875183}};
49
50 Eigen::Matrix<double, N, 1> answer;
51 answer.setZero();
52 for (int i = 0; i < 5; ++i) {
53 const double y = (b - a) * (x[i] + 1) / 2.0 + a;
54 answer += (b - a) / 2.0 * w[i] * fn(y);
55 }
56 return answer;
57}
58
Austin Schuh173a1592018-12-19 16:20:54 +110059} // namespace control_loops
60} // namespace frc971
61
62#endif // FRC971_CONTROL_LOOPS_FIXED_QUADRATURE_H_