@@ -25,7 +25,7 @@ def fit_spectral_factor_mimo_ct(
2525 tol_bisection : float = 1e-5 ,
2626 max_iter_bisection : int = 100 ,
2727 max_iter_bisection_init : int = 15 ,
28- omega_power_constraint : Optional [ np . ndarray ] = None ,
28+ nbr_power_constraint : int = 500 ,
2929) -> control .StateSpace :
3030 """Fit a stable and minimum-phase biproper MIMO spectral factor to power spectrum.
3131
@@ -52,8 +52,8 @@ def fit_spectral_factor_mimo_ct(
5252 Maximum number of iterations for the bisection algorithm.
5353 max_iter_bisection_init : int
5454 Maximum number of iterations for the bisection algorithm initialization.
55- omega_power_constraint : Optional[np.ndarray]
56- Angular frequencies to enforce non-negativity of power spectrum.
55+ nbr_power_constraint : Optional[np.ndarray]
56+ Number of frequencies to enforce non-negativity of power spectrum.
5757
5858 Returns
5959 -------
@@ -81,11 +81,6 @@ def fit_spectral_factor_mimo_ct(
8181 # Pre-warp frequency (continuous- to discrete-time) with bilinear transformation
8282 alpha = np .sqrt (omega [0 ] * omega [- 1 ])
8383 theta = 2 * np .atan (omega / alpha )
84- theta_power_constraint = (
85- 2 * np .atan (omega_power_constraint / alpha )
86- if omega_power_constraint is not None
87- else None
88- )
8984
9085 # Parse frequency-dependent weight
9186 if weight is None :
@@ -103,7 +98,7 @@ def fit_spectral_factor_mimo_ct(
10398 tol_bisection ,
10499 max_iter_bisection ,
105100 max_iter_bisection_init ,
106- theta_power_constraint ,
101+ nbr_power_constraint ,
107102 )
108103
109104 # Discrete-time spectral factor fit model
@@ -133,7 +128,7 @@ def fit_power_mimo_dt(
133128 tol_bisection : float = 1e-5 ,
134129 max_iter_bisection : int = 100 ,
135130 max_iter_bisection_init : int = 15 ,
136- theta_power_constraint : Optional [ np . ndarray ] = None ,
131+ nbr_power_constraint : int = 500 ,
137132) -> Tuple [np .ndarray , np .ndarray ]:
138133 """Fit a biproper discrete-time MIMO power spectrum transfer function.
139134
@@ -160,9 +155,8 @@ def fit_power_mimo_dt(
160155 Maximum number of iterations for the bisection algorithm.
161156 max_iter_bisection_init : int
162157 Maximum number of iterations for the bisection algorithm initialization.
163- theta_power_constraint : Optional[np.ndarray]
164- Discrete-time frequencies to enforce non-negativity of power spectrum. The
165- frequencies range from [0, pi].
158+ nbr_power_constraint : Optional[np.ndarray]
159+ Number of frequencies to enforce non-negativity of power spectrum.
166160
167161 Returns
168162 -------
@@ -177,9 +171,6 @@ def fit_power_mimo_dt(
177171 # Parse arguments
178172 solver_params = _parse_solver_param (solver_params )
179173 weight = np .ones_like (theta ) if weight is None else weight
180- theta_power_constraint = (
181- theta if theta_power_constraint is None else theta_power_constraint
182- )
183174
184175 # Auxiliary parameters
185176 nbr_signals = power_fit .shape [1 ]
@@ -210,7 +201,7 @@ def fit_power_mimo_dt(
210201 theta ,
211202 order ,
212203 weight ,
213- theta_power_constraint ,
204+ nbr_power_constraint ,
214205 )
215206
216207 # Optimization objective
@@ -253,7 +244,7 @@ def _generate_constraints_power_mimo_dt(
253244 theta : np .ndarray ,
254245 order : int ,
255246 weight : np .ndarray ,
256- theta_power_constraint : np . ndarray ,
247+ nbr_power_constraint : int ,
257248) -> List [cvxpy .Constraint ]:
258249 """Generate the constraints for the fit of discrete-time MIMO power spectrums.
259250
@@ -281,9 +272,8 @@ def _generate_constraints_power_mimo_dt(
281272 Order of the power spectrum numerator and denominator polynomials.
282273 weight : np.ndarray,
283274 Frequency-dependent weight for fit accuracy.
284- theta_power_constraint : Optional[np.ndarray]
285- Discrete-time frequencies to enforce positive semidefiniteness of power
286- spectrum. The frequencies range from [0, pi].
275+ nbr_power_constraint : Optional[np.ndarray]
276+ Number of frequencies to enforce positive semidefiniteness of power spectrum.
287277
288278 Returns
289279 -------
@@ -306,7 +296,7 @@ def _generate_constraints_power_mimo_dt(
306296
307297 # Power spectrum positive definiteness constraints
308298 constraint_power_psd = _construct_power_psd_constraints_mimo_dt (
309- num_coef_sym_list , num_coef_skew_list , den_coef , theta_power_constraint , order
299+ num_coef_sym_list , num_coef_skew_list , den_coef , order , nbr_power_constraint
310300 )
311301
312302 # Numerator variable structure constraints
@@ -472,8 +462,8 @@ def _construct_power_psd_constraints_mimo_dt(
472462 num_coef_sym_list : List [cvxpy .Variable ],
473463 num_coef_skew_list : List [cvxpy .Variable ],
474464 den_coef : cvxpy .Variable ,
475- theta : np .ndarray ,
476465 order : int ,
466+ nbr_theta : int ,
477467) -> List [cvxpy .Constraint ]:
478468 """Construct the power spectrum positive semidefiniteness constraints.
479469
@@ -503,6 +493,9 @@ def _construct_power_psd_constraints_mimo_dt(
503493 # Parameters
504494 nbr_signals = num_coef_sym_list [0 ].shape [0 ]
505495
496+ # Frequency points
497+ theta = np .linspace (0 , np .pi , nbr_theta )
498+
506499 # Augmented variables
507500 num_coef_sym_stack = cvxpy .vstack (num_coef_sym_list )
508501 num_coef_skew_stack = cvxpy .vstack (num_coef_skew_list )
@@ -704,7 +697,7 @@ def fit_magnitude_siso_ct(
704697 tol_bisection : float = 1e-3 ,
705698 max_iter_bisection : int = 500 ,
706699 max_iter_bisection_init : int = 15 ,
707- omega_power_constraint : Optional [ np . ndarray ] = None ,
700+ nbr_power_constraint : int = 500 ,
708701) -> control .StateSpace :
709702 """Fit a stable and minimum-phase biproper SISO system to magnitude.
710703
@@ -734,8 +727,8 @@ def fit_magnitude_siso_ct(
734727 Maximum allowable number of iterations in the bisection algorithm.
735728 max_iter_bisection_init : int
736729 Maximum number of iterations for the bisection algorithm initialization.
737- omega_power_constraint : Optional[np.ndarray]
738- Angular frequencies to enforce non-negativity of power spectrum.
730+ nbr_power_constraint : Optional[np.ndarray]
731+ Number of frequencies to enforce non-negativity of power spectrum.
739732
740733 Returns
741734 -------
@@ -774,11 +767,6 @@ def fit_magnitude_siso_ct(
774767 # Pre-warp frequency (continuous- to discrete-time) with bilinear transformation
775768 alpha = np .sqrt (omega [0 ] * omega [- 1 ])
776769 theta = 2 * np .atan (omega / alpha )
777- theta_power_constraint = (
778- 2 * np .atan (omega_power_constraint / alpha )
779- if omega_power_constraint is not None
780- else None
781- )
782770
783771 # Parse frequency-dependent weight
784772 if weight is None :
@@ -796,7 +784,7 @@ def fit_magnitude_siso_ct(
796784 tol_bisection ,
797785 max_iter_bisection ,
798786 max_iter_bisection_init ,
799- theta_power_constraint ,
787+ nbr_power_constraint ,
800788 )
801789
802790 # Discrete-time spectral factor model
@@ -822,7 +810,7 @@ def fit_power_siso_dt(
822810 tol_bisection : float = 1e-5 ,
823811 max_iter_bisection : int = 100 ,
824812 max_iter_bisection_init : int = 15 ,
825- theta_power_constraint : Optional [ np . ndarray ] = None ,
813+ nbr_power_constraint : int = 500 ,
826814) -> Tuple [np .ndarray , np .ndarray ]:
827815 """Fit a biproper discrete-time SISO power spectrum transfer function.
828816
@@ -849,9 +837,8 @@ def fit_power_siso_dt(
849837 Maximum number of iterations for the bisection algorithm.
850838 max_iter_bisection_init : int
851839 Maximum number of iterations for the bisection algorithm initialization.
852- theta_power_constraint : Optional[np.ndarray]
853- Discrete-time frequencies to enforce non-negativity of power spectrum. The
854- frequencies range from [0, pi].
840+ nbr_power_constraint : Optional[np.ndarray]
841+ Number of frequencies to enforce non-negativity of power spectrum.
855842
856843 Returns
857844 -------
@@ -882,9 +869,6 @@ def fit_power_siso_dt(
882869 # Parse arguments
883870 solver_params = _parse_solver_param (solver_params )
884871 weight = np .ones_like (theta ) if weight is None else weight
885- theta_power_constraint = (
886- theta if theta_power_constraint is None else theta_power_constraint
887- )
888872
889873 # Optimization variables and parameters
890874 num_coef = cvxpy .Variable (shape = order + 1 , name = "num_coef" )
@@ -902,7 +886,7 @@ def fit_power_siso_dt(
902886 theta ,
903887 order ,
904888 weight ,
905- theta_power_constraint ,
889+ nbr_power_constraint ,
906890 )
907891
908892 # Optimization problem
@@ -945,7 +929,7 @@ def _generate_constraints_power_siso_dt(
945929 theta : np .ndarray ,
946930 order : int ,
947931 weight : np .ndarray ,
948- theta_power_constraints : np . ndarray ,
932+ nbr_power_constraints : int ,
949933) -> List [cvxpy .Constraint ]:
950934 """Generate the constraints for the discrete-time SISO power spectrums.
951935
@@ -969,9 +953,8 @@ def _generate_constraints_power_siso_dt(
969953 Order of the power spectrum model.
970954 weight : np.ndarray
971955 Frequency-dependent weight for fit accuracy.
972- theta_power_constraint : Optional[np.ndarray]
973- Discrete-time frequencies to enforce non-negativity of power spectrum. The
974- frequencies range from [0, pi].
956+ nbr_power_constraint : int
957+ Discrete-time frequencies to enforce non-negativity of power spectrum.
975958
976959 Returns
977960 -------
@@ -996,7 +979,7 @@ def _generate_constraints_power_siso_dt(
996979 num_coef ,
997980 den_coef ,
998981 order ,
999- theta_power_constraints ,
982+ nbr_power_constraints ,
1000983 )
1001984
1002985 # Normalization of the transfer function coefficients
@@ -1135,7 +1118,10 @@ def _construct_bound_constraints_siso_dt(
11351118
11361119
11371120def _construct_spectral_factorization_constraint_siso_dt (
1138- num_coef : cvxpy .Variable , den_coef : cvxpy .Variable , order : int , theta : np .ndarray
1121+ num_coef : cvxpy .Variable ,
1122+ den_coef : cvxpy .Variable ,
1123+ order : int ,
1124+ nbr_theta : np .ndarray ,
11391125) -> List [cvxpy .Constraint ]:
11401126 """Construct power spectrum spectral factorization constraints.
11411127
@@ -1150,6 +1136,8 @@ def _construct_spectral_factorization_constraint_siso_dt(
11501136 Power spectrum denominator coefficient variable.
11511137 order : int
11521138 Order of the power spectrum model.
1139+ nbr_theta : int
1140+ Number of frequencies to enforce constraint.
11531141
11541142 Returns
11551143 -------
@@ -1158,6 +1146,9 @@ def _construct_spectral_factorization_constraint_siso_dt(
11581146 constraints.
11591147 """
11601148
1149+ # Frequencies to enforce power spectrum non-negativity
1150+ theta = np .linspace (0 , np .pi , nbr_theta )
1151+
11611152 constraint_spectral_factorization_list = []
11621153 for theta_idx in theta :
11631154 # Constraint data matrices
0 commit comments