1+ # utils.py - VRFT utility functions
2+ #
3+ # Code author: [Alessio Russo - alessior@kth.se]
4+ # Last update: 07th January 2020, by alessior@kth.se
5+ #
16# Copyright [2017-2020] [Alessio Russo - alessior@kth.se]
27# This file is part of PythonVRFT.
38# PythonVRFT is free software: you can redistribute it and/or modify
1015# You should have received a copy of the GNU General Public License
1116# along with PythonVRFT. If not, see <http://www.gnu.org/licenses/>.
1217#
13- # Code author: [Alessio Russo - alessior@kth.se]
14- # Last update: 06th January 2020, by alessior@kth.se
15- #
18+
1619
1720import numpy as np
1821import scipy .signal as scipysig
1922from vrft .iddata import iddata
23+ from typing import overload
2024
2125def Doperator (p : int , q : int , x : float ) -> np .ndarray :
2226 D = np .zeros ((p * q , q ))
2327 for i in range (q ):
2428 D [i * p :(i + 1 ) * p , i ] = x
2529 return D
2630
31+ @overload
32+ def checkSystem (tf : scipysig .dlti ) -> bool :
33+ """Returns true if a transfer function is causal
34+ Parameters
35+ ----------
36+ tf : scipy.signal.dlti
37+ discrete time rational transfer function
38+ """
39+
40+ return checkSystem (tf .num , tf .den )
41+
2742def checkSystem (num : np .ndarray , den : np .ndarray ) -> bool :
43+ """Returns true if a transfer function is causal
44+ Parameters
45+ ----------
46+ num : np.ndarray
47+ numerator of the transfer function
48+ den : np.ndarray
49+ denominator of the transfer function
50+
51+ """
2852 try :
2953 M , N = systemOrder (num , den )
3054 except ValueError :
@@ -35,7 +59,37 @@ def checkSystem(num: np.ndarray, den: np.ndarray) -> bool:
3559
3660 return True
3761
62+ @overload
63+ def systemOrder (tf : scipysig .dlti ) -> tuple :
64+ """Returns the order of the numerator and denominator
65+ of a transfer function
66+ Parameters
67+ ----------
68+ tf : scipy.signal.dlti
69+ discrete time rational transfer function
70+
71+ Returns
72+ ----------
73+ (num, den): tuple
74+ Tuple containing the orders
75+ """
76+ return systemOrder (tf .num , tf .den )
77+
3878def systemOrder (num : np .ndarray , den : np .ndarray ) -> tuple :
79+ """Returns the order of the numerator and denominator
80+ of a transfer function
81+ Parameters
82+ ----------
83+ num : np.ndarray
84+ numerator of the transfer function
85+ den : np.ndarray
86+ denominator of the transfer function
87+
88+ Returns
89+ ----------
90+ (num, den): tuple
91+ Tuple containing the orders
92+ """
3993 den = den if isinstance (den , np .ndarray ) else np .array ([den ]).flatten ()
4094 num = num if isinstance (num , np .ndarray ) else np .array ([num ]).flatten ()
4195
@@ -45,32 +99,23 @@ def systemOrder(num: np.ndarray, den: np.ndarray) -> tuple:
4599 if den .ndim == 0 :
46100 den = np .expand_dims (den , axis = 0 )
47101
48- N = den .size
49- M = num .size
50-
51- denOrder = - 1
52- numOrder = - 1
53-
54- for i , d in enumerate (den ):
55- if not np .isclose (d , 0 ):
56- denOrder = N - i - 1
57- break
58-
59- for i , n in enumerate (num ):
60- if not np .isclose (n , 0 ):
61- numOrder = M - i - 1
62- break
63-
64- if (denOrder == - 1 ):
65- raise ValueError ("Denominator can not be zero." )
66-
67- if (numOrder == - 1 ):
68- raise ValueError ("Numerator can not be zero." )
69-
70- return (numOrder , denOrder )
102+ return (np .poly1d (num ).order , np .poly1d (den ).order )
71103
72104
73105def filter_iddata (data : iddata , L : scipysig .dlti ) -> iddata :
106+ """Filter data in an iddata object
107+ Parameters
108+ ----------
109+ data : iddata
110+ iddata object containing the data to filter
111+ L : scipy.signal.dlti
112+ Transfer function used to filter the data
113+
114+ Returns
115+ -------
116+ data : iddata
117+ Filtered iddata object
118+ """
74119 t_start = 0
75120 t_step = data .ts
76121 t_end = len (data .y ) * t_step
@@ -84,9 +129,25 @@ def filter_iddata(data: iddata, L: scipysig.dlti) -> iddata:
84129 return data
85130
86131def deconvolve_signal (T : scipysig .dlti , x : np .ndarray , dt : float ) -> np .ndarray :
132+ """Deconvolve a signal x using a specified transfer function T
133+ Parameters
134+ ----------
135+ T : scipy.signal.dlti
136+ Discrete-time rational transfer function used to
137+ deconvolve the signal
138+ x : np.ndarray
139+ Signal to deconvolve
140+ dt: float
141+ Sampling time
142+
143+ Returns
144+ -------
145+ signal : np.ndarray
146+ Deconvolved signal
147+ """
87148 impulse = scipysig .dimpulse (T )[1 ][0 ].flatten ()
88149 idx1 = np .argwhere (impulse != 0 )[0 ].item ()
89150 idx2 = np .argwhere (np .isclose (impulse [idx1 :], 0. ) == True )
90151 idx2 = - 1 if idx2 .size == 0 else idx2 [0 ].item ()
91- recovered , _ = scipysig .deconvolve (x , impulse [idx1 :idx2 ])
92- return recovered [np .argwhere (impulse != 0 )[0 ].item ():]
152+ signal , _ = scipysig .deconvolve (x , impulse [idx1 :idx2 ])
153+ return signal [np .argwhere (impulse != 0 )[0 ].item ():]
0 commit comments