メインコンテンツへスキップ

CasADiのSX, MX, DMクラスを比較する

·1295 文字·3 分
目次

はじめに
#

最適化ライブラリCasADiには、行列を扱える3つのクラス (SX, MX, DM) があります。これらのクラスの違いをまとめました。

この記事では、CasADiのPythonインターフェイスを使用しています。PythonとCasADiのバージョンは以下の通りです。

  • Python 3.9.7
  • CasADi 3.5.5

各クラスの基礎
#

CasADiの公式リファレンスでは、SX, MX, DMクラスの説明は以下となっています。

  • SX: 単項演算や二項演算で表現されるシンボルを要素に持つ行列 (scalar expression)
  • MX: SXに似ているが、行列をシンボルで表現する (matrix expression)
  • DM: 非ゼロ要素を数値として持ち、シンボルによる表現は持たない行列

シンボルとは、数学の記号(xやyなど)のような概念です。DMクラスはシンボルを定義できないので、NumPyのarrayクラスに似ています。

各クラスのオブジェクトを定義する例を以下に示します。

import casadi as ca

s0 = ca.SX.sym("a",2,3) # シンボルaとして定義
s1 = ca.SX(2,3)
s2 = ca.SX([[1,2],[3,4]])

m0 = ca.MX.sym("c",2,3) # シンボルcとして定義
m1 = ca.MX(2,3)
# m2 = ca.MX([[1,2],[3,4]]) # NG

# d0 = ca.DM("b",2,3) # NG
d1 = ca.DM(2,3)
d2 = ca.DM([[1,2],[3,4]])

ca.SX(2,3)などは2x3サイズの行列を表します。また、ca.SX([[1,2],[3,4]])などは具体的な数値を持つ行列の定義を表します。 NG例の通り、シンボルを持つDMオブジェクトd0と、数値を持つMXオブジェクトm2は作成できません。

また、SXとMXのシンボルの違いを以下に示します。SXオブジェクトでは、a_0, a_1などのように各要素がシンボルを持ちます。一方、MXオブジェクトでは行列がcというシンボルを持ちます。

>>> s0
SX(
[[a_0, a_2, a_4], 
 [a_1, a_3, a_5]])

>>> m0
MX(c)

異なるクラス同士の演算
#

異なるクラス同士の演算を解説します。SXオブジェクトとMXオブジェクトを組み合わせた計算は出来ませんが、以下の組み合わせは計算可能です。

  • SXとDM→SXオブジェクトになる
  • MXとDM→MXオブジェクトになる

例を以下に示します。

>>> # s0 + m0 # NG
>>> s0 + d1 # SX
SX(
[[a_0, a_2, a_4], 
 [a_1, a_3, a_5]])

>>> m1 + d1 # MX
MX(zeros(2x3,0nz))

当然、同じ種類のオブジェクト同士は計算可能です。

CasADi固有のクラス
#

CasADiに実装されている固有のクラスと、SX, MX, DMクラスとの関係を見ていきます。

Lookup table
#

CasADiには、テーブルを補間するinterpolantクラスが実装されています。interpolantオブジェクトの引数にはスカラー、MX, DMクラスを取ることができますが、SXクラスは不可です。

>>> xgrid = [1,2,3]
>>> val = [1,4,9]
>>> lut = ca.interpolant('LUT','linear',[xgrid],val)
>>> lut(1.5) # DM
DM(2.5)
>>> # lut(s0) # NG
>>> lut(m0)
MX(((((((zeros(2x3)[0] = LUT(c[0]){0})[1] = LUT(c[1]){0})[2] = LUT(c[2]){0})[3] = LUT(c[3]){0})[4] = LUT(c[4]){0})[5] = LUT(c[5]){0}))
>>> lut(d1)
DM(
[[-2, -2, -2], 
 [-2, -2, -2]])

引数をスカラーにした場合、戻り値はDMクラスとなります。

Opti stack
#

CasADiには、数理最適化計算を実行するためのOpti stackというフレームワークが実装されています。Optiオブジェクトのvariable()メソッドで変数を定義します。この変数はMXオブジェクトとなります。

>>> opti = ca.Opti()
>>> x = opti.variable() # MX
MX(opti0_x_1)

MXオブジェクトとSXオブジェクトは合わせて計算することができないため、Opti stackを使用する場合、変数やパラメータはMXやDMクラスで宣言すると良いでしょう。

参考
#

CasADiの公式リファレンス

Helve
著者
Helve
関西在住、電機メーカ勤務のエンジニア。X(旧Twitter)で新着記事を配信中です

関連記事

PythonとCasADiを使ったDirect Multiple Shooting法による最適制御
·2473 文字·5 分
Pythonと最適化ライブラリCasADiを使って、Direct Multiple Shooting法と呼ばれる手法によって最適制御問題を解きました。
最適制御向け最適化ライブラリOpEnのRust build of TCP interface failedエラーについて
·1185 文字·3 分
OpEnで発生するRust build of TCP interface failedエラーの解消方法を示します。
PythonとCasADiを使ったDirect Single Shooting法による最適制御
·2545 文字·6 分
Pythonと最適化ライブラリCasADiを使って、Direct Single Shooting法と呼ばれる手法によって最適制御問題を解きました。対象とした例題は斜方投射(物体を斜め方向に上げる)で、指定の時刻・距離に物体を到達させる最小の初速度を求めます。
最適制御向け最適化ライブラリOpEnに入門する
··1759 文字·4 分
Rust製の最適制御向け最適化ライブラリOpEnに入門するためチュートリアルの非線形計画問題を解いたので、備忘録を兼ねてまとめた。
PythonとCasADiで常微分方程式を解く
·1228 文字·3 分
Pythonと自動微分・最適化ライブラリCasADiを使って、常微分方程式解く方法をまとめた。
CasADiとBONMINで混合整数非線形計画問題を解く
·913 文字·2 分
Pythonで自動微分・非線形最適化ライブラリCasADiと最適化ソルバBONMINを使って、混合整数非線形計画問題を解く方法をまとめた。