集合¶
SymPy が提供するクラス Set およびその諸サブクラスについて記す。 Python も組み込みでクラス set を提供しているが、記号演算と集合演算に特化させる目的で
SymPy としてもこれらを持っているのだろう。
Note
本文中のすべての IPython セッション中のサンプルコードで、以下のインポートおよび出力書式設定が済んでいるものとする。
init_printing(pretty_print=False)
主要クラス図¶
サブパッケージ sympy.sets が提供する集合を表現するクラスたち。インデントが派生関係を意味する。一行空けは特に意味はない。
クラス
SetのスーパークラスはクラスBasicである。クラス
Setのサブクラスには、もう一つ別のクラスをスーパークラスに持つことがある。一部のサブクラスは
from sympy.sets.fancysets import ...しないと利用可能にならない。
集合に関する機能(属性、操作)は、期待しているものがクラス Set のインターフェイスとして提供されている。
クラス Set¶
ここをしっかり押さえれば SymPy の集合を把握できたも同然。
プロパティー¶
クラス単位のものとオブジェクト単位のものがある。後者に興味があるので、ここでまとめておく。
基本的には各プロパティーの意味はその名前から推測できるとおり。
inf,supそれぞれ集合の下限と上限を返す。
measure集合のルベーグ測度を返す。
boundary集合の境界を返す。
is_open,is_closedそれぞれ集合が開集合であるか、閉集合であるかを返す。
集合 E が開集合 ⇔ E と E の境界の共通部分が空集合。
集合 E が閉集合 ⇔ E の境界が E に含まれる。
closure集合の閉包を返す。すなわち E と E の境界の和集合を返す。
interior集合の内部(内点すべての集合)を返す。 E の境界の補集合として表現する。
位相空間論的プロパティーの核となるものは boundary である。
演算子による集合演算¶
集合オブジェクト同士の各種演算を演算子で表現できる。ここで E と T をオブジェクトとする。
E + T,E | Tは和集合。E & Tは共通集合。E * Tは直積集合。E ** nはE * E * ... * Eの形をとる直積集合。E - TはEに対するTの補集合。
メソッド¶
ここで E と T をそれぞれ自身およびメソッド引数となる集合オブジェクトとする。
unionUnion(E, T)を返す。intersect,intersectionIntersection(E, T)を返す。complementComplement(T, E)を返す。これは引数が全体を示す方のオブジェクトなので間違えぬようにする。symmetric_differenceSymmetricDifference(E, T)を返す。powersetEのべき集合オブジェクトを返す。isdisjoint,is_disjointEとTの共通集合が空であるかを返す。issubset,is_subsetEがTの部分集合であるかを返す。issuperset,is_supersetissubsetを逆方向に試す。is_proper_subsetEがTの部分集合であり、かつE != Tであるかを返す。is_proper_supersetis_proper_subsetを逆方向に試す。containsこれは引数が集合ではなく、何かの値
xである。つまりxがEの元であるかを返す。x in Eとも書ける。
サブクラス¶
クラス Set のサブクラスのうち、面白そうなものを見ていく。
クラス EmptySet¶
クラス EmptySet は空集合を表現する。空集合を表現するためにクラスを定義することで、色々とメリットがあるようだ。
コンストラクターでオブジェクトを生成することも、シングルトン管理オブジェクトから
S.EmptySetとして参照することもできる。クラスEmptySetがシングルトンゆえ、両者は同一のオブジェクトだ。関数
lenをEmptySetオブジェクトに適用すると常に0を返す。ルベーグ測度が常に
0である。メソッド
containsは常に SymPy のS.falseを返す。メソッド
intersectionは常に空集合オブジェクトを返す。メソッド
union,complement,symmetric_differenceは常に引数の集合オブジェクト自身を返す。
クラス UniversalSet¶
クラス UniversalSet は全体集合を表現する。クラス UniversalSet の着想は
EmptySet と同じだろう。
クラス
EmptySet同様、シングルトンである。シングルトン管理オブジェクトからS.UniversalSetとして参照できる。関数
lenは利用不可。ルベーグ測度が常に
S.Inifinityである。メソッド
boundaryは常にS.EmptySetを返す。メソッド
containsは常に SymPy のS.trueを返す。その他の集合演算系メソッドはそれぞれ、与えられた引数に対する想像通りの値を返す。
集合演算クラス¶
集合演算の結果を表現する一連のクラスを、C++ の標準ライブラリー関数との連想で覚えておく。
サブクラス |
C++ <algorithm> |
|---|---|
|
|
|
|
|
|
|
|
コンストラクターについて
引数にとる集合オブジェクトの個数は、次のとおり。
UnionとIntersectionは任意の個数。ComplementとSymmetricDifferenceはちょうど二個だけ。
サポートするキーワード引数は
evaluateだけとなる。キーワード引数
evaluateは Python のブーリアン値をとる。これがTrueのときには要素を簡略化する。つまり静的メソッドreduceが呼ばれる。
静的メソッド
reduceUnionとIntersectionのそれの実装を見ると何をしているのか理解できる。実装に Python の組み込み型
setを利用している。
イテレーターについて
RangeのUnionに対するイテレーターが動かない?
クラス ProductSet¶
クラス ProductSet は集合の直積(デカルト積)を表現する。
コンストラクターで各集合を指示して直積集合オブジェクトを生成する。
集合演算は
ProductSetオブジェクト同士でなければならない。プロパティー
setsにて、直積の各集合にアクセスできる。オブジェクトが iterable である場合とそうでない場合がある。
プロパティー
is_iterableで判定できる。アクセス順は Python 標準の関数
productを各集合に適用したものと同じらしい。
クラス Interval¶
クラス Interval は実数区間を表現する。開区間、閉区間、半開区間もサポート。
コンストラクター
呼び出し形式は
Interval(start, end, left_open=False, right_open=False)である。キーワード引数の意味は、その名前が示す通り。start < endとなるように引数を指示しないと、空集合オブジェクトになってしまう。start == endとなるように指示すると、一点からなるFiniteSetオブジェクトが生成してしまう。端点として
S.Infinity等も指定できる。メソッド
Lopen,Ropen等により、指定端点を開区間にしたオブジェクトを複製できる。
メソッド
evalfが利用可能。
クラス FiniteSet¶
クラス FiniteSet は有限集合、すなわち元が有限個の集合を表現する。
コンストラクターには元を列挙しておけばよい。
オブジェクトは iterable である。集合の元は内部的にはソートされた状態なので、その順序に従って値が
yieldされる。メソッド
boundaryは自分自身を返す。メソッド
measureは0を返す。メソッド
evalfが利用可能。
その他のサブクラス¶
頻出する集合はサブクラスとしてモジュール sympy.sets.fancysets に定義されている。
クラス Naturals, Naturals0, Integers¶
名前が示す通りの整数を元とする集合を表現するクラス。それぞれのシングルトンオブジェクトが存在しており、例えば S.Natural などとしてアクセスできる。
クラス Reals¶
Interval(-S.Infinity, S.Infinity) と同じ。シングルトンオブジェクト
S.Reals としてアクセス可能。
クラス ComplexRegion, Complexes¶
クラス ComplexRegion は複素平面の領域を表現するクラス。
例えば
Intervalの直積で生成すると、複素平面上の矩形領域を表現できる。極座標のような与え方もできる。そのときはキーワード引数
polar=Trueを用いる。
一方、クラス Complexes は複素平面全体を表現するクラス。ユーザーはいつでもシングルトンオブジェクト S.Complexes にアクセスできる。
クラス ImageSet¶
ある集合とある写像に対する像を表現するクラス。オブジェクトの生成は
ImageSet(f, E) のようにすればよい。
あるいは関数
imagesetを用いてimageset(x, expr, E)のようにする。または
imageset(lambda x: f(x), E)のような。他にもある。
クラス Range¶
Python 組み込みの range とよく似ている集合。
演習¶
単体テストのコードを読んでおく。
条件を満たせば記号オブジェクトを
Intervalの端点に指定することができる。あとでメソッド
subsを利用して値を代入することもできる。
単一の集合オブジェクトだけを引数として
Union,ProductSet等の オブジェクトを生成できる。ただし、結果は元の集合と同じものになる。FiniteSetの元は数に限らない。R2 = S.Reals * S.RealsまたはR2 = S.Reals ** 2とすれば \(\RR^2\) を表現できる。(0, 0) in R2のようなコードが書ける。
Interval(0, 1, True, True) ** 2に対するメソッドboundaryの戻り値がおもしろい。座標平面上の原点を中心とする円の定義法の例。テストコード改。
In [1]: r, th = symbols('r theta', real=True) In [2]: L = Lambda((r, th), (r * cos(th), r * sin(th))) In [3]: D = ImageSet(L, Interval(0, 1) * Interval(0, 2 * pi, False, True)); D Out[3]: ImageSet(Lambda((r, theta), (r*cos(theta), r*sin(theta))), [0, 1] x [0, 2*pi)) In [4]: D.issubset(S.Reals * S.Reals) Out[4]: False
[2] 写像 \({\fnm{\RR^2}{\RR^2}{(r, \theta)}(r \cos \theta, r \sin \theta)}\) を定義する。
[3] \({[0, 1]} \times {[0, 2 \pi)}\) の
fによる像を計算する。それらしいオブジェクトが得られる。[4] これはおかしい。\({D \subset \RR^2}\) のつもりなのだが。