私は 25 年以上にわたって MATLAB を使っています。 (そして、その前に、スピンオフ、あるいはパクリである、遅くて嘆かわしい試みの MATRIXx をも使用していました)。 MATLABは私が最初にプログラミングを学んだ言語ではありませんが、私が数学的に成熟した言語なのです。 MATLAB を知っていることは、私のキャリアにとって非常に有益でした。
しかし、科学的コンピューティングにおける Python の台頭を無視することはできません。 MathWorks 社は、MATLAB 内から直接 Python を呼び出す機能を追加しただけでなく、二項演算子のオペランドに対してより積極的なブロードキャストなど、その言語機能の一部を借用しています。 しかし、多くのことが簡単にできるようになり、そのための教材にも多くの投資をしているので、何か新しいことを本当に学ぶモチベーションを取り戻すのは困難でした。 この本には 40 以上の関数と 160 以上の計算例があり、数値科学計算のための MATLAB の使用について徹底した基礎知識を網羅していると思います。 そこで、自己啓発の意味もあり、また、この本の有用性を高めるために、今年、JuliaとPythonにコードを翻訳することにしました。 この経験により、科学技術計算に関する 3 つの言語について、以下に示すような特別な視点を持つようになりました。 MATLAB は Python や Julia とは異なり、ビールもスピーチも自由ではありません。 これは実に大きな違いであり、人によっては決定的な違いですが、私は技術的なメリットを考えたいと思います。 長年にわたり、MATLABは非常に有用な多くの点で無料の製品を凌駕しており、もし生産性を高めたいのであれば、コストは気にする必要はないでしょう。 これは、言語やエコシステムのプラトニックな魅力とは別の検討事項です。
コストを脇に置く場合、これらの言語間の多くの違いに対する有用な枠組みは、その起源にあります。 MATLAB は最も古い取り組みで、数学、特に数値指向の数学に重点を置いていました。 1980年代後半に本格的に始まったPythonは、コンピュータサイエンスに重点を置いている。 2009 年に開始された Julia は、これらの側面の間でよりバランスを取ることに着手しました。
MATLAB
元々、MATLAB のすべての値は倍精度浮動小数点数の配列でした。 浮動小数点数は文字や整数を表現する最も効率的な方法ではありませんでしたが、科学者やエンジニア、そして次第に数学者が最も使いたいと思うものでした。 さらに、変数を宣言する必要も、メモリを明示的に割り当てる必要もない。 線形代数の数値アルゴリズムが LINPACK や EISPACK の形で独自のものになりつつあったので、配列は重要だったのです。 しかし、科学計算の標準的な担い手である FORTRAN 77 でそれらにアクセスすることは、変数の宣言、暗号のような名前のルーチンの呼び出し、コードのコンパイル、そしてデータや出力ファイルの調査など、多段階のプロセスを必要としたのです。 行列の掛け算を A*B
と書き、すぐに答えがプリントアウトされることは画期的なことでした。 低レベルの呼び出しを伴う厄介なマシン固有のライブラリはなく、plot(x,y)
を実行するだけで、MATLAB を使用している他の誰もが見ることのできるものをほとんど見ることができたのです。 複素数、疎行列、クロスプラットフォームのグラフィカル ユーザー インターフェイスを構築するツール、最先端の ODE ソルバーなど、さらに多くの革新的な技術により、MATLAB は科学計算を思考速度で実行する場所となったのです。 多くの関数間でデータを移動するには、多くの変数を調整し、入力および出力引数に関するドキュメントを頻繁に参照する必要がありました。 ディスクファイル1つにつき1つの関数、しかもフラットな名前空間というのは、小さなプロジェクトでは新鮮なほどシンプルですが、大きなプロジェクトでは頭痛の種になります。 スピードのボトルネックを避けるには、特定のプログラミングパターン(ベクトル化、メモリの事前割り当て)を適用する必要がありました。 科学技術計算が、より多くのドメインに適用され、膨大な量の異なるネイティブタイプのデータを扱うようになったのです。 インライン関数、ネストされた関数、変数クロージャ、多数のデータ型、オブジェクト指向機能、ユニット テスト フレームワークなど、MathWorks は MATLAB 内で革新し続けることによって対応しました。 それぞれの技術革新は、おそらく重要な問題に対する解決策だったのでしょう。 しかし、40年にわたるこうした変化の積み重ねは、シンプルさやコンセプトの統一性を損なうという副作用をもたらしました。 2009年、私は100ページ足らずの本の中で、MATLABのエッセンスと思われるものをかなり網羅した本を書きました。 私が知る限り、それらはすべて今でも入手可能です。
Python
Python の歴史は、ある意味で、MATLAB の鏡像のように思えます。 どちらも対話的なコマンドライン (現在では “read-eval-print loop” の略で REPL と広く呼ばれています) と変数宣言やコンパイルからの解放を特徴としています。 しかし、MATLABは数値解析者の遊び場として作られたのに対し、Pythonはハッカーを意識して作られた。
私の目には、Python はまだ数学的な魅力に欠けているように見えます。 例えば、^
の代わりに **
、行列の乗算に @
(最近の革新!) 、行列のサイズではなく shape
、行指向のストレージ、などの醜さと小さな悩みを抱えています。 もし、V.conj().T@D**3@V
が $V^*D^3V$ を書くためのエレガントな方法だと信じているなら、医者に診てもらった方がいいかもしれませんね。 そして、ゼロインデックスがあります(1から始まるインデックスとは対照的です)。 議論を読みましたが、決定的なものは見当たりません。 これは明らかに好みの問題で、ネット上の聖戦のようなものです。なぜなら、どちらの慣習でも得体の知れない例を挙げることができるからです。 私が決定的だと思うのは、ベクトルや行列を 1 からインデックス付けする数学的実践が何十年もあり、ほとんどの擬似コードはその前提で作られているということです。 その証拠に、この言語はオブジェクト指向に専念しているにもかかわらず、行列クラスが存在し、その使用は推奨されず、非推奨になるという事実があります。 おそらくMATLABが私を堕落させたのでしょうが、私は行列は維持し、促進するのに十分重要なオブジェクトの一種であると思います。 配列と行列に対して*
に異なることをさせることができるのは、OOPの大きなセールスポイントではないでしょうか? この点については、他にも多くの不都合な点があります。 (なぜ spsolve というコマンドが必要なのでしょうか? 疎な行列に対して solve
を呼び出すだけではだめなのでしょうか? といった具合です。)
また、数値的なエコシステムが少し薄く見えるところがあります。 たとえば、求積法とODEソルバーは2019年の最小セットみたいです。 AFAICT DAE、DDE、シンプレクティックソルバー、インナークリロフイテレーションを可能にする陰解法ソルバーなどのメソッドはありません。 これらの関数のリファレンスを見てください。彼らはほとんど30年以上前のもので、まだ良いですが、完全にはほど遠いものです。 Matplotlib パッケージは素晴らしい作品であり、しばらくの間、MATLAB よりも良く見えましたが、まだ 3D ではかなり不足していると思います。
一部の専門家は、Python コードがコンパイル言語と実行速度で追いつくのに苦労するのには深い理由があると主張しています。 Python is too slow」で検索した結果には面食らいました。 Pythonのチャンピオンは、昔MATLABのために人々がしたのと同じ議論や謝罪をたくさんしているのです。 それは、彼らが間違っているわけではありませんが、認識の問題以上のものがあります。
Python が科学技術計算の多くの人々にとってなぜそれほど刺激的であったのか、私は理解できると思います。 Python は MATLAB のような構文とパワーを持ち、REPL から利用できます。 Python には素晴らしいツールがあり、他の言語やコンピューティングの分野とうまく連携しています。 それを無償で提供し、長期的な再現性を高めているのです。 明らかに、多くの人々にとってうまく機能しており、おそらく変更する理由はほとんどないでしょう。
しかし、私が科学技術計算で行う方法を知っていることについては、Python は私が慣れているよりも、学び、使うのがずっと面倒に感じます。 このままコミュニティを席巻していくのか、それともすでにピークに近づいているのか、しばらくはわかりません。 私には特別な予測能力はありませんが、弱気です。
Julia
Julia には後発であることの利点と欠点があります。 私は、Julia の作成者がもっとうまくやれると考えたことに拍手を送ります:
私たちは、オープンソースで、自由なライセンスの言語を望んでいます。 C のスピードと Ruby のダイナミズムが欲しい。 Lisp のような真のマクロを持ちながら、Matlab のような明白で馴染みのある数学的表記法を持つ、ホモイコニックな言語が欲しいのです。 Pythonのように一般的なプログラミングに使え、Rのように統計が簡単で、Perlのように文字列処理が自然で、Matlabのように線形代数に強力で、シェルのようにプログラムをまとめるのに適した言語が欲しいのです。 学ぶのがとても簡単で、しかも本格的なハッカーが満足できるようなもの。 私たちはインタラクティブでコンパイル可能なものを求めています。 バージョン 1.0 への道のりの後半では、REPL を少し軽視しているように見えましたし、MATLAB からほとんど無償で離れていくようなものもありました。 (
linspace
よりLinRange
の方が良いとはどういうことか?) これらは些細なことですが、これは私が使った中で、ASCII を超える最初の言語です。 今でも
ϕ
のような変数や≈
のような演算子を使うと、理不尽なほどの満足感を得られます。 それは外見的なものよりも、私たちが書く数学的な表現に近いものができることは、教えや文書化を少し複雑にしますが、本当にプラスです。Julia で作業していると、MATLAB の選択のおかげで、固有の優位性ではなく、いくつかのプログラミング習慣を身につけたことがわかりました。 ベクトル化は、多くのものにとって自然なことではありません。 Julia では、どんな関数でもその名前にドットを加えるだけでベクトル化できることがわかり、目を見張るものがあります。 内包によって行列を構築することは、入れ子ループ(あるいは
meshgrid
トリック)をバグだらけの鞭のように見せてしまいますし、単純な総和のための生成器によって行列を完全に避けることは、何かを得るための無駄のように感じられます。 (Python にも同様の言語機能があることは承知しています。)多重ディスパッチという大きな特徴は、いくつかのことをオブジェクト指向よりもずっと簡単かつ明確にします。 たとえば、伝統的なオブジェクト指向言語で Wall クラスと Ball クラスがあるとします。 BallがWallに衝突した場合、どちらのクラスが検出すべきでしょうか。 それとも審判をするRoomクラスが必要なのでしょうか? このような疑問があると、気が散って仕方がない。 多重ディスパッチでは、データはオブジェクト型にパッケージ化されますが、データを操作するメソッドはクラスに束縛されることはありません。 つまり、
function detect_collision(B::Ball,W::Wall)
は型について知っていますが、型から独立して定義されています。 複数のディスパッチという概念が、言語を拡張するためにどれほど興味深く、潜在的に重要であるかを理解するには、かなりの量のプログラミングを行う必要がありました。 私の一番の例は、素晴らしい Chris Rackauckas によって書かれた DifferentialEquations.jl です。 このソフトウェアがすぐに Wilkinson 賞を受賞しないようであれば、システムは壊れています。
私はまだ、Julia が約束する MATLAB を超える大きなスピードアップを見たことがありません。 それは、私の経験が浅いことと、私が行うタスクの種類のせいでもありますが、MathWorks がコードを自動的に最適化する信じられないような仕事をしたせいでもあります。 いずれにせよ、私が最も注力するのはコーディングの側面ではありません。
Julia でのプログラミングは、快適に感じるまでに時間がかかりました (年をとって結晶化しただけかもしれません)。 それは、私が望む以上にデータ型について考えさせられ、何かをするための正しい方法を見逃しているのではないかという疑念が常につきまといます。
要点
MATLAB は、特にエンジニアリングにおいて、企業向けソリューションです。 おそらく今でも、基本的な数値計算のタスクについては、最も簡単に学ぶことができます。 綿密なドキュメントと何十年にもわたって貢献してきた学習ツールは、間違いなく重要です。 高価であり、それは付属品 (ツールボックス) について話し始める前の話です。 堅実でスムーズなパフォーマンスとサービスに対してお金を払っているのです。 また、Python は不釣り合いなほどの憎悪を集めています。 それは (米国で) ユビキタスで多くの人に愛されています。 それはあなたが望むすべてを行うことができますし、他の車ができないいくつかのことを行うために構築されています。 時々、借りたいと思うこともあるでしょう。 しかし、純粋な運転体験はできない。
JuliaはTeslaだ。 未来を変えるという大胆な目標を持って作られていますし、そうなるかもしれません。 また、単なる脚光を浴びる存在になるかもしれない。 しかしその間、あなたはスタイリッシュに、そして余裕のあるパワーで、目的地にたどり着くことができるのです。