@@ -60,6 +60,14 @@ def siso_ss2(self, siso_ss1):
60
60
61
61
return T
62
62
63
+ @pytest .fixture
64
+ def siso_ss2_dtnone (self , siso_ss2 ):
65
+ """System with unspecified timebase"""
66
+ ss2 = siso_ss2 .sys
67
+ T = TSys (StateSpace (ss2 .A , ss2 .B , ss2 .C , 0 , None ))
68
+ T .t = np .arange (0 , 10 , 1. )
69
+ return T
70
+
63
71
@pytest .fixture
64
72
def siso_tf1 (self ):
65
73
# Create some transfer functions
@@ -349,7 +357,7 @@ def mimo_tf_step_info(self,
349
357
@pytest .fixture
350
358
def tsystem (self ,
351
359
request ,
352
- siso_ss1 , siso_ss2 , siso_tf1 , siso_tf2 ,
360
+ siso_ss1 , siso_ss2 , siso_ss2_dtnone , siso_tf1 , siso_tf2 ,
353
361
mimo_ss1 , mimo_ss2 , mimo_tf2 ,
354
362
siso_dtf0 , siso_dtf1 , siso_dtf2 ,
355
363
siso_dss1 , siso_dss2 ,
@@ -361,6 +369,7 @@ def tsystem(self,
361
369
siso_tf_asymptotic_from_neg1 ):
362
370
systems = {"siso_ss1" : siso_ss1 ,
363
371
"siso_ss2" : siso_ss2 ,
372
+ "siso_ss2_dtnone" : siso_ss2_dtnone ,
364
373
"siso_tf1" : siso_tf1 ,
365
374
"siso_tf2" : siso_tf2 ,
366
375
"mimo_ss1" : mimo_ss1 ,
@@ -840,10 +849,11 @@ def test_default_timevector_functions_d(self, fun, dt):
840
849
@pytest .mark .parametrize ("tsystem" ,
841
850
["siso_ss2" , # continuous
842
851
"siso_tf1" ,
843
- "siso_dss1" , # no timebase
852
+ "siso_dss1" , # unspecified sampling time
844
853
"siso_dtf1" ,
845
854
"siso_dss2" , # matching timebase
846
855
"siso_dtf2" ,
856
+ "siso_ss2_dtnone" , # undetermined timebase
847
857
"mimo_ss2" , # MIMO
848
858
pytest .param ("mimo_tf2" , marks = slycotonly ),
849
859
"mimo_dss1" ,
@@ -868,9 +878,9 @@ def test_time_vector(self, tsystem, fun, squeeze, matarrayout):
868
878
kw ['T' ] = t
869
879
if fun == forced_response :
870
880
kw ['U' ] = np .vstack ([np .sin (t ) for i in range (sys .ninputs )])
871
- elif fun == forced_response and isctime (sys ):
881
+ elif fun == forced_response and isctime (sys , strict = True ):
872
882
pytest .skip ("No continuous forced_response without time vector." )
873
- if hasattr (tsystem . sys , "nstates" ):
883
+ if hasattr (sys , "nstates" ):
874
884
kw ['X0' ] = np .arange (sys .nstates ) + 1
875
885
if sys .ninputs > 1 and fun in [step_response , impulse_response ]:
876
886
kw ['input' ] = 1
@@ -884,14 +894,18 @@ def test_time_vector(self, tsystem, fun, squeeze, matarrayout):
884
894
if hasattr (tsystem , 't' ):
885
895
# tout should always match t, which has shape (n, )
886
896
np .testing .assert_allclose (tout , tsystem .t )
897
+ elif fun == forced_response and sys .dt in [None , True ]:
898
+ np .testing .assert_allclose (
899
+ np .diff (tout ), np .full_like (tout [:- 1 ], 1. ))
887
900
888
901
if squeeze is False or not sys .issiso ():
889
902
assert yout .shape [0 ] == sys .noutputs
890
903
assert yout .shape [- 1 ] == tout .shape [0 ]
891
904
else :
892
905
assert yout .shape == tout .shape
893
906
894
- if sys .dt > 0 and sys .dt is not True and not np .isclose (sys .dt , 0.5 ):
907
+ if sys .isdtime (strict = True ) and sys .dt is not True and not \
908
+ np .isclose (sys .dt , 0.5 ):
895
909
kw ['T' ] = np .arange (0 , 5 , 0.5 ) # incompatible timebase
896
910
with pytest .raises (ValueError ):
897
911
fun (sys , ** kw )
0 commit comments