71089


私はPythonでmatplotlibを使って制御工学の勉強をしている者です。今回はlsimの使い方について質問させていただきます。

・まず認識から述べます。

lsimは線形システムの応答を出力する関数です。引数に、システム、時間、入力信号、初期状態を求めます。

・分からない点

lsimそれだけを実行してもグラフがプロットされると聞きましたが、僕の以下のコードではなりません。実行すると多量の数値が出てくるので、それをplotに突っ込んで初めてグラフがでます。  
また、プロットするときは

[code]

    y,_,_=lsim(P,Ud,Td,0)
    
[/code]

のように、三つの返り値を設定してやらないと動きません。これはなぜでしょうか？おまけに、このコードでは、yは二本の波形が出てきます。  
lsimに三つの返り値を設定しなければいけない理由、そしてそれぞれは何を表しているのか教えてください。

[code]

    import numpy as np
    
    from matplotlib import pyplot as plt 
    from numpy.random import *
    from control.matlab import *
    
    A="0,1;-4,-5"
    B="0;1"
    C="1,0;0,1"
    D="0;0"
    P=ss(A,B,C,D)
    
    w=np.pi
    n=1
    
    Td=np.arange(0,2*np.pi,0.01)
    Ud=np.cos(n*w*Td)
    
    y,_,_=lsim(P,Ud,Td,0)
    
    fig,ax=plt.subplots(1,2)
    
    ax[0].plot(Td,Ud)
    ax[1].plot(y)
    
[/code]


CC BY-SA 4.0
2020-09-30T22:00:25.063
70852
2020-10-11T00:21:38.357
2020-10-01T00:41:11.410
3060
41334
question
python python3 matplotlib
matplotlib の lsim の使い方


コメントのやり取りで解決したようなので、回答として投稿しておきます。

`lsim`は`matplotlib`ではなく`control.matlab`のメソッドのようですね。  
[control.matlab.lsim](https://python-
control.readthedocs.io/en/0.8.3/generated/control.matlab.lsim.html)  
[python control での lsim の使い方](https://teratail.com/questions/201607)  
[PythonControlで正弦波に対する応答を求める。](https://qiita.com/nnn112358/items/5de7a5664bb7668ed2e7)

他に`scipy`にも同名のメソッドがあり、機能としては類似らしいですが、こちらは戻り値の内容や並び方が違うので別物のようです。  
[scipy.signal.lsim](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.lsim.html)

* * *

「三つの返り値を設定してやらないと動きません。これはなぜでしょうか？」というのは、以下のようにそれがこのメソッドの仕様だからです。

> control.matlab.lsim(sys, U=0.0, T=None, X0=0.0)
>
> Returns:
>
>   * yout (array) – Response of the system.
>   * T (array) – Time values of the output.
>   * xout (array) – Time evolution of the state vector.
>

そして「三つの返り値...それぞれは何を表しているのか」については、上記`control.matlab.lsim`仕様の記述と、名前から推測できる元であろう`MATLAB`の解説で以下のように記述されています。  
[lsim](https://jp.mathworks.com/help/control/ref/lsim.html)

> 推定に使用したものと同じ入力データと推定コマンドによって返された初期状態を使用して、sys の応答をシミュレートします。
[code]

>     [y,t,x] = lsim(sys,z.InputData,[],x0);
>  
[/code]

>
> ここで、y はシステム応答、t はシミュレーションに使用される時間ベクトル、x は状態軌跡です。

* * *

「おまけに、このコードでは、yは二本の波形が出てきます。」については同様に`MATLAB`の解説を見ると、2本の波形は入力信号とシステム応答と思われます。  
[システム応答のプロット](https://jp.mathworks.com/help/control/examples/plotting-system-
responses.html)

> lsim コマンドを使用すると、任意の信号 (たとえば正弦波)
> に対する応答をシミュレートすることもできます。入力信号は灰色、システムの応答は青色で表示されます。

「lsimそれだけを実行してもグラフがプロットされる」というのは上記ページのようにMATLABの開発環境とかツール上の話か、Pythonでも何か同様の環境の話と思われます。

* * *

「帰ってくる二本の波形のうち、一本だけをプロットしたい場合はどうすれば良いのでしょうか？」について：

`print(type(y))`と`print(y)`してみればわかりますが、`y`は2次元の`numpy.ndarray`です。  
こちらの記事[NumPy配列ndarrayの要素・行・列を取得（抽出）、代入](https://note.nkmk.me/python-numpy-
select-element-row-column-array/)にあるように

[code]

    d0 = y[:, 0]
    d1 = y[:, 1]
    
[/code]

とすれば抽出できるのでは？

数値は`Ud`とは同じではないようですが、それを

[code]

    ax[0].plot(Td,d0)
    ax[1].plot(Td,d1)
    
[/code]

としてみれば分けて表示出来るでしょう。

* * *

「ax[1].plot(y)のコードだけで時間軸もx軸にプロット出来ているという点です。これはなぜでしょうか？」について：

表示されたグラフの`X`軸の目盛りとか[matplotlib.pyplot.plot](https://matplotlib.org/3.3.2/api/_as_gen/matplotlib.pyplot.plot.html)の仕様を見ると、以下の`plot(y)
# plot y using x as index array
0..N-1`のようにパラメータが1個だけ指定されたなら`Y`軸データを指定したことになり、`X`軸にはデータのインデックス(何番目であるか)が使われるようです。

>
[code]

>     >>> plot(x, y)        # plot x and y using default line style and color
>     >>> plot(x, y, 'bo')  # plot x and y using blue circle markers
>     >>> plot(y)           # plot y using x as index array 0..N-1
>     >>> plot(y, 'r+')     # ditto, but with red plusses
>  
[/code]


CC BY-SA 4.0
2020-10-10T23:37:36.843
71089
2020-10-11T00:21:38.357
2020-10-11T00:21:38.357
26370
26370
70852
answer