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: <kk...@us...> - 2011-02-08 22:19:29
|
Revision: 116 http://python-control.svn.sourceforge.net/python-control/?rev=116&view=rev Author: kkchen Date: 2011-02-08 22:19:23 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Upgraded the testing further to avoid manually updates I changed some things in test.py and the individual tests. In test.py, in no circumstance do you need to add the test modules manually. It finds them itself based on their name. I made some of the tests more unittest-oriented as well but a lot still to be done on that. bb...@ra... Modified Paths: -------------- branches/control-0.4a/src/TestConvert.py branches/control-0.4a/src/TestFreqRsp.py branches/control-0.4a/src/TestModelsimp.py branches/control-0.4a/src/TestStatefbk.py branches/control-0.4a/src/test.py Modified: branches/control-0.4a/src/TestConvert.py =================================================================== --- branches/control-0.4a/src/TestConvert.py 2011-02-08 22:19:18 UTC (rev 115) +++ branches/control-0.4a/src/TestConvert.py 2011-02-08 22:19:23 UTC (rev 116) @@ -25,13 +25,13 @@ """Set up testing parameters.""" # Number of times to run each of the randomized tests. - self.numTests = 10 + self.numTests = 10 #almost guarantees failure # Maximum number of states to test + 1 - self.maxStates = 3 + self.maxStates = 20 # Maximum number of inputs and outputs to test + 1 - self.maxIO = 3 + self.maxIO = 20 # Set to True to print systems to the output. - self.debug = True + self.debug = False def printSys(self, sys, ind): """Print system to the standard output.""" @@ -42,23 +42,47 @@ def testConvert(self): """Test state space to transfer function conversion.""" + #Currently it only tests that a TF->SS->TF generates an unchanged TF - print __doc__ + #print __doc__ for states in range(1, self.maxStates): for inputs in range(1, self.maxIO): for outputs in range(1, self.maxIO): - sys1 = matlab.rss(states, inputs, outputs) - self.printSys(sys1, 1) + #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) + self.printSys(ssOriginal, 1) - sys2 = matlab.tf(sys1) - self.printSys(sys2, 2) - - sys3 = matlab.ss(sys2) - self.printSys(sys3, 3) + tfOriginal = matlab.tf(ssOriginal) + self.printSys(tfOriginal, 2) + + ssTransformed = matlab.ss(tfOriginal) + self.printSys(ssTransformed, 3) - sys4 = matlab.tf(sys3) - self.printSys(sys4, 4) + tfTransformed = matlab.tf(ssTransformed) + self.printSys(tfTransformed, 4) + + for inputNum in range(inputs): + for outputNum in range(outputs): + np.testing.assert_array_almost_equal(\ + tfOriginal.num[outputNum][inputNum],\ + tfTransformed.num[outputNum][inputNum]) + + np.testing.assert_array_almost_equal(\ + tfOriginal.den[outputNum][inputNum],\ + tfTransformed.den[outputNum][inputNum]) + + #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. + + def suite(): return unittest.TestLoader().loadTestsFromTestCase(TestConvert) Modified: branches/control-0.4a/src/TestFreqRsp.py =================================================================== --- branches/control-0.4a/src/TestFreqRsp.py 2011-02-08 22:19:18 UTC (rev 115) +++ branches/control-0.4a/src/TestFreqRsp.py 2011-02-08 22:19:23 UTC (rev 116) @@ -56,5 +56,8 @@ #plt.figure(4) #bode(sysMIMO,omega) + def suite(): - return unittest.TestLoader().loadTestsFromTestCase(TestConvert) + pass + #Uncomment this once it is a real unittest + #return unittest.TestLoader().loadTestsFromTestCase(TestFreqRsp) Modified: branches/control-0.4a/src/TestModelsimp.py =================================================================== --- branches/control-0.4a/src/TestModelsimp.py 2011-02-08 22:19:18 UTC (rev 115) +++ branches/control-0.4a/src/TestModelsimp.py 2011-02-08 22:19:23 UTC (rev 116) @@ -88,6 +88,8 @@ np.testing.assert_array_almost_equal(rsys.C, Crtrue,decimal=4) np.testing.assert_array_almost_equal(rsys.D, Drtrue,decimal=4) +def suite(): + return unittest.TestLoader().loadTestsFromTestCase(TestModelsimp) if __name__ == '__main__': Modified: branches/control-0.4a/src/TestStatefbk.py =================================================================== --- branches/control-0.4a/src/TestStatefbk.py 2011-02-08 22:19:18 UTC (rev 115) +++ branches/control-0.4a/src/TestStatefbk.py 2011-02-08 22:19:23 UTC (rev 116) @@ -80,5 +80,9 @@ self.assertRaises(ValueError, gram, sys, 'o') self.assertRaises(ValueError, gram, sys, 'c') +def suite(): + return unittest.TestLoader().loadTestsFromTestCase(TestStatefbk) + + if __name__ == '__main__': unittest.main() Modified: branches/control-0.4a/src/test.py =================================================================== --- branches/control-0.4a/src/test.py 2011-02-08 22:19:18 UTC (rev 115) +++ branches/control-0.4a/src/test.py 2011-02-08 22:19:23 UTC (rev 116) @@ -17,6 +17,45 @@ print SP.Popen(['./'+test],stdout=SP.PIPE).communicate()[0] print 'Completed',test + +############################################################################### + +def getFileList(dir,fileExtension=''): + """ Finds all files in the given directory that have the given file extension""" + filesRaw = SP.Popen(['ls',dir],stdout=SP.PIPE).communicate()[0] + #files separated by endlines + filename= '' + fileList=[] + #print 'filesRaw is ',filesRaw + for c in filesRaw: + if c!='\n': + filename+=c + else: #completed file name + if fileExtension != '' and filename[-len(fileExtension):] == fileExtension: + fileList.append(filename) + else: + pass #fileList.append(dir+filename) + filename='' + return fileList + +############################################################################### + + +def findTests(testdir='./'): + """Since python <2.7 doesn't have test discovery, this finds tests in the + provided directory. The default is to check the current directory. Any files + that match test* or Test* are considered unittest modules and checked for + a module.suite() function (in tests()).""" + fileList = getFileList(testdir,fileExtension='.py') + testModules= [] + for fileName in fileList: + if (fileName[:4] =='test' or fileName[:4]=='Test') and fileName!='test.py': + testModules.append(fileName[:-len('.py')]) + return testModules + +############################################################################### + + def tests(): import unittest try: #auto test discovery is only implemented in python 2.7+ @@ -43,21 +82,29 @@ print 'Tests may be incomplete' t=unittest.TextTestRunner() - - testModules = ['TestBDAlg','TestConvert','TestFreqRsp','TestMatlab','TestModelsimp',\ - 'TestStateSp','TestStatefbk','TestXferFcn'] #add additional tests here, or discovery? + + testModules = findTests() + suite = unittest.TestSuite() + suiteList=[] for mod in testModules: exec('import '+mod+' as currentModule') - print 'TEST',mod - suite = currentModule.suite() - t.run(suite) #After tests have been debugged and made into unittests, remove #the above (except the import) and replace with something like this: - #suiteList.append(ts.suite()) - #alltests = unittest.TestSuite(suiteList) - #t.run(alltests) - + try: + currentSuite = currentModule.suite() + if isinstance(currentSuite,unittest.TestSuite): + suiteList.append(currentModule.suite()) + else: + print mod+'.suite() doesnt return a unittest.TestSuite!, please fix!' + except: + print 'The test module '+mod+' doesnt have '+\ + 'a proper suite() function that returns a unittest.TestSuite object'+\ + ' Please fix this!' + alltests = unittest.TestSuite(suiteList) + t.run(unittest.TestSuite(alltests)) + +############################################################################### if __name__=='__main__': tests() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:19:23
|
Revision: 115 http://python-control.svn.sourceforge.net/python-control/?rev=115&view=rev Author: kkchen Date: 2011-02-08 22:19:18 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Changed warning message for td04ad Lauren Padilla <lpa...@pr...> Modified Paths: -------------- branches/control-0.4a/src/statesp.py Modified: branches/control-0.4a/src/statesp.py =================================================================== --- branches/control-0.4a/src/statesp.py 2011-02-08 22:19:13 UTC (rev 114) +++ branches/control-0.4a/src/statesp.py 2011-02-08 22:19:18 UTC (rev 115) @@ -455,7 +455,7 @@ den = array([den for i in range(sys.outputs)]) # TODO: transfer function to state space conversion is still buggy! print "Warning: transfer function to state space conversion by td04ad \ -is still buggy!" +is still buggy! Advise converting state space sys back to tf to verify the transformation was correct." #print num #print shape(num) ssout = td04ad(sys.inputs, sys.outputs, index, den, num) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:19:20
|
Revision: 114 http://python-control.svn.sourceforge.net/python-control/?rev=114&view=rev Author: kkchen Date: 2011-02-08 22:19:13 +0000 (Tue, 08 Feb 2011) Log Message: ----------- merging changes bb...@ra... Modified Paths: -------------- branches/control-0.4a/examples/pvtol-lqr.py branches/control-0.4a/examples/pvtol-nested-ss.py branches/control-0.4a/examples/pvtol-nested.py branches/control-0.4a/examples/secord-matlab.py branches/control-0.4a/examples/slicot-test.py branches/control-0.4a/src/freqplot.py branches/control-0.4a/src/pzmap.py branches/control-0.4a/src/statesp.py branches/control-0.4a/src/xferfcn.py Modified: branches/control-0.4a/examples/pvtol-lqr.py =================================================================== --- branches/control-0.4a/examples/pvtol-lqr.py 2011-02-08 22:19:07 UTC (rev 113) +++ branches/control-0.4a/examples/pvtol-lqr.py 2011-02-08 22:19:13 UTC (rev 114) @@ -119,7 +119,7 @@ subplot(221); title("Identity weights") # plot(T, Y[:,1, 1], '-', T, Y[:,2, 2], '--'); hold(True); -plot(Tx, Yx[0,:].T, '-', Ty, Yy[0,:].T, '--'); hold(True); +plot(Tx.T, Yx[0,:].T, '-', Ty.T, Yy[0,:].T, '--'); hold(True); plot([0, 10], [1, 1], 'k-'); hold(True); axis([0, 10, -0.1, 1.4]); @@ -141,9 +141,9 @@ [T3, Y3] = step(H1cx, T=linspace(0,10,100)); subplot(222); title("Effect of input weights") -plot(T1, Y1[0,:].T, 'b-'); hold(True); -plot(T2, Y2[0,:].T, 'b-'); hold(True); -plot(T3, Y3[0,:].T, 'b-'); hold(True); +plot(T1.T, Y1[0,:].T, 'b-'); hold(True); +plot(T2.T, Y2[0,:].T, 'b-'); hold(True); +plot(T3.T, Y3[0,:].T, 'b-'); hold(True); plot([0 ,10], [1, 1], 'k-'); hold(True); axis([0, 10, -0.1, 1.4]); @@ -162,7 +162,7 @@ subplot(223); title("Output weighting") [T2x, Y2x] = step(H2x, T=linspace(0,10,100)); [T2y, Y2y] = step(H2y, T=linspace(0,10,100)); -plot(T2x, Y2x[0,:].T, T2y, Y2y[0,:].T) +plot(T2x.T, Y2x[0,:].T, T2y.T, Y2y[0,:].T) ylabel('position'); xlabel('time'); ylabel('position'); legend(('x', 'y'), loc='lower right'); @@ -185,7 +185,7 @@ # step(H3x, H3y, 10); [T3x, Y3x] = step(H3x, T=linspace(0,10,100)); [T3y, Y3y] = step(H3y, T=linspace(0,10,100)); -plot(T3x, Y3x[0,:].T, T3y, Y3y[0,:].T) +plot(T3x.T, Y3x[0,:].T, T3y.T, Y3y[0,:].T) title("Physically motivated weights") xlabel('time'); legend(('x', 'y'), loc='lower right'); Modified: branches/control-0.4a/examples/pvtol-nested-ss.py =================================================================== --- branches/control-0.4a/examples/pvtol-nested-ss.py 2011-02-08 22:19:07 UTC (rev 113) +++ branches/control-0.4a/examples/pvtol-nested-ss.py 2011-02-08 22:19:13 UTC (rev 114) @@ -10,6 +10,7 @@ from matplotlib.pyplot import * # Grab MATLAB plotting functions from control.matlab import * # MATLAB-like functions +import numpy as np # System parameters m = 4; # mass of aircraft @@ -107,7 +108,7 @@ subplot(phaseh); semilogx([10^-4, 10^3], [-180, -180], 'k-') hold(True); -semilogx(w, phase, 'b-') +semilogx(w, np.squeeze(phase), 'b-') axis([10^-4, 10^3, -360, 0]); xlabel('Frequency [deg]'); ylabel('Phase [deg]'); # set(gca, 'YTick', [-360, -270, -180, -90, 0]); @@ -144,14 +145,15 @@ figure(9); (Tvec, Yvec) = step(T, None, linspace(1, 20)); -plot(Tvec, Yvec); hold(True); +plot(Tvec.T, Yvec.T); hold(True); (Tvec, Yvec) = step(Co*S, None, linspace(1, 20)); -plot(Tvec, Yvec); +plot(Tvec.T, Yvec.T); +#TODO: PZmap for statespace systems has not yet been implemented. figure(10); clf(); -(P, Z) = pzmap(T, Plot=True) -print "Closed loop poles and zeros: ", P, Z +#(P, Z) = pzmap(T, Plot=True) +#print "Closed loop poles and zeros: ", P, Z # Gang of Four figure(11); clf(); Modified: branches/control-0.4a/examples/pvtol-nested.py =================================================================== --- branches/control-0.4a/examples/pvtol-nested.py 2011-02-08 22:19:07 UTC (rev 113) +++ branches/control-0.4a/examples/pvtol-nested.py 2011-02-08 22:19:13 UTC (rev 114) @@ -10,6 +10,7 @@ from matplotlib.pyplot import * # Grab MATLAB plotting functions from control.matlab import * # MATLAB-like functions +import numpy as np # System parameters m = 4; # mass of aircraft @@ -23,8 +24,8 @@ Po = tf([1], [m, c, 0]); # outer loop (position) # Use state space versions -# Pi = tf2ss(Pi); -# Po = tf2ss(Po); +Pi = tf2ss(Pi); +Po = tf2ss(Po); # # Inner loop control design @@ -97,7 +98,7 @@ subplot(phaseh); semilogx([10^-4, 10^3], [-180, -180], 'k-') hold(True); -semilogx(w, phase, 'b-') +semilogx(w, np.squeeze(phase), 'b-') axis([10^-4, 10^3, -360, 0]); xlabel('Frequency [deg]'); ylabel('Phase [deg]'); # set(gca, 'YTick', [-360, -270, -180, -90, 0]); @@ -134,10 +135,10 @@ figure(9); (Tvec, Yvec) = step(T, None, linspace(1, 20)); -plot(Tvec, Yvec); hold(True); +plot(Tvec.T, Yvec.T); hold(True); (Tvec, Yvec) = step(Co*S, None, linspace(1, 20)); -plot(Tvec, Yvec); +plot(Tvec.T, Yvec.T); figure(10); clf(); (P, Z) = pzmap(T, Plot=True) Modified: branches/control-0.4a/examples/secord-matlab.py =================================================================== --- branches/control-0.4a/examples/secord-matlab.py 2011-02-08 22:19:07 UTC (rev 113) +++ branches/control-0.4a/examples/secord-matlab.py 2011-02-08 22:19:13 UTC (rev 114) @@ -18,7 +18,7 @@ # Step response for the system figure(1) T, yout = step(sys) -plot(T, yout) +plot(T.T, yout.T) # Bode plot for the system figure(2) Modified: branches/control-0.4a/examples/slicot-test.py =================================================================== --- branches/control-0.4a/examples/slicot-test.py 2011-02-08 22:19:07 UTC (rev 113) +++ branches/control-0.4a/examples/slicot-test.py 2011-02-08 22:19:13 UTC (rev 114) @@ -17,7 +17,7 @@ sys = ss(A, B, C, 0); # Eigenvalue placement -from slycot import sb01bd +#from slycot import sb01bd K = place(A, B, [-3, -2, -1]) print "Pole place: K = ", K print "Pole place: eigs = ", np.linalg.eig(A - B * K)[0] Modified: branches/control-0.4a/src/freqplot.py =================================================================== --- branches/control-0.4a/src/freqplot.py 2011-02-08 22:19:07 UTC (rev 113) +++ branches/control-0.4a/src/freqplot.py 2011-02-08 22:19:13 UTC (rev 114) @@ -177,7 +177,12 @@ # 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) for sys in syslist: if (sys.inputs > 1 or sys.outputs > 1): #TODO: Add MIMO nyquist plots. Modified: branches/control-0.4a/src/pzmap.py =================================================================== --- branches/control-0.4a/src/pzmap.py 2011-02-08 22:19:07 UTC (rev 113) +++ branches/control-0.4a/src/pzmap.py 2011-02-08 22:19:13 UTC (rev 114) @@ -42,6 +42,7 @@ import matplotlib.pyplot as plt import scipy as sp +import numpy as np import xferfcn # Compute poles and zeros for a system @@ -49,10 +50,10 @@ def pzmap(sys, Plot=True): """Plot a pole/zero map for a transfer function""" if (isinstance(sys, xferfcn.TransferFunction)): - poles = sp.roots(sys.den); - zeros = sp.roots(sys.num); + poles = sp.roots(np.squeeze(np.asarray(sys.den))); + zeros = sp.roots(np.squeeze(np.asarray(sys.num))); else: - raise TypeException + raise NotImplementedError("pzmap not implemented for state space systems yet.") if (Plot): # Plot the locations of the poles and zeros Modified: branches/control-0.4a/src/statesp.py =================================================================== --- branches/control-0.4a/src/statesp.py 2011-02-08 22:19:07 UTC (rev 113) +++ branches/control-0.4a/src/statesp.py 2011-02-08 22:19:13 UTC (rev 114) @@ -73,7 +73,7 @@ """ from numpy import all, angle, any, array, concatenate, cos, delete, dot, \ - empty, exp, eye, matrix, ones, pi, poly, poly1d, roots, sin, zeros + empty, exp, eye, matrix, ones, pi, poly, poly1d, roots, shape, sin, zeros from numpy.random import rand, randn from numpy.linalg import inv, det, solve from numpy.linalg.linalg import LinAlgError @@ -456,6 +456,8 @@ # TODO: transfer function to state space conversion is still buggy! print "Warning: transfer function to state space conversion by td04ad \ is still buggy!" + #print num + #print shape(num) ssout = td04ad(sys.inputs, sys.outputs, index, den, num) states = ssout[0] Modified: branches/control-0.4a/src/xferfcn.py =================================================================== --- branches/control-0.4a/src/xferfcn.py 2011-02-08 22:19:07 UTC (rev 113) +++ branches/control-0.4a/src/xferfcn.py 2011-02-08 22:19:13 UTC (rev 114) @@ -344,14 +344,14 @@ def __div__(self, other): """Divide two LTI objects.""" + # Convert the second argument to a transfer function. + other = _convertToTransferFunction(other) + if (self.inputs > 1 or self.outputs > 1 or other.inputs > 1 or other.outputs > 1): raise NotImplementedError("TransferFunction.__div__ is currently \ implemented only for SISO systems.") - # Convert the second argument to a transfer function. - other = _convertToTransferFunction(other) - num = polymul(self.num[0][0], other.den[0][0]) den = polymul(self.den[0][0], other.num[0][0]) @@ -487,8 +487,9 @@ computes the single denominator containing all the poles of sys.den, and reports it as the array d. The output numerator array n is modified to - use the common denominator. It is an sys.outputs-by-sys.inputs-by- - [something] array. + use the common denominator; the coefficient arrays are also padded with + zeros to be the same size as d. n is an sys.outputs-by-sys.inputs-by- + len(d) array. """ @@ -588,16 +589,12 @@ # Multiply in the missing poles. for p in missingpoles[i][j]: num[i][j] = polymul(num[i][j], [1., -p]) - # Find the largest numerator polynomial size. - largest = 0 + # Pad all numerator polynomials with zeros so that the numerator arrays + # are the same size as the denominator. for i in range(self.outputs): for j in range(self.inputs): - largest = max(largest, len(num[i][j])) - # Pad all smaller numerator polynomials with zeros. - for i in range(self.outputs): - for j in range(self.inputs): - num[i][j] = insert(num[i][j], zeros(largest - len(num[i][j])), - zeros(largest - len(num[i][j]))) + num[i][j] = insert(num[i][j], zeros(len(den) - len(num[i][j])), + zeros(len(den) - len(num[i][j]))) # Finally, convert the numerator to a 3-D array. num = array(num) # Remove trivial imaginary parts. Check for nontrivial imaginary parts. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:19:13
|
Revision: 113 http://python-control.svn.sourceforge.net/python-control/?rev=113&view=rev Author: kkchen Date: 2011-02-08 22:19:07 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Updated test.py to be in repository I forgot to hg add test.py last time, oops. Made a few other minor edits, removing some duplicate code with "execs" in test.py for python versions <2.7 bb...@ra... Modified Paths: -------------- branches/control-0.4a/examples/pvtol-lqr.py branches/control-0.4a/examples/pvtol-nested-ss.py branches/control-0.4a/examples/pvtol-nested.py branches/control-0.4a/examples/secord-matlab.py branches/control-0.4a/examples/slicot-test.py branches/control-0.4a/src/freqplot.py branches/control-0.4a/src/pzmap.py branches/control-0.4a/src/statesp.py branches/control-0.4a/src/xferfcn.py Added Paths: ----------- branches/control-0.4a/src/test.py Modified: branches/control-0.4a/examples/pvtol-lqr.py =================================================================== --- branches/control-0.4a/examples/pvtol-lqr.py 2011-02-08 22:18:58 UTC (rev 112) +++ branches/control-0.4a/examples/pvtol-lqr.py 2011-02-08 22:19:07 UTC (rev 113) @@ -119,7 +119,7 @@ subplot(221); title("Identity weights") # plot(T, Y[:,1, 1], '-', T, Y[:,2, 2], '--'); hold(True); -plot(Tx.T, Yx[0,:].T, '-', Ty.T, Yy[0,:].T, '--'); hold(True); +plot(Tx, Yx[0,:].T, '-', Ty, Yy[0,:].T, '--'); hold(True); plot([0, 10], [1, 1], 'k-'); hold(True); axis([0, 10, -0.1, 1.4]); @@ -141,9 +141,9 @@ [T3, Y3] = step(H1cx, T=linspace(0,10,100)); subplot(222); title("Effect of input weights") -plot(T1.T, Y1[0,:].T, 'b-'); hold(True); -plot(T2.T, Y2[0,:].T, 'b-'); hold(True); -plot(T3.T, Y3[0,:].T, 'b-'); hold(True); +plot(T1, Y1[0,:].T, 'b-'); hold(True); +plot(T2, Y2[0,:].T, 'b-'); hold(True); +plot(T3, Y3[0,:].T, 'b-'); hold(True); plot([0 ,10], [1, 1], 'k-'); hold(True); axis([0, 10, -0.1, 1.4]); @@ -162,7 +162,7 @@ subplot(223); title("Output weighting") [T2x, Y2x] = step(H2x, T=linspace(0,10,100)); [T2y, Y2y] = step(H2y, T=linspace(0,10,100)); -plot(T2x.T, Y2x[0,:].T, T2y.T, Y2y[0,:].T) +plot(T2x, Y2x[0,:].T, T2y, Y2y[0,:].T) ylabel('position'); xlabel('time'); ylabel('position'); legend(('x', 'y'), loc='lower right'); @@ -185,7 +185,7 @@ # step(H3x, H3y, 10); [T3x, Y3x] = step(H3x, T=linspace(0,10,100)); [T3y, Y3y] = step(H3y, T=linspace(0,10,100)); -plot(T3x.T, Y3x[0,:].T, T3y.T, Y3y[0,:].T) +plot(T3x, Y3x[0,:].T, T3y, Y3y[0,:].T) title("Physically motivated weights") xlabel('time'); legend(('x', 'y'), loc='lower right'); Modified: branches/control-0.4a/examples/pvtol-nested-ss.py =================================================================== --- branches/control-0.4a/examples/pvtol-nested-ss.py 2011-02-08 22:18:58 UTC (rev 112) +++ branches/control-0.4a/examples/pvtol-nested-ss.py 2011-02-08 22:19:07 UTC (rev 113) @@ -10,7 +10,6 @@ from matplotlib.pyplot import * # Grab MATLAB plotting functions from control.matlab import * # MATLAB-like functions -import numpy as np # System parameters m = 4; # mass of aircraft @@ -108,7 +107,7 @@ subplot(phaseh); semilogx([10^-4, 10^3], [-180, -180], 'k-') hold(True); -semilogx(w, np.squeeze(phase), 'b-') +semilogx(w, phase, 'b-') axis([10^-4, 10^3, -360, 0]); xlabel('Frequency [deg]'); ylabel('Phase [deg]'); # set(gca, 'YTick', [-360, -270, -180, -90, 0]); @@ -145,15 +144,14 @@ figure(9); (Tvec, Yvec) = step(T, None, linspace(1, 20)); -plot(Tvec.T, Yvec.T); hold(True); +plot(Tvec, Yvec); hold(True); (Tvec, Yvec) = step(Co*S, None, linspace(1, 20)); -plot(Tvec.T, Yvec.T); +plot(Tvec, Yvec); -#TODO: PZmap for statespace systems has not yet been implemented. figure(10); clf(); -#(P, Z) = pzmap(T, Plot=True) -#print "Closed loop poles and zeros: ", P, Z +(P, Z) = pzmap(T, Plot=True) +print "Closed loop poles and zeros: ", P, Z # Gang of Four figure(11); clf(); Modified: branches/control-0.4a/examples/pvtol-nested.py =================================================================== --- branches/control-0.4a/examples/pvtol-nested.py 2011-02-08 22:18:58 UTC (rev 112) +++ branches/control-0.4a/examples/pvtol-nested.py 2011-02-08 22:19:07 UTC (rev 113) @@ -10,7 +10,6 @@ from matplotlib.pyplot import * # Grab MATLAB plotting functions from control.matlab import * # MATLAB-like functions -import numpy as np # System parameters m = 4; # mass of aircraft @@ -24,8 +23,8 @@ Po = tf([1], [m, c, 0]); # outer loop (position) # Use state space versions -Pi = tf2ss(Pi); -Po = tf2ss(Po); +# Pi = tf2ss(Pi); +# Po = tf2ss(Po); # # Inner loop control design @@ -98,7 +97,7 @@ subplot(phaseh); semilogx([10^-4, 10^3], [-180, -180], 'k-') hold(True); -semilogx(w, np.squeeze(phase), 'b-') +semilogx(w, phase, 'b-') axis([10^-4, 10^3, -360, 0]); xlabel('Frequency [deg]'); ylabel('Phase [deg]'); # set(gca, 'YTick', [-360, -270, -180, -90, 0]); @@ -135,10 +134,10 @@ figure(9); (Tvec, Yvec) = step(T, None, linspace(1, 20)); -plot(Tvec.T, Yvec.T); hold(True); +plot(Tvec, Yvec); hold(True); (Tvec, Yvec) = step(Co*S, None, linspace(1, 20)); -plot(Tvec.T, Yvec.T); +plot(Tvec, Yvec); figure(10); clf(); (P, Z) = pzmap(T, Plot=True) Modified: branches/control-0.4a/examples/secord-matlab.py =================================================================== --- branches/control-0.4a/examples/secord-matlab.py 2011-02-08 22:18:58 UTC (rev 112) +++ branches/control-0.4a/examples/secord-matlab.py 2011-02-08 22:19:07 UTC (rev 113) @@ -18,7 +18,7 @@ # Step response for the system figure(1) T, yout = step(sys) -plot(T.T, yout.T) +plot(T, yout) # Bode plot for the system figure(2) Modified: branches/control-0.4a/examples/slicot-test.py =================================================================== --- branches/control-0.4a/examples/slicot-test.py 2011-02-08 22:18:58 UTC (rev 112) +++ branches/control-0.4a/examples/slicot-test.py 2011-02-08 22:19:07 UTC (rev 113) @@ -17,7 +17,7 @@ sys = ss(A, B, C, 0); # Eigenvalue placement -#from slycot import sb01bd +from slycot import sb01bd K = place(A, B, [-3, -2, -1]) print "Pole place: K = ", K print "Pole place: eigs = ", np.linalg.eig(A - B * K)[0] Modified: branches/control-0.4a/src/freqplot.py =================================================================== --- branches/control-0.4a/src/freqplot.py 2011-02-08 22:18:58 UTC (rev 112) +++ branches/control-0.4a/src/freqplot.py 2011-02-08 22:19:07 UTC (rev 113) @@ -177,12 +177,7 @@ # 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) + for sys in syslist: if (sys.inputs > 1 or sys.outputs > 1): #TODO: Add MIMO nyquist plots. Modified: branches/control-0.4a/src/pzmap.py =================================================================== --- branches/control-0.4a/src/pzmap.py 2011-02-08 22:18:58 UTC (rev 112) +++ branches/control-0.4a/src/pzmap.py 2011-02-08 22:19:07 UTC (rev 113) @@ -42,7 +42,6 @@ import matplotlib.pyplot as plt import scipy as sp -import numpy as np import xferfcn # Compute poles and zeros for a system @@ -50,10 +49,10 @@ def pzmap(sys, Plot=True): """Plot a pole/zero map for a transfer function""" if (isinstance(sys, xferfcn.TransferFunction)): - poles = sp.roots(np.squeeze(np.asarray(sys.den))); - zeros = sp.roots(np.squeeze(np.asarray(sys.num))); + poles = sp.roots(sys.den); + zeros = sp.roots(sys.num); else: - raise NotImplementedError("pzmap not implemented for state space systems yet.") + raise TypeException if (Plot): # Plot the locations of the poles and zeros Modified: branches/control-0.4a/src/statesp.py =================================================================== --- branches/control-0.4a/src/statesp.py 2011-02-08 22:18:58 UTC (rev 112) +++ branches/control-0.4a/src/statesp.py 2011-02-08 22:19:07 UTC (rev 113) @@ -73,7 +73,7 @@ """ from numpy import all, angle, any, array, concatenate, cos, delete, dot, \ - empty, exp, eye, matrix, ones, pi, poly, poly1d, roots, shape, sin, zeros + empty, exp, eye, matrix, ones, pi, poly, poly1d, roots, sin, zeros from numpy.random import rand, randn from numpy.linalg import inv, det, solve from numpy.linalg.linalg import LinAlgError @@ -456,8 +456,6 @@ # TODO: transfer function to state space conversion is still buggy! print "Warning: transfer function to state space conversion by td04ad \ is still buggy!" - #print num - #print shape(num) ssout = td04ad(sys.inputs, sys.outputs, index, den, num) states = ssout[0] Added: branches/control-0.4a/src/test.py =================================================================== --- branches/control-0.4a/src/test.py (rev 0) +++ branches/control-0.4a/src/test.py 2011-02-08 22:19:07 UTC (rev 113) @@ -0,0 +1,63 @@ +import subprocess as SP + +def tests_old(): + """ Runs all of the tests written for python-control. This should be + changed in the future so it does run seperate main functions/scripts, + but is integrated into the package. Also, the tests should be in their + own directory /trunk/tests. Running the test should be as simple as: + "import control; control.tests()" + """ + testList = ['TestBDAlg.py','TestConvert.py','TestFreqRsp.py',\ + 'TestMatlab.py','TestModelsimp.py','TestSlycot.py',\ + 'TestStateSp.py','TestStatefbk.py','TestXferFcn.py'] + #Add more tests to this list as they are created. Each is assumed to run + #as a script, as is usually done with unittest. + for test in testList: + print 'Running',test + print SP.Popen(['./'+test],stdout=SP.PIPE).communicate()[0] + print 'Completed',test + +def tests(): + import unittest + try: #auto test discovery is only implemented in python 2.7+ + start_dir='./' #change to a tests directory eventually. + pattern = 'Test*.py' + top_level_dir = './' #this might change? see + #http://docs.python.org/library/unittest.html#unittest.TestLoader.discover + test_mods=unittest.defaultTestLoader.discover(start_dir,pattern=pattern,\ + top_level_dir=top_level_dir) + #now go through each module and run all of its tests. + print 'found test mods and they are',test_mods + for mod in test_mods: + print 'Running tests in',mod + tests = unittest.defaultTestLoader.loadTestFromModule(mod) + t = unittest.TextTestRunner() + t.run(tests) + print 'Completed tests in',mod + except: + #If can't do auto discovery, for now it is hard-coded. This is not ideal for + #when new tests are added or existing ones are reorganized/renamed. + + #remove all of the print commands once tests are debugged and converted to + #unittests. + + print 'Tests may be incomplete' + t=unittest.TextTestRunner() + + testModules = ['TestBDAlg','TestConvert','TestFreqRsp','TestMatlab','TestModelsimp',\ + 'TestStateSp','TestStatefbk','TestXferFcn'] #add additional tests here, or discovery? + suite = unittest.TestSuite() + for mod in testModules: + exec('import '+mod+' as currentModule') + print 'TEST',mod + suite = currentModule.suite() + t.run(suite) + #After tests have been debugged and made into unittests, remove + #the above (except the import) and replace with something like this: + #suiteList.append(ts.suite()) + #alltests = unittest.TestSuite(suiteList) + #t.run(alltests) + + +if __name__=='__main__': + tests() Modified: branches/control-0.4a/src/xferfcn.py =================================================================== --- branches/control-0.4a/src/xferfcn.py 2011-02-08 22:18:58 UTC (rev 112) +++ branches/control-0.4a/src/xferfcn.py 2011-02-08 22:19:07 UTC (rev 113) @@ -344,14 +344,14 @@ def __div__(self, other): """Divide two LTI objects.""" - # Convert the second argument to a transfer function. - other = _convertToTransferFunction(other) - if (self.inputs > 1 or self.outputs > 1 or other.inputs > 1 or other.outputs > 1): raise NotImplementedError("TransferFunction.__div__ is currently \ implemented only for SISO systems.") + # Convert the second argument to a transfer function. + other = _convertToTransferFunction(other) + num = polymul(self.num[0][0], other.den[0][0]) den = polymul(self.den[0][0], other.num[0][0]) @@ -487,9 +487,8 @@ computes the single denominator containing all the poles of sys.den, and reports it as the array d. The output numerator array n is modified to - use the common denominator; the coefficient arrays are also padded with - zeros to be the same size as d. n is an sys.outputs-by-sys.inputs-by- - len(d) array. + use the common denominator. It is an sys.outputs-by-sys.inputs-by- + [something] array. """ @@ -589,12 +588,16 @@ # 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. + # Find the largest numerator polynomial size. + largest = 0 for i in range(self.outputs): for j in range(self.inputs): - num[i][j] = insert(num[i][j], zeros(len(den) - len(num[i][j])), - zeros(len(den) - len(num[i][j]))) + largest = max(largest, len(num[i][j])) + # Pad all smaller numerator polynomials with zeros. + for i in range(self.outputs): + for j in range(self.inputs): + num[i][j] = insert(num[i][j], zeros(largest - len(num[i][j])), + zeros(largest - len(num[i][j]))) # Finally, convert the numerator to a 3-D array. num = array(num) # Remove trivial imaginary parts. Check for nontrivial imaginary parts. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:19:05
|
Revision: 112 http://python-control.svn.sourceforge.net/python-control/?rev=112&view=rev Author: kkchen Date: 2011-02-08 22:18:58 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Fixed pzmap.py for transfer functions. Still not implemented for state space. Lauren Padilla <lpa...@pr...> Modified Paths: -------------- branches/control-0.4a/examples/pvtol-nested.py branches/control-0.4a/examples/type2_type3.py branches/control-0.4a/src/pzmap.py Modified: branches/control-0.4a/examples/pvtol-nested.py =================================================================== --- branches/control-0.4a/examples/pvtol-nested.py 2011-02-08 22:18:53 UTC (rev 111) +++ branches/control-0.4a/examples/pvtol-nested.py 2011-02-08 22:18:58 UTC (rev 112) @@ -24,8 +24,8 @@ Po = tf([1], [m, c, 0]); # outer loop (position) # Use state space versions -# Pi = tf2ss(Pi); -# Po = tf2ss(Po); +Pi = tf2ss(Pi); +Po = tf2ss(Po); # # Inner loop control design Modified: branches/control-0.4a/examples/type2_type3.py =================================================================== --- branches/control-0.4a/examples/type2_type3.py 2011-02-08 22:18:53 UTC (rev 111) +++ branches/control-0.4a/examples/type2_type3.py 2011-02-08 22:18:58 UTC (rev 112) @@ -15,7 +15,7 @@ Kii = Ki # Plant transfer function from torque to rate -inertia = integrator*(1/J) +inertia = integrator*1/J friction = b # transfer function from rate to torque P = inertia # friction is modelled as a separate block Modified: branches/control-0.4a/src/pzmap.py =================================================================== --- branches/control-0.4a/src/pzmap.py 2011-02-08 22:18:53 UTC (rev 111) +++ branches/control-0.4a/src/pzmap.py 2011-02-08 22:18:58 UTC (rev 112) @@ -42,6 +42,7 @@ import matplotlib.pyplot as plt import scipy as sp +import numpy as np import xferfcn # Compute poles and zeros for a system @@ -49,8 +50,8 @@ def pzmap(sys, Plot=True): """Plot a pole/zero map for a transfer function""" if (isinstance(sys, xferfcn.TransferFunction)): - poles = sp.roots(sys.den); - zeros = sp.roots(sys.num); + poles = sp.roots(np.squeeze(np.asarray(sys.den))); + zeros = sp.roots(np.squeeze(np.asarray(sys.num))); else: raise NotImplementedError("pzmap not implemented for state space systems yet.") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:18:59
|
Revision: 111 http://python-control.svn.sourceforge.net/python-control/?rev=111&view=rev Author: kkchen Date: 2011-02-08 22:18:53 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Fixes in xferfcn.py - Division by a scalar now works. - _common_den() modified so that the numerator coefficient arrays have the same size as the common denominator. This is done by padding with zeros. Kevin K. Chen <kk...@pr...> Modified Paths: -------------- branches/control-0.4a/src/xferfcn.py Modified: branches/control-0.4a/src/xferfcn.py =================================================================== --- branches/control-0.4a/src/xferfcn.py 2011-02-08 22:18:49 UTC (rev 110) +++ branches/control-0.4a/src/xferfcn.py 2011-02-08 22:18:53 UTC (rev 111) @@ -344,14 +344,14 @@ def __div__(self, other): """Divide two LTI objects.""" + # Convert the second argument to a transfer function. + other = _convertToTransferFunction(other) + if (self.inputs > 1 or self.outputs > 1 or other.inputs > 1 or other.outputs > 1): raise NotImplementedError("TransferFunction.__div__ is currently \ implemented only for SISO systems.") - # Convert the second argument to a transfer function. - other = _convertToTransferFunction(other) - num = polymul(self.num[0][0], other.den[0][0]) den = polymul(self.den[0][0], other.num[0][0]) @@ -487,8 +487,9 @@ computes the single denominator containing all the poles of sys.den, and reports it as the array d. The output numerator array n is modified to - use the common denominator. It is an sys.outputs-by-sys.inputs-by- - [something] array. + use the common denominator; the coefficient arrays are also padded with + zeros to be the same size as d. n is an sys.outputs-by-sys.inputs-by- + len(d) array. """ @@ -588,16 +589,12 @@ # Multiply in the missing poles. for p in missingpoles[i][j]: num[i][j] = polymul(num[i][j], [1., -p]) - # Find the largest numerator polynomial size. - largest = 0 + # Pad all numerator polynomials with zeros so that the numerator arrays + # are the same size as the denominator. for i in range(self.outputs): for j in range(self.inputs): - largest = max(largest, len(num[i][j])) - # Pad all smaller numerator polynomials with zeros. - for i in range(self.outputs): - for j in range(self.inputs): - num[i][j] = insert(num[i][j], zeros(largest - len(num[i][j])), - zeros(largest - len(num[i][j]))) + num[i][j] = insert(num[i][j], zeros(len(den) - len(num[i][j])), + zeros(len(den) - len(num[i][j]))) # Finally, convert the numerator to a 3-D array. num = array(num) # Remove trivial imaginary parts. Check for nontrivial imaginary parts. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:18:57
|
Revision: 110 http://python-control.svn.sourceforge.net/python-control/?rev=110&view=rev Author: kkchen Date: 2011-02-08 22:18:49 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Modified examples so that they are compatible with the new classes. Minor changes to some of the python-control files to handle bugs found in examples. Lauren Padilla <lpa...@pr...> Modified Paths: -------------- branches/control-0.4a/examples/pvtol-lqr.py branches/control-0.4a/examples/pvtol-nested-ss.py branches/control-0.4a/examples/pvtol-nested.py branches/control-0.4a/examples/secord-matlab.py branches/control-0.4a/examples/slicot-test.py branches/control-0.4a/examples/type2_type3.py branches/control-0.4a/src/freqplot.py branches/control-0.4a/src/pzmap.py branches/control-0.4a/src/statesp.py Modified: branches/control-0.4a/examples/pvtol-lqr.py =================================================================== --- branches/control-0.4a/examples/pvtol-lqr.py 2011-02-08 22:18:42 UTC (rev 109) +++ branches/control-0.4a/examples/pvtol-lqr.py 2011-02-08 22:18:49 UTC (rev 110) @@ -119,7 +119,7 @@ subplot(221); title("Identity weights") # plot(T, Y[:,1, 1], '-', T, Y[:,2, 2], '--'); hold(True); -plot(Tx, Yx[0,:].T, '-', Ty, Yy[0,:].T, '--'); hold(True); +plot(Tx.T, Yx[0,:].T, '-', Ty.T, Yy[0,:].T, '--'); hold(True); plot([0, 10], [1, 1], 'k-'); hold(True); axis([0, 10, -0.1, 1.4]); @@ -141,9 +141,9 @@ [T3, Y3] = step(H1cx, T=linspace(0,10,100)); subplot(222); title("Effect of input weights") -plot(T1, Y1[0,:].T, 'b-'); hold(True); -plot(T2, Y2[0,:].T, 'b-'); hold(True); -plot(T3, Y3[0,:].T, 'b-'); hold(True); +plot(T1.T, Y1[0,:].T, 'b-'); hold(True); +plot(T2.T, Y2[0,:].T, 'b-'); hold(True); +plot(T3.T, Y3[0,:].T, 'b-'); hold(True); plot([0 ,10], [1, 1], 'k-'); hold(True); axis([0, 10, -0.1, 1.4]); @@ -162,7 +162,7 @@ subplot(223); title("Output weighting") [T2x, Y2x] = step(H2x, T=linspace(0,10,100)); [T2y, Y2y] = step(H2y, T=linspace(0,10,100)); -plot(T2x, Y2x[0,:].T, T2y, Y2y[0,:].T) +plot(T2x.T, Y2x[0,:].T, T2y.T, Y2y[0,:].T) ylabel('position'); xlabel('time'); ylabel('position'); legend(('x', 'y'), loc='lower right'); @@ -185,7 +185,7 @@ # step(H3x, H3y, 10); [T3x, Y3x] = step(H3x, T=linspace(0,10,100)); [T3y, Y3y] = step(H3y, T=linspace(0,10,100)); -plot(T3x, Y3x[0,:].T, T3y, Y3y[0,:].T) +plot(T3x.T, Y3x[0,:].T, T3y.T, Y3y[0,:].T) title("Physically motivated weights") xlabel('time'); legend(('x', 'y'), loc='lower right'); Modified: branches/control-0.4a/examples/pvtol-nested-ss.py =================================================================== --- branches/control-0.4a/examples/pvtol-nested-ss.py 2011-02-08 22:18:42 UTC (rev 109) +++ branches/control-0.4a/examples/pvtol-nested-ss.py 2011-02-08 22:18:49 UTC (rev 110) @@ -10,6 +10,7 @@ from matplotlib.pyplot import * # Grab MATLAB plotting functions from control.matlab import * # MATLAB-like functions +import numpy as np # System parameters m = 4; # mass of aircraft @@ -107,7 +108,7 @@ subplot(phaseh); semilogx([10^-4, 10^3], [-180, -180], 'k-') hold(True); -semilogx(w, phase, 'b-') +semilogx(w, np.squeeze(phase), 'b-') axis([10^-4, 10^3, -360, 0]); xlabel('Frequency [deg]'); ylabel('Phase [deg]'); # set(gca, 'YTick', [-360, -270, -180, -90, 0]); @@ -144,14 +145,15 @@ figure(9); (Tvec, Yvec) = step(T, None, linspace(1, 20)); -plot(Tvec, Yvec); hold(True); +plot(Tvec.T, Yvec.T); hold(True); (Tvec, Yvec) = step(Co*S, None, linspace(1, 20)); -plot(Tvec, Yvec); +plot(Tvec.T, Yvec.T); +#TODO: PZmap for statespace systems has not yet been implemented. figure(10); clf(); -(P, Z) = pzmap(T, Plot=True) -print "Closed loop poles and zeros: ", P, Z +#(P, Z) = pzmap(T, Plot=True) +#print "Closed loop poles and zeros: ", P, Z # Gang of Four figure(11); clf(); Modified: branches/control-0.4a/examples/pvtol-nested.py =================================================================== --- branches/control-0.4a/examples/pvtol-nested.py 2011-02-08 22:18:42 UTC (rev 109) +++ branches/control-0.4a/examples/pvtol-nested.py 2011-02-08 22:18:49 UTC (rev 110) @@ -10,6 +10,7 @@ from matplotlib.pyplot import * # Grab MATLAB plotting functions from control.matlab import * # MATLAB-like functions +import numpy as np # System parameters m = 4; # mass of aircraft @@ -97,7 +98,7 @@ subplot(phaseh); semilogx([10^-4, 10^3], [-180, -180], 'k-') hold(True); -semilogx(w, phase, 'b-') +semilogx(w, np.squeeze(phase), 'b-') axis([10^-4, 10^3, -360, 0]); xlabel('Frequency [deg]'); ylabel('Phase [deg]'); # set(gca, 'YTick', [-360, -270, -180, -90, 0]); @@ -134,10 +135,10 @@ figure(9); (Tvec, Yvec) = step(T, None, linspace(1, 20)); -plot(Tvec, Yvec); hold(True); +plot(Tvec.T, Yvec.T); hold(True); (Tvec, Yvec) = step(Co*S, None, linspace(1, 20)); -plot(Tvec, Yvec); +plot(Tvec.T, Yvec.T); figure(10); clf(); (P, Z) = pzmap(T, Plot=True) Modified: branches/control-0.4a/examples/secord-matlab.py =================================================================== --- branches/control-0.4a/examples/secord-matlab.py 2011-02-08 22:18:42 UTC (rev 109) +++ branches/control-0.4a/examples/secord-matlab.py 2011-02-08 22:18:49 UTC (rev 110) @@ -18,7 +18,7 @@ # Step response for the system figure(1) T, yout = step(sys) -plot(T, yout) +plot(T.T, yout.T) # Bode plot for the system figure(2) Modified: branches/control-0.4a/examples/slicot-test.py =================================================================== --- branches/control-0.4a/examples/slicot-test.py 2011-02-08 22:18:42 UTC (rev 109) +++ branches/control-0.4a/examples/slicot-test.py 2011-02-08 22:18:49 UTC (rev 110) @@ -17,7 +17,7 @@ sys = ss(A, B, C, 0); # Eigenvalue placement -from slycot import sb01bd +#from slycot import sb01bd K = place(A, B, [-3, -2, -1]) print "Pole place: K = ", K print "Pole place: eigs = ", np.linalg.eig(A - B * K)[0] Modified: branches/control-0.4a/examples/type2_type3.py =================================================================== --- branches/control-0.4a/examples/type2_type3.py 2011-02-08 22:18:42 UTC (rev 109) +++ branches/control-0.4a/examples/type2_type3.py 2011-02-08 22:18:49 UTC (rev 110) @@ -15,7 +15,7 @@ Kii = Ki # Plant transfer function from torque to rate -inertia = integrator*1/J +inertia = integrator*(1/J) friction = b # transfer function from rate to torque P = inertia # friction is modelled as a separate block Modified: branches/control-0.4a/src/freqplot.py =================================================================== --- branches/control-0.4a/src/freqplot.py 2011-02-08 22:18:42 UTC (rev 109) +++ branches/control-0.4a/src/freqplot.py 2011-02-08 22:18:49 UTC (rev 110) @@ -177,7 +177,12 @@ # 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) for sys in syslist: if (sys.inputs > 1 or sys.outputs > 1): #TODO: Add MIMO nyquist plots. Modified: branches/control-0.4a/src/pzmap.py =================================================================== --- branches/control-0.4a/src/pzmap.py 2011-02-08 22:18:42 UTC (rev 109) +++ branches/control-0.4a/src/pzmap.py 2011-02-08 22:18:49 UTC (rev 110) @@ -52,7 +52,7 @@ poles = sp.roots(sys.den); zeros = sp.roots(sys.num); else: - raise TypeException + raise NotImplementedError("pzmap not implemented for state space systems yet.") if (Plot): # Plot the locations of the poles and zeros Modified: branches/control-0.4a/src/statesp.py =================================================================== --- branches/control-0.4a/src/statesp.py 2011-02-08 22:18:42 UTC (rev 109) +++ branches/control-0.4a/src/statesp.py 2011-02-08 22:18:49 UTC (rev 110) @@ -73,7 +73,7 @@ """ from numpy import all, angle, any, array, concatenate, cos, delete, dot, \ - empty, exp, eye, matrix, ones, pi, poly, poly1d, roots, sin, zeros + empty, exp, eye, matrix, ones, pi, poly, poly1d, roots, shape, sin, zeros from numpy.random import rand, randn from numpy.linalg import inv, det, solve from numpy.linalg.linalg import LinAlgError @@ -456,6 +456,8 @@ # TODO: transfer function to state space conversion is still buggy! print "Warning: transfer function to state space conversion by td04ad \ is still buggy!" + #print num + #print shape(num) ssout = td04ad(sys.inputs, sys.outputs, index, den, num) states = ssout[0] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:18:48
|
Revision: 109 http://python-control.svn.sourceforge.net/python-control/?rev=109&view=rev Author: kkchen Date: 2011-02-08 22:18:42 +0000 (Tue, 08 Feb 2011) Log Message: ----------- reorganized testing into src/test.py I changed a bunch of things, basically enabling one to do import control control.tests() I'm a little unsure on the whole setup of the directories, so if it doesn't work then I'll fix it. -brandt bb...@ra... Modified Paths: -------------- branches/control-0.4a/src/TestBDAlg.py branches/control-0.4a/src/TestConvert.py branches/control-0.4a/src/TestFreqRsp.py branches/control-0.4a/src/TestMatlab.py branches/control-0.4a/src/TestSlycot.py branches/control-0.4a/src/TestStateSp.py branches/control-0.4a/src/TestXferFcn.py branches/control-0.4a/src/__init__.py Modified: branches/control-0.4a/src/TestBDAlg.py =================================================================== --- branches/control-0.4a/src/TestBDAlg.py 2011-02-08 22:18:35 UTC (rev 108) +++ branches/control-0.4a/src/TestBDAlg.py 2011-02-08 22:18:42 UTC (rev 109) @@ -159,6 +159,8 @@ [[[1., 4., 11., 16., 13.]]]) np.testing.assert_array_almost_equal(ans2.num, [[[1., 4., 7., 6.]]]) np.testing.assert_array_almost_equal(ans2.den, [[[1., 4., 9., 8., 5.]]]) +def suite(): + return unittest.TestLoader().loadTestsFromTestCase(TestFeedback) if __name__ == "__main__": unittest.main() Modified: branches/control-0.4a/src/TestConvert.py =================================================================== --- branches/control-0.4a/src/TestConvert.py 2011-02-08 22:18:35 UTC (rev 108) +++ branches/control-0.4a/src/TestConvert.py 2011-02-08 22:18:42 UTC (rev 109) @@ -60,5 +60,8 @@ sys4 = matlab.tf(sys3) self.printSys(sys4, 4) +def suite(): + return unittest.TestLoader().loadTestsFromTestCase(TestConvert) + if __name__ == "__main__": unittest.main() Modified: branches/control-0.4a/src/TestFreqRsp.py =================================================================== --- branches/control-0.4a/src/TestFreqRsp.py 2011-02-08 22:18:35 UTC (rev 108) +++ branches/control-0.4a/src/TestFreqRsp.py 2011-02-08 22:18:42 UTC (rev 109) @@ -1,8 +1,13 @@ #!/usr/bin/env python +### MUST BE CONVERTED TO A UNIT TEST!!! + + # Script to test frequency response and frequency response plots like bode, nyquist and gang of 4. # Especially need to ensure that nothing SISO is broken and that MIMO at least handles exceptions and has some default to SISO in place. + +import unittest from statesp import StateSpace from matlab import ss, tf, bode import numpy as np @@ -49,4 +54,7 @@ #plt.semilogx(omega,20*np.log10(np.squeeze(frq[0]))) #plt.figure(4) -#bode(sysMIMO,omega) \ No newline at end of file +#bode(sysMIMO,omega) + +def suite(): + return unittest.TestLoader().loadTestsFromTestCase(TestConvert) Modified: branches/control-0.4a/src/TestMatlab.py =================================================================== --- branches/control-0.4a/src/TestMatlab.py 2011-02-08 22:18:35 UTC (rev 108) +++ branches/control-0.4a/src/TestMatlab.py 2011-02-08 22:18:42 UTC (rev 109) @@ -40,5 +40,8 @@ # np.testing.assert_array_almost_equal(yout, youttrue,decimal=4) +def suite(): + return unittest.TestLoader().loadTestsFromTestCase(TestMatlab) + if __name__ == '__main__': unittest.main() Modified: branches/control-0.4a/src/TestSlycot.py =================================================================== --- branches/control-0.4a/src/TestSlycot.py 2011-02-08 22:18:35 UTC (rev 108) +++ branches/control-0.4a/src/TestSlycot.py 2011-02-08 22:18:42 UTC (rev 109) @@ -1,3 +1,8 @@ +#!/usr/bin/env python + +#### THIS MUST BE MADE INTO A UNITTEST TO BE PART OF THE TESTING FUNCTIONS!!!! + + import numpy as np from slycot import tb04ad, td04ad import matlab @@ -28,3 +33,10 @@ print "sys4" print sys4 +#These are here for once the above is made into a unittest. +def suite(): + return unittest.TestLoader().loadTestsFromTestCase(TestSlycot) + +if __name__=='__main__': + unittest.main() + Modified: branches/control-0.4a/src/TestStateSp.py =================================================================== --- branches/control-0.4a/src/TestStateSp.py 2011-02-08 22:18:35 UTC (rev 108) +++ branches/control-0.4a/src/TestStateSp.py 2011-02-08 22:18:42 UTC (rev 109) @@ -199,6 +199,11 @@ p = sys.pole() for z in p: self.assertTrue(abs(z) < 1) - + + +def suite(): + return unittest.TestLoader().loadTestsFromTestCase(TestStateSpace) + + if __name__ == "__main__": unittest.main() Modified: branches/control-0.4a/src/TestXferFcn.py =================================================================== --- branches/control-0.4a/src/TestXferFcn.py 2011-02-08 22:18:35 UTC (rev 108) +++ branches/control-0.4a/src/TestXferFcn.py 2011-02-08 22:18:42 UTC (rev 109) @@ -430,5 +430,8 @@ np.testing.assert_array_almost_equal(tfsys.num[i][j], num[i][j]) np.testing.assert_array_almost_equal(tfsys.den[i][j], den[i][j]) +def suite(): + return unittest.TestLoader().loadTestsFromTestCase(TestXferFcn) + if __name__ == "__main__": unittest.main() Modified: branches/control-0.4a/src/__init__.py =================================================================== --- branches/control-0.4a/src/__init__.py 2011-02-08 22:18:35 UTC (rev 108) +++ branches/control-0.4a/src/__init__.py 2011-02-08 22:18:42 UTC (rev 109) @@ -62,3 +62,5 @@ from bdalg import * from statefbk import * from delay import * + +from test import * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:18:41
|
Revision: 108 http://python-control.svn.sourceforge.net/python-control/?rev=108&view=rev Author: kkchen Date: 2011-02-08 22:18:35 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Bug fix in StateSpace._remove_useless_states. Kevin K. Chen <kk...@pr...> Modified Paths: -------------- branches/control-0.4a/src/statesp.py Modified: branches/control-0.4a/src/statesp.py =================================================================== --- branches/control-0.4a/src/statesp.py 2011-02-08 22:18:31 UTC (rev 107) +++ branches/control-0.4a/src/statesp.py 2011-02-08 22:18:35 UTC (rev 108) @@ -157,7 +157,7 @@ # Remove the useless states. if all(useless == range(self.states)): # All the states were useless. - self.A = 0 + self.A = zeros((1, 1)) self.B = zeros((1, self.inputs)) self.C = zeros((self.outputs, 1)) else: @@ -167,6 +167,10 @@ self.B = delete(self.B, useless, 0) self.C = delete(self.C, useless, 1) + self.states = self.A.shape[0] + self.inputs = self.B.shape[1] + self.outputs = self.C.shape[0] + def copy(self): """Return a deep copy of the instance.""" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:18:37
|
Revision: 107 http://python-control.svn.sourceforge.net/python-control/?rev=107&view=rev Author: kkchen Date: 2011-02-08 22:18:31 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Modified freqplot.py to fix Nyquist, Nichols and Gangof4 to handle SISO systems again. Steven Brunton <sbr...@pr...> Modified Paths: -------------- branches/control-0.4a/src/freqplot.py Modified: branches/control-0.4a/src/freqplot.py =================================================================== --- branches/control-0.4a/src/freqplot.py 2011-02-08 22:18:27 UTC (rev 106) +++ branches/control-0.4a/src/freqplot.py 2011-02-08 22:18:31 UTC (rev 107) @@ -179,17 +179,22 @@ omega = default_frequency_range(syslist) for sys in syslist: - # Get the magnitude and phase of the system - mag, phase, omega = sys.freqresp(omega) + if (sys.inputs > 1 or sys.outputs > 1): + #TODO: Add MIMO nyquist plots. + raise NotImplementedError("Nyquist is currently only implemented for SISO systems.") + else: + # Get the magnitude and phase of the system + mag_tmp, phase_tmp, omega = sys.freqresp(omega) + mag = np.squeeze(mag_tmp) + phase = np.squeeze(phase_tmp) + + # Compute the primary curve + x = sp.multiply(mag, sp.cos(phase)); + y = sp.multiply(mag, sp.sin(phase)); - # Compute the primary curve - x = sp.multiply(mag, sp.cos(phase)); - y = sp.multiply(mag, sp.sin(phase)); - - # Plot the primary curve and mirror image - plt.plot(x, y, '-'); - plt.plot(x, -y, '--'); - + # Plot the primary curve and mirror image + plt.plot(x, y, '-'); + plt.plot(x, -y, '--'); # Mark the -1 point plt.plot([-1], [0], 'r+') @@ -225,17 +230,24 @@ if (omega == None): omega = default_frequency_range(syslist) + for sys in syslist: - # Get the magnitude and phase of the system - mag, phase, omega = sys.freqresp(omega) + if (sys.inputs > 1 or sys.outputs > 1): + #TODO: Add MIMO nichols plots. + raise NotImplementedError("Nichols is currently only implemented for SISO systems.") + else: + # Get the magnitude and phase of the system + mag_tmp, phase_tmp, omega = sys.freqresp(omega) + mag = np.squeeze(mag_tmp) + phase = np.squeeze(phase_tmp) + + # Convert to Nichols-plot format (phase in degrees, + # and magnitude in dB) + x = unwrap(sp.degrees(phase), 360) + y = 20*sp.log10(mag) - # Convert to Nichols-plot format (phase in degrees, - # and magnitude in dB) - x = unwrap(sp.degrees(phase), 360) - y = 20*sp.log10(mag) - - # Generate the plot - plt.plot(x, y) + # Generate the plot + plt.plot(x, y) plt.xlabel('Phase (deg)') plt.ylabel('Magnitude (dB)') @@ -267,31 +279,43 @@ ------------- None """ + if (P.inputs > 1 or P.outputs > 1 or C.inputs > 1 or C.outputs >1): + #TODO: Add MIMO go4 plots. + raise NotImplementedError("Gang of four is currently only implemented for SISO systems.") + else: + + # Select a default range if none is provided + #! TODO: This needs to be made more intelligent + if (omega == None): + omega = default_frequency_range((P,C)) - # Select a default range if none is provided - #! TODO: This needs to be made more intelligent - if (omega == None): - omega = default_frequency_range((P,C)) + # Compute the senstivity functions + L = P*C; + S = feedback(1, L); + T = L * S; - # Compute the senstivity functions - L = P*C; - S = feedback(1, L); - T = L * S; + # Plot the four sensitivity functions + #! TODO: Need to add in the mag = 1 lines + mag_tmp, phase_tmp, omega = T.freqresp(omega); + mag = np.squeeze(mag_tmp) + phase = np.squeeze(phase_tmp) + plt.subplot(221); plt.loglog(omega, mag); - # Plot the four sensitivity functions - #! TODO: Need to add in the mag = 1 lines - mag, phase, omega = T.freqresp(omega); - plt.subplot(221); plt.loglog(omega, mag); + mag_tmp, phase_tmp, omega = (P*S).freqresp(omega); + mag = np.squeeze(mag_tmp) + phase = np.squeeze(phase_tmp) + plt.subplot(222); plt.loglog(omega, mag); - mag, phase, omega = (P*S).freqresp(omega); - plt.subplot(222); plt.loglog(omega, mag); + mag_tmp, phase_tmp, omega = (C*S).freqresp(omega); + mag = np.squeeze(mag_tmp) + phase = np.squeeze(phase_tmp) + plt.subplot(223); plt.loglog(omega, mag); - mag, phase, omega = (C*S).freqresp(omega); - plt.subplot(223); plt.loglog(omega, mag); + mag_tmp, phase_tmp, omega = S.freqresp(omega); + mag = np.squeeze(mag_tmp) + phase = np.squeeze(phase_tmp) + plt.subplot(224); plt.loglog(omega, mag); - mag, phase, omega = S.freqresp(omega); - plt.subplot(224); plt.loglog(omega, mag); - # # Utility functions # This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:18:33
|
Revision: 106 http://python-control.svn.sourceforge.net/python-control/?rev=106&view=rev Author: kkchen Date: 2011-02-08 22:18:27 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Added warnings about state space / transfer function conversion still being buggy. Kevin K. Chen <kk...@pr...> Modified Paths: -------------- branches/control-0.4a/src/TestConvert.py branches/control-0.4a/src/statesp.py branches/control-0.4a/src/xferfcn.py Modified: branches/control-0.4a/src/TestConvert.py =================================================================== --- branches/control-0.4a/src/TestConvert.py 2011-02-08 22:18:23 UTC (rev 105) +++ branches/control-0.4a/src/TestConvert.py 2011-02-08 22:18:27 UTC (rev 106) @@ -27,9 +27,9 @@ # Number of times to run each of the randomized tests. self.numTests = 10 # Maximum number of states to test + 1 - self.maxStates = 2 + self.maxStates = 3 # Maximum number of inputs and outputs to test + 1 - self.maxIO = 2 + self.maxIO = 3 # Set to True to print systems to the output. self.debug = True Modified: branches/control-0.4a/src/statesp.py =================================================================== --- branches/control-0.4a/src/statesp.py 2011-02-08 22:18:23 UTC (rev 105) +++ branches/control-0.4a/src/statesp.py 2011-02-08 22:18:27 UTC (rev 106) @@ -449,9 +449,9 @@ 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)]) - #print index - #print den - #print num + # TODO: transfer function to state space conversion is still buggy! + print "Warning: transfer function to state space conversion by td04ad \ +is still buggy!" ssout = td04ad(sys.inputs, sys.outputs, index, den, num) states = ssout[0] Modified: branches/control-0.4a/src/xferfcn.py =================================================================== --- branches/control-0.4a/src/xferfcn.py 2011-02-08 22:18:23 UTC (rev 105) +++ branches/control-0.4a/src/xferfcn.py 2011-02-08 22:18:27 UTC (rev 106) @@ -697,7 +697,10 @@ raise TypeError("If sys is a StateSpace, _convertToTransferFunction \ cannot take keywords.") - # Use Slycot to make the transformation. + # Use Slycot to make the transformation. TODO: this is still somewhat + # buggy! + print "Warning: state space to transfer function conversion by tb04ad \ +is still buggy!" tfout = tb04ad(sys.states, sys.inputs, sys.outputs, sys.A, sys.B, sys.C, sys.D, sys.outputs, sys.outputs, sys.inputs) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:18:29
|
Revision: 105 http://python-control.svn.sourceforge.net/python-control/?rev=105&view=rev Author: kkchen Date: 2011-02-08 22:18:23 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Modified _common_den to handle complex roots more accurately. Minor changes in TestConvert.py and TestBDAlg.py. Kevin K. Chen <kk...@pr...> Modified Paths: -------------- branches/control-0.4a/src/TestBDAlg.py branches/control-0.4a/src/TestConvert.py branches/control-0.4a/src/xferfcn.py Modified: branches/control-0.4a/src/TestBDAlg.py =================================================================== --- branches/control-0.4a/src/TestBDAlg.py 2011-02-08 22:18:19 UTC (rev 104) +++ branches/control-0.4a/src/TestBDAlg.py 2011-02-08 22:18:23 UTC (rev 105) @@ -38,7 +38,6 @@ ans1 = feedback(self.x1, self.sys2) ans2 = feedback(self.x1, self.sys2, 1.) - # This one doesn't work yet. The feedback system has too many states. np.testing.assert_array_almost_equal(ans1.A, [[-1.5, 4.], [13., 2.]]) np.testing.assert_array_almost_equal(ans1.B, [[2.5], [-10.]]) np.testing.assert_array_almost_equal(ans1.C, [[-2.5, 0.]]) @@ -65,7 +64,6 @@ ans1 = feedback(self.sys2, self.x1) ans2 = feedback(self.sys2, self.x1, 1.) - # This one doesn't work yet. The feedback system has too many states. np.testing.assert_array_almost_equal(ans1.A, [[-1.5, 4.], [13., 2.]]) np.testing.assert_array_almost_equal(ans1.B, [[1.], [-4.]]) np.testing.assert_array_almost_equal(ans1.C, [[1., 0.]]) Modified: branches/control-0.4a/src/TestConvert.py =================================================================== --- branches/control-0.4a/src/TestConvert.py 2011-02-08 22:18:19 UTC (rev 104) +++ branches/control-0.4a/src/TestConvert.py 2011-02-08 22:18:23 UTC (rev 105) @@ -4,11 +4,14 @@ Test state space and transfer function conversion. -Currently, this unit test script is not complete. It converts -several random state spaces back and forth between state space and transfer -function representations, and asserts that the conversion outputs are correct. -As it stands, tests pass but there is some rounding error in one of the conversions leading to imaginary numbers. See the warning message. This script may be used to diagnose errors. +Currently, this unit test script is not complete. It converts several random +state spaces back and forth between state space and transfer function +representations. Ideally, it should be able to assert that the conversion +outputs are correct. This is not yet implemented. +Also, the conversion seems to enter an infinite loop once in a while. The cause +of this is unknown. + """ import numpy as np @@ -22,11 +25,11 @@ """Set up testing parameters.""" # Number of times to run each of the randomized tests. - self.numTests = 1 + self.numTests = 10 # Maximum number of states to test + 1 - self.maxStates = 3 + self.maxStates = 2 # Maximum number of inputs and outputs to test + 1 - self.maxIO = 3 + self.maxIO = 2 # Set to True to print systems to the output. self.debug = True Modified: branches/control-0.4a/src/xferfcn.py =================================================================== --- branches/control-0.4a/src/xferfcn.py 2011-02-08 22:18:19 UTC (rev 104) +++ branches/control-0.4a/src/xferfcn.py 2011-02-08 22:18:23 UTC (rev 105) @@ -75,8 +75,8 @@ """ # External function declarations -from numpy import angle, array, empty, finfo, insert, ndarray, ones, polyadd, \ - polymul, polyval, roots, sort, zeros +from numpy import angle, any, array, empty, finfo, insert, ndarray, ones, \ + polyadd, polymul, polyval, roots, sort, sqrt, zeros from scipy.signal import lti from copy import deepcopy from slycot import tb04ad @@ -491,7 +491,10 @@ [something] array. """ - + + # Machine precision for floats. + eps = finfo(float).eps + # A sorted list to keep track of cumulative poles found as we scan # self.den. poles = [] @@ -512,8 +515,7 @@ # cumulative poles, until one of them reaches the end. Keep in # mind that both lists are always sorted. while cp_ind < len(currentpoles) and p_ind < len(poles): - if abs(currentpoles[cp_ind] - poles[p_ind]) < (10 * - finfo(float).eps): + if abs(currentpoles[cp_ind] - poles[p_ind]) < (10 * eps): # If the current element of both lists match, then we're # good. Move to the next pair of elements. cp_ind += 1 @@ -558,9 +560,22 @@ # Construct the common denominator. den = 1. - for p in poles: - den = polymul(den, [1., -p]) + n = 0 + while n < len(poles): + 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 < eps), "The quadratic has a nontrivial \ +imaginary part: %g" % quad.imag.max() + quad = quad.real + den = polymul(den, quad) + n += 2 + else: + den = polymul(den, [1., -poles[n].real]) + n += 1 + # Modify the numerators so that they each take the common denominator. num = deepcopy(self.num) for i in range(self.outputs): @@ -585,6 +600,11 @@ zeros(largest - len(num[i][j]))) # 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" + % abs(num.imag).max()) + num = num.real return num, den This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:18:25
|
Revision: 104 http://python-control.svn.sourceforge.net/python-control/?rev=104&view=rev Author: kkchen Date: 2011-02-08 22:18:19 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Changed the message in TestConvert.py so that it reads there is a complex numbers error but all of the tests pass. This error is due to rounding in the common denominator routine. It can be seen by printing num, den right before passing to td04ad in _convertToStateSpace. td04ad can only have real proper transfer functions (although the roots of course can still be imaginary.) Have also added TestSlycot.py which can be used to isolate debugging slycot routines from python-control. Lauren Padilla <lpa...@pr...> Modified Paths: -------------- branches/control-0.4a/src/TestConvert.py branches/control-0.4a/src/statesp.py Added Paths: ----------- branches/control-0.4a/src/TestSlycot.py Modified: branches/control-0.4a/src/TestConvert.py =================================================================== --- branches/control-0.4a/src/TestConvert.py 2011-02-08 22:18:14 UTC (rev 103) +++ branches/control-0.4a/src/TestConvert.py 2011-02-08 22:18:19 UTC (rev 104) @@ -4,11 +4,10 @@ Test state space and transfer function conversion. -Currently, this unit test script is not complete. Ideally, it would convert +Currently, this unit test script is not complete. It converts several random state spaces back and forth between state space and transfer -function representations, and assert that the conversion outputs are correct. -As they currently stand, the td04ad and tb04ad functions appear to be buggy from -time to time. Therefore, this script can be used to diagnose the errors. +function representations, and asserts that the conversion outputs are correct. +As it stands, tests pass but there is some rounding error in one of the conversions leading to imaginary numbers. See the warning message. This script may be used to diagnose errors. """ @@ -29,7 +28,7 @@ # Maximum number of inputs and outputs to test + 1 self.maxIO = 3 # Set to True to print systems to the output. - self.debug = False + self.debug = True def printSys(self, sys, ind): """Print system to the standard output.""" @@ -51,7 +50,7 @@ sys2 = matlab.tf(sys1) self.printSys(sys2, 2) - + sys3 = matlab.ss(sys2) self.printSys(sys3, 3) Added: branches/control-0.4a/src/TestSlycot.py =================================================================== --- branches/control-0.4a/src/TestSlycot.py (rev 0) +++ branches/control-0.4a/src/TestSlycot.py 2011-02-08 22:18:19 UTC (rev 104) @@ -0,0 +1,30 @@ +import numpy as np +from slycot import tb04ad, td04ad +import matlab + +numTests = 1 +maxStates = 3 +maxIO = 3 + +for states in range(1, maxStates): + for inputs in range(1, maxIO): + for outputs in range(1, maxIO): + sys1 = matlab.rss(states, inputs, outputs) + print "sys1" + print sys1 + + sys2 = tb04ad(states,inputs,outputs,sys1.A,sys1.B,sys1.C,sys1.D,outputs,outputs,inputs) + print "sys2" + print sys2 + + ldwork = 100*max(1,states+max(states,max(3*inputs,3*outputs))) + dwork = np.zeros(ldwork) + sys3 = td04ad(inputs,outputs,sys2[4],sys2[5],sys2[6]) + #sys3 = td04ad(inputs,outputs,sys2[4],sys2[5],sys2[6],ldwork) + print "sys3" + print sys3 + + sys4 = tb04ad(states,inputs,outputs,sys3[1][0:states,0:states],sys3[2][0:states,0:inputs],sys3[3][0:outputs,0:states],sys3[4],outputs,outputs,inputs) + print "sys4" + print sys4 + Modified: branches/control-0.4a/src/statesp.py =================================================================== --- branches/control-0.4a/src/statesp.py 2011-02-08 22:18:14 UTC (rev 103) +++ branches/control-0.4a/src/statesp.py 2011-02-08 22:18:19 UTC (rev 104) @@ -449,9 +449,11 @@ 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)]) - + #print index + #print den + #print num ssout = td04ad(sys.inputs, sys.outputs, index, den, num) - + states = ssout[0] return StateSpace(ssout[1][:states, :states], ssout[2][:states, :sys.inputs], This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:18:20
|
Revision: 103 http://python-control.svn.sourceforge.net/python-control/?rev=103&view=rev Author: kkchen Date: 2011-02-08 22:18:14 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Changed gram back to not needed 'deepcopy' now that slycot sb03md is fixed. Also added a unittest to check that an exception is raised when gram is give something other than StateSpace object. Lauren Padilla <lpa...@pr...> Modified Paths: -------------- branches/control-0.4a/doc/Makefile branches/control-0.4a/src/TestStatefbk.py branches/control-0.4a/src/statefbk.py Modified: branches/control-0.4a/doc/Makefile =================================================================== --- branches/control-0.4a/doc/Makefile 2011-02-08 22:18:08 UTC (rev 102) +++ branches/control-0.4a/doc/Makefile 2011-02-08 22:18:14 UTC (rev 103) @@ -3,7 +3,7 @@ # You can set these variables from the command line. SPHINXOPTS = -SPHINXBUILD = /Users/steve/CODES/Sphinx-1.0.6/sphinx-build.py +SPHINXBUILD = /Applications/Sphinx-1.0.6/sphinx-build.py PAPER = BUILDDIR = _build Modified: branches/control-0.4a/src/TestStatefbk.py =================================================================== --- branches/control-0.4a/src/TestStatefbk.py 2011-02-08 22:18:08 UTC (rev 102) +++ branches/control-0.4a/src/TestStatefbk.py 2011-02-08 22:18:14 UTC (rev 103) @@ -73,6 +73,12 @@ Wo = gram(sys,'o') np.testing.assert_array_almost_equal(Wo, Wotrue) + def testGramsys(self): + num =[1.] + den = [1., 1., 1.] + sys = tf(num,den) + self.assertRaises(ValueError, gram, sys, 'o') + self.assertRaises(ValueError, gram, sys, 'c') if __name__ == '__main__': unittest.main() Modified: branches/control-0.4a/src/statefbk.py =================================================================== --- branches/control-0.4a/src/statefbk.py 2011-02-08 22:18:08 UTC (rev 102) +++ branches/control-0.4a/src/statefbk.py 2011-02-08 22:18:14 UTC (rev 103) @@ -43,6 +43,7 @@ import numpy as np import ctrlutil from exception import * +import statesp # Pole placement def place(A, B, p): @@ -255,6 +256,7 @@ Raises ------ ValueError + if system is not instance of StateSpace class if `type` is not 'c' or 'o' if system is unstable (sys.A has eigenvalues not in left half plane) ImportError @@ -267,10 +269,10 @@ """ - from copy import deepcopy - - #Check for ss system object, need a utility for this? - + #Check for ss system object + if not isinstance(sys,statesp.StateSpace): + raise ValueError, "System must be StateSpace!" + #TODO: Check for continous or discrete, only continuous supported right now # if isCont(): # dico = 'C' @@ -302,7 +304,7 @@ raise ControlSlycot("can't find slycot module 'sb03md'") n = sys.states U = np.zeros((n,n)) - A = deepcopy(sys.A) + A = sys.A out = sb03md(n, C, A, U, dico, 'X', 'N', trana) gram = out[0] return gram This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:18:17
|
Revision: 102 http://python-control.svn.sourceforge.net/python-control/?rev=102&view=rev Author: kkchen Date: 2011-02-08 22:18:08 +0000 (Tue, 08 Feb 2011) Log Message: ----------- convertTo{StateSpace,TransferFunction} made 'private'. Kevin K. Chen <kk...@pr...> Modified Paths: -------------- branches/control-0.4a/src/TestXferFcn.py branches/control-0.4a/src/bdalg.py branches/control-0.4a/src/matlab.py branches/control-0.4a/src/statesp.py branches/control-0.4a/src/xferfcn.py Modified: branches/control-0.4a/src/TestXferFcn.py =================================================================== --- branches/control-0.4a/src/TestXferFcn.py 2011-02-08 22:18:03 UTC (rev 101) +++ branches/control-0.4a/src/TestXferFcn.py 2011-02-08 22:18:08 UTC (rev 102) @@ -2,7 +2,7 @@ import numpy as np from statesp import StateSpace -from xferfcn import TransferFunction, convertToTransferFunction +from xferfcn import TransferFunction, _convertToTransferFunction import unittest class TestXferFcn(unittest.TestCase): @@ -417,7 +417,7 @@ D = [[1., 0.], [0., 1.], [1., 0.]] sys = StateSpace(A, B, C, D) - tfsys = convertToTransferFunction(sys) + tfsys = _convertToTransferFunction(sys) num = [[np.array([1., -7., 10.]), np.array([-1., 10.])], [np.array([2., -8.]), np.array([1., -2., -8.])], Modified: branches/control-0.4a/src/bdalg.py =================================================================== --- branches/control-0.4a/src/bdalg.py 2011-02-08 22:18:03 UTC (rev 101) +++ branches/control-0.4a/src/bdalg.py 2011-02-08 22:18:08 UTC (rev 102) @@ -211,11 +211,11 @@ # its feedback member function. if isinstance(sys1, (int, long, float, complex)): if isinstance(sys2, tf.TransferFunction): - sys1 = tf.convertToTransferFunction(sys1) + sys1 = tf._convertToTransferFunction(sys1) elif isinstance(sys2, ss.StateSpace): - sys1 = ss.convertToStateSpace(sys1) + sys1 = ss._convertToStateSpace(sys1) else: # sys2 is a scalar. - sys1 = tf.convertToTransferFunction(sys1) - sys2 = tf.convertToTransferFunction(sys2) + sys1 = tf._convertToTransferFunction(sys1) + sys2 = tf._convertToTransferFunction(sys2) return sys1.feedback(sys2, sign) Modified: branches/control-0.4a/src/matlab.py =================================================================== --- branches/control-0.4a/src/matlab.py 2011-02-08 22:18:03 UTC (rev 101) +++ branches/control-0.4a/src/matlab.py 2011-02-08 22:18:08 UTC (rev 102) @@ -67,8 +67,8 @@ # Control system library import ctrlutil import freqplot -from statesp import StateSpace, _rss_generate, convertToStateSpace -from xferfcn import TransferFunction, convertToTransferFunction +from statesp import StateSpace, _rss_generate, _convertToStateSpace +from xferfcn import TransferFunction, _convertToTransferFunction from exception import ControlArgument # Import MATLAB-like functions that can be used as-is @@ -413,12 +413,12 @@ if len(args) == 4: # Assume we were given the A, B, C, D matrix - return convertToTransferFunction(StateSpace(args[0], args[1], args[2], + return _convertToTransferFunction(StateSpace(args[0], args[1], args[2], args[3])) elif len(args) == 1: sys = args[0] if isinstance(sys, StateSpace): - return convertToTransferFunction(sys) + return _convertToTransferFunction(sys) else: raise TypeError("ss2tf(sys): sys must be a StateSpace object. It \ is %s." % type(sys)) @@ -472,13 +472,13 @@ if len(args) == 2: # Assume we were given the num, den - return convertToStateSpace(TransferFunction(args[0], args[1])) + return _convertToStateSpace(TransferFunction(args[0], args[1])) elif len(args) == 1: sys = args[0] if not isinstance(sys, TransferFunction): raise TypeError("tf2ss(sys): sys must be a TransferFunction \ object.") - return convertToStateSpace(sys) + return _convertToStateSpace(sys) else: raise ValueError("Needs 1 or 2 arguments; received %i." % len(args)) Modified: branches/control-0.4a/src/statesp.py =================================================================== --- branches/control-0.4a/src/statesp.py 2011-02-08 22:18:03 UTC (rev 101) +++ branches/control-0.4a/src/statesp.py 2011-02-08 22:18:08 UTC (rev 102) @@ -27,7 +27,7 @@ StateSpace.zero StateSpace.feedback StateSpace.returnScipySignalLti -convertToStateSpace +_convertToStateSpace _rss_generate """ @@ -197,7 +197,7 @@ A, B, C = self.A, self.B, self.C; D = self.D + other; else: - other = convertToStateSpace(other) + other = _convertToStateSpace(other) # Check to make sure the dimensions are OK if ((self.inputs != other.inputs) or @@ -245,7 +245,7 @@ C = self.C * other D = self.D * other else: - other = convertToStateSpace(other) + other = _convertToStateSpace(other) # Check to make sure the dimensions are OK if self.inputs != other.outputs: @@ -357,7 +357,7 @@ def feedback(self, other, sign=-1): """Feedback interconnection between two LTI systems.""" - other = convertToStateSpace(other) + other = _convertToStateSpace(other) # Check to make sure the dimensions are OK if ((self.inputs != other.outputs) or (self.outputs != other.inputs)): @@ -414,7 +414,7 @@ return out -def convertToStateSpace(sys, **kw): +def _convertToStateSpace(sys, **kw): """Convert a system to state space form (if needed). If sys is already a state space, then it is returned. If sys is a transfer @@ -422,8 +422,8 @@ is a scalar, then the number of inputs and outputs can be specified manually, as in: - >>> sys = convertToStateSpace(3.) # Assumes inputs = outputs = 1 - >>> sys = convertToStateSpace(1., inputs=3, outputs=2) + >>> sys = _convertToStateSpace(3.) # Assumes inputs = outputs = 1 + >>> sys = _convertToStateSpace(1., inputs=3, outputs=2) In the latter example, A = B = C = 0 and D = [[1., 1., 1.] [1., 1., 1.]]. @@ -432,14 +432,14 @@ if isinstance(sys, StateSpace): if len(kw): - raise TypeError("If sys is a StateSpace, convertToStateSpace \ + raise TypeError("If sys is a StateSpace, _convertToStateSpace \ cannot take keywords.") # Already a state space system; just return it return sys elif isinstance(sys, xferfcn.TransferFunction): if len(kw): - raise TypeError("If sys is a TransferFunction, convertToStateSpace \ + raise TypeError("If sys is a TransferFunction, _convertToStateSpace \ cannot take keywords.") # Change the numerator and denominator arrays so that the transfer Modified: branches/control-0.4a/src/xferfcn.py =================================================================== --- branches/control-0.4a/src/xferfcn.py 2011-02-08 22:18:03 UTC (rev 101) +++ branches/control-0.4a/src/xferfcn.py 2011-02-08 22:18:08 UTC (rev 102) @@ -30,7 +30,7 @@ TransferFunction._common_den _tfpolyToString _addSISO -convertToTransferFunction +_convertToTransferFunction """ @@ -261,7 +261,7 @@ # Convert the second argument to a transfer function. if not isinstance(other, TransferFunction): - other = convertToTransferFunction(other, inputs=self.inputs, + other = _convertToTransferFunction(other, inputs=self.inputs, outputs=self.outputs) # Check that the input-output sizes are consistent. @@ -303,10 +303,10 @@ # Convert the second argument to a transfer function. if isinstance(other, (int, float, long, complex)): - other = convertToTransferFunction(other, inputs=self.inputs, + other = _convertToTransferFunction(other, inputs=self.inputs, outputs=self.inputs) else: - other = convertToTransferFunction(other) + other = _convertToTransferFunction(other) # Check that the input-output sizes are consistent. if self.inputs != other.outputs: @@ -350,7 +350,7 @@ implemented only for SISO systems.") # Convert the second argument to a transfer function. - other = convertToTransferFunction(other) + other = _convertToTransferFunction(other) num = polymul(self.num[0][0], other.den[0][0]) den = polymul(self.den[0][0], other.num[0][0]) @@ -435,7 +435,7 @@ def feedback(self, other, sign=-1): """Feedback interconnection between two LTI objects.""" - other = convertToTransferFunction(other) + other = _convertToTransferFunction(other) if (self.inputs > 1 or self.outputs > 1 or other.inputs > 1 or other.outputs > 1): @@ -650,7 +650,7 @@ return num, den -def convertToTransferFunction(sys, **kw): +def _convertToTransferFunction(sys, **kw): """Convert a system to transfer function form (if needed). If sys is already a transfer function, then it is returned. If sys is a @@ -658,8 +658,8 @@ returned. If sys is a scalar, then the number of inputs and outputs can be specified manually, as in: - >>> sys = convertToTransferFunction(3.) # Assumes inputs = outputs = 1 - >>> sys = convertToTransferFunction(1., inputs=3, outputs=2) + >>> sys = _convertToTransferFunction(3.) # Assumes inputs = outputs = 1 + >>> sys = _convertToTransferFunction(1., inputs=3, outputs=2) In the latter example, sys's matrix transfer function is [[1., 1., 1.] [1., 1., 1.]]. @@ -669,12 +669,12 @@ if isinstance(sys, TransferFunction): if len(kw): raise TypeError("If sys is a TransferFunction, \ -convertToTransferFunction cannot take keywords.") +_convertToTransferFunction cannot take keywords.") return sys elif isinstance(sys, statesp.StateSpace): if len(kw): - raise TypeError("If sys is a StateSpace, convertToTransferFunction \ + raise TypeError("If sys is a StateSpace, _convertToTransferFunction \ cannot take keywords.") # Use Slycot to make the transformation. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:18:09
|
Revision: 101 http://python-control.svn.sourceforge.net/python-control/?rev=101&view=rev Author: kkchen Date: 2011-02-08 22:18:03 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Modified TestConvert.py so that future developers can understand its issues. Kevin K. Chen <kk...@pr...> Modified Paths: -------------- branches/control-0.4a/src/TestConvert.py Modified: branches/control-0.4a/src/TestConvert.py =================================================================== --- branches/control-0.4a/src/TestConvert.py 2011-02-08 22:17:59 UTC (rev 100) +++ branches/control-0.4a/src/TestConvert.py 2011-02-08 22:18:03 UTC (rev 101) @@ -1,5 +1,17 @@ #!/usr/bin/env python +"""TestConvert.py + +Test state space and transfer function conversion. + +Currently, this unit test script is not complete. Ideally, it would convert +several random state spaces back and forth between state space and transfer +function representations, and assert that the conversion outputs are correct. +As they currently stand, the td04ad and tb04ad functions appear to be buggy from +time to time. Therefore, this script can be used to diagnose the errors. + +""" + import numpy as np import matlab import unittest @@ -11,26 +23,40 @@ """Set up testing parameters.""" # Number of times to run each of the randomized tests. - self.numTests = 10 + self.numTests = 1 # Maximum number of states to test + 1 - self.maxStates = 5 + self.maxStates = 3 # Maximum number of inputs and outputs to test + 1 - self.maxIO = 5 + self.maxIO = 3 + # Set to True to print systems to the output. + self.debug = False + def printSys(self, sys, ind): + """Print system to the standard output.""" + + if self.debug: + print "sys%i:\n" % ind + print sys + def testConvert(self): """Test state space to transfer function conversion.""" + + print __doc__ for states in range(1, self.maxStates): for inputs in range(1, self.maxIO): for outputs in range(1, self.maxIO): - sys = matlab.rss(states, inputs, outputs) - print "sys1:\n", sys - sys2 = matlab.tf(sys) - print "sys2:\n", sys2 - #sys3 = matlab.ss(sys2) - #print "sys3:\n", sys3 - #sys4 = matlab.tf(sys3) - #print "sys4:\n", sys4 + sys1 = matlab.rss(states, inputs, outputs) + self.printSys(sys1, 1) + sys2 = matlab.tf(sys1) + self.printSys(sys2, 2) + + sys3 = matlab.ss(sys2) + self.printSys(sys3, 3) + + sys4 = matlab.tf(sys3) + self.printSys(sys4, 4) + if __name__ == "__main__": unittest.main() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:18:05
|
Revision: 100 http://python-control.svn.sourceforge.net/python-control/?rev=100&view=rev Author: kkchen Date: 2011-02-08 22:17:59 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Removed the system copying in hsvd. Kevin K. Chen <kk...@pr...> Modified Paths: -------------- branches/control-0.4a/src/modelsimp.py Modified: branches/control-0.4a/src/modelsimp.py =================================================================== --- branches/control-0.4a/src/modelsimp.py 2011-02-08 22:17:55 UTC (rev 99) +++ branches/control-0.4a/src/modelsimp.py 2011-02-08 22:17:59 UTC (rev 100) @@ -72,9 +72,8 @@ >>> H = hsvd(sys) """ - sys2 = StateSpace(sys.A,sys.B,sys.C,sys.D) Wc = gram(sys,'c') - Wo = gram(sys2,'o') + Wo = gram(sys,'o') WoWc = np.dot(Wo, Wc) w, v = np.linalg.eig(WoWc) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:18:02
|
Revision: 99 http://python-control.svn.sourceforge.net/python-control/?rev=99&view=rev Author: kkchen Date: 2011-02-08 22:17:55 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Implemented deep copy of A in gram. This is a temporary solution. Kevin K. Chen <kk...@pr...> Modified Paths: -------------- branches/control-0.4a/src/statefbk.py Modified: branches/control-0.4a/src/statefbk.py =================================================================== --- branches/control-0.4a/src/statefbk.py 2011-02-08 22:17:51 UTC (rev 98) +++ branches/control-0.4a/src/statefbk.py 2011-02-08 22:17:55 UTC (rev 99) @@ -266,6 +266,9 @@ >>> Wo = gram(sys,'o') """ + + from copy import deepcopy + #Check for ss system object, need a utility for this? #TODO: Check for continous or discrete, only continuous supported right now @@ -299,7 +302,8 @@ raise ControlSlycot("can't find slycot module 'sb03md'") n = sys.states U = np.zeros((n,n)) - out = sb03md(n, C, sys.A, U, dico, 'X', 'N', trana) + A = deepcopy(sys.A) + out = sb03md(n, C, A, U, dico, 'X', 'N', trana) gram = out[0] return gram This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:17:57
|
Revision: 98 http://python-control.svn.sourceforge.net/python-control/?rev=98&view=rev Author: kkchen Date: 2011-02-08 22:17:51 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Added a copy() deepcopy routine to Lti subclasses. Also renamed rss_generate to _rss_generate and corrected some comments. Kevin K. Chen <kk...@pr...> Modified Paths: -------------- branches/control-0.4a/src/bdalg.py branches/control-0.4a/src/lti.py branches/control-0.4a/src/matlab.py branches/control-0.4a/src/statesp.py branches/control-0.4a/src/xferfcn.py Modified: branches/control-0.4a/src/bdalg.py =================================================================== --- branches/control-0.4a/src/bdalg.py 2011-02-08 22:17:44 UTC (rev 97) +++ branches/control-0.4a/src/bdalg.py 2011-02-08 22:17:51 UTC (rev 98) @@ -9,7 +9,9 @@ negate feedback -Copyright (c) 2010 by California Institute of Technology +""" + +"""Copyright (c) 2010 by California Institute of Technology All rights reserved. Redistribution and use in source and binary forms, with or without Modified: branches/control-0.4a/src/lti.py =================================================================== --- branches/control-0.4a/src/lti.py 2011-02-08 22:17:44 UTC (rev 97) +++ branches/control-0.4a/src/lti.py 2011-02-08 22:17:51 UTC (rev 98) @@ -21,6 +21,7 @@ "virtual" functions. These are: __init__ + copy __str__ __neg__ __add__ Modified: branches/control-0.4a/src/matlab.py =================================================================== --- branches/control-0.4a/src/matlab.py 2011-02-08 22:17:44 UTC (rev 97) +++ branches/control-0.4a/src/matlab.py 2011-02-08 22:17:51 UTC (rev 98) @@ -13,7 +13,9 @@ have the same names as their MATLAB equivalents are automatically imported here. -Copyright (c) 2009 by California Institute of Technology +""" + +"""Copyright (c) 2009 by California Institute of Technology All rights reserved. Redistribution and use in source and binary forms, with or without @@ -65,7 +67,7 @@ # Control system library import ctrlutil import freqplot -from statesp import StateSpace, rss_generate, convertToStateSpace +from statesp import StateSpace, _rss_generate, convertToStateSpace from xferfcn import TransferFunction, convertToTransferFunction from exception import ControlArgument @@ -511,7 +513,7 @@ """ - return rss_generate(states, inputs, outputs, 'c') + return _rss_generate(states, inputs, outputs, 'c') def drss(states=1, inputs=1, outputs=1): """ @@ -544,7 +546,7 @@ """ - return rss_generate(states, inputs, outputs, 'd') + return _rss_generate(states, inputs, outputs, 'd') def pole(sys): """ Modified: branches/control-0.4a/src/statesp.py =================================================================== --- branches/control-0.4a/src/statesp.py 2011-02-08 22:17:44 UTC (rev 97) +++ branches/control-0.4a/src/statesp.py 2011-02-08 22:17:51 UTC (rev 98) @@ -9,6 +9,8 @@ Routines in this module: StateSpace.__init__ +StateSpace._remove_useless_states +StateSpace.copy StateSpace.__str__ StateSpace.__neg__ StateSpace.__add__ @@ -26,9 +28,11 @@ StateSpace.feedback StateSpace.returnScipySignalLti convertToStateSpace -rss_generate +_rss_generate -Copyright (c) 2010 by California Institute of Technology +""" + +"""Copyright (c) 2010 by California Institute of Technology All rights reserved. Redistribution and use in source and binary forms, with or without @@ -74,6 +78,7 @@ from numpy.linalg import inv, det, solve from numpy.linalg.linalg import LinAlgError from scipy.signal import lti +from copy import deepcopy from slycot import td04ad from lti import Lti import xferfcn @@ -162,6 +167,11 @@ self.B = delete(self.B, useless, 0) self.C = delete(self.C, useless, 1) + def copy(self): + """Return a deep copy of the instance.""" + + return deepcopy(self) + def __str__(self): """String representation of the state space.""" @@ -207,9 +217,9 @@ return StateSpace(A, B, C, D) - # Reverse addition - just switch the arguments + # Right addition - just switch the arguments def __radd__(self, other): - """Reverse add two LTI systems (parallel connection).""" + """Right add two LTI systems (parallel connection).""" return self + other @@ -220,7 +230,7 @@ return self + (-other) def __rsub__(self, other): - """Reverse subtract two LTI systems.""" + """Right subtract two LTI systems.""" return other + (-self) @@ -253,10 +263,10 @@ return StateSpace(A, B, C, D) - # Reverse multiplication of two transfer functions (series interconnection) + # Right multiplication of two transfer functions (series interconnection) # Just need to convert LH argument to a state space object def __rmul__(self, other): - """Reverse multiply two LTI objects (serial connection).""" + """Right multiply two LTI objects (serial connection).""" # Check for a couple of special cases if isinstance(other, (int, long, float, complex)): @@ -276,7 +286,7 @@ raise NotImplementedError("StateSpace.__div__ is not implemented yet.") def __rdiv__(self, other): - """Reverse divide two LTI systems.""" + """Right divide two LTI systems.""" raise NotImplementedError("StateSpace.__rdiv__ is not implemented yet.") @@ -465,7 +475,7 @@ else: raise TypeError("Can't convert given type to StateSpace system.") -def rss_generate(states, inputs, outputs, type): +def _rss_generate(states, inputs, outputs, type): """Generate a random state space. This does the actual random state space generation expected from rss and Modified: branches/control-0.4a/src/xferfcn.py =================================================================== --- branches/control-0.4a/src/xferfcn.py 2011-02-08 22:17:44 UTC (rev 97) +++ branches/control-0.4a/src/xferfcn.py 2011-02-08 22:17:51 UTC (rev 98) @@ -10,6 +10,7 @@ TransferFunction.__init__ TransferFunction._truncatecoeff +TransferFunction.copy TransferFunction.__str__ TransferFunction.__neg__ TransferFunction.__add__ @@ -31,7 +32,9 @@ _addSISO convertToTransferFunction -Copyright (c) 2010 by California Institute of Technology +""" + +"""Copyright (c) 2010 by California Institute of Technology All rights reserved. Redistribution and use in source and binary forms, with or without @@ -208,6 +211,11 @@ data[p][i][j] = data[p][i][j][nonzero:] [self.num, self.den] = data + def copy(self): + """Return a deep copy of the instance.""" + + return deepcopy(self) + def __str__(self): """String representation of the transfer function.""" @@ -276,7 +284,7 @@ return TransferFunction(num, den) def __radd__(self, other): - """Reverse add two LTI objects (parallel connection).""" + """Right add two LTI objects (parallel connection).""" return self + other; @@ -286,7 +294,7 @@ return self + (-other) def __rsub__(self, other): - """Reverse subtract two LTI objects.""" + """Right subtract two LTI objects.""" return other + (-self) @@ -328,7 +336,7 @@ return TransferFunction(num, den) def __rmul__(self, other): - """Reverse multiply two LTI objects (serial connection).""" + """Right multiply two LTI objects (serial connection).""" return self * other @@ -351,7 +359,7 @@ # TODO: Division of MIMO transfer function objects is not written yet. def __rdiv__(self, other): - """Reverse divide two LTI objects.""" + """Right divide two LTI objects.""" if (self.inputs > 1 or self.outputs > 1 or other.inputs > 1 or other.outputs > 1): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:17:50
|
Revision: 97 http://python-control.svn.sourceforge.net/python-control/?rev=97&view=rev Author: kkchen Date: 2011-02-08 22:17:44 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Removed testBalredMatchDC from TestModelsimp.py. Kevin K. Chen <kk...@pr...> Modified Paths: -------------- branches/control-0.4a/src/TestModelsimp.py Modified: branches/control-0.4a/src/TestModelsimp.py =================================================================== --- branches/control-0.4a/src/TestModelsimp.py 2011-02-08 22:17:40 UTC (rev 96) +++ branches/control-0.4a/src/TestModelsimp.py 2011-02-08 22:17:44 UTC (rev 97) @@ -66,28 +66,6 @@ np.testing.assert_array_almost_equal(rsys.C, Crtrue) np.testing.assert_array_almost_equal(rsys.D, Drtrue) -# def testBalredMatchDC(self): -# #controlable canonical realization computed in matlab for the transfer function: -# # num = [1 11 45 32], den = [1 15 60 200 60] -# A = np.matrix('-15., -7.5, -6.25, -1.875; \ -# 8., 0., 0., 0.; \ -# 0., 4., 0., 0.; \ -# 0., 0., 1., 0.') -# B = np.matrix('2.; 0.; 0.; 0.') -# C = np.matrix('0.5, 0.6875, 0.7031, 0.5') -# D = np.matrix('0.') -# sys = ss(A,B,C,D) -# orders = 1 -# rsys = balred(sys,orders,method='matchdc') -# Artrue = np.matrix('-0.566') -# Brtrue = np.matrix('-0.414') -# Crtrue = np.matrix('-0.5728') -# Drtrue = np.matrix('0.1145') -# np.testing.assert_array_almost_equal(sys.A, Artrue) -# np.testing.assert_array_almost_equal(sys.B, Brtrue) -# np.testing.assert_array_almost_equal(sys.C, Crtrue) -# np.testing.assert_array_almost_equal(sys.D, Drtrue) - def testBalredTruncate(self): #controlable canonical realization computed in matlab for the transfer function: # num = [1 11 45 32], den = [1 15 60 200 60] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:17:46
|
Revision: 96 http://python-control.svn.sourceforge.net/python-control/?rev=96&view=rev Author: kkchen Date: 2011-02-08 22:17:40 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Made a couple changes to make hsvd pass tests. Steven Brunton <sbr...@pr...> Modified Paths: -------------- branches/control-0.4a/src/TestMatlab.py branches/control-0.4a/src/TestModelsimp.py branches/control-0.4a/src/TestStatefbk.py branches/control-0.4a/src/modelsimp.py branches/control-0.4a/src/statefbk.py Modified: branches/control-0.4a/src/TestMatlab.py =================================================================== --- branches/control-0.4a/src/TestMatlab.py 2011-02-08 22:17:34 UTC (rev 95) +++ branches/control-0.4a/src/TestMatlab.py 2011-02-08 22:17:40 UTC (rev 96) @@ -27,17 +27,17 @@ youttrue = np.matrix("86. 70.1808 57.3753 46.9975 38.5766 31.7344 26.1668 21.6292 17.9245 14.8945") np.testing.assert_array_almost_equal(yout, youttrue,decimal=4) - def testInitial(self): - A = np.matrix("1. -2.; 3. -4.") - B = np.matrix("5.; 7.") - C = np.matrix("6. 8.") - D = np.matrix("9.") - sys = ss(A,B,C,D) - t = np.linspace(0, 1, 10) - x0 = np.matrix(".5; 1.") - t, yout = initial(sys, T=t, X0=x0) - youttrue = np.matrix("11. 8.1494 5.9361 4.2258 2.9118 1.9092 1.1508 0.5833 0.1645 -0.1391") - np.testing.assert_array_almost_equal(yout, youttrue,decimal=4) +# def testInitial(self): +# A = np.matrix("1. -2.; 3. -4.") +# B = np.matrix("5.; 7.") +# C = np.matrix("6. 8.") +# D = np.matrix("9.") +# sys = ss(A,B,C,D) +# t = np.linspace(0, 1, 10) +# x0 = np.matrix(".5; 1.") +# t, yout = initial(sys, T=t, X0=x0) +# youttrue = np.matrix("11. 8.1494 5.9361 4.2258 2.9118 1.9092 1.1508 0.5833 0.1645 -0.1391") +# np.testing.assert_array_almost_equal(yout, youttrue,decimal=4) if __name__ == '__main__': Modified: branches/control-0.4a/src/TestModelsimp.py =================================================================== --- branches/control-0.4a/src/TestModelsimp.py 2011-02-08 22:17:34 UTC (rev 95) +++ branches/control-0.4a/src/TestModelsimp.py 2011-02-08 22:17:40 UTC (rev 96) @@ -66,27 +66,27 @@ np.testing.assert_array_almost_equal(rsys.C, Crtrue) np.testing.assert_array_almost_equal(rsys.D, Drtrue) - def testBalredMatchDC(self): - #controlable canonical realization computed in matlab for the transfer function: - # num = [1 11 45 32], den = [1 15 60 200 60] - A = np.matrix('-15., -7.5, -6.25, -1.875; \ - 8., 0., 0., 0.; \ - 0., 4., 0., 0.; \ - 0., 0., 1., 0.') - B = np.matrix('2.; 0.; 0.; 0.') - C = np.matrix('0.5, 0.6875, 0.7031, 0.5') - D = np.matrix('0.') - sys = ss(A,B,C,D) - orders = 1 - rsys = balred(sys,orders,method='matchdc') - Artrue = np.matrix('-0.566') - Brtrue = np.matrix('-0.414') - Crtrue = np.matrix('-0.5728') - Drtrue = np.matrix('0.1145') - np.testing.assert_array_almost_equal(sys.A, Artrue) - np.testing.assert_array_almost_equal(sys.B, Brtrue) - np.testing.assert_array_almost_equal(sys.C, Crtrue) - np.testing.assert_array_almost_equal(sys.D, Drtrue) +# def testBalredMatchDC(self): +# #controlable canonical realization computed in matlab for the transfer function: +# # num = [1 11 45 32], den = [1 15 60 200 60] +# A = np.matrix('-15., -7.5, -6.25, -1.875; \ +# 8., 0., 0., 0.; \ +# 0., 4., 0., 0.; \ +# 0., 0., 1., 0.') +# B = np.matrix('2.; 0.; 0.; 0.') +# C = np.matrix('0.5, 0.6875, 0.7031, 0.5') +# D = np.matrix('0.') +# sys = ss(A,B,C,D) +# orders = 1 +# rsys = balred(sys,orders,method='matchdc') +# Artrue = np.matrix('-0.566') +# Brtrue = np.matrix('-0.414') +# Crtrue = np.matrix('-0.5728') +# Drtrue = np.matrix('0.1145') +# np.testing.assert_array_almost_equal(sys.A, Artrue) +# np.testing.assert_array_almost_equal(sys.B, Brtrue) +# np.testing.assert_array_almost_equal(sys.C, Crtrue) +# np.testing.assert_array_almost_equal(sys.D, Drtrue) def testBalredTruncate(self): #controlable canonical realization computed in matlab for the transfer function: Modified: branches/control-0.4a/src/TestStatefbk.py =================================================================== --- branches/control-0.4a/src/TestStatefbk.py 2011-02-08 22:17:34 UTC (rev 95) +++ branches/control-0.4a/src/TestStatefbk.py 2011-02-08 22:17:40 UTC (rev 96) @@ -63,5 +63,16 @@ Wo = gram(sys,'o') np.testing.assert_array_almost_equal(Wo, Wotrue) + def testGramWo2(self): + A = np.matrix("1. -2.; 3. -4.") + B = np.matrix("5.; 7.") + C = np.matrix("6. 8.") + D = np.matrix("9.") + sys = ss(A,B,C,D) + Wotrue = np.matrix("198. -72.; -72. 44.") + Wo = gram(sys,'o') + np.testing.assert_array_almost_equal(Wo, Wotrue) + + if __name__ == '__main__': unittest.main() Modified: branches/control-0.4a/src/modelsimp.py =================================================================== --- branches/control-0.4a/src/modelsimp.py 2011-02-08 22:17:34 UTC (rev 95) +++ branches/control-0.4a/src/modelsimp.py 2011-02-08 22:17:40 UTC (rev 96) @@ -72,10 +72,9 @@ >>> H = hsvd(sys) """ - + sys2 = StateSpace(sys.A,sys.B,sys.C,sys.D) Wc = gram(sys,'c') - Wo = gram(sys,'o') - + Wo = gram(sys2,'o') WoWc = np.dot(Wo, Wc) w, v = np.linalg.eig(WoWc) Modified: branches/control-0.4a/src/statefbk.py =================================================================== --- branches/control-0.4a/src/statefbk.py 2011-02-08 22:17:34 UTC (rev 95) +++ branches/control-0.4a/src/statefbk.py 2011-02-08 22:17:40 UTC (rev 96) @@ -266,7 +266,6 @@ >>> Wo = gram(sys,'o') """ - #Check for ss system object, need a utility for this? #TODO: Check for continous or discrete, only continuous supported right now @@ -283,7 +282,6 @@ for e in D: if e.real >= 0: raise ValueError, "Oops, the system is unstable!" - if type=='c': trana = 'T' C = -np.dot(sys.B,sys.B.transpose()) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:17:41
|
Revision: 95 http://python-control.svn.sourceforge.net/python-control/?rev=95&view=rev Author: kkchen Date: 2011-02-08 22:17:34 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Added Sphinx documentation in trunk/doc. See trunk/doc/README for install notes. Steven Brunton <sbr...@pr...> Added Paths: ----------- branches/control-0.4a/doc/Makefile branches/control-0.4a/doc/README branches/control-0.4a/doc/bdalg_strings.rst branches/control-0.4a/doc/class_strings.rst branches/control-0.4a/doc/conf.py branches/control-0.4a/doc/index.rst branches/control-0.4a/doc/intro.rst branches/control-0.4a/doc/matlab_strings.rst branches/control-0.4a/doc/modsimp_strings.rst Added: branches/control-0.4a/doc/Makefile =================================================================== --- branches/control-0.4a/doc/Makefile (rev 0) +++ branches/control-0.4a/doc/Makefile 2011-02-08 22:17:34 UTC (rev 95) @@ -0,0 +1,130 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = /Users/steve/CODES/Sphinx-1.0.6/sphinx-build.py +PAPER = +BUILDDIR = _build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest + +help: + @echo "Please use \`make <target>' where <target> is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/PythonControl.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PythonControl.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/PythonControl" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/PythonControl" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + make -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." Added: branches/control-0.4a/doc/README =================================================================== --- branches/control-0.4a/doc/README (rev 0) +++ branches/control-0.4a/doc/README 2011-02-08 22:17:34 UTC (rev 95) @@ -0,0 +1,15 @@ +Sphinx Documentation +-------------------- + +Note: Sphinx actually runs and imports python code, so broken code, or code not in conf.py sys.path, cannot be documented! + +1. Get Sphinx [http://sphinx.pocoo.org/] + [python setup.py build/install] + +2. Install numpydoc [http://pypi.python.org/pypi/numpydoc] + +3. In Makefile point to your own copy of sphinx-build, e.g. + [SPHINXBUILD = /Users/steve/CODES/Sphinx-1.0.6/sphinx-build.py] + +4. >> touch *.rst + >> make html [or make latex] Added: branches/control-0.4a/doc/bdalg_strings.rst =================================================================== --- branches/control-0.4a/doc/bdalg_strings.rst (rev 0) +++ branches/control-0.4a/doc/bdalg_strings.rst 2011-02-08 22:17:34 UTC (rev 95) @@ -0,0 +1,7 @@ +Block Diagram Algebra Routines +****************************** + +The Block Diagram Algebra Module +================================ +.. automodule:: bdalg + :members: Added: branches/control-0.4a/doc/class_strings.rst =================================================================== --- branches/control-0.4a/doc/class_strings.rst (rev 0) +++ branches/control-0.4a/doc/class_strings.rst 2011-02-08 22:17:34 UTC (rev 95) @@ -0,0 +1,12 @@ +Python-Control Classes +********************** + +The State Space Module +====================== +.. automodule:: statesp + :members: + +The Transfer Function Module +============================ +.. automodule:: xferfcn + :members: \ No newline at end of file Added: branches/control-0.4a/doc/conf.py =================================================================== --- branches/control-0.4a/doc/conf.py (rev 0) +++ branches/control-0.4a/doc/conf.py 2011-02-08 22:17:34 UTC (rev 95) @@ -0,0 +1,217 @@ +# -*- coding: utf-8 -*- +# +# Python Control documentation build configuration file, created by +# sphinx-quickstart on Tue Jan 11 16:11:31 2011. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath('.')) +sys.path.append(os.path.abspath('../src')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc','numpydoc'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Python Control' +copyright = u'2011, Richard M. Murray et al.' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '0.0' +# The full version, including alpha/beta/rc tags. +release = '0.0' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# "<project> v<release> documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a <link> tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'PythonControldoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +# The paper size ('letter' or 'a4'). +#latex_paper_size = 'letter' + +# The font size ('10pt', '11pt' or '12pt'). +#latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'PythonControl.tex', u'Python Control Documentation', + u'Python Control Developers', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Additional stuff for the LaTeX preamble. +#latex_preamble = '' + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'pythoncontrol', u'Python Control Documentation', + [u'Python Control Developers'], 1) +] Added: branches/control-0.4a/doc/index.rst =================================================================== --- branches/control-0.4a/doc/index.rst (rev 0) +++ branches/control-0.4a/doc/index.rst 2011-02-08 22:17:34 UTC (rev 95) @@ -0,0 +1,25 @@ +.. Python-Control documentation master file, created by + sphinx-quickstart on Thu Jan 6 09:49:36 2011. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Python-Control's documentation! +========================================== + +Contents: + +.. toctree:: + + intro + class_strings + modsimp_strings + matlab_strings + bdalg_strings + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + Added: branches/control-0.4a/doc/intro.rst =================================================================== --- branches/control-0.4a/doc/intro.rst (rev 0) +++ branches/control-0.4a/doc/intro.rst 2011-02-08 22:17:34 UTC (rev 95) @@ -0,0 +1,17 @@ +============ +Introduction +============ + +Welcome to the Python-Control project. +This is sample documentation and will include our Princeton University APC524 contribution. + +We can incorporate any existing documentation as well. For example from R.Murray's earlier tex document: + +Differences from MATLAB +----------------------- +* You must include commas in vectors. So [1 2 3] must be [1, 2, 3]. +* Functions that return multiple arguments use tuples +* Can't use braces for collections; use tuples instead +* Transfer functions are only implemented for SISO systems (due to limitations in the underlying signals.lti class); use state space representations for MIMO systems. + + Added: branches/control-0.4a/doc/matlab_strings.rst =================================================================== --- branches/control-0.4a/doc/matlab_strings.rst (rev 0) +++ branches/control-0.4a/doc/matlab_strings.rst 2011-02-08 22:17:34 UTC (rev 95) @@ -0,0 +1,7 @@ +Matlab-like Routines +******************** + +The Matlab Module +================= +.. automodule:: matlab + :members: \ No newline at end of file Added: branches/control-0.4a/doc/modsimp_strings.rst =================================================================== --- branches/control-0.4a/doc/modsimp_strings.rst (rev 0) +++ branches/control-0.4a/doc/modsimp_strings.rst 2011-02-08 22:17:34 UTC (rev 95) @@ -0,0 +1,7 @@ +Model Simplification Tools +************************** + +The modelsimp Module +==================== +.. automodule:: modelsimp + :members: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:17:33
|
Revision: 94 http://python-control.svn.sourceforge.net/python-control/?rev=94&view=rev Author: kkchen Date: 2011-02-08 22:17:26 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Modified docstrings for h2syn, hinfsyn, ctrb, obsv, gram, era, markov, step, impulse, initial, bode Steven Brunton <sbr...@pr...> Modified Paths: -------------- branches/control-0.4a/src/matlab.py branches/control-0.4a/src/modelsimp.py branches/control-0.4a/src/robust.py branches/control-0.4a/src/statefbk.py Modified: branches/control-0.4a/src/matlab.py =================================================================== --- branches/control-0.4a/src/matlab.py 2011-02-08 22:17:21 UTC (rev 93) +++ branches/control-0.4a/src/matlab.py 2011-02-08 22:17:26 UTC (rev 94) @@ -685,13 +685,13 @@ def bode(*args, **keywords): """Bode plot of the frequency response - Usage - ===== - bode(sys) - bode(sys, w) - bode(sys1, sys2, ..., sysN) - bode(sys1, sys2, ..., sysN, w) - bode(sys1, 'plotstyle1', ..., sysN, 'plotstyleN') + Examples + -------- + >>> bode(sys) + >>> bode(sys, w) + >>> bode(sys1, sys2, ..., sysN) + >>> bode(sys1, sys2, ..., sysN, w) + >>> bode(sys1, 'plotstyle1', ..., sysN, 'plotstyleN') """ # If the first argument is a list, then assume python-control calling format @@ -749,20 +749,23 @@ def lsim(*args, **keywords): """Simulate the output of a linear system - Usage - ===== - (T, yout, xout) = lsim(sys, u, T, X0) + Examples + -------- + >>> T, yout, xout = lsim(sys, u, T, X0) - Inputs: - sys LTI system - u input array giving input at each time T - T time steps at which the input is defined - X0 initial condition (optional, default = 0) + Parameters + ---------- + sys: StateSpace, or TransferFunction + LTI system to simulate + u: input array giving input at each time T + T: time steps at which the input is defined + X0: initial condition (optional, default = 0) - Outputs: - T time values of the output - yout response of the system - xout time evolution of the state vector + Returns + ------- + T: time values of the output + yout: response of the system + xout: time evolution of the state vector """ sys = args[0] ltiobjs = sys.returnScipySignalLti() @@ -775,18 +778,24 @@ def step(*args, **keywords): """Step response of a linear system - Usage - ===== - (T, yout) = step(sys, T, X0) + Examples + -------- + >>> T, yout = step(sys, T, X0) - Inputs: - sys LTI system - T time steps (optional; autocomputed if not gien) - X0 initial condition (optional, default = 0) + Parameters + ---------- + sys: StateSpace, or TransferFunction + T: array + T is the time vector (optional; autocomputed if not given) + X0: array + X0 is the initial condition (optional; default = 0) - Outputs: - T time values of the output - yout response of the system + Returns + ------- + T: array + Time values of the output + yout: array + response of the system """ sys = args[0] ltiobjs = sys.returnScipySignalLti() @@ -804,18 +813,25 @@ def initial(*args, **keywords): """Initial condition response of a linear system - Usage - ===== - (T, yout) = initial(sys, T, X0) + Examples + -------- + >>> T, yout = initial(sys, T, X0) - Inputs: - sys LTI system - T time steps (optional; autocomputed if not gien) - X0 initial condition (optional, default = 0) + Parameters + ---------- + sys: StateSpace, or TransferFunction + T: array + T is the time vector (optional; autocomputed if not given) + X0: array + X0 is the initial condition (optional; default = 0) - Outputs: - T time values of the output - yout response of the system + Returns + ------- + T: array + Time values of the output + yout: array + response of the system + """ sys = args[0] ltiobjs = sys.returnScipySignalLti() @@ -827,20 +843,27 @@ # Redefine impulse to use initial() #! Not yet implemented (uses impulse for now) def impulse(*args, **keywords): - """Step response of a linear system + """Impulse response of a linear system - Usage - ===== - (T, yout) = impulse(sys, T, X0) + Examples + -------- + >>> T, yout = impulse(sys, T, X0) - Inputs: - sys LTI system - T time steps (optional; autocomputed if not gien) - X0 initial condition (optional, default = 0) + Parameters + ---------- + sys: StateSpace, or TransferFunction + T: array + T is the time vector (optional; autocomputed if not given) + X0: array + X0 is the initial condition (optional; default = 0) - Outputs: - T time values of the output - yout response of the system + Returns + ------- + T: array + Time values of the output + yout: array + response of the system + """ sys = args[0] ltiobjs = sys.returnScipySignalLti() Modified: branches/control-0.4a/src/modelsimp.py =================================================================== --- branches/control-0.4a/src/modelsimp.py 2011-02-08 22:17:21 UTC (rev 93) +++ branches/control-0.4a/src/modelsimp.py 2011-02-08 22:17:26 UTC (rev 94) @@ -69,7 +69,7 @@ Examples -------- - H = hsvd(sys) + >>> H = hsvd(sys) """ @@ -107,7 +107,7 @@ Examples -------- - rsys = modred(sys,ELIM,method) + >>> rsys = modred(sys,ELIM,method='truncate') """ @@ -193,7 +193,7 @@ Examples -------- - rsys = balred(sys,order,elimination,method) + >>> rsys = balred(sys,order,method='truncate') """ @@ -245,42 +245,45 @@ def era(YY,m,n,nin,nout,r): """Calculate an ERA model of order r based on the impulse-response data YY - Usage - ===== - sys = era(YY,m,n,nin,nout,r) + Parameters + ---------- + YY: nout x nin dimensional impulse-response data + m: number of rows in Hankel matrix + n: number of columns in Hankel matrix + nin: number of input variables + nout: number of output variables + r: order of model - Inputs - ------ - YY : nout x nin dimensional impulse-response data - m : number of rows in Hankel matrix - n : number of columns in Hankel matrix - nin : number of input variables - nout : number of output variables - r : order of model - - Outputs + Returns ------- - sys : a reduced order model sys=ss(Ar,Br,Cr,Dr) + sys: a reduced order model sys=ss(Ar,Br,Cr,Dr) + Examples + -------- + >>> rsys = era(YY,m,n,nin,nout,r) + """ def markov(Y,U,M): """Calculate the first M Markov parameters [D CB CAB ...] from input U, output Y - Usage - ===== - H = markov(Y,U,M) + Parameters + ---------- + Y: output data + U: input data + M: number of Markov parameters to output + + Returns + ------- + H: first M Markov parameters + + Notes + ----- Currently only works for SISO - Inputs - ------ - Y : output data - U : input data - M : number of Markov parameters to output + Examples + -------- + >>> H = markov(Y,U,M) - Outputs - ------- - H : first M Markov parameters - """ # Convert input parameters to matrices (if they aren't already) Modified: branches/control-0.4a/src/robust.py =================================================================== --- branches/control-0.4a/src/robust.py 2011-02-08 22:17:21 UTC (rev 93) +++ branches/control-0.4a/src/robust.py 2011-02-08 22:17:26 UTC (rev 94) @@ -49,19 +49,29 @@ def h2syn(P,nmeas,ncon): """H_2 control synthesis for plant P. - Usage - ===== - K = h2syn(P,nmeas,ncon) + Parameters + ---------- + P: partitioned lti plant (State-space sys) + nmeas: number of measurements (input to controller) + ncon: number of control inputs (output from controller) - Inputs - ====== - P : partitioned lti plant - nmeas : number of measurements (input to controller) - ncon : number of control inputs (output from controller) + Returns + ------- + K: controller to stabilize P (State-space sys) - Outputs - ======= - K : controller to stabilize P + Raises + ------ + ImportError + if slycot routine sb10hd is not loaded + + See Also + -------- + StateSpace + + Examples + -------- + >>> K = h2syn(P,nmeas,ncon) + """ #Check for ss system object, need a utility for this? @@ -95,22 +105,32 @@ def hinfsyn(P,nmeas,ncon): """H_{inf} control synthesis for plant P. - Usage - ===== - K, CL, gam, info = hinfsyn(P,nmeas,ncon) + Parameters + ---------- + P: partitioned lti plant + nmeas: number of measurements (input to controller) + ncon: number of control inputs (output from controller) - Inputs - ====== - P : partitioned lti plant - nmeas : number of measurements (input to controller) - ncon : number of control inputs (output from controller) + Returns + ------- + K: controller to stabilize P (State-space sys) + CL: closed loop system (State-space sys) + gam: infinity norm of closed loop system + info: info returned from siycot routine - Outputs - ======= - K : controller to stabilize P - CL : closed loop system - gam : infinity norm of closed loop system - info : info returned from siycot routine + Raises + ------ + ImportError + if slycot routine sb10ad is not loaded + + See Also + -------- + StateSpace + + Examples + -------- + >>> K, CL, gam, info = hinfsyn(P,nmeas,ncon) + """ #Check for ss system object, need a utility for this? Modified: branches/control-0.4a/src/statefbk.py =================================================================== --- branches/control-0.4a/src/statefbk.py 2011-02-08 22:17:21 UTC (rev 93) +++ branches/control-0.4a/src/statefbk.py 2011-02-08 22:17:26 UTC (rev 94) @@ -188,17 +188,18 @@ def ctrb(A,B): """Controllabilty matrix - Usage - ===== - C = ctrb(A, B) - - Inputs - ------ + Parameters + ---------- A, B: Dynamics and input matrix of the system - Outputs + Returns ------- C: Controllability matrix + + Examples + -------- + >>> C = ctrb(A, B) + """ # Convert input parameters to matrices (if they aren't already) @@ -214,19 +215,20 @@ def obsv(A, C): """Observability matrix - Usage - ===== - O = obsv(A, C) - - Inputs - ------ + Parameters + ---------- A, C: Dynamics and output matrix of the system - Outputs + Returns ------- O: Observability matrix - """ + Examples + -------- + >>> O = obsv(A, C) + + """ + # Convert input parameters to matrices (if they aren't already) amat = np.mat(A) cmat = np.mat(C) @@ -239,12 +241,30 @@ return obsv def gram(sys,type): - """Gramian - - Usage - ===== - Wc = gram(sys,'c') - Wo = gram(sys,'o') + """Gramian (controllability or observability) + + Parameters + ---------- + sys: state-space system to compute Gramian for + type: type is either 'c' (controllability) or 'o' (observability) + + Returns + ------- + gram: Gramian of system + + Raises + ------ + ValueError + if `type` is not 'c' or 'o' + if system is unstable (sys.A has eigenvalues not in left half plane) + ImportError + if slycot routin sb03md cannot be found + + Examples + -------- + >>> Wc = gram(sys,'c') + >>> Wo = gram(sys,'o') + """ #Check for ss system object, need a utility for this? This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:17:27
|
Revision: 93 http://python-control.svn.sourceforge.net/python-control/?rev=93&view=rev Author: kkchen Date: 2011-02-08 22:17:21 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Changed docstrings for hsv, balred, modred Steven Brunton <sbr...@pr...> Modified Paths: -------------- branches/control-0.4a/src/modelsimp.py Modified: branches/control-0.4a/src/modelsimp.py =================================================================== --- branches/control-0.4a/src/modelsimp.py 2011-02-08 22:17:17 UTC (rev 92) +++ branches/control-0.4a/src/modelsimp.py 2011-02-08 22:17:21 UTC (rev 93) @@ -51,20 +51,26 @@ def hsvd(sys): """Calculate the Hankel singular values - Usage - ===== - H = hsvd(sys) - - The Hankel singular values are the singular values of the Hankel operator. In practice, we compute the square root of the eigenvalues of the matrix formed by taking the product of the observability and controllability gramians. There are other (more efficient) methods based on solving the Lyapunov equation in a particular way (more details soon). - - Inputs - ------ + Parameters + ---------- sys : a state space system - Outputs + Returns ------- H : a list of Hankel singular values + See Also + -------- + gram + + Notes + ----- + The Hankel singular values are the singular values of the Hankel operator. In practice, we compute the square root of the eigenvalues of the matrix formed by taking the product of the observability and controllability gramians. There are other (more efficient) methods based on solving the Lyapunov equation in a particular way (more details soon). + + Examples + -------- + H = hsvd(sys) + """ Wc = gram(sys,'c') @@ -83,20 +89,26 @@ def modred(sys,ELIM,method): """Model reduction of sys by eliminating the states in ELIM using a given method - Usage - ===== - rsys = modred(sys,ELIM,method) + Parameters + ---------- + sys: original system to reduce + ELIM: vector of states to eliminate + method: method of removing states in ELIM (truncate or matchdc) - Inputs - ====== - sys : original system to reduce - ELIM : vector of states to eliminate - method : method of removing states in ELIM (truncate or matchdc) + Returns + ------- + rsys: a reduced order model - Outputs - ======= - rsys : a reduced order model + Raises + ------ + ValueError + if `method` is not either `matchdc` or `truncate` + if eigenvalues of `sys.A` are not all in left half plane (sys must be stable) + Examples + -------- + rsys = modred(sys,ELIM,method) + """ #Check for ss system object, need a utility for this? @@ -114,15 +126,12 @@ for e in D: if e.real >= 0: raise ValueError, "Oops, the system is unstable!" - print ELIM ELIM = np.sort(ELIM) - print ELIM NELIM = [] # Create list of elements not to eliminate (NELIM) for i in range(0,len(sys.A)): if i not in ELIM: NELIM.append(i) - print NELIM # A1 is a matrix of all columns of sys.A not to eliminate A1 = sys.A[:,NELIM[0]] for i in NELIM[1:]: @@ -141,7 +150,6 @@ B1 = sys.B[NELIM,:] B2 = sys.B[ELIM,:] - print np.shape(A22) A22I = np.linalg.inv(A22) if method=='matchdc': @@ -165,21 +173,28 @@ def balred(sys,orders,method='truncate'): """Balanced reduced order model of sys of a given order. States are eliminated based on Hankel singular value. - Usage - ===== - rsys = balred(sys,order,elimination,method) + Parameters + ---------- + sys: original system to reduce + orders: desired order of reduced order model (if a vector, returns a vector of systems) + method: method of removing states (truncate or matchdc) - Inputs - ====== - sys : original system to reduce - orders : desired order of reduced order model (if a vector, returns a vector of systems) - elimination : if elimination is specified, use 'method' - method : method of removing states (truncate or matchdc) + Returns + ------- + rsys: a reduced order model - Outputs - ======= - rsys : a reduced order model + Raises + ------ + ValueError + if `method` is not `truncate` + if eigenvalues of `sys.A` are not all in left half plane (sys must be stable) + ImportError + if slycot routine ab09ad is not found + Examples + -------- + rsys = balred(sys,order,elimination,method) + """ #Check for ss system object, need a utility for this? This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <kk...@us...> - 2011-02-08 22:17:25
|
Revision: 92 http://python-control.svn.sourceforge.net/python-control/?rev=92&view=rev Author: kkchen Date: 2011-02-08 22:17:17 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Modified freqplot to plot magnitude and phase in same color; included keyword color=None, so that bode can specify color. Steven Brunton <sbr...@pr...> Modified Paths: -------------- branches/control-0.4a/src/freqplot.py Modified: branches/control-0.4a/src/freqplot.py =================================================================== --- branches/control-0.4a/src/freqplot.py 2011-02-08 22:17:13 UTC (rev 91) +++ branches/control-0.4a/src/freqplot.py 2011-02-08 22:17:17 UTC (rev 92) @@ -54,7 +54,7 @@ # # Bode plot -def bode(syslist, omega=None, dB=False, Hz=False): +def bode(syslist, omega=None, dB=False, Hz=False, color=None): """Bode plot for a system Usage @@ -111,10 +111,16 @@ # Magnitude plot plt.subplot(211); if dB: - plt.semilogx(omega, mag) + if color==None: + plt.semilogx(omega, mag) + else: + plt.semilogx(omega, mag, color=color) plt.ylabel("Magnitude (dB)") else: - plt.loglog(omega, mag) + if color==None: + plt.loglog(omega, mag) + else: + plt.loglog(omega, mag, color=color) plt.ylabel("Magnitude") # Add a grid to the plot @@ -124,7 +130,10 @@ # Phase plot plt.subplot(212); - plt.semilogx(omega, phase) + if color==None: + plt.semilogx(omega, phase) + else: + plt.semilogx(omega, phase, color=color) plt.hold(True) # Add a grid to the plot This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |