JavaScriptを有効にしてください

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

 ·   3 min read

はじめに

最適化ライブラリ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クラスに似ています。

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
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というシンボルを持ちます。

1
2
3
4
5
6
7
>>> 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オブジェクトになる

例を以下に示します。

1
2
3
4
5
6
7
8
>>> # 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クラスは不可です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
>>> 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オブジェクトとなります。

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

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

参考

CasADiの公式リファレンス

シェアする

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

サイト内検索