def iterAllRealizations(self): """ Iterate over all the possible structures, to build (and return through a generator) all the possible realization of a given Filter filter (lti) Parameters ---------- - filter: the filter (Filter object) we want to implement - exceptStructures: (list) list of structure name we don't want to use Returns ------- a generator of >>> from fixif.LTI import Filter >>> f = Filter( num=[1, 2, 3, 4], den=[5.0,6.0,7.0, 8.0]) >>> for R in f.iterAllRealizations(): >>> print(R) print the realizations (filter f implemeted in all the existing structures wih all the possible options) (ie Direct Form I (with nbSum=1 and also nbSum=2), State-Space (balanced, canonical observable form, canonical controlable, etc.), etc.) """ from fixif.Structures.Structure import Structure for st in Structure.iterAllStructures(): if st.options: # list of all the possible values for dictionnary # see http://stackoverflow.com/questions/5228158/cartesian-product-of-a-dictionary-of-lists vl = (dict(zip(st.options, x)) for x in product(*st.options.values())) for options in vl: if st.canAcceptFilter(self, **options): yield st.makeRealization(self, **options) else: if st.canAcceptFilter(self): yield st.makeRealization(self)
# path to the LWDF matlab toolbox from TU Delf (http://www.latech.nl/mtbx) MH.addpath('fixif/Structures/LWDF/matlab/wdf_tbx') # call the TF2LWDF2SIF matlab function from matlab import double as m_double R = MH.TF2LWDF2SIF(m_double(filt.dTF.num.tolist()), m_double(filt.dTF.den.tolist())) # TODO: catch the errors ?? # build SIF return { "JtoS": (mat(R['J']), mat(R['K']), mat(R['L']), mat(R['M']), mat(R['N']), mat(R['P']), mat(R['Q']), mat(R['R']), mat(R['S'])) } def acceptLWDF(filt): """ a LWDF realization can be build only if the filter is SISO and has ODD order """ return (filt.order % 2 == 1) and filt.isSISO() # the LWDF structure is created only if Matlab (and the engine) are installed if isMatlabInstalled(): LWDF = Structure(shortName='LWDF', fullName="Lattice Wave Digital Filter", make=makeLWDF, accept=acceptLWDF)
The forms 'ctrl' and 'obs' cannot be applied to MIMO filters 'balanced' form is for stable filter otherwise, it can always be used """ if form == 'balanced': return filt.isStable() if form == 'ctrl' or form == 'obs': return filt.isSISO() # otherwise return True # do not propose "balanced" form when slycot is not installed try: import slycot except ImportError: State_Space = Structure(shortName="dSS", fullName="State-Space", options={'form': (None, 'ctrl', 'obs')}, make=makeSS, accept=acceptSS) else: #State_Space = Structure(shortName="dSS", fullName="State-Space", options={'form': (None, 'ctrl', 'obs')}, make=makeSS, accept=acceptSS) State_Space = Structure( shortName="dSS", fullName="State-Space", options={'form': (None, 'balanced', 'ctrl', 'obs')}, make=makeSS, accept=acceptSS) # TODO: add the balanced form, when the balanced computation will be reliable...
if transposed: var_T = None var_X = None else: var_T = [('v', None, -1)] # t(k+1) := v(k) var_X = [('v', None, -i) for i in range(n, 0, -1)] # x_i(k) := v(k-i) # return useful infos to build the Realization return { "JtoS": (J, K, L, M, N, P, Q, R, S), "surnameVarT": var_T, "surnameVarX": var_X } def acceptDFII(filt, **_): # other parameters are ignored """ return True only if the filter is SISO """ return filt.isSISO() # build the Direct Form II # as an instance of the class structure DFII = Structure(shortName='DFII', fullName="Direct Form II", options={"transposed": (False, True)}, make=makeDFII, accept=acceptDFII)
# On construit les matrices qui forment Z JtoS = Matrice_JtoS_LCW(Ad, As, Bs, Cs, d) # TODO: use transposed ??? # return useful infos to build the Realization return {"JtoS": JtoS} def acceptLGSLCW(filt, **options): """ return True only if the filter is SISO and stable """ return filt.isSISO() and filt.isStable() # build the Direct Form I # as an instance of the class structure LGS = Structure(shortName='LGS', fullName="Li-Gevers-Sun", options={"transposed": (False, True)}, make=makeLGS, accept=acceptLGSLCW) LCW = Structure(shortName='LCW', fullName="Li-Chu-Wu", options={"transposed": (False, True)}, make=makeLCW, accept=acceptLGSLCW) # TODO: read, comment in english, remove the lists (and use numpy matrix instead), etc. # TODO: and of course, use multiprecision (if one day we know wich precision is enough...)
var_X.extend([('u', None, -i) for i in range(n, 0, -1)]) # x_{i+n}(k) := u(k-i) # return useful infos to build the Realization return { "JtoS": (J, K, L, M, N, P, Q, R, S), "surnameVarX": None if transposed else var_X } def acceptDFI(filt, **_): # other parameters are ignored """ return True only if the filter is SISO """ return filt.isSISO() # build the Direct Form I # as an instance of the class structure DFI = Structure(shortName='DFI', fullName="Direct Form I", options={ "nbSum": (1, 2), "transposed": (False, True) }, make=makeDFI, accept=acceptDFI) # TODO: nbSum=3 and transposed=True is the same as nbSum=1 and transposed=True # (just an extra useless temporary variable (t_2=t_1))
if not transposed: # matrices J, K, L, M, N, P, Q, R and S were for transposed form K, M = M.transpose(), K.transpose() P = P.transpose() R, Q = Q.transpose(), R.transpose() L, N = N.transpose(), L.transpose() J = J.transpose() S = S.transpose() # no need to really do this, since S is a scalar # TODO: store gamma !! return {"JtoS": (J, K, L, M, N, P, Q, R, S)} def acceptrhoDFII(filt, **options): """ return True only if the filter is SISO """ return filt.isSISO() and filt.isStable() rhoDFII = Structure(shortName="rhoDFII", fullName="rho Direct Form II", options={ 'transposed': (True, False), 'equiv_dSS': (False, True), 'scaling': (None, 'l2', 'l2-relaxed') }, make=makerhoDFII, accept=acceptrhoDFII)