Luaレッスン17「ヒントと秘訣(その2)」和訳

出典

http://compasstech.com.au/TNS_Authoring/Scripting/script_tut17.html

レッスン17「ヒントと秘訣(その2)」

math.eval

わたくしはこれまで、この強力な素晴らしいコマンドの使い方を楽しく学んできました(ときに少なからぬフラストレーションも感じてきましたが)。

しょせん我々は、まっさらなキャンバスに一からプログラムを記述するLua使いではありません。我々は、TI-Nspireという、まったく強力で機能満載の数学的環境で作業しているのです。2つの数の最大公約数を求めるようなルーチンは確かにインターネット上に転がってはいますが、TI-Nspireの最大公約数函数を利用する手立てはないものでしょうか? math.evalが必要とされる理由がそれです。

今、numおよびdenという2つの数があって、その両者に公約数があるかどうかを知りたいとします。その場合は、2つの数を分割できるまで分割して、num.."/"..denという分数を最も簡約した形にする必要があります。そのためには、numとdenとを引数とするGCD函数が必要です。

以下、ここでの処理の内容を示す手段として、Nspireに関連する箇所は赤色で表示します(訳註:赤色は原文のみ)。

一番簡単な方法はおそらく、以下のようにnumおよびdenをNspireに渡す方法でしょう。

var.store("num", num)

var.store("den", den)

nspireLuaとに同じ変数名が存在していても問題ありません。両者の競合することはないからです)。そのあとで以下のように記述します。

local gcd = math.eval("gcd(num,den)")

どのような処理が行われるのか、じっくり考えてください。math.eval函数の引数(引用符で括られた部分)がNspireへ渡され、Nspireが答をLuaに返すという仕組みです。すてきですね。

以下のようにすればもっと良いでしょう。

local gcd = math.eval("gcd("..num..","..den..")")

こうすれば、LuaとNspireとの間で変数をやり取りする処理を記述する必要がないからです。ここでもやはり、どのような処理が行われるのか、じっくり考えてください。

この機能についてちょっと考えてみれば、どれほどの可能性を秘めた機能であることかがわるでしょう。正当なコマンドであれば、TI-Nspireに計算させることができるのです。

最初わたくしは、TI-Nspireの組込函数だけで働く機能だと思っていましたが、ユーザーが自分で作った函数でも機能します。しかもCASについても機能します。ただし、Luaで認識できる変数型(数字、文字列)以外はLuaでは処理できません。つまり、リスト、式、行列は処理できません。

fnというユーザー定義函数にPolyRoots函数を適用した結果を取得する手順を考えてみましょう。fnはfn = "x^2-5"と定義するとします。次のように記述できます。

result = math.eval("polyroots("..fn..",x)")

しかしこれでは機能しません。なぜでしょう? 

polyroots函数の結果はリストです。結果をLuaで取得できるよう、結果を文字列に変換する必要があります。ですから、以下のようにすればうまくいきます。

result = math.eval("string(polyroots("..fn..",x))")

同じように、CAS機能で式を因数分解したい場合も、計算結果が代数式になりますので、Luaでは処理できません。以下のようにして、文字列がLuaに返されるようにする必要があります。

result = math.eval("string(Factor("..fn..",x))")

函数をNspireに渡す場合、その函数は文字列として渡されます。そのため、factor函数を機能させるためには、渡された文字列を元の形に戻して処理し、また文字列に変えてからLuaに戻す必要があるということです。慣れればどうということもありませんが、ややこしいですね。代わりに以下のようにする方法もあります。

var.store("fn", fn)

result = math.eval("string(Factor(expr(fn),x))")

何か特別な目的でもない限りは、変数をやり取りしなくて済むもっとエレガントな方法をお勧めします。たとえば、前述したユーザー定義函数fnのグラフも閲覧したい場合はどうすればよいでしょうか? その場合は、fn函数をnspireに渡せばf1(x) = expr(fn)と定義できますので、fnがどのような函数であろうと、そのグラフが描けます。

 

添附ドキュメントpretty.tnsの作成には、こうしたさまざまなルーチンおよび発想がすべて使われました。このスクリプトには、代数表示のためのPretty Printルーチンだけでなく、分数表示函数が含まれているほか、多項式の根ンを見つけて数値形式で返すmath.evalルーチンも含まれています。

もっと完成度の高い添附ドキュメントfractions_template.tnsにはキーパッドも追加されています。

レッスン18へ進んでください。今度は、Luaドキュメントに独自のメニューを追加する方法を学びます。

-------------------------------------------------------------------

(訳註)今回の実行例(スクリプトはオリジナルのままである)。x^3+x^2の根を求めている。

f:id:ti-nspire:20141126131241g:plain