blob: 53bb0dc7db189f4edcdd785c4573c2f365d90fcf [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
Austin Schuh173a1592018-12-19 16:20:54 +11008namespace frc971 {
9namespace control_loops {
10
Philipp Schrader790cb542023-07-05 21:06:52 -070011// Implements Gaussian Quadrature integration (5th order). fn is the function
12// to integrate. It must take 1 argument of type T. The integration is between
13// a and b.
Austin Schuha935a082023-02-20 21:45:54 -080014template <typename T, typename F>
15double GaussianQuadrature5(const F &fn, T a, T b) {
Austin Schuh173a1592018-12-19 16:20:54 +110016 // Pulled from Python.
17 // numpy.set_printoptions(precision=20)
18 // scipy.special.p_roots(5)
Philipp Schrader790cb542023-07-05 21:06:52 -070019 const ::std::array<double, 5> x{
20 {-9.06179845938663630633e-01, -5.38469310105682885670e-01,
21 3.24607628916367383789e-17, 5.38469310105683218737e-01,
22 9.06179845938663408589e-01}};
Austin Schuh173a1592018-12-19 16:20:54 +110023
Philipp Schrader790cb542023-07-05 21:06:52 -070024 const ::std::array<double, 5> w{
25 {0.23692688505618844652, 0.4786286704993669705, 0.56888888888888811124,
26 0.47862867049936674846, 0.23692688505618875183}};
Austin Schuh173a1592018-12-19 16:20:54 +110027
28 double answer = 0.0;
29 for (int i = 0; i < 5; ++i) {
30 const double y = (b - a) * (x[i] + 1) / 2.0 + a;
31 answer += (b - a) / 2.0 * w[i] * fn(y);
32 }
33 return answer;
34}
35
Austin Schuha935a082023-02-20 21:45:54 -080036template <size_t N, typename F>
37Eigen::Matrix<double, N, 1> MatrixGaussianQuadrature5(const F &fn, double a,
38 double b) {
39 // Pulled from Python.
40 // numpy.set_printoptions(precision=20)
41 // scipy.special.p_roots(5)
Philipp Schrader790cb542023-07-05 21:06:52 -070042 const ::std::array<double, 5> x{
43 {-9.06179845938663630633e-01, -5.38469310105682885670e-01,
44 3.24607628916367383789e-17, 5.38469310105683218737e-01,
45 9.06179845938663408589e-01}};
Austin Schuha935a082023-02-20 21:45:54 -080046
Philipp Schrader790cb542023-07-05 21:06:52 -070047 const ::std::array<double, 5> w{
48 {0.23692688505618844652, 0.4786286704993669705, 0.56888888888888811124,
49 0.47862867049936674846, 0.23692688505618875183}};
Austin Schuha935a082023-02-20 21:45:54 -080050
51 Eigen::Matrix<double, N, 1> answer;
52 answer.setZero();
53 for (int i = 0; i < 5; ++i) {
54 const double y = (b - a) * (x[i] + 1) / 2.0 + a;
55 answer += (b - a) / 2.0 * w[i] * fn(y);
56 }
57 return answer;
58}
59
Austin Schuh173a1592018-12-19 16:20:54 +110060} // namespace control_loops
61} // namespace frc971
62
63#endif // FRC971_CONTROL_LOOPS_FIXED_QUADRATURE_H_