oocon 2020
Mathematica上の
二重遅延定義による
関数化された
OOP
@kozukorio
1
目次
0. なぜにMathematica
1. OOPになれるか?Mathematica
2. クラスとは二重の遅延定義
3. それはOOPか?
4. OOPを関数とみなす
5. Mathematicaの基本
6. 関数化とオブジェクト操作
7. オブジェクト操作の抽象化
8. ここでSetとUpSet
9. 連想の導入とプロパティの設定
2
10. OOPとモデル記述
11. オブジェクト指向の本質
12. インスタンス数とメモリ制限
13. OOPは並列計算
3

0. 何故に?
   Mathematica
(現在、Mathematicaとは環境全体を指し、プログラム言語はWolfram言語と呼ばれている)
1. Mathematicaはオブジェクト指向言語ではない → オブ
ジェクト指向パラダイムが使えたらさらに強力
2. 開発の発端→ クロージャを実現→ オブジェクト指向もでき
るのでは? 
3. OOPの実現方法 → 慣例的なnotation(X.A)を使うべき
か?→ かつて存在したスクリプト表現の今さら感→ 
genuinな方法→ 関数型OOP
4
������������
�����������
1. クラスとは?→ 二重になった遅延定義である
���������
2. コンストラクションとは?→ クラス関数にインスタンス名を
引数として与え→ インスタンス名に初期値を引数を与える
こと
�����������������
3. メソッドの実行とは?→ メソッド関数にインスタンス名を
(あるいはインスタンス関数にメソッドを)引数として与える
こと
������������������
������������������
5
��������
�������
Pythonとの比較
>>> ����� ��������
��� ��� __����__(����� ��������� ��������)�
��� ������ = ��������
��� ������ = ��������
���
>>> � = �������(���� -���)
>>> ���� ���
(���� -���)
6
Mathematicaのクラス表現は、二重の遅延定義(:=)で構成される関数
�������[���_[�����_]] �= ������[{����� = �����}�
���[���] �= ������
]
コンストラクションとは、クラス関数のインスタンス関数(初期値付き)を引数とした呼び出し
�������[���������[{���� -���}]]
メソッドの実行とは、生成されたインスタンス関数のメソッドを引数とした呼び出し
���������[���]
{3., -4.5}
7
3. それはOOPか
◼ �����
1. Module関数によりカプセル化された内部変数
2. パターン呼び出しによるメソッドの部分的なカプセル化
8
◼ ��
スーパークラスの定義
����������������������������������������������
���������[���_] �= ������[{�� = ����}�
���[�����[�_]] �= �� = ��
���[�����] �= ���
]
サブクラスの定義
����������������������������������������������������������������
���������[���_] �= ������[{������� = ����}�
���������[���]�
���[������[�_]] �= ������� = ��
���[������] �= ��������
]
���������������������������������������������������������������
9
���������[���_] �= ������[{��������� = ����}�
���������[���]�
���[������[�_]] �= ��������� = ��
���[������] �= ����������
]
サブクラスのインスタンスを生成する
�����������������������������
���������[����]�
����[�����[����]]�
����[������[��������]]�
�������������������������������
���������[������]�
������[�����[����]]�
������[������[�������]]�
10
メソッドの実行
�����������
{���[����� {������ ������}]�
���[������� {������ ������}]}
{{1001, personel}, {2001, physics}}
�����������
���������[����]�
����[�����[����]]�
����[������[�������]]�
���������������
���[����� {������ ������}]
{����� �������}
11
◼ ���
������������������
{����[�� �]� ����[�� �� �]}
{3, 6}
���������������������������������������������������
�������������
�����������[���_] �= ������[{}�
���[����[�_]] �= ����
]�
����������[���_] �= ������[{}�
���[����[�_]] �= ����
]�
�����������[���������]�
����������[���������]�
12
{���������[����[�]]� ���������[����[�]]}
{�� �}
13
4. OOPを関数とみなす
クラスの定義→ 二重の関数として定義すること
クラスの定義→ Module関数による内部変数
�����[���_]�= ������[{�����}�
���[���]�= ������
���[���[�_]]�= �����= �
]
インスタンスの生成→ クラス関数にインスタンス名を与えて実行すること
�����[��������]
書き込みメソッドの実行→ インスタンス関数にメソッド関数を与えること
��������[���[����]]
3.14
14
読み出しメソッドの実行→ インスタンス関数にメソッド関数を与えること
��������[���]
3.14
15
◼ オブジェクト指向のnotationはどこから?
16
E.W.������, C.A.R.���, O.-J.����, ����,���,�����, ������������������1975�
17
◼ 関数化から見えてくるOOPとは?
...導かれるOOPの本質とは、
1. ラムダ計算による無名化→ 時間発展するインスタンス→ ス
テータスとステータスを操作するメソッド
2. 本質はインスタンスをオブジェクトにより抽象的に扱う手法
→ 起源としてのSimula 67
3. 時間発展するインスタンスはメモリ空間にデプロイされるこ
と→ マルチコアへのインスタンスのデプロイ
...の説明の前に
18
5. Mathematicaの
基本
◼ 構文を持たずAtomがあるだけ
Blank������������Atom�
_
Expression(�)
_[_]
Sequence
_[_, _, _]
19
◼ 関数の定義 → Blankの置き換え
����������������������������
x_
f��������������x_����
�[�_]
������������������������(x�������)
�[�_] �= � + �
��������� → ������������
�[�]
1 + a
20
◼ Mathematicaの純関数
名前のついていない関数に値を与える(#がスロット、&は関数の終わりを示す)
#^2 &[4]
16
���Head�������
#[Pi / 4] &[Cos]
1
2
Map��������
Map[#[Pi / 2] &, {Sin, Cos}]
{1, 0}
21
�������
��������
◼ 関数化されたOOP(IPD)
クラスの原型:インスタンス優先定義(Instance Preceded De�nition)
�����[���_]�= ������[{�����}�
���[���������]�= ������
���[���������[�_]]�= �����= ��
]
インスタンスを別々にコンストラクト
{�����[���������]� �����[���������]}
{Null, Null}
22
メソッドの実行〜書き込み
{���������[���������[�]]�
���������[���������[�]]}
{1, 2}
メソッドの実行〜読み出し
{���������[���������]�
���������[���������]}
{1, 2}
◼ インスタンスリストの導入
インスタンスのリスト(オブジェクトと呼ぶ)から一度にコンストラクト
������ = {���������� ���������� ���������� ���������� ���������}�
���[������ ������]�
23
インスタンスのリスト(オブジェクト)からメソッドを一度に実行〜setMethod
�=��
���[#[���������[�++]]��������]
{1, 2, 3, 4, 5}
インスタンスのリスト(オブジェクト)からメソッドを一度に実行〜getMethod
���[#[���������]��������]
{1, 2, 3, 4, 5}
����������������������
24
◼ メソッド優先定義(MPD)
クラスの原型:メソッド優先定義(Method Preceded De�nition)
�����[���_]�= ������[{�����}�
���������[���]��= ������
���������[���[�_]]��= �����= ��
]
インスタンスのリスト(オブジェクトと呼ぶ)から一度にコンストラクト
������ = {���������� ���������� ���������� ���������� ���������}�
���[������ ������]�
インスタンスのリスト(オブジェクト)からメソッドを一度に実行〜書き込み
�=��
���[���������[#[�++]]��������]
{1, 2, 3, 4, 5}
25
インスタンスのリスト(オブジェクト)からメソッドを一度に実行〜読み出し
���[���������[#]��������]
{1, 2, 3, 4, 5}
純関数のスロットが関数の引数の位置にある
26
������������
�������
1. インスタンスを抽象的に扱う手法は何か→インスタンスの集
合を扱う →インスタンスの集合をオブジェクトと定義する
2. オブジェクトを抽象的に扱う手法は何か→オブジェクトにシン
ボルを割り当てる→オブジェクトシンボルを通して各インスタ
ンスを操作する
27
◼ インスタンスの時間発展
1. インスタンスは独立している→ インスタンスは別々に時間発
展する
2. 時間発展するインスタンス→ 基本的にダイナミックな存在→ 
メモリ空間にデプロイされる
28
◼ インスタンスの並列実行
1. インスタンスは独立している→ 並列的に記述することが出
来る→ 集合とみなした操作が出来る
2. 並列的に記述することが出来る→ 並列的に動作することが
出来る→ 並列計算インスタンス
3. 並列計算インスタンス→ マルチコアへのインスタンスのデプ
ロイ
29
���������������
(関数名と引数について)対称的な二つの純関数に、引数xを与える
�[#]�[�]
y[x]
#[�]�[�]
x[y]
SetとUpSetを用いた、user関数の対称的な定義
�[�_]=����
�_[�]�=����
対称的な関数の実行定義
{�[�]� �[�]}
{9, 9}
30
���������
��������
�����������2�������������
インスタンスプロパティを連想に定義
(インスタンスの名前リストと初期値を統合する)
��� = {
�����������[������ -> ������ ������� -> {����� ����}]�
�����������[������ -> ������ ������� -> {����� ����}]
}�
クラス定義
��������[���_] �= ������[{��� ��}�
����[���[{�_� �_}]] ��= {��� ��} = {�� �}�
����[���] ��= ������[�����[��� ��]� ������[��# - �] �]
]�
31
インスタンスのコンストラクション
���[��������[#����] �� ���]�
各インスタンスのパラメータ設定
���[����[#����[#�����]] �� ���]
{{1000, 2000}, {2001, 3000}}
各インスタンスの計算実行
���[����[#����] �� ���]
{{1279}, {2203, 2281}}
32
�������������
◼ モデルへの応用→ エージェントモデル
レムニスケート曲線上の動点
�������� �������������[{
� = ���
����� = �����
���������� = {��� ��}�
�� = ������������[
�����[{���[�]� ���[� �]}� {�� �� � ��� ��/����}]� ���� -> ����]}�
����� �����������
�����[���_] �= ������[{� = �� � = �}�
���[����[�_]] �= � = ��
���[����] �= (�++� �����[{���[�*�]� ���[� �*�]}])
]�
33
������ ����������
���������� = �����[������[]� {�}]�
���[�����[#] �� ����������]�
���[#[����[�����*����������[����������]]] �� ����������]�
���� ���������
������������ �= ��������[{���������[�����]� ���[#[����] �� ����������]}]�
�������[��
����[{��� ������������}� ��������� -> ���]�
{�� �� ���� �}� ���������������� -> �����]
]
34
��������
�
35
◼ モデルへの応用→3次元グラフィックスモデル
�������������[{
� = ���
����� = �����
���������� = {��� ��}�
�� = ����������������[{(� + ���[� �]) ���[�]� (� + ���[� �]) ���[�]� ���[� �]}�
{�� �� � ��}� ���������������� -> ����
��������� -> {���������[�����]}� ���� -> ����]�
����������}�
����� ���������� (���)�
������[���_] �= ������[{� = �� � = �}�
����[���[�_]] ��= � = ��
����[���] ��= (�++� � = �*��
{�����������[������ ��]�
������[{(� + ���[� �]) ���[�]� (� + ���[� �]) ���[�]� ���[� �]}� ���]}
)
36
]� ���� - ������ ������ ���������
������ ����������
���������� = �����[������[]� {�}]�
���[������[#] �� ����������]�
���[����[#[�����*����������[����������]]] �� ����������]�
���� ���������
�������������� �= ����������[{���[����[#] �� ����������]}]�
�������[��
����[{��� ��������������}]� {�� �� ���� �}� ���������������� -> �����]
]
37
�
38
�������������
��
◼ 本質は削ぎ落として残ったもの
本質の1
・メソッドはインスタンスに従属している
本質の2
・インスタンスは時間発展する
本質の3
・インスタンスはメモリ空間に配備される
39
������������
�����
◼ インスタンスはメモリの許す限り生成することができる
10^6 個のインスタンスそれぞれの10 個の近傍オブジェクトを探索
������� = �����
nearestFunctionであるnfはグローバルな関数
��������� = ���
�����[���_[����_]] �= ������[{����� = ����}�
���[���] ��= ������
��������[���] ��= ��[������ ���������]�
]�
40
10^6個のインスタンスから構成されるオブジェクトをコンストラクトし、それぞれに初期位置を与える
����������[������]�
������[������ = �����[�����������[����[������� ������[]]�
����[�������� {����������[]� ����������[]� ����������[]}]]� {�������}]�
���[�����[#����[#�����]] �� ������]�]
{23.3239, Null}
Nearestfunctionのセットアップ
������[�� = �������[���[���[#����] �� ������] → ���[#���� �� ������]]�]
{8.70849, Null}
全てのインスタンスの近傍にある10個のインスタンスの検出とその計算時間
������[���[��������[#����] �� ������]�]
{42.0709, Null}
41
実行メモリーサイズ
�������������[]
2 064 980 640
42
特定のオブジェクトの近傍neighbors個を3Dプロット
��� = ������
�������� =
���[���[#] �� �������[���[��������[#����] �� ������[[��� �� ��� + ��]]]]]�
���������������[��������� ������������� → ��������[{�� �� �}� ���[�]]�
��������� → {{��� ��}� {�� ��}� {�� �}}]
43
������������
◼ マルチコアの利用
��������������������������
シングルコアで計算した場合
�� = �����������[]�
��� = ������[�����[����� �����]� ������[��# - �] �]�
{�����������[] - ��� ���}
{53.869337, {9689, 9941}}
������������������
コア毎に1個のインスタンスを置く場合
44
45
1. コアカーネルの起動
������������[]�
�������������[]�
���������� = ����������������[���������]�
{�� = ������[����������]� ����������}
{�� {�� �� �� �}}
2. クラスの定義
�������������[���_] �= ������[{���� = ���� ���� ���}�
���[���[{��_� ��_}]] �= {���� ���} = {��� ��}�
��[] �= {����� ������[�����[���� ���]� ������[��# - �] �]}
]�
46
3. 並列計算インスタンスのプロパティ設定のための連想
������ = {
�����������[������ → ������[�]� ������� → {����� ����}� �������� → ����������[[�]]]�
�����������[������ → ������[�]� ������� → {����� ����}� �������� → ����������[[�]]]�
�����������[������ → ������[�]� ������� → {����� ����}� �������� → ����������[[�]]]�
�����������[������ → ������[�]� ������� → {����� �����}� �������� → ����������[[�]]
]}�
4. インスタンスのコンストラクションと各コアへのデプロイ
���[����������������[ �������������[#����]� #������] �� ������]�
5. インスタンスのプロパティの設定
���[����������������[#����[���[#�����]]� #������] �� ������]
{{9000, 9399}, {9400, 9699}, {9700, 9899}, {9900, 10 000}}
47
6. パラレル計算の実行
�� = �����������[]�
��� = ����������������[��[]]�
{�����������[] - ��� ���}
{���������� {{������� {}}� {������� {����}}� {������� {}}� {������� {����}}}}
48
1.新刊 「Mathematicaで理解するオブジェ
クト指向」@技術書典8 day1 2020年2月
29日@お46
2.既刊 「アイデア実現のための Raspberry
Piデザインパターン 電子回路から
MathematicaによるArduinoコラボま
で」 オーム社, 2019年10月.
49

Oocon2020 presentation slide @kozukorio