blob: 88d52e81615fe969f28aa7cfa7b731524ffa917e [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
4#include <array>
5
Philipp Schrader790cb542023-07-05 21:06:52 -07006#include <Eigen/Dense>
7
Stephan Pleinesd99b1ee2024-02-02 20:56:44 -08008namespace frc971::control_loops {
Austin Schuh173a1592018-12-19 16:20:54 +11009
Philipp Schrader790cb542023-07-05 21:06:52 -070010// Implements Gaussian Quadrature integration (5th order). fn is the function
11// to integrate. It must take 1 argument of type T. The integration is between
12// a 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)
Philipp Schrader790cb542023-07-05 21:06:52 -070018 const ::std::array<double, 5> x{
19 {-9.06179845938663630633e-01, -5.38469310105682885670e-01,
20 3.24607628916367383789e-17, 5.38469310105683218737e-01,
21 9.06179845938663408589e-01}};
Austin Schuh173a1592018-12-19 16:20:54 +110022
Philipp Schrader790cb542023-07-05 21:06:52 -070023 const ::std::array<double, 5> w{
24 {0.23692688505618844652, 0.4786286704993669705, 0.56888888888888811124,
25 0.47862867049936674846, 0.23692688505618875183}};
Austin Schuh173a1592018-12-19 16:20:54 +110026
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)
Philipp Schrader790cb542023-07-05 21:06:52 -070041 const ::std::array<double, 5> x{
42 {-9.06179845938663630633e-01, -5.38469310105682885670e-01,
43 3.24607628916367383789e-17, 5.38469310105683218737e-01,
44 9.06179845938663408589e-01}};
Austin Schuha935a082023-02-20 21:45:54 -080045
Philipp Schrader790cb542023-07-05 21:06:52 -070046 const ::std::array<double, 5> w{
47 {0.23692688505618844652, 0.4786286704993669705, 0.56888888888888811124,
48 0.47862867049936674846, 0.23692688505618875183}};
Austin Schuha935a082023-02-20 21:45:54 -080049
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
Stephan Pleinesd99b1ee2024-02-02 20:56:44 -080059} // namespace frc971::control_loops
Austin Schuh173a1592018-12-19 16:20:54 +110060
61#endif // FRC971_CONTROL_LOOPS_FIXED_QUADRATURE_H_