You can subscribe to this list here.
2010 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(19) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(11) |
Dec
(5) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2011 |
Jan
|
Feb
(113) |
Mar
(12) |
Apr
(27) |
May
(2) |
Jun
(16) |
Jul
(6) |
Aug
(6) |
Sep
|
Oct
(3) |
Nov
(9) |
Dec
(2) |
2012 |
Jan
(5) |
Feb
(11) |
Mar
|
Apr
(3) |
May
|
Jun
|
Jul
|
Aug
(3) |
Sep
(7) |
Oct
(18) |
Nov
(18) |
Dec
|
2013 |
Jan
(4) |
Feb
(1) |
Mar
(3) |
Apr
(1) |
May
|
Jun
(33) |
Jul
(2) |
Aug
(5) |
Sep
|
Oct
|
Nov
|
Dec
(1) |
2014 |
Jan
(1) |
Feb
|
Mar
(8) |
Apr
|
May
(3) |
Jun
(3) |
Jul
(9) |
Aug
(5) |
Sep
(6) |
Oct
|
Nov
|
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(4) |
2017 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(5) |
Nov
|
Dec
|
2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2019 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(6) |
Sep
|
Oct
|
Nov
(2) |
Dec
|
2020 |
Jan
(1) |
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2021 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(4) |
Oct
|
Nov
|
Dec
|
From: Dale L. P. <haz...@gm...> - 2012-10-29 20:53:30
|
Richard, I am running Python 3.2. In order to run python control, I have to use the 2to3 tool to convert on each .py file. It fixes things like print "x" by changing it to print("x"). For some reason, it is changing the import statements in both xferfcn.py and statesp.py from: import statesp import xferfcn to: from . import statesp from . import xferfcn Then when try to import control, I get the same error as before: --------------------------------------------------------------------------- ImportError Traceback (most recent call last) <ipython-input-1-4964879682bf> in <module>() ----> 1 import control /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/__init__.py in <module>() 58 # Import functions from within the control system library 59 #! Should probably only import the exact functions we use... ---> 60 from .bdalg import series, parallel, negate, feedback 61 from .delay import pade 62 from .dtime import sample_system /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/bdalg.py in <module>() 53 54 import scipy as sp ---> 55 from . import xferfcn as tf 56 from . import statesp as ss 57 /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/xferfcn.py in <module>() 82 from .lti import Lti, timebaseEqual, timebase, isdtime 83 from warnings import warn ---> 84 from . import statesp 85 86 class TransferFunction(Lti): /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/statesp.py in <module>() 83 import warnings 84 from .lti import Lti, timebaseEqual, isdtime ---> 85 from . import xferfcn 86 87 class StateSpace(Lti): ImportError: cannot import name xferfcn I think this may stem from how src/__init__.py and each of the modules in src/ are importing each others functionality. The design patterned that I have been following and have used with no issues in the sympy project can be seen in these two files: https://github.com/hazelnusse/sympy/blob/master/sympy/physics/mechanics/__init__.py https://github.com/hazelnusse/sympy/blob/master/sympy/physics/mechanics/particle.py Basically, in each module, we set the __all__ list to include the names of the publicly available class and functions. Within each module, we never do relative imports, we always use the absolute import syntax. The __init__.py file is heavily commented so you should be able to see how we make those symbols available when people import the module or sub-package. Luke On Sat, Oct 27, 2012 at 4:54 PM, Richard Murray <mu...@cd...> wrote: > Both of these issues should now be fixed in the latest version of trunk. Let me know if you continue to have problems. > > -richard > > On 25 Oct 2012, at 23:58 , Dale Lukas Peterson <haz...@gm...> wrote: > >> In src/lti.py, NoneType is being imported and used in the Lti class in >> two locations. Is there a reason this can't be just None? NoneType >> is deprecated in Python3 and this is causing issues for me. >> >> Also, I am getting this import error when I import control: >> --------------------------------------------------------------------------- >> ImportError Traceback (most recent call last) >> <ipython-input-1-4964879682bf> in <module>() >> ----> 1 import control >> >> /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/__init__.py >> in <module>() >> 58 # Import functions from within the control system library >> 59 #! Should probably only import the exact functions we use... >> ---> 60 from .bdalg import series, parallel, negate, feedback >> 61 from .delay import pade >> 62 from .dtime import sample_system >> >> /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/bdalg.py >> in <module>() >> 53 >> 54 import scipy as sp >> ---> 55 from . import xferfcn as tf >> 56 from . import statesp as ss >> 57 >> >> /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/xferfcn.py >> in <module>() >> 82 from .lti import Lti, timebaseEqual, timebase, isdtime >> 83 from warnings import warn >> ---> 84 from . import statesp >> 85 >> 86 class TransferFunction(Lti): >> >> /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/statesp.py >> in <module>() >> 83 import warnings >> 84 from .lti import Lti, timebaseEqual, isdtime >> ---> 85 from . import xferfcn >> 86 >> 87 class StateSpace(Lti): >> >> ImportError: cannot import name xferfcn >> >> I noticed that xferfcn.py has: >> from . import statesp >> >> and that statesp.py has: >> from . import xferfcn >> >> I am guessing is a circular dependency issue. From what I can tell, >> each of these modules only imports these to do some type checking of >> arguments. >> >> Luke >> >> >> -- >> “People call me a perfectionist, but I'm not. I'm a rightist. I do >> something until it's right, and then I move on to the next thing.” >> ― James Cameron >> >> ------------------------------------------------------------------------------ >> Everyone hates slow websites. So do we. >> Make your web apps faster with AppDynamics >> Download AppDynamics Lite for free today: >> http://p.sf.net/sfu/appdyn_sfd2d_oct >> _______________________________________________ >> python-control-discuss mailing list >> pyt...@li... >> https://lists.sourceforge.net/lists/listinfo/python-control-discuss > > > ------------------------------------------------------------------------------ > WINDOWS 8 is here. > Millions of people. Your app in 30 days. > Visit The Windows 8 Center at Sourceforge for all your go to resources. > http://windows8center.sourceforge.net/ > join-generation-app-and-make-money-coding-fast/ > _______________________________________________ > python-control-discuss mailing list > pyt...@li... > https://lists.sourceforge.net/lists/listinfo/python-control-discuss -- “People call me a perfectionist, but I'm not. I'm a rightist. I do something until it's right, and then I move on to the next thing.” ― James Cameron |
From: Richard M. <mu...@cd...> - 2012-10-28 02:20:43
|
Both of these issues should now be fixed in the latest version of trunk. Let me know if you continue to have problems. -richard On 25 Oct 2012, at 23:58 , Dale Lukas Peterson <haz...@gm...> wrote: > In src/lti.py, NoneType is being imported and used in the Lti class in > two locations. Is there a reason this can't be just None? NoneType > is deprecated in Python3 and this is causing issues for me. > > Also, I am getting this import error when I import control: > --------------------------------------------------------------------------- > ImportError Traceback (most recent call last) > <ipython-input-1-4964879682bf> in <module>() > ----> 1 import control > > /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/__init__.py > in <module>() > 58 # Import functions from within the control system library > 59 #! Should probably only import the exact functions we use... > ---> 60 from .bdalg import series, parallel, negate, feedback > 61 from .delay import pade > 62 from .dtime import sample_system > > /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/bdalg.py > in <module>() > 53 > 54 import scipy as sp > ---> 55 from . import xferfcn as tf > 56 from . import statesp as ss > 57 > > /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/xferfcn.py > in <module>() > 82 from .lti import Lti, timebaseEqual, timebase, isdtime > 83 from warnings import warn > ---> 84 from . import statesp > 85 > 86 class TransferFunction(Lti): > > /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/statesp.py > in <module>() > 83 import warnings > 84 from .lti import Lti, timebaseEqual, isdtime > ---> 85 from . import xferfcn > 86 > 87 class StateSpace(Lti): > > ImportError: cannot import name xferfcn > > I noticed that xferfcn.py has: > from . import statesp > > and that statesp.py has: > from . import xferfcn > > I am guessing is a circular dependency issue. From what I can tell, > each of these modules only imports these to do some type checking of > arguments. > > Luke > > > -- > “People call me a perfectionist, but I'm not. I'm a rightist. I do > something until it's right, and then I move on to the next thing.” > ― James Cameron > > ------------------------------------------------------------------------------ > Everyone hates slow websites. So do we. > Make your web apps faster with AppDynamics > Download AppDynamics Lite for free today: > http://p.sf.net/sfu/appdyn_sfd2d_oct > _______________________________________________ > python-control-discuss mailing list > pyt...@li... > https://lists.sourceforge.net/lists/listinfo/python-control-discuss |
From: Richard M. <mu...@cd...> - 2012-10-26 13:59:53
|
The NoneType issues came up when I put in the timebase functionality (for continuous versus discrete time). If dt == None, then the timebase is not specified and the system can be combined with either a discrete or continuous system (useful for constant systems). Seems easy enough to rewrite so that it doesn't use NoneType. I'll take a look this weekend if someone doesn't fix it before that. I'll also have a look at the circular dependency. Surprised that this didn't pop up on the unit tests. There are lots of places where there is a check isinstance(sys, (StateSpace, TransferFunction)) that should probably check against Lti. A change will definitely be required as we add in the FRD class. -richard On 25 Oct 2012, at 23:58 , Dale Lukas Peterson <haz...@gm...> wrote: > In src/lti.py, NoneType is being imported and used in the Lti class in > two locations. Is there a reason this can't be just None? NoneType > is deprecated in Python3 and this is causing issues for me. > > Also, I am getting this import error when I import control: > --------------------------------------------------------------------------- > ImportError Traceback (most recent call last) > <ipython-input-1-4964879682bf> in <module>() > ----> 1 import control > > /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/__init__.py > in <module>() > 58 # Import functions from within the control system library > 59 #! Should probably only import the exact functions we use... > ---> 60 from .bdalg import series, parallel, negate, feedback > 61 from .delay import pade > 62 from .dtime import sample_system > > /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/bdalg.py > in <module>() > 53 > 54 import scipy as sp > ---> 55 from . import xferfcn as tf > 56 from . import statesp as ss > 57 > > /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/xferfcn.py > in <module>() > 82 from .lti import Lti, timebaseEqual, timebase, isdtime > 83 from warnings import warn > ---> 84 from . import statesp > 85 > 86 class TransferFunction(Lti): > > /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/statesp.py > in <module>() > 83 import warnings > 84 from .lti import Lti, timebaseEqual, isdtime > ---> 85 from . import xferfcn > 86 > 87 class StateSpace(Lti): > > ImportError: cannot import name xferfcn > > I noticed that xferfcn.py has: > from . import statesp > > and that statesp.py has: > from . import xferfcn > > I am guessing is a circular dependency issue. From what I can tell, > each of these modules only imports these to do some type checking of > arguments. > > Luke > > > -- > “People call me a perfectionist, but I'm not. I'm a rightist. I do > something until it's right, and then I move on to the next thing.” > ― James Cameron > > ------------------------------------------------------------------------------ > Everyone hates slow websites. So do we. > Make your web apps faster with AppDynamics > Download AppDynamics Lite for free today: > http://p.sf.net/sfu/appdyn_sfd2d_oct > _______________________________________________ > python-control-discuss mailing list > pyt...@li... > https://lists.sourceforge.net/lists/listinfo/python-control-discuss |
From: Dale L. P. <haz...@gm...> - 2012-10-26 06:58:16
|
In src/lti.py, NoneType is being imported and used in the Lti class in two locations. Is there a reason this can't be just None? NoneType is deprecated in Python3 and this is causing issues for me. Also, I am getting this import error when I import control: --------------------------------------------------------------------------- ImportError Traceback (most recent call last) <ipython-input-1-4964879682bf> in <module>() ----> 1 import control /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/__init__.py in <module>() 58 # Import functions from within the control system library 59 #! Should probably only import the exact functions we use... ---> 60 from .bdalg import series, parallel, negate, feedback 61 from .delay import pade 62 from .dtime import sample_system /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/bdalg.py in <module>() 53 54 import scipy as sp ---> 55 from . import xferfcn as tf 56 from . import statesp as ss 57 /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/xferfcn.py in <module>() 82 from .lti import Lti, timebaseEqual, timebase, isdtime 83 from warnings import warn ---> 84 from . import statesp 85 86 class TransferFunction(Lti): /home/hazelnusse/usr/lib64/python3.2/site-packages/control-0.6a-py3.2.egg/control/statesp.py in <module>() 83 import warnings 84 from .lti import Lti, timebaseEqual, isdtime ---> 85 from . import xferfcn 86 87 class StateSpace(Lti): ImportError: cannot import name xferfcn I noticed that xferfcn.py has: from . import statesp and that statesp.py has: from . import xferfcn I am guessing is a circular dependency issue. From what I can tell, each of these modules only imports these to do some type checking of arguments. Luke -- “People call me a perfectionist, but I'm not. I'm a rightist. I do something until it's right, and then I move on to the next thing.” ― James Cameron |
From: Richard M. <mu...@cd...> - 2012-10-22 00:55:43
|
Confirmed the same issue (and working fix) on matplotlib 1.1.0 -richard On 21 Oct 2012, at 10:56 , Scott C. Livingston <sli...@ca...> wrote: > I cannot run the example genswitch.py without modifying the calls to legend() to use tuples. Can someone confirm my observation? I am testing with Matplotlib version 1.1.1rc. My proposed patch is to lines 43 and 65, which should now be > > mpl.legend(('z1, f(z1)', 'z2, f(z2)')) # legend(lgh, 'boxoff'); > > and > > mpl.legend(('z1 (A)', 'z2 (B)')) # 'Orientation', 'horizontal'); > > respectively. > ------------------------------------------------------------------------------ > Everyone hates slow websites. So do we. > Make your web apps faster with AppDynamics > Download AppDynamics Lite for free today: > http://p.sf.net/sfu/appdyn_sfd2d_oct > _______________________________________________ > python-control-discuss mailing list > pyt...@li... > https://lists.sourceforge.net/lists/listinfo/python-control-discuss |
From: Richard M. <mu...@cd...> - 2012-10-22 00:50:23
|
Looks good to me (I think I'm the original author of the phase_plot function). -richard On 21 Oct 2012, at 11:22 , Scott C. Livingston <sli...@ca...> wrote: > The docstring for phase_plot() (in src/phaseplot.py) concerning the parameter "T" is > > Length of time to run simulations that generate streamlines. > If a single number, the same simulation time is used for all > initial conditions. Otherwise, should be a list of length > len(X0) that gives the simulation time for each initial > condition. Default value = 50. > > It appears to me that the second possibility of "list of length len(X0)" is not actually implemented. Instead, if T is an array, then it is used in the call to odeint() directly. I propose adding the claimed functionality and further, in the case that T is a list, allowing any element to be an array itself. A patch achieving this is below. Existing code that uses phase_plot() would be unaffected by this change assuming that T is never given as a list. > > Index: src/phaseplot.py > =================================================================== > --- src/phaseplot.py (revision 202) > +++ src/phaseplot.py (working copy) > @@ -176,6 +176,8 @@ > dx = np.empty((nr, Narrows, 2)) > > # See if we were passed a simulation time > + if isinstance(T, list) and len(T) != nr: > + raise TypeError("Insufficient number of simulation times given for initial conditions.") > if (T == None): > T = 50 > > @@ -197,6 +199,10 @@ > > # Generate the streamlines for each initial condition > for i in range(nr): > + if isinstance(T, list): > + TSPAN = T[i] > + if (isinstance(TSPAN, (int, float))): > + TSPAN = np.linspace(0, TSPAN, 100); > state = odeint(odefun, X0[i], TSPAN, args=parms); > time = TSPAN > mpl.hold(True); > > > ------------------------------------------------------------------------------ > Everyone hates slow websites. So do we. > Make your web apps faster with AppDynamics > Download AppDynamics Lite for free today: > http://p.sf.net/sfu/appdyn_sfd2d_oct > _______________________________________________ > python-control-discuss mailing list > pyt...@li... > https://lists.sourceforge.net/lists/listinfo/python-control-discuss |
From: Scott C. L. <sli...@ca...> - 2012-10-21 18:22:14
|
The docstring for phase_plot() (in src/phaseplot.py) concerning the parameter "T" is Length of time to run simulations that generate streamlines. If a single number, the same simulation time is used for all initial conditions. Otherwise, should be a list of length len(X0) that gives the simulation time for each initial condition. Default value = 50. It appears to me that the second possibility of "list of length len(X0)" is not actually implemented. Instead, if T is an array, then it is used in the call to odeint() directly. I propose adding the claimed functionality and further, in the case that T is a list, allowing any element to be an array itself. A patch achieving this is below. Existing code that uses phase_plot() would be unaffected by this change assuming that T is never given as a list. Index: src/phaseplot.py =================================================================== --- src/phaseplot.py (revision 202) +++ src/phaseplot.py (working copy) @@ -176,6 +176,8 @@ dx = np.empty((nr, Narrows, 2)) # See if we were passed a simulation time + if isinstance(T, list) and len(T) != nr: + raise TypeError("Insufficient number of simulation times given for initial conditions.") if (T == None): T = 50 @@ -197,6 +199,10 @@ # Generate the streamlines for each initial condition for i in range(nr): + if isinstance(T, list): + TSPAN = T[i] + if (isinstance(TSPAN, (int, float))): + TSPAN = np.linspace(0, TSPAN, 100); state = odeint(odefun, X0[i], TSPAN, args=parms); time = TSPAN mpl.hold(True); |
From: Scott C. L. <sli...@ca...> - 2012-10-21 17:56:56
|
I cannot run the example genswitch.py without modifying the calls to legend() to use tuples. Can someone confirm my observation? I am testing with Matplotlib version 1.1.1rc. My proposed patch is to lines 43 and 65, which should now be mpl.legend(('z1, f(z1)', 'z2, f(z2)')) # legend(lgh, 'boxoff'); and mpl.legend(('z1 (A)', 'z2 (B)')) # 'Orientation', 'horizontal'); respectively. |
From: Rene v. P. <ren...@gm...> - 2012-10-19 07:22:04
|
On 17 October 2012 01:12, Scott C. Livingston <sli...@ca...>wrote: > The documentation for root_locus() (in rlocus.py) claims two return > values, whereas there is actually only one: the root list, "rlist". > > rlocus() in matlab.py has default argument klist=None. Inside the > function body, if klist is found to be None, then it is set to logspace(-3, > 3). Is there a reason to do that rather than use > > def rlocus(sys, klist = logspace(-3, 3), **keywords) > > There is a valid reason for this, see for example http://www.deadlybloodyserious.com/2008/05/default-argument-blunders/ Also, since at the end of the function klist is returned, if that list is kept by the application and later modified, the next call to rlocus will have strange results. Should I start sending patches instead of complaining? :-) No, use the discussion list first, that is what it is there for. > Thanks, > You are welcome. René |
From: Scott C. L. <sli...@ca...> - 2012-10-16 23:12:26
|
The documentation for root_locus() (in rlocus.py) claims two return values, whereas there is actually only one: the root list, "rlist". rlocus() in matlab.py has default argument klist=None. Inside the function body, if klist is found to be None, then it is set to logspace(-3, 3). Is there a reason to do that rather than use def rlocus(sys, klist = logspace(-3, 3), **keywords) Should I start sending patches instead of complaining? :-) Thanks, Scott |
From: Richard M. <mu...@cd...> - 2012-10-16 23:00:01
|
Thanks, Scott. Will fix in the next set of commits (via a warning + docs). -richard On Oct 16, 2012, at 3:28 PM, "Scott C. Livingston" <sli...@ca...> wrote: > I noticed an error in loading python-control after updating to trunk on a machine that has SciPy version 0.9.0 installed. In this situation, "import control" will fail since __init__.py imports a method from dtime, which uses cont2discrete(), a method introduced in SciPy 0.10. > > I did not see mention of this in the documentation and thus notify the list here. > > ~Scott Livingston > > > ------------------------------------------------------------------------------ > Everyone hates slow websites. So do we. > Make your web apps faster with AppDynamics > Download AppDynamics Lite for free today: > http://p.sf.net/sfu/appdyn_sfd2d_oct > _______________________________________________ > python-control-discuss mailing list > pyt...@li... > https://lists.sourceforge.net/lists/listinfo/python-control-discuss |
From: Scott C. L. <sli...@ca...> - 2012-10-16 22:28:52
|
I noticed an error in loading python-control after updating to trunk on a machine that has SciPy version 0.9.0 installed. In this situation, "import control" will fail since __init__.py imports a method from dtime, which uses cont2discrete(), a method introduced in SciPy 0.10. I did not see mention of this in the documentation and thus notify the list here. ~Scott Livingston |
From: Richard M. <mu...@cd...> - 2012-10-07 05:57:14
|
I'm not sure whether SourceForge 2.0 sends out commit messages to everyone on the developers list (can someone let me know if you did/didn't get the note below?), but wanted to briefly comment on the most recent commit, which has a first cut implementation for discrete time systems. After thinking about this for a bit and looking at what others had done (eg, the new discrete time capability in scipy.signals), I decided to add a 'dt' class variable to both the StateSpace and TransferFunction classes that can be used to specify the "timebase" for a system: * dt = None => system timebase not specified (default) * dt = 0 => system is continuous time * dt > 0 => system is discrete time, with dt as the sampling time The ways things are set up, if you interconnected two systems using series (*), parallel (+) or feedback, then it will check to make sure that the timebases are consistent. If both systems have a timebase (dt != Null), then the timebase for both systems must match. If only one of the system has a timebase, the return timebase will be set to match it. By default, systems are created with dt=None and everything works as it did before. So if all you care about is continuous time systems, nothing changes. Right now, most other operations (bode, lsim, etc) will generate a NotImplementedError if you call them, but I'll start to add that functionality pretty soon. There are functions 'timebase' (returns 'ctime', 'dtime' or None), 'isctime' and 'isdtime' to test the timebase of a system without having to look at dt. I've updated the version number for the toolbox to 0.6a since this represents a reasonably large charge. As you should have also seen (via a post to python-control-announce), I also kicked out a release of the code just before this set of changes. Comments and feedback is welcome. The next set of things to do are implement c2d, time and frequency responses and perhaps a few other basic commands. I may also let dt = True be used to specify a discrete time system without a specific sampling period. -richard On 6 Oct 2012, at 21:44 , "Repository Python Control Systems Library code" <no...@co...> wrote: > : Initial support for discrete time systems (version 0.6) > > • Added dt class variable to keep track of whether system is discrete > • Algebraic operations check for timebase consistency > • Functions that don't support discrete time generate NotImplementedError > • Added unit tests for code that has been implemented so far > • Updated version number to 0.6a > http://sourceforge.net/p/python-control/code/193/ > > Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/python-control/code/ > > To unsubscribe from further messages, please visit https://sourceforge.net/auth/prefs/ > |
From: Richard M. <mu...@cd...> - 2012-09-05 18:14:44
|
As far as I can tell, sourceforge doesn't have anything in particular to automate the conversion, it just allows you to have both a subversion and git repository at the same time. -richard On 5 Sep 2012, at 9:56 , Dale Lukas Peterson <haz...@gm...> wrote: >> As far as how to switch to github, I guess the easiest way, if SF offers a >> "convert this repository to git" button, is to press that button and then >> clone the SF repository to your local computer, create a github repository >> and then push your local repository onto github. (Then maybe delete the SF >> one or at least block writing to it.) > > Andrew has summed it up much better than I could is right on the money > in his description. > > Is there such a shiny button in SF? A bit of googling seemed to > indicate that the svn->git process might involve several steps, and > the final structure of the generated repo depends on those steps. If > SF has taken care of this, it would be really nice. Once a git repo > is generated, Andrew's description of how to put it on github is > definitely the easiest way. > > Luke > > ------------------------------------------------------------------------------ > Live Security Virtual Conference > Exclusive live event will cover all the ways today's security and > threat landscape has changed and how IT managers can respond. Discussions > will include endpoint security, mobile security and the latest in malware > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ > _______________________________________________ > python-control-discuss mailing list > pyt...@li... > https://lists.sourceforge.net/lists/listinfo/python-control-discuss |
From: Dale L. P. <haz...@gm...> - 2012-09-05 16:56:47
|
> As far as how to switch to github, I guess the easiest way, if SF offers a > "convert this repository to git" button, is to press that button and then > clone the SF repository to your local computer, create a github repository > and then push your local repository onto github. (Then maybe delete the SF > one or at least block writing to it.) Andrew has summed it up much better than I could is right on the money in his description. Is there such a shiny button in SF? A bit of googling seemed to indicate that the svn->git process might involve several steps, and the final structure of the generated repo depends on those steps. If SF has taken care of this, it would be really nice. Once a git repo is generated, Andrew's description of how to put it on github is definitely the easiest way. Luke |
From: Andrew S. <str...@as...> - 2012-09-05 08:31:29
|
On 09/05/2012 08:10 AM, Richard Murray wrote: > There hasn't been much conversation about this, but converting to git is probably the way to go in the long run (better functionality for distributed development). Sourceforge supports git and we can easily transfer projects from subversion to git: > > https://sourceforge.net/apps/trac/sourceforge/ticket/24534 > > I don't have much experience with github versus sourceforge in terms of the various features, and so don't have a strong preference beyond doing whatever works best for the people who are actively developing code for the library. As an example, when matplotlib switched from the code repository using svn + sourceforce to git + github, there was a dramatic increase in contributions. MPL continues to use sourceforge for the email lists. The issue tracking was later switched to github, despite some missing functionality, in order to have integration with the version control system (having "closed issue" messages linked to the commit that closed them). All that said, these data are from some time ago (2 years, approximately) -- since that time, sourceforge seems to have made some dramatic changes (adding git, revising their issue tracking system) and I cannot fairly compare sourceforge's current offerings. See https://github.com/matplotlib/matplotlib for the MPL github respository. So, my evidence is that your criterion of "whatever works best for the people who are actively developing code for the library" will be best served by moving to github because you'll gain new contributors. This was more-or-less the discussion we had in the matplotlib email list and, although I haven't quantified it, the evidence of new contributors is very clear. You'll also gain resonance with similar minds using similar tools and also possibly interested in python-control, thus increasing the likely number of high-quality contributions. Here are some projects that all use github as their primary repository as far as I know: * numpy https://github.com/numpy/numpy * IPython https://github.com/ipython/ipython * sympy https://github.com/sympy/sympy * scipy https://github.com/scipy/scipy * ROS https://github.com/ros As far as how to switch to github, I guess the easiest way, if SF offers a "convert this repository to git" button, is to press that button and then clone the SF repository to your local computer, create a github repository and then push your local repository onto github. (Then maybe delete the SF one or at least block writing to it.) -Andrew |
From: Dale L. P. <haz...@gm...> - 2012-09-05 06:27:58
|
> There hasn't been much conversation about this, but converting to git is probably the way to go in the long run (better functionality for distributed development). Sourceforge supports git and we can easily transfer projects from subversion to git: > > https://sourceforge.net/apps/trac/sourceforge/ticket/24534 I agree, git is definitely the way to go. > I don't have much experience with github versus sourceforge in terms of the various features, and so don't have a strong preference beyond doing whatever works best for the people who are actively developing code for the library. I haven't hosted a project with sourceforge, but I use github for all of my projects that I put online and it works really well and I have been very happy with it. I don't know of anybody who prefers sourceforge over github, though I can see why a well established project wouldn't switch since there are a lot of other things beside the source migration that are probably less trivial (forum, mailing list, etc.). I'll spend a few minutes and see how difficult it would be to convert from svn-sourceforge to git-github and report back. Luke |
From: Richard M. <mu...@cd...> - 2012-09-05 06:10:28
|
There hasn't been much conversation about this, but converting to git is probably the way to go in the long run (better functionality for distributed development). Sourceforge supports git and we can easily transfer projects from subversion to git: https://sourceforge.net/apps/trac/sourceforge/ticket/24534 I don't have much experience with github versus sourceforge in terms of the various features, and so don't have a strong preference beyond doing whatever works best for the people who are actively developing code for the library. -richard On 4 Sep 2012, at 22:58 , Dale Lukas Peterson <haz...@gm...> wrote: > Has there been any discussion of moving from svn to git? git is very > nice to work with, makes branching and merging seamless, and also > works nicely with sites like github.com, which offers a wiki, > pull-requests, lots of very nice online code review tools, and also > has a clever way to hosted a project website. I've been involved with > github.com for > 3 years and really like it. There are many high > quality projects on github and a very good user community. > > If there is interest, I could help with moving from svn to git. I > believe sourceforge offers git as an option now, so you could keep the > same project page if you didn't want to switch to github. > > Here is a little link comparing svn with git: > > https://git.wiki.kernel.org/index.php/GitSvnComparison > > Luke > > On Tue, Sep 4, 2012 at 9:51 PM, Richard Murray <mu...@cd...> wrote: >> You should have all gotten the message below about a new URL for the python-control source repository. The move occured because I upgraded to SourceForge 2.0, the new version of the software (based on the Allura platform). If you have a checkout of the old subversion repository, you should recheckout using the URL below. >> >> A couple of other updates: >> >> * SourceForge is going to be discontinued their hosted apps, which include the MediaWiki application that we are currently using. I'll be shifting the developer information off of that wiki onto the default SourceForge wiki. The one thing that won't transfer is the detailed VTOL example, since equations are not supported on the SF wiki. I've copied that information to my own wiki for now. >> >> * I'll be using python-control for our undergrad controls course at Caltech this fall, and will try to use that as a driver for updating various functions and adding in any missing capabilities. If you have requests for features you would like to see added, please send e-mail to this list or create a new feature request on the SourceForge page. >> >> -richard >> >> Begin forwarded message: >> >>> From: SourceForge.net <nor...@in...> >>> Subject: SourceForge Repo Clone Complete >>> Date: 2 September 2012 22:25:47 PDT >>> To: no...@in... >>> Reply-To: no...@in... >>> >>> Your cloned repository code in project python-control is now ready for use. >>> >>> Old repository url: http://python-control.svn.sourceforge.net/svnroot/python-control >>> >>> New repository checkout command: svn checkout --username=murrayrm svn+ssh://mur...@sv.../p/python-control/code/trunk python-control-code >>> >>> You and any other developers should do a fresh checkout using the new repository location. >>> >> >> >> ------------------------------------------------------------------------------ >> Live Security Virtual Conference >> Exclusive live event will cover all the ways today's security and >> threat landscape has changed and how IT managers can respond. Discussions >> will include endpoint security, mobile security and the latest in malware >> threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ >> _______________________________________________ >> python-control-discuss mailing list >> pyt...@li... >> https://lists.sourceforge.net/lists/listinfo/python-control-discuss > > > > -- > “People call me a perfectionist, but I'm not. I'm a rightist. I do > something until it's right, and then I move on to the next thing.” > ― James Cameron > > ------------------------------------------------------------------------------ > Live Security Virtual Conference > Exclusive live event will cover all the ways today's security and > threat landscape has changed and how IT managers can respond. Discussions > will include endpoint security, mobile security and the latest in malware > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ > _______________________________________________ > python-control-discuss mailing list > pyt...@li... > https://lists.sourceforge.net/lists/listinfo/python-control-discuss |
From: Dale L. P. <haz...@gm...> - 2012-09-05 05:59:01
|
Has there been any discussion of moving from svn to git? git is very nice to work with, makes branching and merging seamless, and also works nicely with sites like github.com, which offers a wiki, pull-requests, lots of very nice online code review tools, and also has a clever way to hosted a project website. I've been involved with github.com for > 3 years and really like it. There are many high quality projects on github and a very good user community. If there is interest, I could help with moving from svn to git. I believe sourceforge offers git as an option now, so you could keep the same project page if you didn't want to switch to github. Here is a little link comparing svn with git: https://git.wiki.kernel.org/index.php/GitSvnComparison Luke On Tue, Sep 4, 2012 at 9:51 PM, Richard Murray <mu...@cd...> wrote: > You should have all gotten the message below about a new URL for the python-control source repository. The move occured because I upgraded to SourceForge 2.0, the new version of the software (based on the Allura platform). If you have a checkout of the old subversion repository, you should recheckout using the URL below. > > A couple of other updates: > > * SourceForge is going to be discontinued their hosted apps, which include the MediaWiki application that we are currently using. I'll be shifting the developer information off of that wiki onto the default SourceForge wiki. The one thing that won't transfer is the detailed VTOL example, since equations are not supported on the SF wiki. I've copied that information to my own wiki for now. > > * I'll be using python-control for our undergrad controls course at Caltech this fall, and will try to use that as a driver for updating various functions and adding in any missing capabilities. If you have requests for features you would like to see added, please send e-mail to this list or create a new feature request on the SourceForge page. > > -richard > > Begin forwarded message: > >> From: SourceForge.net <nor...@in...> >> Subject: SourceForge Repo Clone Complete >> Date: 2 September 2012 22:25:47 PDT >> To: no...@in... >> Reply-To: no...@in... >> >> Your cloned repository code in project python-control is now ready for use. >> >> Old repository url: http://python-control.svn.sourceforge.net/svnroot/python-control >> >> New repository checkout command: svn checkout --username=murrayrm svn+ssh://mur...@sv.../p/python-control/code/trunk python-control-code >> >> You and any other developers should do a fresh checkout using the new repository location. >> > > > ------------------------------------------------------------------------------ > Live Security Virtual Conference > Exclusive live event will cover all the ways today's security and > threat landscape has changed and how IT managers can respond. Discussions > will include endpoint security, mobile security and the latest in malware > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ > _______________________________________________ > python-control-discuss mailing list > pyt...@li... > https://lists.sourceforge.net/lists/listinfo/python-control-discuss -- “People call me a perfectionist, but I'm not. I'm a rightist. I do something until it's right, and then I move on to the next thing.” ― James Cameron |
From: Richard M. <mu...@cd...> - 2012-09-05 04:51:11
|
You should have all gotten the message below about a new URL for the python-control source repository. The move occured because I upgraded to SourceForge 2.0, the new version of the software (based on the Allura platform). If you have a checkout of the old subversion repository, you should recheckout using the URL below. A couple of other updates: * SourceForge is going to be discontinued their hosted apps, which include the MediaWiki application that we are currently using. I'll be shifting the developer information off of that wiki onto the default SourceForge wiki. The one thing that won't transfer is the detailed VTOL example, since equations are not supported on the SF wiki. I've copied that information to my own wiki for now. * I'll be using python-control for our undergrad controls course at Caltech this fall, and will try to use that as a driver for updating various functions and adding in any missing capabilities. If you have requests for features you would like to see added, please send e-mail to this list or create a new feature request on the SourceForge page. -richard Begin forwarded message: > From: SourceForge.net <nor...@in...> > Subject: SourceForge Repo Clone Complete > Date: 2 September 2012 22:25:47 PDT > To: no...@in... > Reply-To: no...@in... > > Your cloned repository code in project python-control is now ready for use. > > Old repository url: http://python-control.svn.sourceforge.net/svnroot/python-control > > New repository checkout command: svn checkout --username=murrayrm svn+ssh://mur...@sv.../p/python-control/code/trunk python-control-code > > You and any other developers should do a fresh checkout using the new repository location. > |
From: <mur...@us...> - 2012-08-30 05:44:39
|
Revision: 185 http://python-control.svn.sourceforge.net/python-control/?rev=185&view=rev Author: murrayrm Date: 2012-08-30 05:44:32 +0000 (Thu, 30 Aug 2012) Log Message: ----------- * Fixed bug in statespace -> transfer function conversation in the way that complex conjugate pairs of poles with multiplicity > 1 were handled * Fixed bugs in tests/convert_test in the way that state space and transfer function conversions were tested; added tf to ss comparison * Replace nd.size() with len() in place() to fix bug reported by R. Bucher * See ChangeLog for more detailed descriptions Modified Paths: -------------- trunk/ChangeLog trunk/src/__init__.py trunk/src/matlab.py trunk/src/statefbk.py trunk/src/statesp.py trunk/src/xferfcn.py trunk/tests/convert_test.py trunk/tests/matlab_test.py Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2012-08-25 17:45:56 UTC (rev 184) +++ trunk/ChangeLog 2012-08-30 05:44:32 UTC (rev 185) @@ -1,5 +1,36 @@ +2012-08-29 Richard Murray <murray@altura.local> + + * src/xferfcn.py (TransferFunction._common_den): fixed up code for + case where poles have multiplicity > 1. Set end limits of check to + avoid overruning the list + combine complex conjugate pole pairs + from the outside in to prevent small errors from growing. + +2012-08-26 Richard Murray <murray@altura.local> + + * tests/convert_test.py (TestConvert.testConvert): replaced previous + test of transfer function coefficients with a frequency response + test. This is necessary because various degenerate conditions will + generate a situation where the transfer functions are of different + forms but still equal. Eg 0/1 = 1e-17 s + 1e-16 / (s^2 + s + 1). + Still getting errors, but looks like actual problem in conversion. + + * src/statesp.py (_mimo2siso): set default value for warn_conversion + to False + + * tests/convert_test.py (TestConvert.testConvert): Added check to + make sure that we don't create problems with uncontrollable or + unobservable systems. + 2012-08-25 Richard Murray <murray@altura.local> + * src/xferfcn.py (TransferFunction._common_den): identified bug in + the way that common denominators are computed; see comments in code + regarding complex conjugate pairs. + + * src/statefbk.py (place): repalced nd.size(placed_eigs) with + len(placed_eigs) to fix intermittent problems pointed out by Roberto + Bucher in control-0.3c. + * tests/rlocus_test.py (TestRootLocus.testRootLocus): added sort() to test to get rid of problems in which ordering was generating an error. Modified: trunk/src/__init__.py =================================================================== --- trunk/src/__init__.py 2012-08-25 17:45:56 UTC (rev 184) +++ trunk/src/__init__.py 2012-08-30 05:44:32 UTC (rev 185) @@ -74,9 +74,9 @@ from xferfcn import TransferFunction # Import some of the more common (and benign) MATLAB shortcuts +# By default, don't import conflicting commands here from matlab import ss, tf, ss2tf, tf2ss, drss from matlab import pole, zero, evalfr, freqresp, dcgain from matlab import nichols, rlocus, margin # bode and nyquist come directly from freqplot.py from matlab import step, impulse, initial, lsim - Modified: trunk/src/matlab.py =================================================================== --- trunk/src/matlab.py 2012-08-25 17:45:56 UTC (rev 184) +++ trunk/src/matlab.py 2012-08-30 05:44:32 UTC (rev 185) @@ -984,6 +984,7 @@ # Warn about unimplemented plotstyles #! TODO: remove this when plot styles are implemented in bode() + #! TODO: uncomment unit test code that tests this out if (len(plotstyle) != 0): print("Warning (matabl.bode): plot styles not implemented"); Modified: trunk/src/statefbk.py =================================================================== --- trunk/src/statefbk.py 2012-08-25 17:45:56 UTC (rev 184) +++ trunk/src/statefbk.py 2012-08-30 05:44:32 UTC (rev 185) @@ -93,7 +93,7 @@ # Call SLICOT routine to place the eigenvalues A_z,w,nfp,nap,nup,F,Z = \ - sb01bd(B_mat.shape[0], B_mat.shape[1], np.size(placed_eigs), alpha, + sb01bd(B_mat.shape[0], B_mat.shape[1], len(placed_eigs), alpha, A_mat, B_mat, placed_eigs, 'C'); # Return the gain matrix, with MATLAB gain convention Modified: trunk/src/statesp.py =================================================================== --- trunk/src/statesp.py 2012-08-25 17:45:56 UTC (rev 184) +++ trunk/src/statesp.py 2012-08-30 05:44:32 UTC (rev 185) @@ -472,7 +472,7 @@ index = [len(den) - 1 for i in range(sys.outputs)] # Repeat the common denominator along the rows. den = array([den for i in range(sys.outputs)]) - # TODO: transfer function to state space conversion is still buggy! + #! TODO: transfer function to state space conversion is still buggy! #print num #print shape(num) ssout = td04ad('R',sys.inputs, sys.outputs, index, den, num,tol=0.0) @@ -624,7 +624,7 @@ return StateSpace(A, B, C, D) # Convert a MIMO system to a SISO system -def _mimo2siso(sys, input, output, warn_conversion): +def _mimo2siso(sys, input, output, warn_conversion=False): #pylint: disable=W0622 """ Convert a MIMO system to a SISO system. (Convert a system with multiple Modified: trunk/src/xferfcn.py =================================================================== --- trunk/src/xferfcn.py 2012-08-25 17:45:56 UTC (rev 184) +++ trunk/src/xferfcn.py 2012-08-30 05:44:32 UTC (rev 185) @@ -638,14 +638,34 @@ if abs(poles[n].imag) > 10 * eps: # To prevent buildup of imaginary part error, handle complex # pole pairs together. - quad = polymul([1., -poles[n]], [1., -poles[n+1]]) - assert all(quad.imag < 10 * eps), \ - "The quadratic has a nontrivial imaginary part: %g" \ - % quad.imag.max() - quad = quad.real + # + # Because we might have repeated real parts of poles + # and the fact that we are using lexigraphical + # ordering, we can't just combine adjacent poles. + # Instead, we have to figure out the multiplicity + # first, then multiple the pairs from the outside in. - den = polymul(den, quad) - n += 2 + # Figure out the multiplicity + m = 1; # multiplicity count + while (n+m < len(poles) and + poles[n].real == poles[n+m].real and + poles[n].imag * poles[n+m].imag > 0): + m += 1 + + if (m > 1): + print "Found pole with multiplicity %d" % m + # print "Poles = ", poles + + # Multiple pairs from the outside in + for i in range(m): + quad = polymul([1., -poles[n]], [1., -poles[n+2*(m-i)-1]]) + assert all(quad.imag < 10 * eps), \ + "Quadratic has a nontrivial imaginary part: %g" \ + % quad.imag.max() + + den = polymul(den, quad.real) + n += 1 # move to next pair + n += m # skip past conjugate pairs else: den = polymul(den, [1., -poles[n].real]) n += 1 @@ -654,6 +674,7 @@ num = deepcopy(self.num) if isinstance(den,float): den = array([den]) + for i in range(self.outputs): for j in range(self.inputs): # The common denominator has leading coefficient 1. Scale out @@ -661,9 +682,11 @@ assert self.den[i][j][0], "The i = %i, j = %i denominator has \ a zero leading coefficient." % (i, j) num[i][j] = num[i][j] / self.den[i][j][0] + # Multiply in the missing poles. for p in missingpoles[i][j]: num[i][j] = polymul(num[i][j], [1., -p]) + # Pad all numerator polynomials with zeros so that the numerator arrays # are the same size as the denominator. for i in range(self.outputs): @@ -672,11 +695,12 @@ if(pad>0): num[i][j] = insert(num[i][j], zeros(pad), zeros(pad)) + # Finally, convert the numerator to a 3-D array. num = array(num) # Remove trivial imaginary parts. Check for nontrivial imaginary parts. if any(abs(num.imag) > sqrt(eps)): - print ("Warning: The numerator has a nontrivial nontrivial part: %g" + print ("Warning: The numerator has a nontrivial imaginary part: %g" % abs(num.imag).max()) num = num.real Modified: trunk/tests/convert_test.py =================================================================== --- trunk/tests/convert_test.py 2012-08-25 17:45:56 UTC (rev 184) +++ trunk/tests/convert_test.py 2012-08-30 05:44:32 UTC (rev 185) @@ -16,6 +16,7 @@ import unittest import numpy as np +import control import control.matlab as matlab class TestConvert(unittest.TestCase): @@ -27,9 +28,9 @@ # Number of times to run each of the randomized tests. self.numTests = 1 #almost guarantees failure # Maximum number of states to test + 1 - self.maxStates = 20 + self.maxStates = 4 # Maximum number of inputs and outputs to test + 1 - self.maxIO = 10 + self.maxIO = 5 # Set to True to print systems to the output. self.debug = False @@ -42,20 +43,35 @@ def testConvert(self): """Test state space to transfer function conversion.""" - #Currently it only tests that a TF->SS->TF generates an unchanged TF verbose = self.debug + from control.statesp import _mimo2siso #print __doc__ + # Machine precision for floats. + eps = np.finfo(float).eps + for states in range(1, self.maxStates): for inputs in range(1, self.maxIO): for outputs in range(1, self.maxIO): - #start with a random SS system and transform to TF - #then back to SS, check that the matrices are the same. + # start with a random SS system and transform to TF then + # back to SS, check that the matrices are the same. ssOriginal = matlab.rss(states, inputs, outputs) if (verbose): self.printSys(ssOriginal, 1) + # Make sure the system is not degenerate + Cmat = control.ctrb(ssOriginal.A, ssOriginal.B) + if (np.linalg.matrix_rank(Cmat) != states): + if (verbose): + print " skipping (not reachable)" + continue + Omat = control.obsv(ssOriginal.A, ssOriginal.C) + if (np.linalg.matrix_rank(Omat) != states): + if (verbose): + print " skipping (not observable)" + continue + tfOriginal = matlab.tf(ssOriginal) if (verbose): self.printSys(tfOriginal, 2) @@ -67,27 +83,77 @@ tfTransformed = matlab.tf(ssTransformed) if (verbose): self.printSys(tfTransformed, 4) - + + # Check to see if the state space systems have same dim + if (ssOriginal.states != ssTransformed.states): + print "WARNING: state space dimension mismatch: " + \ + "%d versus %d" % \ + (ssOriginal.states, ssTransformed.states) + + # Now make sure the frequency responses match + # Since bode() only handles SISO, go through each I/O pair + # For phase, take sine and cosine to avoid +/- 360 offset for inputNum in range(inputs): for outputNum in range(outputs): - np.testing.assert_array_almost_equal(\ - tfOriginal.num[outputNum][inputNum], \ - tfTransformed.num[outputNum][inputNum], \ - err_msg='numerator mismatch') + if (verbose): + print "Checking input %d, output %d" \ + % (inputNum, outputNum) + ssorig_mag, ssorig_phase, ssorig_omega = \ + control.bode(_mimo2siso(ssOriginal, \ + inputNum, outputNum), \ + deg=False, Plot=False) + ssorig_real = ssorig_mag * np.cos(ssorig_phase) + ssorig_imag = ssorig_mag * np.sin(ssorig_phase) + + # + # Make sure TF has same frequency response + # + num = tfOriginal.num[outputNum][inputNum] + den = tfOriginal.den[outputNum][inputNum] + tforig = control.tf(num, den) + + tforig_mag, tforig_phase, tforig_omega = \ + control.bode(tforig, ssorig_omega, \ + deg=False, Plot=False) + + tforig_real = tforig_mag * np.cos(tforig_phase) + tforig_imag = tforig_mag * np.sin(tforig_phase) + np.testing.assert_array_almost_equal( \ + ssorig_real, tforig_real) + np.testing.assert_array_almost_equal( \ + ssorig_imag, tforig_imag) + + # + # Make sure xform'd SS has same frequency response + # + ssxfrm_mag, ssxfrm_phase, ssxfrm_omega = \ + control.bode(_mimo2siso(ssTransformed, \ + inputNum, outputNum), \ + ssorig_omega, \ + deg=False, Plot=False) + ssxfrm_real = ssxfrm_mag * np.cos(ssxfrm_phase) + ssxfrm_imag = ssxfrm_mag * np.sin(ssxfrm_phase) + np.testing.assert_array_almost_equal( \ + ssorig_real, ssxfrm_real) + np.testing.assert_array_almost_equal( \ + ssorig_imag, ssxfrm_imag) + + # + # Make sure xform'd TF has same frequency response + # + num = tfTransformed.num[outputNum][inputNum] + den = tfTransformed.den[outputNum][inputNum] + tfxfrm = control.tf(num, den) + tfxfrm_mag, tfxfrm_phase, tfxfrm_omega = \ + control.bode(tfxfrm, ssorig_omega, \ + deg=False, Plot=False) - np.testing.assert_array_almost_equal(\ - tfOriginal.den[outputNum][inputNum], \ - tfTransformed.den[outputNum][inputNum], - err_msg='denominator mismatch') - - #To test the ss systems is harder because they aren't the same - #realization. This could be done with checking that they have the - #same freq response with bode, but apparently it doesn't work - #the way it should right now: - ## Bode should work like this: - #[mag,phase,freq]=bode(sys) - #it doesn't seem to...... - #This should be added. + tfxfrm_real = tfxfrm_mag * np.cos(tfxfrm_phase) + tfxfrm_imag = tfxfrm_mag * np.sin(tfxfrm_phase) + np.testing.assert_array_almost_equal( \ + ssorig_real, tfxfrm_real) + np.testing.assert_array_almost_equal( \ + ssorig_imag, tfxfrm_imag) def suite(): return unittest.TestLoader().loadTestsFromTestCase(TestConvert) Modified: trunk/tests/matlab_test.py =================================================================== --- trunk/tests/matlab_test.py 2012-08-25 17:45:56 UTC (rev 184) +++ trunk/tests/matlab_test.py 2012-08-30 05:44:32 UTC (rev 185) @@ -238,7 +238,8 @@ w = logspace(-3, 3); bode(self.siso_ss1, w) bode(self.siso_ss1, self.siso_tf2, w) - bode(self.siso_ss1, '-', self.siso_tf1, 'b--', self.siso_tf2, 'k.') +# Not yet implemented +# bode(self.siso_ss1, '-', self.siso_tf1, 'b--', self.siso_tf2, 'k.') def testRlocus(self): rlocus(self.siso_ss1) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mur...@us...> - 2012-08-25 17:46:02
|
Revision: 184 http://python-control.svn.sourceforge.net/python-control/?rev=184&view=rev Author: murrayrm Date: 2012-08-25 17:45:56 +0000 (Sat, 25 Aug 2012) Log Message: ----------- commiting missing unit test with fix for ordering differences Modified Paths: -------------- trunk/ChangeLog Added Paths: ----------- trunk/tests/rlocus_test.py Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2012-08-25 16:11:20 UTC (rev 183) +++ trunk/ChangeLog 2012-08-25 17:45:56 UTC (rev 184) @@ -1,3 +1,27 @@ +2012-08-25 Richard Murray <murray@altura.local> + + * tests/rlocus_test.py (TestRootLocus.testRootLocus): added sort() + to test to get rid of problems in which ordering was generating an + error. + + * src/freqplot.py (nyquist_plot): added code from Kevin Davies to + label frequency points in Nyquist plot + + * src/__init__.py: import non-conflicting MATLAB functions by default + + * src/freqplot.py (bode_plot, nyquist_plot): simplified code and + removed unneeded options. To set color, linestyle, etc use keywords + and pass to matplotlib. + +2012-08-24 Richard Murray <murray@altura.local> + + * src/freqplot.py: added in plot enhancements from Kevin Davies + (bode_plot): pass optional arguments and keywords to matplotlib + (get_pow1000): new function for determinine engineering exponent + (gen_prefix): new function to get SI prefix for power of 1000 + + * src/freqplot.py (bode_plot): removed extraneous phase_deg calculation + 2012-01-07 Richard Murray <murray@malabar.local> * doc/modules.rst: added new sections for analysis, synthesis, Added: trunk/tests/rlocus_test.py =================================================================== --- trunk/tests/rlocus_test.py (rev 0) +++ trunk/tests/rlocus_test.py 2012-08-25 17:45:56 UTC (rev 184) @@ -0,0 +1,38 @@ +#!/usr/bin/env python +# +# rlocus_test.py - unit test for root locus diagrams +# RMM, 1 Jul 2011 + +import unittest +import numpy as np +from control.rlocus import root_locus +from control.xferfcn import TransferFunction +from control.statesp import StateSpace +from control.bdalg import feedback + +class TestRootLocus(unittest.TestCase): + """These are tests for the feedback function in rlocus.py.""" + + def setUp(self): + """This contains some random LTI systems and scalars for testing.""" + + # Two random SISO systems. + self.sys1 = TransferFunction([1, 2], [1, 2, 3]) + self.sys2 = StateSpace([[1., 4.], [3., 2.]], [[1.], [-4.]], + [[1., 0.]], [[0.]]) + + def testRootLocus(self): + """Basic root locus plot""" + klist = [-1, 0, 1]; + rlist = root_locus(self.sys1, [-1, 0, 1], Plot=False) + + for k in klist: + np.testing.assert_array_almost_equal( + np.sort(rlist[k]), + np.sort(feedback(self.sys1, klist[k]).pole())) + +def suite(): + return unittest.TestLoader().loadTestsFromTestCase(TestRootLocus) + +if __name__ == "__main__": + unittest.main() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <mur...@us...> - 2012-08-25 16:11:26
|
Revision: 183 http://python-control.svn.sourceforge.net/python-control/?rev=183&view=rev Author: murrayrm Date: 2012-08-25 16:11:20 +0000 (Sat, 25 Aug 2012) Log Message: ----------- improvements to nyquist and bode plots Modified Paths: -------------- trunk/src/__init__.py trunk/src/freqplot.py Modified: trunk/src/__init__.py =================================================================== --- trunk/src/__init__.py 2012-02-15 06:25:15 UTC (rev 182) +++ trunk/src/__init__.py 2012-08-25 16:11:20 UTC (rev 183) @@ -72,3 +72,11 @@ from timeresp import forced_response, initial_response, step_response, \ impulse_response from xferfcn import TransferFunction + +# Import some of the more common (and benign) MATLAB shortcuts +from matlab import ss, tf, ss2tf, tf2ss, drss +from matlab import pole, zero, evalfr, freqresp, dcgain +from matlab import nichols, rlocus, margin + # bode and nyquist come directly from freqplot.py +from matlab import step, impulse, initial, lsim + Modified: trunk/src/freqplot.py =================================================================== --- trunk/src/freqplot.py 2012-02-15 06:25:15 UTC (rev 182) +++ trunk/src/freqplot.py 2012-08-25 16:11:20 UTC (rev 183) @@ -56,7 +56,7 @@ # Bode plot def bode_plot(syslist, omega=None, dB=False, Hz=False, deg=True, - color=None, Plot=True): + Plot=True, *args, **kwargs): """Bode plot for a system Plots a Bode plot for the system over a (optional) frequency range. @@ -71,12 +71,12 @@ If True, plot result in dB Hz : boolean If True, plot frequency in Hz (omega must be provided in rad/sec) - color : matplotlib color - Color of line in bode plot deg : boolean If True, return phase in degrees (else radians) Plot : boolean If True, plot magnitude and phase + *args, **kwargs: + Additional options to matplotlib (color, linestyle, etc) Returns ------- @@ -95,7 +95,6 @@ Examples -------- - >>> from matlab import ss >>> sys = ss("1. -2; 3. -4", "5.; 7", "6. 8", "9.") >>> mag, phase, omega = bode(sys) """ @@ -132,45 +131,28 @@ # Magnitude plot plt.subplot(211); if dB: - if color==None: - plt.semilogx(omega, mag) - else: - plt.semilogx(omega, mag, color=color) - plt.ylabel("Magnitude (dB)") + plt.semilogx(omega, mag, *args, **kwargs) else: - if color==None: - plt.loglog(omega, mag) - else: - plt.loglog(omega, mag, color=color) - plt.ylabel("Magnitude") + plt.loglog(omega, mag, *args, **kwargs) + plt.hold(True); - # Add a grid to the plot + # Add a grid to the plot + labeling plt.grid(True) plt.grid(True, which='minor') - plt.hold(True); + plt.ylabel("Magnitude (dB)" if dB else "Magnitude") # Phase plot plt.subplot(212); - if deg: - phase_deg = phase - else: - phase_deg = phase * 180 / sp.pi - if color==None: - plt.semilogx(omega, phase_deg) - else: - plt.semilogx(omega, phase_deg, color=color) - plt.hold(True) + plt.semilogx(omega, phase, *args, **kwargs) + plt.hold(True); - # Add a grid to the plot + # Add a grid to the plot + labeling plt.grid(True) plt.grid(True, which='minor') - plt.ylabel("Phase (deg)") + plt.ylabel("Phase (deg)" if deg else "Phase (rad)") # Label the frequency axis - if Hz: - plt.xlabel("Frequency (Hz)") - else: - plt.xlabel("Frequency (rad/sec)") + plt.xlabel("Frequency (Hz)" if Hz else "Frequency (rad/sec)") if len(syslist) == 1: return mags[0], phases[0], omegas[0] @@ -178,7 +160,8 @@ return mags, phases, omegas # Nyquist plot -def nyquist_plot(syslist, omega=None, Plot=True): +def nyquist_plot(syslist, omega=None, Plot=True, color='b', + labelFreq=0, *args, **kwargs): """Nyquist plot for a system Plots a Nyquist plot for the system over a (optional) frequency range. @@ -190,7 +173,11 @@ omega : freq_range Range of frequencies (list or bounds) in rad/sec Plot : boolean - if True, plot magnitude + If True, plot magnitude + labelFreq : int + Label every nth frequency on the plot + *args, **kwargs: + Additional options to matplotlib (color, linestyle, etc) Returns ------- @@ -203,7 +190,6 @@ Examples -------- - >>> from matlab import ss >>> sys = ss("1. -2; 3. -4", "5.; 7", "6. 8", "9.") >>> real, imag, freq = nyquist(sys) """ @@ -214,12 +200,14 @@ # Select a default range if none is provided if (omega == None): omega = default_frequency_range(syslist) + # Interpolate between wmin and wmax if a tuple or list are provided elif (isinstance(omega,list) | isinstance(omega,tuple)): # Only accept tuple or list of length 2 if (len(omega) != 2): raise ValueError("Supported frequency arguments are (wmin,wmax) tuple or list, or frequency vector. ") - omega = np.logspace(np.log10(omega[0]),np.log10(omega[1]),num=50,endpoint=True,base=10.0) + omega = np.logspace(np.log10(omega[0]), np.log10(omega[1]), + num=50, endpoint=True, base=10.0) for sys in syslist: if (sys.inputs > 1 or sys.outputs > 1): #TODO: Add MIMO nyquist plots. @@ -236,11 +224,33 @@ if (Plot): # Plot the primary curve and mirror image - plt.plot(x, y, '-'); - plt.plot(x, -y, '--'); + plt.plot(x, y, '-', color=color, *args, **kwargs); + plt.plot(x, -y, '--', color=color, *args, **kwargs); # Mark the -1 point plt.plot([-1], [0], 'r+') + # Label the frequencies of the points + if (labelFreq): + for xpt, ypt, omegapt in zip(x, y, omega)[::labelFreq]: + # Convert to Hz + f = omegapt/(2*sp.pi) + + # Factor out multiples of 1000 and limit the + # result to the range [-8, 8]. + pow1000 = max(min(get_pow1000(f),8),-8) + + # Get the SI prefix. + prefix = gen_prefix(pow1000) + + # Apply the text. (Use a space before the text to + # prevent overlap with the data.) + # + # np.round() is used because 0.99... appears + # instead of 1.0, and this would otherwise be + # truncated to 0. + plt.text(xpt, ypt, + ' ' + str(int(np.round(f/1000**pow1000, 0))) + + ' ' + prefix + 'Hz') return x, y, omega # Gang of Four @@ -362,6 +372,49 @@ return omega +# +# KLD 5/23/11: Two functions to create nice looking labels +# +def get_pow1000(num): + '''Determine the exponent for which the significand of a number is within the + range [1, 1000). + ''' + # Based on algorithm from http://www.mail-archive.com/mat...@li.../msg14433.html, accessed 2010/11/7 + # by Jason Heeris 2009/11/18 + from decimal import Decimal + from math import floor + dnum = Decimal(str(num)) + if dnum == 0: + return 0 + elif dnum < 0: + dnum = -dnum + return int(floor(dnum.log10()/3)) + +def gen_prefix(pow1000): + '''Return the SI prefix for a power of 1000. + ''' + # Prefixes according to Table 5 of [BIPM 2006] (excluding hecto, + # deca, deci, and centi). + if pow1000 < -8 or pow1000 > 8: + raise ValueError("Value is out of the range covered by the SI prefixes.") + return ['Y', # yotta (10^24) + 'Z', # zetta (10^21) + 'E', # exa (10^18) + 'P', # peta (10^15) + 'T', # tera (10^12) + 'G', # giga (10^9) + 'M', # mega (10^6) + 'k', # kilo (10^3) + '', # (10^0) + 'm', # milli (10^-3) + r'$\mu$', # micro (10^-6) + 'n', # nano (10^-9) + 'p', # pico (10^-12) + 'f', # femto (10^-15) + 'a', # atto (10^-18) + 'z', # zepto (10^-21) + 'y'][8 - pow1000] # yocto (10^-24) + # Function aliases bode = bode_plot nyquist = nyquist_plot This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: Scott C. L. <sli...@ca...> - 2012-04-03 15:07:39
|
On 3 Apr 2012, at 07:32, Richard Murray wrote: >> src does not exist ? Perhaps from a different Python installation >> package. >> >> I am using Python2.7 on a Mac. >> I installed Pythons using fonnesbeck-ScipySuperpack-fb2fc07 . >> >> I believe that I have installed scipy, numpy and matplotlib, and other >> items in the package. >> >> Perhaps more detailed instruction for control-Python might assist me. In your debugging effort, first make sure that you are invoking the correct Python binary by looking at $ which -a python To see the details of the installation process, call Python with the "-v" flag (for "verbose"). I suggest redirecting to a plain text file so that you can grep for keywords. E.g., $ sudo python -v setup.py install > foo.txt 2>&1 $ grep -i numpy foo.txt ~Scott |
From: Richard M. <mu...@cd...> - 2012-04-03 14:33:04
|
Strange. Here's what I got running this on a Mac running 10.7.3: > (malabar18) tar xf control-0.5b.tar.gz > (malabar19) cd control-0.5b > (malabar20) sudo python setup.py install > Password: > running install > running bdist_egg > running egg_info > writing control.egg-info/PKG-INFO > writing top-level names to control.egg-info/top_level.txt > writing dependency_links to control.egg-info/dependency_links.txt > reading manifest file 'control.egg-info/SOURCES.txt' > reading manifest template 'MANIFEST.in' > writing manifest file 'control.egg-info/SOURCES.txt' > installing library code to build/bdist.macosx-10.7-x86_64/egg > running install_lib > running build_py > creating build > creating build/lib > creating build/lib/control > copying src/__init__.py -> build/lib/control > copying src/bdalg.py -> build/lib/control > copying src/ctrlutil.py -> build/lib/control > copying src/delay.py -> build/lib/control > copying src/exception.py -> build/lib/control > copying src/freqplot.py -> build/lib/control > copying src/lti.py -> build/lib/control > copying src/margins.py -> build/lib/control > copying src/mateqn.py -> build/lib/control > copying src/matlab.py -> build/lib/control > copying src/modelsimp.py -> build/lib/control > copying src/nichols.py -> build/lib/control > copying src/phaseplot.py -> build/lib/control > copying src/pzmap.py -> build/lib/control > copying src/rlocus.py -> build/lib/control > copying src/robust.py -> build/lib/control > copying src/statefbk.py -> build/lib/control > copying src/statesp.py -> build/lib/control > copying src/test.py -> build/lib/control > copying src/timeresp.py -> build/lib/control > copying src/xferfcn.py -> build/lib/control > creating build/bdist.macosx-10.7-x86_64 > creating build/bdist.macosx-10.7-x86_64/egg > creating build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/__init__.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/bdalg.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/ctrlutil.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/delay.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/exception.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/freqplot.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/lti.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/margins.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/mateqn.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/matlab.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/modelsimp.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/nichols.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/phaseplot.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/pzmap.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/rlocus.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/robust.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/statefbk.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/statesp.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/test.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/timeresp.py -> build/bdist.macosx-10.7-x86_64/egg/control > copying build/lib/control/xferfcn.py -> build/bdist.macosx-10.7-x86_64/egg/control > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/__init__.py to __init__.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/bdalg.py to bdalg.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/ctrlutil.py to ctrlutil.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/delay.py to delay.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/exception.py to exception.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/freqplot.py to freqplot.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/lti.py to lti.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/margins.py to margins.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/mateqn.py to mateqn.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/matlab.py to matlab.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/modelsimp.py to modelsimp.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/nichols.py to nichols.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/phaseplot.py to phaseplot.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/pzmap.py to pzmap.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/rlocus.py to rlocus.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/robust.py to robust.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/statefbk.py to statefbk.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/statesp.py to statesp.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/test.py to test.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/timeresp.py to timeresp.pyc > byte-compiling build/bdist.macosx-10.7-x86_64/egg/control/xferfcn.py to xferfcn.pyc > creating build/bdist.macosx-10.7-x86_64/egg/EGG-INFO > copying control.egg-info/PKG-INFO -> build/bdist.macosx-10.7-x86_64/egg/EGG-INFO > copying control.egg-info/SOURCES.txt -> build/bdist.macosx-10.7-x86_64/egg/EGG-INFO > copying control.egg-info/dependency_links.txt -> build/bdist.macosx-10.7-x86_64/egg/EGG-INFO > copying control.egg-info/top_level.txt -> build/bdist.macosx-10.7-x86_64/egg/EGG-INFO > zip_safe flag not set; analyzing archive contents... > creating dist > creating 'dist/control-0.5b-py2.7.egg' and adding 'build/bdist.macosx-10.7-x86_64/egg' to it > removing 'build/bdist.macosx-10.7-x86_64/egg' (and everything under it) > Processing control-0.5b-py2.7.egg > creating /sw/lib/python2.7/site-packages/control-0.5b-py2.7.egg > Extracting control-0.5b-py2.7.egg to /sw/lib/python2.7/site-packages > Adding control 0.5b to easy-install.pth file > > Installed /sw/lib/python2.7/site-packages/control-0.5b-py2.7.egg > Processing dependencies for control==0.5b > Finished processing dependencies for control==0.5b Which version of the package did you download? -richard On 2 Apr 2012, at 11:31 , Alan Zinober wrote: > > To install control-Python Ryan Krauss advised me to type: > > sudo python setup.py install > > in Terminal on my Mac. > > I obtain: > > Python2012 alanzinober$ sudo python setup.py install > Password: > running install > running bdist_egg > running egg_info > writing control.egg-info/PKG-INFO > writing top-level names to control.egg-info/top_level.txt > writing dependency_links to control.egg-info/dependency_links.txt > error: package directory 'src' does not exist > unknown-78-ca-39-b1-18-cf:Python2012 alanzinober$ > > src does not exist ? Perhaps from a different Python installation > package. > > I am using Python2.7 on a Mac. > I installed Pythons using fonnesbeck-ScipySuperpack-fb2fc07 . > > I believe that I have installed scipy, numpy and matplotlib, and other > items in the package. > > Perhaps more detailed instruction for control-Python might assist me. > > Alan > > -- > Sent from my MacBook Pro > > ------------------------------------------------------------------------------ > Better than sec? Nothing is better than sec when it comes to > monitoring Big Data applications. Try Boundary one-second > resolution app monitoring today. Free. > http://p.sf.net/sfu/Boundary-dev2dev > _______________________________________________ > python-control-discuss mailing list > pyt...@li... > https://lists.sourceforge.net/lists/listinfo/python-control-discuss |