ilayn / harold

An open-source systems and controls toolbox for Python3
MIT License
172 stars 19 forks source link

Sum of Transfer results a ValueError: Noncausal transfer functions are not allowed. #92

Open jamestjsp opened 1 year ago

jamestjsp commented 1 year ago

Sum of multiple higher order transferfunction results in a 'ValueError: Noncausal transfer functions are not allowed.' I have written PolyFrac class and do arithmetic then convert to Transfer object works fine!

The below code can be used to reproduce the issue.


import numpy as np
import harold

class PolyFrac():
    def __init__(self, num, den) -> None:
        self.num = num
        self.den = den
        self._num = np.polynomial.Polynomial(self.num[::-1])
        self._den = np.polynomial.Polynomial(self.den[::-1])
    def __add__(self, other):
        self._rnum = self._num * other._den + self._den * other._num
        self._rden = self._den * other._den
        return PolyFrac(self._rnum.coef[::-1], self._rden.coef[::-1])

num = [0.00048873990334,0.00008022868673,0.000004688964039,0.000000119457633,0.000000001314395,0.00000000000487 ]
den = [713971.3912200001,157343.82838884002,14104.582786048937,663.9560606101594,17.793303846830465,0.27893627449232,0.002591707015312,
       0.00001456551703,0.000000046427704,0.000000000061138]
G1 = PolyFrac(num,den)
Gh1 = harold.Transfer(num, den)
num = [0.000248910547815,0.000040859701097,0.000002388044438,0.000000060838627,0.000000000669409,0.00000000000248]
den = [468539.19521279994,104086.4548127616,9436.270955826356,451.5149614339922,12.39566355720315,0.201316286426998,0.001963464678425,
       0.000011684559727,0.000000040217318,0.000000000061138]
G2 = PolyFrac(num,den)
Gh2 = harold.Transfer(num, den)
num = [0.000589835421362,0.000096823936248,0.000005658873075,0.000000144167363,0.000000001586277,0.000000000005877]
den = [2416.14684,524.28995448,45.95699773796595,2.091367387046341,0.053136840811452,0.000764126679123,0.000006184705029,0.000000028361462,
       0.000000000061138]
G3 = PolyFrac(num,den)
Gh3 = harold.Transfer(num, den)

G4 = G1+G2+G3
Gh4 = Gh1+Gh2+Gh3

G = harold.Transfer(G4.num, G4.den)
print(G.dcgain)
print(Gh4.dcgain)
ilayn commented 1 year ago

I am still looking at this and it needs some major surgery apparently. Since the poles and zeros are very close it cancels some but doesn't the rest leading to noncausal models. I'll keep on working on it as time permits.