Controlpp
Loading...
Searching...
No Matches
DiscreteTransferFunction.hpp
Go to the documentation of this file.
1#pragma once
2
4
5namespace controlpp
6{
22 template<class T, int NumOrder, int DenOrder>
24 public:
25 using value_type = T;
31
32 private:
34
35 public:
36
37 constexpr DiscreteTransferFunction() = default;
39
41
42
43 template<int NumOrder2, int DenOrder2>
44 requires(((NumOrder2 < NumOrder) || (DenOrder2 < DenOrder)) && (NumOrder2 <= NumOrder) && (DenOrder2 <= DenOrder))
45 DiscreteTransferFunction(const DiscreteTransferFunction<T, NumOrder2, DenOrder2>& other)
46 : tf_(other.transfer_function()){}
47
48 template<int NumOrder2, int DenOrder2>
49 requires(((NumOrder2 < NumOrder) || (DenOrder2 < DenOrder)) && (NumOrder2 <= NumOrder) && (DenOrder2 <= DenOrder))
50 DiscreteTransferFunction& operator=(const DiscreteTransferFunction<T, NumOrder2, DenOrder2>& other){
51 this->tf_ = other.transfer_function();
52 return *this;
53 }
54
58 : tf_(num, den){}
59
62
63 constexpr explicit DiscreteTransferFunction(
64 const num_vector_type& num,
65 const den_vector_type& den
66 )
67 : tf_(num, den){}
68
69 constexpr explicit DiscreteTransferFunction(
70 const value_type(&num)[NumOrder+1],
71 const value_type(&den)[DenOrder+1])
72 : tf_(num, den){}
73
74
75 constexpr T eval(const Eigen::Vector<T, NumOrder+1>& input_series, const Eigen::Vector<T, DenOrder>& output_series){
76 const T B = this->num().vector().dot(input_series);
77 const T A = this->den().vector().tail(DenOrder).dot(output_series);
78 const T y = (B - A) / this->den(0);
79 return y;
80 }
81
91 template<int N>
92 constexpr Eigen::Vector<T, N> eval(const Eigen::Vector<T, N> input_series) const {
93 Eigen::Vector<T, N> output_series;
94 output_series.setZero();
95 for(int i = 0; i < N; ++i){
96 const int num_start = std::max(0, i - NumOrder);
97 const int num_end = i + 1;
98 const int den_start = std::max(0, i - DenOrder);
99 const int den_end = i;
100
101 const T B = this->num().vector().segment(num_start, num_end - num_start).dot(input_series.segment(num_start, num_end - num_start));
102 const T A = this->den().vector().segment(den_start + 1, den_end - den_start).dot(output_series.segment(den_start, den_end - den_start));
103 output_series(i) = (B - A) / this->den(0);
104 }
105 return output_series;
106 }
107
108 constexpr transfer_function_type& transfer_function() {return this->tf_;}
109 constexpr const transfer_function_type& transfer_function() const {return this->tf_;}
110
111 constexpr num_type& num() {return this->tf_.num();}
112 constexpr const num_type& num() const {return this->tf_.num();}
113
114 constexpr T& num(int i) {return this->tf_.num(i);}
115 constexpr const T& num(int i) const {return this->tf_.num(i);}
116
117 constexpr den_type& den() {return this->tf_.den();}
118 constexpr const den_type& den() const {return this->tf_.den();}
119
120 constexpr T& den(int i) {return this->tf_.den(i);}
121 constexpr const T& den(int i) const {return this->tf_.den(i);}
122
123 friend inline std::ostream& operator<<(std::ostream& stream, const DiscreteTransferFunction& dtf){
124 dtf.transfer_function().print(stream, [](int i){
125 if(i == 0){
126 return std::string("");
127 }else {
128 std::string s ("z^(-");
129 s += std::to_string(i);
130 s += ")";
131 return s;
132 }
133 });
134 return stream;
135 }
136 };
137
138 // operator +
139 // -----------
140
141 template<class T, int NumOrder1, int DenOrder1, int NumOrder2, int DenOrder2>
145
146 template<class Tpoly, std::convertible_to<Tpoly> Tscalar, int NumOrder, int DenOrder>
147 constexpr auto operator+(const Tscalar& lhs, const DiscreteTransferFunction<Tpoly, NumOrder, DenOrder>& rhs){
148 return DiscreteTransferFunction(static_cast<Tpoly>(lhs) + rhs.transfer_function());
149 }
150
151 template<class Tpoly, std::convertible_to<Tpoly> Tscalar, int NumOrder, int DenOrder>
152 constexpr auto operator+(const DiscreteTransferFunction<Tpoly, NumOrder, DenOrder>& lhs, const Tscalar& rhs){
153 return DiscreteTransferFunction(lhs.transfer_function() + static_cast<Tpoly>(rhs));
154 }
155
156 // operator -
157 // -----------
158
159 template<class T, int NumOrder1, int DenOrder1, int NumOrder2, int DenOrder2>
163
164 template<class T, std::convertible_to<T> Tscalar, int NumOrder, int DenOrder>
165 constexpr auto operator-(const Tscalar& lhs, const DiscreteTransferFunction<T, NumOrder, DenOrder>& rhs){
166 return DiscreteTransferFunction(static_cast<T>(lhs) - rhs.transfer_function());
167 }
168
169 template<class T, std::convertible_to<T> Tscalar, int NumOrder, int DenOrder>
170 constexpr auto operator-(const DiscreteTransferFunction<T, NumOrder, DenOrder>& lhs, const Tscalar& rhs){
171 return DiscreteTransferFunction(lhs.transfer_function() - static_cast<T>(rhs));
172 }
173
174 // operator *
175 // -----------
176
177 template<class T, int NumOrder1, int DenOrder1, int NumOrder2, int DenOrder2>
181
182 template<class T, std::convertible_to<T> Tscalar, int NumOrder, int DenOrder>
183 constexpr auto operator*(const Tscalar& lhs, const DiscreteTransferFunction<T, NumOrder, DenOrder>& rhs){
184 return DiscreteTransferFunction(static_cast<T>(lhs) * rhs.transfer_function());
185 }
186
187 template<class T, std::convertible_to<T> Tscalar, int NumOrder, int DenOrder>
188 constexpr auto operator*(const DiscreteTransferFunction<T, NumOrder, DenOrder>& lhs, const Tscalar& rhs){
189 return DiscreteTransferFunction(lhs.transfer_function() * static_cast<T>(rhs));
190 }
191
192 // operator /
193 // -----------
194
195 template<class T, int NumOrder1, int DenOrder1, int NumOrder2, int DenOrder2>
199
200 template<class T, std::convertible_to<T> Tscalar, int NumOrder, int DenOrder>
201 constexpr auto operator/(const Tscalar& lhs, const DiscreteTransferFunction<T, NumOrder, DenOrder>& rhs){
202 return DiscreteTransferFunction(static_cast<T>(lhs) / rhs.transfer_function());
203 }
204
205 template<class T, std::convertible_to<T> Tscalar, int NumOrder, int DenOrder>
206 constexpr auto operator/(const DiscreteTransferFunction<T, NumOrder, DenOrder>& lhs, const Tscalar& rhs){
207 return DiscreteTransferFunction(lhs.transfer_function() / static_cast<T>(rhs));
208 }
209
210 namespace tf{
211
217 template<class T=double>
218 static inline const DiscreteTransferFunction<T, 1, 0> z_1({T(0), T(1)}, {T(1)});
219 }
220
221} // namespace controlpp
222
223
224
Continuous transfer functions in the s lapace plain.
Definition DiscreteTransferFunction.hpp:23
constexpr const T & den(int i) const
Definition DiscreteTransferFunction.hpp:121
T value_type
Definition DiscreteTransferFunction.hpp:25
constexpr Eigen::Vector< T, N > eval(const Eigen::Vector< T, N > input_series) const
Evaluates the transfer function for a given input series.
Definition DiscreteTransferFunction.hpp:92
constexpr DiscreteTransferFunction(const value_type(&num)[NumOrder+1], const value_type(&den)[DenOrder+1])
Definition DiscreteTransferFunction.hpp:69
constexpr den_type & den()
Definition DiscreteTransferFunction.hpp:117
constexpr const T & num(int i) const
Definition DiscreteTransferFunction.hpp:115
constexpr num_type & num()
Definition DiscreteTransferFunction.hpp:111
constexpr DiscreteTransferFunction(const TransferFunction< T, NumOrder, DenOrder > &transfer_function)
Definition DiscreteTransferFunction.hpp:60
constexpr DiscreteTransferFunction()=default
constexpr DiscreteTransferFunction & operator=(const DiscreteTransferFunction &)=default
constexpr T & den(int i)
Definition DiscreteTransferFunction.hpp:120
constexpr DiscreteTransferFunction(const DiscreteTransferFunction &)=default
typename transfer_function_type::num_type num_type
Definition DiscreteTransferFunction.hpp:27
constexpr T eval(const Eigen::Vector< T, NumOrder+1 > &input_series, const Eigen::Vector< T, DenOrder > &output_series)
Definition DiscreteTransferFunction.hpp:75
constexpr const num_type & num() const
Definition DiscreteTransferFunction.hpp:112
constexpr const transfer_function_type & transfer_function() const
Definition DiscreteTransferFunction.hpp:109
constexpr DiscreteTransferFunction(const num_vector_type &num, const den_vector_type &den)
Definition DiscreteTransferFunction.hpp:63
constexpr T & num(int i)
Definition DiscreteTransferFunction.hpp:114
constexpr const den_type & den() const
Definition DiscreteTransferFunction.hpp:118
friend std::ostream & operator<<(std::ostream &stream, const DiscreteTransferFunction &dtf)
Definition DiscreteTransferFunction.hpp:123
typename transfer_function_type::num_vector_type num_vector_type
Definition DiscreteTransferFunction.hpp:29
constexpr DiscreteTransferFunction(const Polynom< T, NumOrder > &num, const Polynom< T, DenOrder > &den)
Definition DiscreteTransferFunction.hpp:55
typename transfer_function_type::den_vector_type den_vector_type
Definition DiscreteTransferFunction.hpp:30
typename transfer_function_type::den_type den_type
Definition DiscreteTransferFunction.hpp:28
constexpr transfer_function_type & transfer_function()
Definition DiscreteTransferFunction.hpp:108
Describes a mathematical polynomial.
Definition Polynom.hpp:39
Definition TransferFunction.hpp:11
Polynom< T, NumOrder > num_type
Definition TransferFunction.hpp:14
typename num_type::vector_type num_vector_type
Definition TransferFunction.hpp:16
typename den_type::vector_type den_vector_type
Definition TransferFunction.hpp:17
constexpr Polynom< T, DenOrder > & den()
returns a reference to the denominator
Definition TransferFunction.hpp:83
void print(std::ostream &stream, std::string_view var="x") const
Definition TransferFunction.hpp:204
Polynom< T, DenOrder > den_type
Definition TransferFunction.hpp:15
constexpr Polynom< T, NumOrder > & num()
returns a reference to the numerator
Definition TransferFunction.hpp:57
Bode< T > operator+(const Bode< T > &l, const Bode< T > &r)
Adds two bode plots together.
Definition Bode.hpp:846
The main namespace for the Control++ library.
Definition Bode.cpp:3
Bode< T > operator-(const Bode< T > &l, const Bode< T > &r)
Definition Bode.hpp:936
Bode< T > operator*(const Bode< T > &l, const Bode< T > &r)
Definition Bode.hpp:979
Bode< T > operator/(const Bode< T > &l, const Bode< T > &r)
TODO: make it also work for bode that have different frequency vectors.
Definition Bode.hpp:1026