-
Notifications
You must be signed in to change notification settings - Fork 438
Cleanup TransferFunction Input Sanitization #135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Added IO cleanup function to xferfcn module.
From .eggs/README.txt: "This directory contains eggs that were downloaded by setuptools to build, test, and run plug-ins. This directory caches those eggs to prevent repeated downloads. However, it is safe to delete this directory."
…function. Added unit tests to test the cleanup function. Added deep copy to TransferFunction args.
control/xferfcn.py
Outdated
@@ -1349,3 +1317,42 @@ def tfdata(sys): | |||
tf = _convertToTransferFunction(sys) | |||
|
|||
return (tf.num, tf.den) | |||
|
|||
def cleanPart(data): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is an internal function, should we name it _cleanPart
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense to me. I just made the changes and pushed.
*Created a branch and then merged the branch so that I can continue working. I wasn't aware that GitHub pull requests always tracked |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Comments are all nitpicks.
control/tests/xferfcn_input_test.py
Outdated
#!/usr/bin/env python | ||
# | ||
# xferfcn_test.py - test TransferFunction class | ||
# RMM, 30 Mar 2011 (based on TestXferFcn from v0.4a) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably worthwhile correcting this header comment
np.testing.assert_array_equal(num_[0][1], array([2.0, 2.0], dtype=float)) | ||
|
||
def testListListListFloats(self): | ||
"""Test 2 lists of ints in a list in a list.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
floats, not ints?
control/xferfcn.py
Outdated
@@ -10,6 +10,7 @@ | |||
# Python 3 compatibility (needs to go here) | |||
from __future__ import print_function | |||
from __future__ import division | |||
from __future__ import absolute_import |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had to look this up. It appears to be necessary for Python 2.5 - do we support that? I didn't quite understand what the related PEP was getting at, but it's not obvious to me that your changes especially need the features it enables anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True, I just used my boilerplate "I need to make something Python 2/3 compatible" code. It can probably be removed.
control/xferfcn.py
Outdated
data: numerator or denominator of a transfer function. | ||
|
||
Returns: | ||
data: correctly formatted transfer function part. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could be a little more specific: return data as a list of lists of ndarrays of type float.
control/xferfcn.py
Outdated
float, float16, float32, float64, float128) | ||
valid_collection = (list, tuple, ndarray) | ||
|
||
if (isinstance(data, valid_types) or |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was going to suggest using np.isreal
instead of isinstance(..,valid_types)
, but then I found np.isreal(file('/dev/null'))
returns True (oops!).
FWIW, this fixes another bug: (ctrl-py35) rory@rory-Inspiron-3521:~/Documents/python-control$ (cd ~/src/python-control && git checkout master)
Switched to branch 'master'
Your branch is up-to-date with 'upstream/master'.
(ctrl-py35) rory@rory-Inspiron-3521:~/Documents/python-control$ python -c "from control import tf; g=tf([[[1]]],[[[1,1]]]); print(g+g)"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/rory/src/python-control/control/xferfcn.py", line 349, in __add__
return TransferFunction(num, den, dt)
File "/home/rory/src/python-control/control/xferfcn.py", line 163, in __init__
MIMO).")
TypeError: The numerator and denominator inputs must be scalars or vectors (for
SISO), or lists of lists of vectors (for SISO or MIMO).
(ctrl-py35) rory@rory-Inspiron-3521:~/Documents/python-control$ (cd ~/src/python-control && git checkout InputSanitization)
Switched to branch 'InputSanitization'
Your branch is up-to-date with 'jed-frey/InputSanitization'.
(ctrl-py35) rory@rory-Inspiron-3521:~/Documents/python-control$ python -c "from control import tf; g=tf([[[1]]],[[[1,1]]]); print(g+g)"
2 s + 2
-------------
s^2 + 2 s + 1 |
A few additional comments on this:
I'll try to do an integration of all of this in the coming days. |
…n-control into jed-frey-InputSanitization
I submitted a pull request back to @jed-frey that addresses the issues above and also merges in the changes from PR #170, which are related, and the additional unit tests from PR #158 (also related). Will wait a few days fro @jed-frey to integrate the changes, otherwise I'll submit a separate pull request with the combined changes. Travis CI results available here (all OK). |
This started out to address #112 & #130, but I found a few other small edge cases.
To simplify unit testing I broke the input cleaning out to a separate function and added as many test cases as I could think of.
Deep copy
It performs a deep copy on args before anything else.
Test Code:
Before:
After:
Validate All Input Types:
The previous input validation would only check the first element if it was a valid input type. This means you could feed in extra bad values in other positions and it would accept it, only to fail later.
Test Code:
Before:
It would accept the values (and mutate the inputs):
But fail when you tried to access the system:
After
It fails immediately:
Added more valid types.
If you passed an numpy array as an input it would possibly fail depending on which architecture you were using it on.
int
resolves toint64
on 64-bit systems. It now accepts valid types ofint, int8, int16, int32, int64, float, float16, float32, float64, float128
. (If for some reason your transfer function parts were generated in another function).Code:
Before:
After:
Added Tuple as valid collection for MIMO systems
It was easy enough to add and a valid ordered Python collection.
Given:
Previously this was the only valid MIMO input:
Now all of these are also valid: