forked from sammy-tri/drake
-
Notifications
You must be signed in to change notification settings - Fork 0
/
symbolic_chebyshev_polynomial.h
134 lines (116 loc) · 4.36 KB
/
symbolic_chebyshev_polynomial.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#pragma once
#ifndef DRAKE_COMMON_SYMBOLIC_HEADER
#error Do not directly include this file. Include "drake/common/symbolic.h".
#endif
#include <ostream>
#include <utility>
#include <vector>
#include <Eigen/Core>
#include "drake/common/drake_copyable.h"
#include "drake/common/hash.h"
#include "drake/common/symbolic.h"
namespace drake {
namespace symbolic {
/**
* Represents the Chebyshev polynomial of the first kind Tₙ(x).
* One definition of Chebyshev polynomial of the first kind is
* Tₙ(cos(θ)) = cos(nθ)
* It can also be defined recursively as
*
* T₀(x) = 1
* T₁(x) = x
* Tₙ₊₁(x) = 2xTₙ(x) − Tₙ₋₁(x)
*/
class ChebyshevPolynomial {
public:
DRAKE_DEFAULT_COPY_AND_MOVE_AND_ASSIGN(ChebyshevPolynomial)
/**
* Constructs a Chebyshev polynomial Tₙ(x)
* @param var The variable x
* @param degree The Chebyshev polynomial is of degree n.
* @pre degree >= 0.
*/
ChebyshevPolynomial(Variable var, int degree);
/** Getter for the variable. */
[[nodiscard]] const Variable& var() const { return var_; }
/** Getter for the degree of the Chebyshev polynomial. */
[[nodiscard]] int degree() const { return degree_; }
/**
* Converts this Chebyshev polynomial to a polynomial with monomial basis.
*/
[[nodiscard]] Polynomial ToPolynomial() const;
/**
* Evaluates this Chebyshev polynomial at @p var_val.
*/
[[nodiscard]] double Evaluate(double var_val) const;
/**
* Checks if this and @p other represent the same Chebyshev polynomial. Two
* Chebyshev polynomials are equal iff their variable and degree are the same,
* or they both have degree 0.
* @note T₀(x) = T₀(y) = 1
*/
bool operator==(const ChebyshevPolynomial& other) const;
/** Checks if this and @p other do not represent the same Chebyshev
* polynomial. */
bool operator!=(const ChebyshevPolynomial& other) const;
/**
* Compare this to another Chebyshev polynomial, returns True if this is
* regarded as less than the other, otherwise returns false.
*
* If this.var() < other.var(), return True.
* If this.var() > other.var(), return False.
* If this.var() == other.var(), then return this.degree() <
* other.degree().
*
* A special case is when this.degree() == 0 or other.degree()
* == 0. In this case the variable doesn't matter, and we return this.degree()
* < other.degree().
*/
bool operator<(const ChebyshevPolynomial& other) const;
/**
* Computes the differentiation of a Chebyshev polynomial
* dTₙ(x)/dx = nUₙ₋₁(x)
* where Uₙ₋₁(x) is a Chebyshev polynomial of the second kind. Uₙ₋₁(x) can
* be written as a summation of Chebyshev polynomials of the first kind
* with lower degrees.
* - If n is even dTₙ(x)/dx = 2n ∑ⱼ Tⱼ(x), j is odd and j <= n-1
* - If n is odd dTₙ(x)/dx = 2n ∑ⱼ Tⱼ(x) - n, j is even and j <= n-1
* - A special case is that dT₀(x)/dx = 0.
* @retval chebyshev_coeff_pairs. sum(chebyshev_coeff_pairs[j].first *
* chebyshev_coeff_pairs[j].second) is the differentiation dTₙ(x)/dx. If n is
* even, then chebyshev_coeff_pairs[j] = (T₂ⱼ₋₁(x), 2n). If n is odd, then
* chebyshev_coeff_pairs[j] = (T₂ⱼ(x), 2n) for j >= 1, and
* chebyshev_coeff_pairs[0] = (T₀(x), n).
* For the special case when degree() == 0, we return an empty vector.
*/
[[nodiscard]] std::vector<std::pair<ChebyshevPolynomial, double>>
Differentiate() const;
/** Implements the @ref hash_append concept. */
template <class HashAlgorithm>
friend void hash_append(HashAlgorithm& hasher,
const ChebyshevPolynomial& item) noexcept {
if (item.degree() == 0) {
hash_append(hasher, item.degree());
} else {
hash_append(hasher, std::make_pair(item.var().get_id(), item.degree()));
}
}
private:
Variable var_{};
int degree_{};
};
std::ostream& operator<<(std::ostream& out, const ChebyshevPolynomial& p);
/**
* Evaluates a Chebyshev polynomial at a given value.
* @param var_val The value of the variable.
* @param degree The degree of the Chebyshev polynomial.
*/
double EvaluateChebyshevPolynomial(double var_val, int degree);
} // namespace symbolic
} // namespace drake
namespace std {
/* Provides std::hash<drake::symbolic::ChebyshevPolynomial>. */
template <>
struct hash<drake::symbolic::ChebyshevPolynomial> : public drake::DefaultHash {
};
} // namespace std