GeezerVison is showing github.com — Complex matrices by lytex · Pull Request #376 · python-control/python-control
Conversation
Now I've written new tests that use complex matrices without touching the old ones
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
|
def test_evalfr_complex(self):
|
|
|
"""Evaluate the frequency response at one frequency."""
|
|
|
|
|
|
resp = [[4.6799374736968655 -34.9854626345217383j,
|
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.
Please be easier on the precision of your reference values. This will almost certainly fail on some build systems due to rounding errors or depending on the used BLAS/LAPACK implementation.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
https://travis-ci.org/python-control/python-control/jobs/656662515#L1598-L1631
======================================================================
1599ERROR: test_multiply_ss_complex (control.tests.statesp_test.TestStateSpace)
1600Multiply two complex MIMO systems.
1601----------------------------------------------------------------------
1602Traceback (most recent call last):
1603 File "/home/travis/build/python-control/python-control/control/tests/statesp_test.py", line 690, in test_multiply_ss_complex
1604 np.testing.assert_array_almost_equal(sys.A, A)
1605 File "/home/travis/miniconda/envs/test-environment/lib/python3.7/site-packages/numpy/testing/_private/utils.py", line 1047, in assert_array_almost_equal
1606 precision=decimal)
1607 File "/home/travis/miniconda/envs/test-environment/lib/python3.7/site-packages/numpy/testing/_private/utils.py", line 834, in assert_array_compare
1608 max_rel_error = max(error[nonzero] / abs(y[nonzero]))
1609 File "/home/travis/miniconda/envs/test-environment/lib/python3.7/site-packages/numpy/matrixlib/defmatrix.py", line 195, in __getitem__
1610 out = N.ndarray.__getitem__(self, index)
1611IndexError: boolean index did not match indexed array along dimension 0; dimension is 1 but corresponding boolean dimension is 25
1612
1613======================================================================
1614FAIL: test_pole_complex (control.tests.statesp_test.TestStateSpace)
1615Evaluate the poles of a complex MIMO system.
1616----------------------------------------------------------------------
1617Traceback (most recent call last):
1618 File "/home/travis/build/python-control/python-control/control/tests/statesp_test.py", line 574, in test_pole_complex
1619 np.testing.assert_array_almost_equal(p, true_p)
1620 File "/home/travis/miniconda/envs/test-environment/lib/python3.7/site-packages/numpy/testing/_private/utils.py", line 1047, in assert_array_almost_equal
1621 precision=decimal)
1622 File "/home/travis/miniconda/envs/test-environment/lib/python3.7/site-packages/numpy/testing/_private/utils.py", line 765, in assert_array_compare
1623 raise AssertionError(msg)
1624AssertionError:
1625Arrays are not almost equal to 6 decimals
1626
1627(shapes (3,), (2,) mismatch)
1628 x: array([-6.462073+2.870158j, 2.709877+6.291667j, 21.752196+7.838175j])
1629 y: array([ 2.709877 +6.291667j, 15.290123+10.708333j])
1630
1631----------------------------------------------------------------------
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
What happens if you call a function that uses slycot and give it a np.array(data, dtype=complex) (with imaginary part or without)? Will it fail gracefully, or will it give the wrong result without indication?
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
lytex
commented
Mar 3, 2020
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
|
I've run statesp_test.py on my local machine, with slycot installed, I'm getting some complex casting warnings, but I don't know if there are more hidden cases failing without indication
slycot/transform.py:560: ComplexWarning: Casting complex values to real discards the imaginary part
out = _wrapper.tb05ad_ng(n, m, p, jomega, A, B, C)
slycot/analysis.py:470: ComplexWarning: Casting complex values to real discards the imaginary part
out = _wrapper.ab08nd(n,m,p,A,B,C,D,equil=equil,tol=tol,ldwork=ldwork)
slycot/transform.py:323: ComplexWarning: Casting complex values to real discards the imaginary part
out = _wrapper.tb04ad_r(n,m,p,A,B,C,D,tol1,tol2,ldwork)
Regarding the second warning, there is a complex routine ab08nz in SLICOT we could use instead of ab08nd, so that should be pretty simple. No clue on the other ones, though.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
lytex
commented
Mar 3, 2020
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
|
I've made a more detailed traceback of the warnings:
======================================================================
ERROR: test_freq_resp_complex (__main__.TestStateSpace)
Evaluate the frequency response at multiple frequencies.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/julian/code/python/python-control/control/tests/statesp_test.py", line 732, in test_freq_resp_complex
mag, phase, omega = self.sysC623.freqresp(true_omega)
File "/home/julian/code/python/python-control/control/statesp.py", line 537, in freqresp
self.B, self.C, job='NG')
File "/home/julian/.virtualenvs/python-control/lib/python3.7/site-packages/slycot-0.3.5.21-py3.7-linux-x86_64.egg/slycot/transform.py", line 560, in tb05ad
out = _wrapper.tb05ad_ng(n, m, p, jomega, A, B, C)
numpy.ComplexWarning: Casting complex values to real discards the imaginary part
======================================================================
ERROR: test_multiply_ss_complex (__main__.TestStateSpace)
Multiply two complex MIMO systems.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/julian/code/python/python-control/control/tests/statesp_test.py", line 692, in test_multiply_ss_complex
np.testing.assert_array_almost_equal(sys.A, A)
File "/home/julian/.virtualenvs/python-control/lib/python3.7/site-packages/numpy/testing/_private/utils.py", line 1047, in assert_array_almost_equal
precision=decimal)
File "/home/julian/.virtualenvs/python-control/lib/python3.7/site-packages/numpy/testing/_private/utils.py", line 834, in assert_array_compare
max_rel_error = max(error[nonzero] / abs(y[nonzero]))
File "/home/julian/.virtualenvs/python-control/lib/python3.7/site-packages/numpy/matrixlib/defmatrix.py", line 195, in __getitem__
out = N.ndarray.__getitem__(self, index)
IndexError: boolean index did not match indexed array along dimension 0; dimension is 1 but corresponding boolean dimension is 25
======================================================================
ERROR: test_zero_mimo_sysC222_square_complex (__main__.TestStateSpace)
Evaluate the zeros of a square complex MIMO system.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/julian/code/python/python-control/control/tests/statesp_test.py", line 609, in test_zero_mimo_sysC222_square_complex
z = np.sort(self.sysC222.zero())
File "/home/julian/code/python/python-control/control/statesp.py", line 584, in zero
self.A, self.B, self.C, self.D)
File "/home/julian/.virtualenvs/python-control/lib/python3.7/site-packages/slycot-0.3.5.21-py3.7-linux-x86_64.egg/slycot/analysis.py", line 470, in ab08nd
out = _wrapper.ab08nd(n,m,p,A,B,C,D,equil=equil,tol=tol,ldwork=ldwork)
numpy.ComplexWarning: Casting complex values to real discards the imaginary part
======================================================================
ERROR: test_zero_mimo_sysC322_square_complex (__main__.TestStateSpace)
Evaluate the zeros of a square complex MIMO system.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/julian/code/python/python-control/control/tests/statesp_test.py", line 599, in test_zero_mimo_sysC322_square_complex
z = np.sort(self.sysC322.zero())
File "/home/julian/code/python/python-control/control/statesp.py", line 584, in zero
self.A, self.B, self.C, self.D)
File "/home/julian/.virtualenvs/python-control/lib/python3.7/site-packages/slycot-0.3.5.21-py3.7-linux-x86_64.egg/slycot/analysis.py", line 470, in ab08nd
out = _wrapper.ab08nd(n,m,p,A,B,C,D,equil=equil,tol=tol,ldwork=ldwork)
numpy.ComplexWarning: Casting complex values to real discards the imaginary part
======================================================================
ERROR: test_zero_mimo_sysC623_non_square_complex (__main__.TestStateSpace)
Evaluate the zeros of a non square complex MIMO system.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/julian/code/python/python-control/control/tests/statesp_test.py", line 618, in test_zero_mimo_sysC623_non_square_complex
z = np.sort(self.sysC623.zero())
File "/home/julian/code/python/python-control/control/statesp.py", line 584, in zero
self.A, self.B, self.C, self.D)
File "/home/julian/.virtualenvs/python-control/lib/python3.7/site-packages/slycot-0.3.5.21-py3.7-linux-x86_64.egg/slycot/analysis.py", line 470, in ab08nd
out = _wrapper.ab08nd(n,m,p,A,B,C,D,equil=equil,tol=tol,ldwork=ldwork)
numpy.ComplexWarning: Casting complex values to real discards the imaginary part
======================================================================
ERROR: test_zero_siso_complex (__main__.TestStateSpace)
Evaluate the zeros of a complex SISO system.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/julian/code/python/python-control/control/tests/statesp_test.py", line 584, in test_zero_siso_complex
tfC111 = ss2tf(self.sysC222)
File "/home/julian/code/python/python-control/control/xferfcn.py", line 1422, in ss2tf
return _convert_to_transfer_function(sys)
File "/home/julian/code/python/python-control/control/xferfcn.py", line 1184, in _convert_to_transfer_function
array(sys.B), array(sys.C), array(sys.D), tol1=0.0)
File "/home/julian/.virtualenvs/python-control/lib/python3.7/site-packages/slycot-0.3.5.21-py3.7-linux-x86_64.egg/slycot/transform.py", line 323, in tb04ad
out = _wrapper.tb04ad_r(n,m,p,A,B,C,D,tol1,tol2,ldwork)
numpy.ComplexWarning: Casting complex values to real discards the imaginary part
======================================================================
FAIL: test_pole_complex (__main__.TestStateSpace)
Evaluate the poles of a complex MIMO system.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/julian/code/python/python-control/control/tests/statesp_test.py", line 576, in test_pole_complex
np.testing.assert_array_almost_equal(p, true_p)
File "/home/julian/.virtualenvs/python-control/lib/python3.7/site-packages/numpy/testing/_private/utils.py", line 1047, in assert_array_almost_equal
precision=decimal)
File "/home/julian/.virtualenvs/python-control/lib/python3.7/site-packages/numpy/testing/_private/utils.py", line 765, in assert_array_compare
raise AssertionError(msg)
AssertionError:
Arrays are not almost equal to 6 decimals
(shapes (3,), (2,) mismatch)
x: array([-6.462073+2.870158j, 2.709877+6.291667j, 21.752196+7.838175j])
y: array([ 2.709877 +6.291667j, 15.290123+10.708333j])
Tests failing with ComplexWarning
test_freq_resp_complex
test_zero_mimo_sysC222_square_complex
test_zero_mimo_sysC623_non_square_complex
test_zero_siso_complex
Test failing without ComplexWarning
test_multiply_ss_complex
test_pole_complex
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
If we compare sys.A against A we get a IndexError (not sure why), but
building a new auxiliary StateSpace seems to do the trick
If we compare sys.A against A we get a IndexError (not sure why), but
building a new auxiliary StateSpace seems to do the trick
lytex
commented
Mar 31, 2020
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
|
Well, it seems that the current f2py interface doesn't support complex arrays as an argument. I've tried to use the complex routine ab08nz instead of ab08nd but I always get a SEGFAULT
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
So you wrote a wrapper for ab08nz? can you share that as PR in slycot and we see if the CI also segfaults?
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Yes f2py does support complex, however I'm not sure if it supports a complex array
I'll do the pull request in a minute
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
So you wrote a wrapper for ab08nz? can you share that as PR in slycot and we see if the CI also segfaults?
Will the CI check a new function that it is just added or there is some config file to declare with functions will be teseted?
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
You need to write unit tests associated with any new functions that you add, otherwise they won't be checked. If you are adding something to slycot, the unit tests should go there, although I think the Travis CI builds for slycot also try running python-control unit tests, since python-control is the primary user of slycot (as far as I know).
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
I've changed control/statesp.py to use the complex-case function ab08nz in the complex branch.
The tests affected by this change should be test_zero_mimi_sysCXXX_square_complex, also new tests written in the complex branch
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
The PR here in python-control will only be able to access the new function in Slycot when your PR over there is merged, a new version is released and the CI in python-control/master is updated to use this new release. So please first amend python-control/Slycot#96 with a unit test, convince the maintainers to merge and wait for a release. The python-control unit tests which are run within Slycot's CI are also from master.
Of course you could also modify the CI scripts here and over at Slycot#96 to use your respective modified branches for development, but that won't be suitable for merging.
Thus I recommend to develop first in Slycot and as soon as that is done continue in python-control.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
I've run statesp_test.py on my local machine, with slycot installed, I'm getting some complex casting warnings, but I don't know if there are more hidden cases failing without indication
slycot/transform.py:560: ComplexWarning: Casting complex values to real discards the imaginary part
out = _wrapper.tb05ad_ng(n, m, p, jomega, A, B, C)
slycot/analysis.py:470: ComplexWarning: Casting complex values to real discards the imaginary part
out = _wrapper.ab08nd(n,m,p,A,B,C,D,equil=equil,tol=tol,ldwork=ldwork)
slycot/transform.py:323: ComplexWarning: Casting complex values to real discards the imaginary part
out = _wrapper.tb04ad_r(n,m,p,A,B,C,D,tol1,tol2,ldwork)
Regarding the second warning, there is a complex routine ab08nz in SLICOT we could use instead of ab08nd, so that should be pretty simple. No clue on the other ones, though.
ab08nd has been successfully changed to ab08nz thanks to @bnavigator
lytex/Slycot#1 and now the test_zero_mimo_sysCXXX_(non_)square_complex test pass.
tb05ad_ng and tb04ad_r are casting complex values to real, but as far as I know it seems there are no complex routine equivalents to these functions
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
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.
So with the new Slycot out, I do not see a reason why python-control should not allow complex arrays. Through the "ComplexWarning", the user is informed that a function discarded the imaginary part and is thus not suitable for complex input (yet).
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Comment on lines
-96
to
+104
|
|
arr = np.matrix(data, dtype=float)
|
|
|
if np.isrealobj(data):
|
|
|
arr = np.matrix(data, dtype=float)
|
|
|
elif np.iscomplexobj(data):
|
|
|
arr = np.matrix(data, dtype=complex)
|
|
|
else:
|
|
|
arr = np.array(data, dtype=float)
|
|
|
if np.isrealobj(data):
|
|
|
arr = np.array(data, dtype=float)
|
|
|
elif np.iscomplexobj(data):
|
|
|
arr = np.array(data, dtype=complex)
|
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.
Is this really necessary? Why not just use matrix() and asarray() without dtype and figure out the dtype later?
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
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.
Turns out if dtype is omitted completely, it could still be int and trip operations later on.
The test suite already has complex casting warnings from Scipy and Slycot functions returning complex arrays (with 0 imaginary part), which are passed to _ssmatrix. Thus, my approach in #438 is to use dtype=np.result_type(np.float, arr), which ensures to cast from int to at least float and retains complex if arr is already complex.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
bnavigator
added a commit
to bnavigator/python-control
that referenced
this pull request
Jul 29, 2020
It is not necessary to enforce float and can raise
ComplexWarning during casting; cf. python-control#376
This was referenced Dec 29, 2020
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Complex state matrices
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|