Skip to content

Commit d09472c

Browse files
committed
change root precision tolerance and imaginary detection
1 parent a4b4c43 commit d09472c

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

control/xferfcn.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,7 @@ def _common_den(self, imag_tol=None):
840840
# Machine precision for floats.
841841
eps = finfo(float).eps
842842

843-
# Decide on the tolerance to use in deciding of a pole is complex
843+
# Decide on the tolerance to use in deciding if a pole is complex
844844
if (imag_tol is None):
845845
imag_tol = 1e-8 # TODO: figure out the right number to use
846846

@@ -874,7 +874,7 @@ def _common_den(self, imag_tol=None):
874874
nothave = ones(currentpoles.shape, dtype=bool)
875875
for ip, p in enumerate(poles[j]):
876876
idx, = nonzero(
877-
(abs(currentpoles - p) < epsnm) * nothave)
877+
(abs(currentpoles - p) < sqrt(epsnm)) * nothave)
878878
if len(idx):
879879
nothave[idx[0]] = False
880880
else:
@@ -890,7 +890,8 @@ def _common_den(self, imag_tol=None):
890890
npmax = max([len(p) for p in poles])
891891
den = zeros((self.inputs, npmax + 1), dtype=float)
892892
num = zeros((max(1, self.outputs, self.inputs),
893-
max(1, self.outputs, self.inputs), npmax + 1),
893+
max(1, self.outputs, self.inputs),
894+
npmax + 1),
894895
dtype=float)
895896
denorder = zeros((self.inputs,), dtype=int)
896897

@@ -901,11 +902,18 @@ def _common_den(self, imag_tol=None):
901902
for i in range(self.outputs):
902903
num[i, j, 0] = poleset[i][j][2]
903904
else:
904-
# create the denominator matching this input polyfromroots
905-
# gives coeffs in opposite order from what we use coefficients
906-
# should be padded on right, ending at np
905+
# create the denominator matching this input
906+
# polyfromroots gives coeffs in opposite order from what we use
907+
# coefficients should be padded on right, ending at np
907908
np = len(poles[j])
908-
den[j, np::-1] = polyfromroots(poles[j]).real
909+
denpoly = polyfromroots(poles[j])
910+
if (abs(denpoly.imag) > imag_tol).any():
911+
warn("The denominator of the transfer function "
912+
"for input {j} to output {i} has a nontrivial "
913+
"imaginary part of {imag}, which was removed".format(
914+
i=i, j=j, imag=max(denpoly.imag)))
915+
denpoly = denpoly.real
916+
den[j, np::-1] = denpoly
909917
denorder[j] = np
910918

911919
# now create the numerator, also padded on the right
@@ -926,13 +934,9 @@ def _common_den(self, imag_tol=None):
926934
num[i, j, np + 1 - len(numpoly):np + 1] = numpoly[::-1]
927935
# print(num[i, j])
928936

929-
if (abs(den.imag) > epsnm).any():
930-
print("Warning: The denominator has a nontrivial imaginary part: "
931-
" %f" % abs(den.imag).max())
932-
den = den.real
933-
934937
return num, den, denorder
935938

939+
936940
def sample(self, Ts, method='zoh', alpha=None):
937941
"""Convert a continuous-time system to discrete time
938942

0 commit comments

Comments
 (0)