Initial gram algorithm in statefbk.py. Passes initial tests. · python-control/python-control@9b5b460
@@ -246,13 +246,44 @@ def gram(sys,type):
246246 Wc = gram(sys,'c')
247247 Wo = gram(sys,'o')
248248 """
249-249+250+#Check for ss system object, need a utility for this?
251+252+#TODO: Check for continous or discrete, only continuous supported right now
253+# if isCont():
254+# dico = 'C'
255+# elif isDisc():
256+# dico = 'D'
257+# else:
258+dico = 'C'
259+260+#TODO: Check system is stable, perhaps a utility in ctrlutil.py
261+# or a method of the StateSpace class?
262+D,V = np.linalg.eig(sys.A)
263+for e in D:
264+if e.real >= 0:
265+raise ValueError, "Oops, the system is unstable!"
266+250267if type=='c':
251268print "controllable"
269+trana = 'T'
270+C = -sys.B*sys.B.transpose()
252271elif type=='o':
253272print "observable"
254-else:
273+trana = 'N'
274+C = -sys.C.transpose()*sys.C
275+else:
255276raise ValueError, "Oops, neither observable, nor controllable!"
256277257-gram = 0.
278+#Compute Gramian by the Slycot routine sb03md
279+#make sure Slycot is installed
280+try:
281+from slycot import sb03md
282+except ImportError:
283+raise ControlSlycot("can't find slycot module 'sb03md'")
284+n = sys.states
285+U = np.zeros((n,n))
286+out = sb03md(n, C, sys.A, U, dico, 'X', 'N', trana)
287+gram = out[0]
258288return gram
289+