Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commiteb146a6

Browse files
authored
Merge pull request#515 from murrayrm/input_output_to_ninput_noutput
Switch LTI class and subclasses to use ninputs, noutputs, nstates
2 parents1502d38 +eb401a9 commiteb146a6

21 files changed

+457
-385
lines changed

‎control/bdalg.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def series(sys1, *sysn):
7676
Raises
7777
------
7878
ValueError
79-
if `sys2.inputs` does not equal `sys1.outputs`
79+
if `sys2.ninputs` does not equal `sys1.noutputs`
8080
if `sys1.dt` is not compatible with `sys2.dt`
8181
8282
See Also
@@ -336,25 +336,25 @@ def connect(sys, Q, inputv, outputv):
336336
"""
337337
inputv,outputv,Q=np.asarray(inputv),np.asarray(outputv),np.asarray(Q)
338338
# check indices
339-
index_errors= (inputv-1>sys.inputs)| (inputv<1)
339+
index_errors= (inputv-1>sys.ninputs)| (inputv<1)
340340
ifnp.any(index_errors):
341341
raiseIndexError(
342342
"inputv index %s out of bounds"%inputv[np.where(index_errors)])
343-
index_errors= (outputv-1>sys.outputs)| (outputv<1)
343+
index_errors= (outputv-1>sys.noutputs)| (outputv<1)
344344
ifnp.any(index_errors):
345345
raiseIndexError(
346346
"outputv index %s out of bounds"%outputv[np.where(index_errors)])
347-
index_errors= (Q[:,0:1]-1>sys.inputs)| (Q[:,0:1]<1)
347+
index_errors= (Q[:,0:1]-1>sys.ninputs)| (Q[:,0:1]<1)
348348
ifnp.any(index_errors):
349349
raiseIndexError(
350350
"Q input index %s out of bounds"%Q[np.where(index_errors)])
351-
index_errors= (np.abs(Q[:,1:])-1>sys.outputs)
351+
index_errors= (np.abs(Q[:,1:])-1>sys.noutputs)
352352
ifnp.any(index_errors):
353353
raiseIndexError(
354354
"Q output index %s out of bounds"%Q[np.where(index_errors)])
355355

356356
# first connect
357-
K=np.zeros((sys.inputs,sys.outputs))
357+
K=np.zeros((sys.ninputs,sys.noutputs))
358358
forrinnp.array(Q).astype(int):
359359
inp=r[0]-1
360360
foroutpinr[1:]:
@@ -365,8 +365,8 @@ def connect(sys, Q, inputv, outputv):
365365
sys=sys.feedback(np.array(K),sign=1)
366366

367367
# now trim
368-
Ytrim=np.zeros((len(outputv),sys.outputs))
369-
Utrim=np.zeros((sys.inputs,len(inputv)))
368+
Ytrim=np.zeros((len(outputv),sys.noutputs))
369+
Utrim=np.zeros((sys.ninputs,len(inputv)))
370370
fori,uinenumerate(inputv):
371371
Utrim[u-1,i]=1.
372372
fori,yinenumerate(outputv):

‎control/canonical.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,24 +79,24 @@ def reachable_form(xsys):
7979
zsys.B[0,0]=1.0
8080
zsys.A=zeros_like(xsys.A)
8181
Apoly=poly(xsys.A)# characteristic polynomial
82-
foriinrange(0,xsys.states):
82+
foriinrange(0,xsys.nstates):
8383
zsys.A[0,i]=-Apoly[i+1]/Apoly[0]
84-
if (i+1<xsys.states):
84+
if (i+1<xsys.nstates):
8585
zsys.A[i+1,i]=1.0
8686

8787
# Compute the reachability matrices for each set of states
8888
Wrx=ctrb(xsys.A,xsys.B)
8989
Wrz=ctrb(zsys.A,zsys.B)
9090

91-
ifmatrix_rank(Wrx)!=xsys.states:
91+
ifmatrix_rank(Wrx)!=xsys.nstates:
9292
raiseValueError("System not controllable to working precision.")
9393

9494
# Transformation from one form to another
9595
Tzx=solve(Wrx.T,Wrz.T).T# matrix right division, Tzx = Wrz * inv(Wrx)
9696

9797
# Check to make sure inversion was OK. Note that since we are inverting
9898
# Wrx and we already checked its rank, this exception should never occur
99-
ifmatrix_rank(Tzx)!=xsys.states:# pragma: no cover
99+
ifmatrix_rank(Tzx)!=xsys.nstates:# pragma: no cover
100100
raiseValueError("Transformation matrix singular to working precision.")
101101

102102
# Finally, compute the output matrix
@@ -133,9 +133,9 @@ def observable_form(xsys):
133133
zsys.C[0,0]=1
134134
zsys.A=zeros_like(xsys.A)
135135
Apoly=poly(xsys.A)# characteristic polynomial
136-
foriinrange(0,xsys.states):
136+
foriinrange(0,xsys.nstates):
137137
zsys.A[i,0]=-Apoly[i+1]/Apoly[0]
138-
if (i+1<xsys.states):
138+
if (i+1<xsys.nstates):
139139
zsys.A[i,i+1]=1
140140

141141
# Compute the observability matrices for each set of states
@@ -145,7 +145,7 @@ def observable_form(xsys):
145145
# Transformation from one form to another
146146
Tzx=solve(Wrz,Wrx)# matrix left division, Tzx = inv(Wrz) * Wrx
147147

148-
ifmatrix_rank(Tzx)!=xsys.states:
148+
ifmatrix_rank(Tzx)!=xsys.nstates:
149149
raiseValueError("Transformation matrix singular to working precision.")
150150

151151
# Finally, compute the output matrix

‎control/frdata.py

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,11 @@ def __init__(self, *args, **kwargs):
155155
def__str__(self):
156156
"""String representation of the transfer function."""
157157

158-
mimo=self.inputs>1orself.outputs>1
158+
mimo=self.ninputs>1orself.noutputs>1
159159
outstr= ['Frequency response data']
160160

161-
foriinrange(self.inputs):
162-
forjinrange(self.outputs):
161+
foriinrange(self.ninputs):
162+
forjinrange(self.noutputs):
163163
ifmimo:
164164
outstr.append("Input %i to output %i:"% (i+1,j+1))
165165
outstr.append('Freq [rad/s] Response')
@@ -201,12 +201,12 @@ def __add__(self, other):
201201
other=_convert_to_FRD(other,omega=self.omega)
202202

203203
# Check that the input-output sizes are consistent.
204-
ifself.inputs!=other.inputs:
204+
ifself.ninputs!=other.ninputs:
205205
raiseValueError("The first summand has %i input(s), but the\
206-
second has %i."% (self.inputs,other.inputs))
207-
ifself.outputs!=other.outputs:
206+
second has %i."% (self.ninputs,other.ninputs))
207+
ifself.noutputs!=other.noutputs:
208208
raiseValueError("The first summand has %i output(s), but the\
209-
second has %i."% (self.outputs,other.outputs))
209+
second has %i."% (self.noutputs,other.noutputs))
210210

211211
returnFRD(self.fresp+other.fresp,other.omega)
212212

@@ -236,14 +236,14 @@ def __mul__(self, other):
236236
other=_convert_to_FRD(other,omega=self.omega)
237237

238238
# Check that the input-output sizes are consistent.
239-
ifself.inputs!=other.outputs:
239+
ifself.ninputs!=other.noutputs:
240240
raiseValueError(
241241
"H = G1*G2: input-output size mismatch: "
242242
"G1 has %i input(s), G2 has %i output(s)."%
243-
(self.inputs,other.outputs))
243+
(self.ninputs,other.noutputs))
244244

245-
inputs=other.inputs
246-
outputs=self.outputs
245+
inputs=other.ninputs
246+
outputs=self.noutputs
247247
fresp=empty((outputs,inputs,len(self.omega)),
248248
dtype=self.fresp.dtype)
249249
foriinrange(len(self.omega)):
@@ -263,14 +263,14 @@ def __rmul__(self, other):
263263
other=_convert_to_FRD(other,omega=self.omega)
264264

265265
# Check that the input-output sizes are consistent.
266-
ifself.outputs!=other.inputs:
266+
ifself.noutputs!=other.ninputs:
267267
raiseValueError(
268268
"H = G1*G2: input-output size mismatch: "
269269
"G1 has %i input(s), G2 has %i output(s)."%
270-
(other.inputs,self.outputs))
270+
(other.ninputs,self.noutputs))
271271

272-
inputs=self.inputs
273-
outputs=other.outputs
272+
inputs=self.ninputs
273+
outputs=other.noutputs
274274

275275
fresp=empty((outputs,inputs,len(self.omega)),
276276
dtype=self.fresp.dtype)
@@ -290,8 +290,8 @@ def __truediv__(self, other):
290290
else:
291291
other=_convert_to_FRD(other,omega=self.omega)
292292

293-
if (self.inputs>1orself.outputs>1or
294-
other.inputs>1orother.outputs>1):
293+
if (self.ninputs>1orself.noutputs>1or
294+
other.ninputs>1orother.noutputs>1):
295295
raiseNotImplementedError(
296296
"FRD.__truediv__ is currently only implemented for SISO "
297297
"systems.")
@@ -313,8 +313,8 @@ def __rtruediv__(self, other):
313313
else:
314314
other=_convert_to_FRD(other,omega=self.omega)
315315

316-
if (self.inputs>1orself.outputs>1or
317-
other.inputs>1orother.outputs>1):
316+
if (self.ninputs>1orself.noutputs>1or
317+
other.ninputs>1orother.noutputs>1):
318318
raiseNotImplementedError(
319319
"FRD.__rtruediv__ is currently only implemented for "
320320
"SISO systems.")
@@ -392,10 +392,10 @@ def eval(self, omega, squeeze=None):
392392
else:
393393
out=self.fresp[:, :,elements]
394394
else:
395-
out=empty((self.outputs,self.inputs,len(omega_array)),
395+
out=empty((self.noutputs,self.ninputs,len(omega_array)),
396396
dtype=complex)
397-
foriinrange(self.outputs):
398-
forjinrange(self.inputs):
397+
foriinrange(self.noutputs):
398+
forjinrange(self.ninputs):
399399
fork,winenumerate(omega_array):
400400
frraw=splev(w,self.ifunc[i,j],der=0)
401401
out[i,j,k]=frraw[0]+1.0j*frraw[1]
@@ -406,7 +406,7 @@ def __call__(self, s, squeeze=None):
406406
"""Evaluate system's transfer function at complex frequencies.
407407
408408
Returns the complex frequency response `sys(s)` of system `sys` with
409-
`m = sys.inputs` number of inputs and `p = sys.outputs` number of
409+
`m = sys.ninputs` number of inputs and `p = sys.noutputs` number of
410410
outputs.
411411
412412
To evaluate at a frequency omega in radians per second, enter
@@ -474,10 +474,10 @@ def feedback(self, other=1, sign=-1):
474474

475475
other=_convert_to_FRD(other,omega=self.omega)
476476

477-
if (self.outputs!=other.inputsorself.inputs!=other.outputs):
477+
if (self.noutputs!=other.ninputsorself.ninputs!=other.noutputs):
478478
raiseValueError(
479479
"FRD.feedback, inputs/outputs mismatch")
480-
fresp=empty((self.outputs,self.inputs,len(other.omega)),
480+
fresp=empty((self.noutputs,self.ninputs,len(other.omega)),
481481
dtype=complex)
482482
# TODO: vectorize this
483483
# TODO: handle omega re-mapping
@@ -487,9 +487,9 @@ def feedback(self, other=1, sign=-1):
487487
fresp[:, :,k]=np.dot(
488488
self.fresp[:, :,k],
489489
linalg.solve(
490-
eye(self.inputs)
490+
eye(self.ninputs)
491491
+np.dot(other.fresp[:, :,k],self.fresp[:, :,k]),
492-
eye(self.inputs))
492+
eye(self.ninputs))
493493
)
494494

495495
returnFRD(fresp,other.omega,smooth=(self.ifuncisnotNone))

‎control/freqplot.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ def bode_plot(syslist, omega=None,
214214

215215
mags,phases,omegas,nyquistfrqs= [], [], [], []
216216
forsysinsyslist:
217-
ifsys.inputs>1orsys.outputs>1:
217+
ifsys.ninputs>1orsys.noutputs>1:
218218
# TODO: Add MIMO bode plots.
219219
raiseNotImplementedError(
220220
"Bode is currently only implemented for SISO systems.")
@@ -582,7 +582,7 @@ def nyquist_plot(syslist, omega=None, plot=True, label_freq=0,
582582
num=50,endpoint=True,base=10.0)
583583

584584
forsysinsyslist:
585-
ifsys.inputs>1orsys.outputs>1:
585+
ifsys.ninputs>1orsys.noutputs>1:
586586
# TODO: Add MIMO nyquist plots.
587587
raiseNotImplementedError(
588588
"Nyquist is currently only implemented for SISO systems.")
@@ -672,7 +672,7 @@ def gangof4_plot(P, C, omega=None, **kwargs):
672672
-------
673673
None
674674
"""
675-
ifP.inputs>1orP.outputs>1orC.inputs>1orC.outputs>1:
675+
ifP.ninputs>1orP.noutputs>1orC.ninputs>1orC.noutputs>1:
676676
# TODO: Add MIMO go4 plots.
677677
raiseNotImplementedError(
678678
"Gang of four is currently only implemented for SISO systems.")

‎control/iosys.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -659,25 +659,25 @@ def __init__(self, linsys, inputs=None, outputs=None, states=None,
659659

660660
# Create the I/O system object
661661
super(LinearIOSystem,self).__init__(
662-
inputs=linsys.inputs,outputs=linsys.outputs,
663-
states=linsys.states,params={},dt=linsys.dt,name=name)
662+
inputs=linsys.ninputs,outputs=linsys.noutputs,
663+
states=linsys.nstates,params={},dt=linsys.dt,name=name)
664664

665665
# Initalize additional state space variables
666666
StateSpace.__init__(self,linsys,remove_useless=False)
667667

668668
# Process input, output, state lists, if given
669669
# Make sure they match the size of the linear system
670670
ninputs,self.input_index=self._process_signal_list(
671-
inputsifinputsisnotNoneelselinsys.inputs,prefix='u')
672-
ifninputsisnotNoneandlinsys.inputs!=ninputs:
671+
inputsifinputsisnotNoneelselinsys.ninputs,prefix='u')
672+
ifninputsisnotNoneandlinsys.ninputs!=ninputs:
673673
raiseValueError("Wrong number/type of inputs given.")
674674
noutputs,self.output_index=self._process_signal_list(
675-
outputsifoutputsisnotNoneelselinsys.outputs,prefix='y')
676-
ifnoutputsisnotNoneandlinsys.outputs!=noutputs:
675+
outputsifoutputsisnotNoneelselinsys.noutputs,prefix='y')
676+
ifnoutputsisnotNoneandlinsys.noutputs!=noutputs:
677677
raiseValueError("Wrong number/type of outputs given.")
678678
nstates,self.state_index=self._process_signal_list(
679-
statesifstatesisnotNoneelselinsys.states,prefix='x')
680-
ifnstatesisnotNoneandlinsys.states!=nstates:
679+
statesifstatesisnotNoneelselinsys.nstates,prefix='x')
680+
ifnstatesisnotNoneandlinsys.nstates!=nstates:
681681
raiseValueError("Wrong number/type of states given.")
682682

683683
def_update_params(self,params={},warning=True):
@@ -1345,9 +1345,9 @@ def __init__(self, io_sys, ss_sys=None):
13451345
# Initialize the state space attributes
13461346
ifisinstance(ss_sys,StateSpace):
13471347
# Make sure the dimension match
1348-
ifio_sys.ninputs!=ss_sys.inputsor \
1349-
io_sys.noutputs!=ss_sys.outputsor \
1350-
io_sys.nstates!=ss_sys.states:
1348+
ifio_sys.ninputs!=ss_sys.ninputsor \
1349+
io_sys.noutputs!=ss_sys.noutputsor \
1350+
io_sys.nstates!=ss_sys.nstates:
13511351
raiseValueError("System dimensions for first and second "
13521352
"arguments must match.")
13531353
StateSpace.__init__(self,ss_sys,remove_useless=False)

‎control/lti.py

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,46 @@ def __init__(self, inputs=1, outputs=1, dt=None):
4747
"""Assign the LTI object's numbers of inputs and ouputs."""
4848

4949
# Data members common to StateSpace and TransferFunction.
50-
self.inputs=inputs
51-
self.outputs=outputs
50+
self.ninputs=inputs
51+
self.noutputs=outputs
5252
self.dt=dt
5353

54+
#
55+
# Getter and setter functions for legacy state attributes
56+
#
57+
# For this iteration, generate a deprecation warning whenever the
58+
# getter/setter is called. For a future iteration, turn it into a
59+
# future warning, so that users will see it.
60+
#
61+
62+
@property
63+
definputs(self):
64+
warn("The LTI `inputs` attribute will be deprecated in a future "
65+
"release. Use `ninputs` instead.",
66+
DeprecationWarning,stacklevel=2)
67+
returnself.ninputs
68+
69+
@inputs.setter
70+
definputs(self,value):
71+
warn("The LTI `inputs` attribute will be deprecated in a future "
72+
"release. Use `ninputs` instead.",
73+
DeprecationWarning,stacklevel=2)
74+
self.ninputs=value
75+
76+
@property
77+
defoutputs(self):
78+
warn("The LTI `outputs` attribute will be deprecated in a future "
79+
"release. Use `noutputs` instead.",
80+
DeprecationWarning,stacklevel=2)
81+
returnself.noutputs
82+
83+
@outputs.setter
84+
defoutputs(self,value):
85+
warn("The LTI `outputs` attribute will be deprecated in a future "
86+
"release. Use `noutputs` instead.",
87+
DeprecationWarning,stacklevel=2)
88+
self.noutputs=value
89+
5490
defisdtime(self,strict=False):
5591
"""
5692
Check to see if a system is a discrete-time system
@@ -88,7 +124,7 @@ def isctime(self, strict=False):
88124

89125
defissiso(self):
90126
'''Check to see if a system is single input, single output'''
91-
returnself.inputs==1andself.outputs==1
127+
returnself.ninputs==1andself.noutputs==1
92128

93129
defdamp(self):
94130
'''Natural frequency, damping ratio of system poles
@@ -126,7 +162,7 @@ def frequency_response(self, omega, squeeze=None):
126162
G(exp(j*omega*dt)) = mag*exp(j*phase).
127163
128164
In general the system may be multiple input, multiple output (MIMO),
129-
where `m = self.inputs` number of inputs and `p = self.outputs` number
165+
where `m = self.ninputs` number of inputs and `p = self.noutputs` number
130166
of outputs.
131167
132168
Parameters
@@ -475,7 +511,7 @@ def evalfr(sys, x, squeeze=None):
475511
476512
Returns the complex frequency response `sys(x)` where `x` is `s` for
477513
continuous-time systems and `z` for discrete-time systems, with
478-
`m = sys.inputs` number of inputs and `p = sys.outputs` number of
514+
`m = sys.ninputs` number of inputs and `p = sys.noutputs` number of
479515
outputs.
480516
481517
To evaluate at a frequency omega in radians per second, enter
@@ -532,7 +568,7 @@ def freqresp(sys, omega, squeeze=None):
532568
"""Frequency response of an LTI system at multiple angular frequencies.
533569
534570
In general the system may be multiple input, multiple output (MIMO), where
535-
`m = sys.inputs` number of inputs and `p = sys.outputs` number of
571+
`m = sys.ninputs` number of inputs and `p = sys.noutputs` number of
536572
outputs.
537573
538574
Parameters

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp