2023年9月26日火曜日

つれづれ思うこと Perl 編 その8

では次に、最近少しは慣れてきた Mathematica について書いてみたいと思う。おっとまずい、どんどん Perl の話題から遠ざかっている。両者の間に何か関連はないだろうか?

このソフトは高価なのですが、無料で楽しめる方法が少なくとも2つあります。一つは、Raspberry pi です。これに Mathematica を無料でインストールできるのです。その代わり速度は遅く、10 倍ぐらいの処理時間がかかってしまうかもしれません。Mathematica は購入しても一つの PC にだけしかインストールできない仕組みになっています。そのため、筆者も家では Raspberry pi にのんびりと計算をさせ、翌日に職場の PC で本格的に計算させていました。Raspberry pi の OS には 32-bit と 64-bit があり、Mathematica は前者にだけインストール可能でした。しかし、今 HP を見てみると、2023/May からは 64-bit でも使えるようなことが書かれています。64-bit 版ですと、メモリーを 8 GB などと積めるので、Mathematica の動きも速くなるかもしれません。まだ試したことがないので、時間の空いた時に試してみたいと思います。

もうひとつ無料で楽しめる方法は、Jupyter lab を使う方法です。実は Mathematica という名前が指しているのは GUI 部分(という表現は変ですが)のことで、実際に計算しているコア部分は Wolfram-engine と呼ばれています。その engine 部分が無料で PC にインストールできるようになりました。すると、Windows のコマンドプロンプトなどから、計算を打ち込むことができます。しかし、いくらなんでも、これは使い勝手が悪い。そこで engine を Jupyter lab につなげると、ちょうど Python を Jupyter lab で操作するのと同じように Wolfram-engine を使うことができるようになります。もちろん Mathematica の方がインターフェースとしてはよいのですが、この Jupyter lab は Mathematica とよく似ているので(というより、Mathematica を見本として作られた?)まずまずのことができます。なお、計算能力は全く同じです。Mathematica ではできて、Wolfram-engine & Jupyter lab ではできないということはありません。今、家では Raspberry pi をやめて、この第二の方法を活用しています。Jupyter lab の上では、グラフをマウスで拡大したり回したりはできないのですが、これもコマンドベースで命令すればできますので、まあなんとかなります。PDF に出力させれば、論文用の高分解能の図も作れます。

この Mathematica は Lisp と呼ばれる言語で作られているらしく、いわゆる関数型言語に分類されるそうです。関数型が何かという専門的な部分は、私にはよく分かりません。使い始めてちょっと驚いたのは、例えば次のような IF 文です。

y = If[x < 0, -x, x]

これを普通?の言語で書くと、

if ($x < 0)
{
    $y = -$x;
}
else
{
    $y = $x;
}

となります(むりやり Perl にしてしまった)。。。

これだけだと特に変わった言語のようにも見えないのですが、もし、else 文の中に複数の行があると、次のようになります。「もし x が負の数ならば -x を y に代入する。逆に正の数ならば、x に 3 をかけて平方根をとり、これを y に代入する。」

y = If[x < 0, -x, z=x*3; Sqrt[z]]

よって、"z=x*3; Sqrt[z]" の部分がまとまって、まるで If 文の第三引数であるかのように振る舞うのです。この時の「;」が重要で、これで "z=x*3" と "Sqrt[z]" の二つが繋がって、あたかも一つの引数であるかのように振る舞います。よって、"Sqrt[z]" の後にまで「;」を付けてはいけません。もし付けてしまうと、もう一つ後ろに何らかの表現が続くことになってしまいます。

さらに、If 文が最終的に Sqrt[z] を返してくる、そして、それが y に代入されるという点も興味深いところです。このように If 文そのものが関数となっているわけです。Excel の =If もそうなっていたような気がする。

筆者は、どうも C, Perl などの癖が出てしまい、Mathematica でも以下のように書いてしまいます。各文末の「,」や「;」に気を付けないといけませんが、これですと一般的な手続き型言語に似た構文となります。ここでも Sqrt[z] の後に「;」を付けないように気をつけないといけません。

(* の箇所はコメントとして無視されます。 *)

If
[
    (* if *) x < 0,
        y = -x,
    (* else *)
        z = x*3;
        y = Sqrt[z]
]

このように If も For も全てが関数として作られており、この関数の引数の中に別の、あるいは同じ関数を入れ込むことができます。この「引数の中に関数を書く」という操作をどんどん繰り返していくと、入れ子(ロシアのマトリョーシカ人形)のようになります。そんな構文を何に使うのかというと、漸化式です。Mathematica においても For 文を使わずに、この漸化式(数学的帰納法)のコンセプトで書く方法があるそうですが、私にはとてもできません。筆者の知っている人で OCaml が大好きという方がおり、何故かと尋ねたところ、一つの理由はこの関数型にあるのだそうです。

0 件のコメント: