MUPAD TIPS (VERSION 0.3.4)

1. はじめに (copy right など)

この文書はもともと (主として Linux 版の) MuPAD (バージョン 2.0.0 以降 (現在 2.5.2) について、使い方を自分用の忘備録としてまとめたものです。この文書は書きかけです。

この文書は GNU Free Documentation License (version 1.1 あるいはそれ以降) に従います。

   (c) Copyright 2000 Yoshifumi Tsuchimoto
    Permission is granted to copy, distribute and/or modify this document
    under the terms of the GNU Free Documentation License, Version 1.1
    or any later version published by the Free Software Foundation;
    with no Invariant Sections, with no  Front-Cover Texts,
    and with no Back-Cover Texts.
    A copy of the license is included in the section entitled "GNU
    Free Documentation License".

2. 関連リンク

愛媛大の平田浩一さまの数式処理 MuPAD 入門

(http://www.ed.ehime-u.ac.jp/~hirata/MuPAD/index.html ),

大阪府立大の川添充さまの How to use MuPAD

(http://magi.cias.osakafu-u.ac.jp/~kawazoe/unix/mupad.html)
KENPEI さまの MuPAD の研究 (http://f28.aaacafe.ne.jp/~kenpei/mupad.htmli)

はとても参考になります。 SciFace Software (MuPAD を販売している会社) にある MuPAD tutorial (http://www.sciface.com/doc/html/eng-noframe/index.shtml) も必見でしょう。

3. 一般的な注意

MuPAD は、大文字、小文字を区別します。

3.1. 起動の仕方と終了の仕方 (quit;) kterm や rxvt のコマンドラインから、

xmupad

で X 版の MuPAD が起動します。

mupad

でターミナル版の MuPAD が起動します。グラフを書くときには X 版が便利ですが、ターミナル版は場所をとらないのでこまわりがききます。しかも、補完機能をもったヒストリ機能が使えます。 (ちょっと宣伝:ここらあたりの使い心地は windows 版や Mac 版よりも Linux 版の方が数段優れています。可能な方は Linux をインストールして Linux 版を入れてみて下さい。 (FreeBSD などをインストールして Linux emulation で動かしてもいいかもしれません。 ))

場合によって使い分けると良いでしょう。

quit;

と打つと終ります。

MuPAD 2.0 以降では xmupad などの GUI 版は quit; では終らないようになったようです。すなおにメニューから終了 (File → exit) を選択するのがいいでしょう。

3.2. ヘルプシステムの使い方 (?) mupad/xmupad のプロンプトに、

? plot3d

などと打ち込むと、 plot3d についてのヘルプが見られます。

X 版のヘルプの便利な所は、ハイパーリンク (関連文書をクリックでたどれる) が使える所ですが、私はもっぱらターミナル版の MuPAD からつかってます。 (MuPAD 起動前にあらかじめ環境変数 PAGER に良いページャを指定しておくのを忘れずに。私は ”less” を使っています。ただし、 less のオプションとして ”-r” を指定しないときれいに出力しないので $MuPADDIR/share/bin/mupad の二行目に

LESS="-r $LESS"

という行を書き加えています。 ) ノートパソコンならこの方が見やすいですし、キーボードで操作できる方が楽です。

さらに、 MuPAD をインストールしたディレクトリのサブディレクトリ share/doc/ascii には、 help の ascii 版があります。 grep などで手っ取り早く検索するにはそれを使うのが便利です。

3.3. プログラムを作って読み込ませる。 (read). MuPAD のプロンプトにいろいろいれて、遊ぶこともできますが、やはり慣れたエディタでプログラムを書いていった方が楽です。

プログラムを読み込むには、

read("xx.mupad");

などと、 read コマンドを MuPAD のプロンプトにいれれば OK です。あるいは、 MuPAD を起動するときにオプションとして指定することもできます。

xmupad xx.mupad

てな感じです。 3.3.1. コメント行 (//, /*...*/). MuPAD では // で始まる行はコメントとみなされます。

(コメントとはそのプログラムを読む人間のために書かれた文章で、コンピュータにとってはあってもなくても同じ、という類のものです。 MuPAD に限らず、どんなプログラムでも、簡単な使い方やプログラムを使うためのポイントなどのコメントをいれておくことは大事です。 )

長いコメントは/* と */ で囲んでもよいでしょう。これらは C(++) ではおなじみですね。

3.4. ゴワサンで願いましては (reset();) 今まで計算して来た結果を全て一旦破棄して、もう一度一番始めから計算したい時があります。そのようなとき、 MuPAD を一旦終了してもう一度起動してもよいのですが、

reset();

としてやるほうが MuPAD の再起動をしなくてすむ分時間の節約になります。 (もっとも、これは MuPAD にメモリリークがないと仮定しての話で、どうしても気になる時にはやはり MuPAD を再起動してやる方が安心のような気もします。 )

3.5. 今まで入力した行の再利用 (history,HISTORY). MuPAD の Linux ターミナル版では、カーソルの上下キーを使えば、 MuPAD セッションを始めてから今までに入力した行 (いわゆるヒストリ) を呼び出して使うことができます。

(この機能はとても有用で、 MuPAD を本格的に使いたい方はこれ一つとっても Linux をインストールして Linux 版を使う価値があると思います。 )

MuPAD が覚えているヒストリの量は HISTORY という変数で決まっていて、デフォルトは 20 です。これでは少なすぎると感じる方は（私がそうでした)、

HISTORY:=100:

などとして HISTORY の量を増やすと良いでしょう。ただしこれをするともちろん消費するメモリの量は増えてしまいます。

ヒストリを直接操作するには history() という関数を使えばよいようです。詳しくは

? history

でご確認ください。

3.6. 表示の幅を変更する (TEXTWIDTH). mupad は 75 行を目安に行を区切って表示するため、大きな行列の計算等を行った結果を表示する際に見にくくなってしまいます。そのようなときには kterm や rxvt などの大きさを大きくして、さらに TEXTWIDTH を大きめに設定してやれば良いでしょう。

3.7. mupad の出力の形式を変える (PRETTYPRINT). mupad はべき乗や行列をできるだけ見栄えよく出力しようとしますが、場合によってはこれがあだになります。 (カットアンドペーストなどで mupad の出力をあらためて入力したい時など。 ) そのような時には PRETTYPRINT という変数を FALSE にするとよろしい。ただし、たまに括弧を外しすぎてまずいこともあるようです。注意して使ってください。

4. 計算

4.1. 文 (;) MuPAD で何かを計算させるには、まず文の終りの記号 (;) を覚えることが必要です。

3+4;

と打ち込んで、 Enter(Mac 版なら Shift+Enter) を押すと、 3+4 が計算できます。これぐらいなら暗算のほうが速いので、満足できないという向きには、 100 の階乗などはいかがでしょうか？

 100!; (Shift+Enter を押す)
93326215443944152681699238856266700490715968264381621468592963895217599993\
22991560894146397615651828625369792082722375825118521091686400000000000000\
0000000000

これが一瞬で出てくるのだからなかなか素晴らしいでしょう。

実は、文の終り方にはもう一つ方法があります。 ”:” で終る方法です。これは、「計算はしなきゃいけないけれどもした結果を出力はしなくてよい」ときに使います。

そんなことがあり得るのでしょうか?その代表的な例が、次の節で述べる「代入」です。

4.2. 代入 (:=). 変数 x に値を代入するには、 ”:=” という記号を用いて、

x:=10;

などとします。

4.3. MuPAD に黙って計算させる (:) 前節の例のように、

x:=10;

と ”;” で終ると、 mupad は御丁寧にも ”10” という値を返してきますから、それがうっとうしいような場合には、

x:=10:

とやればよいのです。 MuPAD は黙って x に 10 を代入してくれます。

4.4. 定義を解除する。 (delete)(...=NIL;). X に 10 という値を一旦代入してみたけど、やっぱり X はただの変数として使いたい、というときには、 MuPAD 2.0 以降では delete というのを使います。

X:=10;
delete X;

旧バージョン (1.4 など) では X に “NIL” という値を「代入」してやればよろしい。

X:=10;
X:=NIL;

4.5. さまざまな演算 (+,-,*,/, ＾ ,sqrt,exp,ln,cos,sin,PI,E,I). 愛媛大の平田浩一さまの数式処理 MuPAD 入門の「数の計算」のところにうまく書かれています。ここでは基本的なものについてずらずら列挙するにとどめましょう。

四則演算

x+y    x と y の和
x-y    x と y の差
x*y    x と y の積

x/y x を y で割った商 (一般には分数) 主な関数

x^y    x の y 乗
sqrt(x)  x の平方根
exp(x)   x の指数関数
ln(x)    x の自然対数
cos(x) 余弦関数
sin(x) 正弦関数

定数 PI 円周率 E 自然対数の底 I 虚数単位

4.6. 整数の演算 (div,mod,igcd,ilcm,fact,binomial).

 x div y x を y で割った商
 x mod y x を y で割った余り
 igcd(a,b,...) a,b,... の最大公約数
 ilcm(a,b,...) a,b,... の最小公倍数
 n! (fact(n) と書いてもよい) n の階乗
 binomial(n,r) 二項係数

4.7. 整数に丸める (ceil, floor, round, trunc).

ceil(x) x 以上の最小の整数
floor(x)   x 以下の最大の整数

round(x) x を「四捨五入」した整数 trunc(x) |x| 以下の最大の整数に x の符号をつけたもの

4.8. 素数関連 (isprime, nextprime,ithprime).

isprime(n)     // n が素数ならば TRUE を、そうでなければ FALSE を返す。
nextprime(n)   // n 以上の最小の素数。
ithprime(k)    // k 番目の素数。

ithprime よりは nextprime のほうがかなり高速ですから、できる限り nextprime を用いたほうがよいと思います。

4.9. 乱整数 (random). 乱整数を発生するには random を使います。

random()     // 0 から 10^12 までの乱数 (整数) を発生

random(a..b) // a から b までの整数に値をとる乱数を発生する関数

random(n)    // random(0,n-1) と同等

random(a..b) はそれ自身関数であることに注意。例えば次のように使うわけです。

r:=random(100..200); //r は 100 から 200 までの整数に値をとる乱数を発生する関数

r(); //実際に乱数を発生してみる。

                                   185

4.10. 複素数の演算 (Re,Im,abs,conjugate). MuPAD は複素数もかなり器用に扱えます。

I 虚数単位

Re(z)    z の実部
Im(z)    z の虚部
abs(z)   z の絶対値
conjugate(z) z の複素共役

MuPAD はオイラーの公式なども知っているので、複素数の exp,cos,sin 等も気がねなしに使えます。

 Re(exp(1+I));
                              cos(1) exp(1)

複素数 z に対する対数は MuPAD の ln 関数では次のように計算されます。

ln(z) = log(|z|) + (z の偏角) × I

但し、偏角 θ の範囲は −π < θ ≤ π です。

 float(ln(-1));
                              3.141592653 I
 float(ln(-1-0.000000000000001*I));
                             - 3.141592653 I

4.10.1. 仮定する (assume, unassume). 例えば、 a, b が実数のとき、 (a + b\sqrt{−1})^{5} の実部、虚部を計算したいとします。このようなときには MuPAD に、 a, b が実数であると仮定させて、 Re, Im を用いればよろしい。

assume (a, Type::Real); // a は実数と仮定
assume (b, Type::Real); // b も実数と仮定
z:=(a+b*I)^5;
Re(z);  // z の実部
Im(z);  // z の虚部

という具合です。

仮定を解除したい場合には、 unassume を使います。

unassume (a); // a についての仮定を解除

4.11. 式を簡単にする.

4.11.1. 式を展開する (expand). 前節までの説明だけで、多分簡単な式の計算などは自由にできると思いますが、一つだけ覚えておきたいのは、 expand という命令です。これは、与えられた式を展開して、簡単にします。例えば、 (x + y)^{2} は、そのままでは、

(x+y)^2;
                                       2
                                (x + y)

と、この形のままで処理しようとしますが、 expand を使うと、次のように展開してくれます。

expand((x+y)^2);
                                      2    2
                             2 x y + x  + y

expand が有効なのは文字式だけではありません。例えば、

x:=(1+sqrt(5))/2;
y:=(1-sqrt(5))/2;

としたあと、 xy を計算しようとして、 x*y を入力すると、

 x*y;
                       /        1/2 \ /  1/2       \
                       |       5    | | 5          |
                       | 1/2 - ---- | | ---- + 1/2 |
                       \        2   / \  2         /

という具合になり、歯がゆい思いをすることになります。こういうときは、 expand を用いてやればいいのです。

 expand(x*y);
                                   -1

ああすっきり。

4.11.2. 根号のある式を簡単にする (radsimp).

4.11.3. 分数を通分してまとめる (normal).

4.11.4. 分数の分母 (denom)、分子 (numer).

4.12. 関数 (fun, func, proc). MuPAD の古いバージョンでは、関数を使うには三つの方法がありました。

(1) fun

(2) func

(3) proc MuPAD 2.0 以降では fun と func は廃止されて、 proc 一本になっています。

4.12.1. fun(古い). fun は関数を記述するもっとも基本的な方法で、変数は args(1), args(2),... というふうに固定されています。

 f:= fun(sin(args(1)^2 + args(2)^2)): f(x, y);
      sin(x^2 + y^2)

block 文を使えば 1 行で書くには難しい関数を書くこともできますが、このようなときには普通 proc を使った方がいいでしょう。

4.12.2. func(古い). fun では変数名が固定されていたのに対して、 func を使えば関数の変数名を自分で決めることができます。

例えば n の関数 f(n) を定義するには、次のようにします。

 f:=func((x^n+y^n-2)/4,n);

つぎのように、 f(3) がちゃんと計算できていることを確かめられます。

 f(3);
                               3    3
                              x    y
                              -- + -- - 1/2
                              4    4

x:=3+2*sqrt(2);
y:=3-2*sqrt(2);

としてから、

expand(f(3));

とやってやると、答え 49 が求まります。 (expand を忘れると、

                           1/2 3       1/2     3
                    (3 - 2 2   )    (2 2    + 3)
                    ------------- + ------------- - 1/2
                         4               4

となってしまうので注意。 )

なお、 f を 3 変数 (n, x, y) の関数として定義するには、

 f:=func((x^n+y^n-2)/4,n,x,y);

としてやればよいわけです。

4.12.3. proc. 「手続き」 (procedure) を定義するには proc をつかいます。 (C 言語などでいうところの「関数」に近いものです。 )

proc のなかでは local 変数 (proc の中のみで通用する一時的な変数) が使えます。書式は次の通り。

proc(変数名)
local (local 変数名);
...
...
begin
...
...
...
...
end_proc:

どういうわけか local 宣言は ”;” で終らせる必要がある (”:” で終らせることはできない) ようです。

f:=proc(x,y,z)
local l;  // l は local 変数
begin
l:=x^2+y^2+z^2:
return(sqrt(l)):            //sqrt(l) を返す
end_proc:

4.12.4. proc の省略したかきかた (“→”). proc は便利ですが、書くのが面倒です。そこで、簡単な関数については “->” という記号を用いた略記法を用いるとよいでしょう。 (キーボードの「マイナス」の記号につづけて「大なり」の記号を打ちます。たとえば、

f:=x -> ln(x)

とやれば、 f(a) = ln(a) となります。

4.13. 代入・置換 (subs). 代入・置換は subs を使って行います。たとえば、

p:=x^2+y^2+z^2;
                               2    2    2
                              x  + y  + z

 subs(p,x=3);   // p の x を 3 に置き換える (つまり x=3 を p に代入)
                                2    2
                               y  + z  + 9

という具合です。

subs は上のような単なる文字式だけではなく、いろいろな対象に対して使えます。たとえば、 (何が起こっているかということの説明という以外には意味のない例ですが、 )

f:=proc(x)
      local y;
       begin
       y:=x
      end_proc:

として、

 subs(f,x=b);
                               proc(b)
                                 name f;
                                 local y;
                               begin
                                 y:=b
                               end_proc

とか、

 subs(f,y=b);
                               proc(x)
                                 name f;

                                 local b;
                               begin
                                 b:=x
                               end_proc

みたいなことができます。まさに「単純な置き換え」ですね。 proc の引数を定数に置換しようとすると、次のようになります。

g:=subs(f,x=3);
                               proc()
                                 name f;
                                 local y;
                               begin
                                 y:=3
                               end_proc

つまり g は「引数をとらない関数」になるわけです。結構賢いですね。

4.14. 近似計算 (float). MuPAD では、\sqrt{2} などは、「二乗して 2 になるモノをあらわす記号」として扱われますから、そのおおよその値を知るにはとくべつな関数 (float) を用いる必要があります。

 float(sqrt(2));
                               1.414213562

三角関数の値などでも同様です。

 sin(1);
                                 sin(1)
 float(sin(1));
                              0.8414709848

4.14.1. 近似計算の精度をかえる (DIGITS:=...) 近似計算の精度は DIGITS という変数の値をかえることによってかえられます。 DIGITS の初期値は 10 で、これは有効数字 10 桁で計算してくれるという意味です。

DIGITS:=1000:
float(sqrt(2)); //2 の平方根を 1000 桁計算
1.414213562373095048801688724209698078569671875376948073176679737990732478\
46210703885038753432764157273501384623091229702492483605585073721264412149\
70999358314132226659275055927557999505011527820605714701095599716059702745\

12 MUPAD TIPS (VERSION 0.3.4)

34596862014728517418640889198609552329230484308714321450839762603627995251\
40798968725339654633180882964062061525835239505474575028775996172983557522\
03375318570113543746034084988471603868999706990048150305440277903164542478\
23068492936918621580578463111596668713013015618568987237235288509264861249\
49771542183342042856860601468247207714358548741556570696776537202264854470\
15858801620758474922657226002085584466521458398893944370926591800311388246\
46815708263010059485870400318648034219489727829064104507263688131373985525\
61173220402450912277002269411275736272804957381089675040183698683684507257\
99364729060762996941380475654823728997180326802474420629269124859052181004\
45984215059112024944134172853147810580360337107730918286931471017111168391\
658172688941975871658215212822951848847

5. 有限列, リスト, 有限集合

5.1. 列. 列とは、幾つかのモノをカンマで区切って並べたものです。例えば

4,1,2,6,4,1,2,6

(数の列) や

X,J,A,P,A,N
HEY,HEY,HEY

(変数の列) など。その他にもいろいろなものを並べられます。

5.1.1. 有限列を変数に代入する。. 有限列を変数に代入する時は、紛れを避けるために、丸括弧で括って、

S:=(X,J,A,P,A,N);

とすればよいでしょう。上のように S を定義した後、 S, T の内容をみると

 S,T;
                           X, J, A, P, A, N, T

とカンマの次に一つモノ (T) がつけ加わっていることが分かります。

5.1.2. 列の要素を取り出す (op).

S:=(X,J,A,P,A,N);

として、 S の二番目の要素を取り出すには、角括弧をもちいて、 S[2] などとします。

S[2];

op という演算子を使っても同じことができます。

op(S,2);//  S の 2 番目の成分を取り出す。
                                    J

などなど。

MUPAD TIPS (VERSION 0.3.4) 13

5.1.3. 列の長さ (nops). 列の長さ (成分の数) は nops という演算子で求められます。

S:=(X,J,A,P,A,N);
 nops(S);
                                    6

5.2. 有限列の簡単な書き方 (＄). 例えば 1 から 10 までの有限列が欲しい時に、いちいち

1, 2, 3, 4, 5, 6, 7, 8, 9, 10

と入力するのは面倒です。 MuPAD では、これの代わりに、

i $ i=1..10

と書くことができます。もちろん

float(sin(i)) $ i=1..10; // sin(1) から sin(10) までの概数を計算
0.8414709848, 0.9092974268, 0.1411200081, -0.7568024953, -0.9589242747,
   -0.2794154982, 0.6569865987, 0.9893582466, 0.4121184852, -0.5440211109

のようなこともできます。 5.3. 有限列の和 (＿ plus) や積 (＿ mult). 列の総和は _plus, 列の全部の積は _mult を使って次のように求めることができます。

_plus(1,2,3,4);
                                   10
_mult(1,2,3,4);
                                   24

もちろん上のものは $ 記号を用いて

_plus(i $ i=1..4);
                                   10
_mult(i $ i=1..4);
                                   24

としてもよろしい。二重数列の和や積なども同様にできます。

_plus(i*j $ i=1..4$ j=1..5);
                                  150
 _mult(i*j $ i=1..4$ j=1..5);
                            1651129712640000

などなど。

5.4. リスト. 有限列を角括弧 [ ] で括ったものがリストです。列との一番の違いは階層化ができるかどうかという所でしょう。

[[1,2],[3,4],[5,6]]

などの「リストのリスト」を考えることができるわけです。この性質を利用して、 MuPAD ではリストを行列やベクトルの表現にも使っています。有限列の方で同じことをしようとすると、

 ((1,2),(3,4),(5,6));
                            1, 2, 3, 4, 5, 6

となって、単に並んだ列が得られます。これはこれでうまく使えば便利です。

5.5. 有限集合. 有限集合は数列を { } で括ればよろしい。集合は列と違って、 • 要素の並び方を変えても同じ集合とみなす。

• 要素が重複している時は同じ要素は一つと考える。という性質があります。つまり、

{1,2,3,4}={1,2,3,3,4}={2,1,3,4,1}

等々という具合です。

5.6. リストや集合のなかから元を取り出してならべる (＄...in...)

S = {2, 3, 4, 6, 12}

に対して、

T = {π/k; k ∈ S}

を考えたいとき、あるいは、リストで、

L = [π/2, π/3, π/4, π/12]

を考えたいときがあります。このようなときには in というのをつかって、

S=[2,3,4,12];
T:={float(PI/k)  $ k in S};
L:=float(PI/k)  $ k in S;

とやればよいでしょう。

6. ループなどの制御

詳しくは MuPAD のディレクトリの share/demo/ 以下にあるファイルをご参照ください。

6.1. if 文.

if (条件文) then
...
end_if;

6.2. for 文. i を (初期値) から (終り値) まで１ずつ増やして繰り返すには

for i from (初期値) to (終り値) do
...;
...;
...;
end_for;

i を (初期値) から (終り値) まで１ずつ減らして繰り返すには

for i from (初期値) downto (終り値) do
...;
...;
...;
end_for;

(リスト) に含まれる i に対して繰り返すには

for i in (リスト) do
...;
...;
...;
end_for;

6.3. while 文.

while (条件式) do
...;
...;
...;
end_while;

例えば、あらかじめ整数 p が決まっているとき、 p をそれ以上の最小の素数に修正するには、

 while (isprime(p)<> TRUE) do
 p:=p+1:
 end_while:
 print (["using p=", p]);

とすればよろしい。 6.4. case 文.

case (ホニャララ)
  of .... do
          ...;
          ...;
          ...;
  of .... do
          ...;
          ...;
          ...;
...................
...................
...................
...................
  otherwise
         ...;
         ...;
         ...;
end_case;

case 文には注意すべきことがあります。 x=A が成り立つときには a を実行、 x=B が成り立つときには b を実行、 x=C が成り立つときには c を実行、それ以外の場合には d を実行という場合には、

case x
  of A  do
         a;
         break;
  of B  do
         b;
         break;
  of C  do
         c;
         break;
  otherwise
        d;
end_case;

と各段階に break を書いてやらねばならないのです。

これは C 言語などでおなじみの fall through という仕様ですね。このような言語仕様に不慣れな方は、 break がなければどうなるのか一度実験してみるとよいと思います。 (あるいは \verb+? case \verb してみてもよいでしょう。 )

6.5. break. for, while, case などの文は break を使って途中で抜け出すことができます。くわしくは ? break してみて下さい。

7. TeX 形式での出力 (generate::TeX, print(Unquoted,...))

generate::TeX をつかうと、 TeX 形式であらわした式が出力されるので便利です。

generate::TeX(3*x+4*x^2);
                              "3 x + 4 x^2"

場合によってはクォーテーションマークがうっとうしい場合があるので、 print(Unquoted, ほにゃらら) というのと併用するといいでしょう。

print(Unquoted,generate::TeX(3*x+4*x^2));
                              3 x + 4 x^2

8. ライブラリについて (export)

mupad では計算の種類に応じてライブラリを読み込んで使うことができます。例えば groebner パッケージはその一つです。 groebner::gbasis 関数を使う際には特に普通の関数と区別することなく

groebner::gbasis([f1,f2]);

のように使うことができます。 “groebner::” の部分が「groebner パッケージの」ということをあらわしている訳ですね。でも、いちいち “groebner::ナンチャラ” とかくのは面倒なので、いっそのこと “groebner::ナンチャラ” のことを単に “ナンチャラ” ですませる方法があります。セッションの際にあらかじめ

export(groebner);

と打っておくとよいのです。あとは

gbasis([f1,f2]);

で上と同じことができるようになります。

9. 環・体

MuPAD では環や体を結構うまく扱うことができます。

9.1. 有理整数環 ℤ (Dom::Integer) と有理数体 ℚ (Dom::Rational). いろいろな環を作るときに、有理整数環 ℤ にあたる Dom::Integer と有理数体 ℚ にあたる Dom::Rational とは基本になります。

Z:=Dom::Integer;   // Z は有理整数環
Z(3);              // Z の元 3
3

9.2. 環 ℤ/nℤ (Dom::IntegerMod()). R = ℤ/18ℤ を使いたいときには

R:=Dom::IntegerMod(18)

というのを使います。

整数 n を R の元とみなすには R(n) という記法を用いればよろしい。そのあと R のなかでの計算をおこなうには、

R(3)*R(5);
R(1)/R(7);
R(2)+R(5);

などと、すればいいのです。有理数も\frac{p}{q} も q が R で可逆である限り R の元とみなすことができます。

R(1/7);
                                13 mod 18

という具合です。

3 などの非可逆な元を分母に持つ有理数は R の元には直せません。

R(1/3);
Error: illegal arguments

とエラーが表示されます。 (但し、

 R(10/14);
                                11 mod 18

のように (10/14 = 5/7 とさきに約分できる場合は大丈夫です。 )

もう一つの注意点としては、

 R(1)+1;
FAIL

のように、 R の単位元としての 1 と単なる 1 とは内部的に区別されていることです。

9.3. 多項式 (poly). mupad では多項式は通常は一般の「式」として扱えば十分なことも多いのですが、グレブナ基底を正しく求めるときなど、には、 “poly” をつかって多項式を定義してやる必要があります。

f1:=poly(x-t^2-t^4,[t,x,y]);
f2:=poly(y-t^3-t^5,[t,x,y]);

等々。また、係数環 (体) を決めてやる必要があるときにも、 “poly” が重宝します。

k:=Dom::IntegerMod(17):
f:=poly(x^2+y^2,[x,y],k):
f^17;
                     34    34
               poly(x   + y  , [x, y], Dom::IntegerMod(17))

R:=Dom::IntegerMod(6):
g:=poly(2*X+Y,[X,Y],R):
h:=poly(3*Y+1,[X,Y],R):
g*h;
                         2
             poly(2 X + 3 Y  + Y, [X, Y], Dom::IntegerMod(6))

9.3.1. poly(等) を外す (expr). poly は正確を期すには便利ですが、半面冗長に感じられるときもありますし、杓子定規なときもあります。そんなときは expr を用いて poly を外してあげましょう。

k:=Dom::IntegerMod(17):
f:=poly(x^2+y^2,[x,y],k):
f^17;
                     34    34
               poly(x   + y  , [x, y], Dom::IntegerMod(17))
R:=Dom::IntegerMod(6):
g:=poly(2*X+Y,[X,Y],R):
h:=poly(3*Y+1,[X,Y],R):
g*h;
                         2
             poly(2 X + 3 Y  + Y, [X, Y], Dom::IntegerMod(6))
expr(g*h); // poly をはずす。
                                2
                             3 Y  + Y + 2 X

要するに expr は「素朴なかたちになおす」ものです。 poly 以外にもいろいろ使えますのでやってみてください。

9.3.2. 1 変数多項式の (余りのある) 割り算 (divide).

divide(f, g)                 // f を g で割った商と余りを返す。
divide(f, g,Quo)                // f を g で割った商を返す。
divide(f, g,Rem)                // f を g で割った余りを返す。

多変数の多項式でも、一つの変数 (たとえば x) のみに着目した割り算を、変数を指定しておこなうことができます。

divide(f, g,[x])                    // f を g で割った商と余りを返す。
divide(f, g,[x] ,Quo)                // f を g で割った商を返す。
divide(f, g,[x] ,Rem)                // f を g で割った余りを返す。

//例
divide (x^2,a*x+b,[x]);
                                        2
                               x    b  b
                               - - --, --
                               a    2   2
                                   a   a

その他の詳細は ? divide でどうぞ。

9.3.3. 多項式の因数分解 (factor). 多項式の因数分解には factor を使います。

 f:=poly((X+1)*(Y+1),Dom::IntegerMod(17));
            poly(X Y + X + Y + 1, [X, Y], Dom::IntegerMod(17))

 factor (f);
[1 mod 17, poly(Y + 1, [X, Y], Dom::IntegerMod(17)), 1,
   poly(X + 1, [X, Y], Dom::IntegerMod(17)), 1]

答えはリストになっていて、上の場合

f = 1 × (Y + 1)^{1} × (X + 1)^{1}

ということを意味しています。一般には、

f = cf_{1}^{e_{1}}f_{2}^{e_{2}}f_{3}^{e_{3}} … f_{n}^{e_{n}}

なら、

[c, f_{1}, e_{1}, f_{2}, e_{2}, f_{3}, e_{3}, … f_{n}, e_{n}]

の形式で答えがかえってきます。ただし体 (あるいは多項式環) 係数以外の多項式の因数分解はできません。

 f:=poly((X+1)*(Y+1),Dom::IntegerMod(18));
            poly(X Y + X + Y + 1, [X, Y], Dom::IntegerMod(18))

 factor (f);
Error: can only factor over fields or polynomial rings [faclib::domfact]

ごもっとも。

9.4. 多項式環 (Dom::DistributedPolynomial, Dom::Polynomial). 環 R にたいし、 R 上の多項式環を指定する方法には二通りあります。

Dom::DistributedPolynomial は、変数を指定した多項式環 (R[X], R[X, Y] など) を指定するのに使います。ただし、 R の元は「標準型」 (normal form) を持たねばならない、という制限があります。これは、 R の元が 0 かどうかを判定する方法を MuPAD が知っている必要があるということです。

Dom::Polynomial は、「変数を指定しない多項式環」 (あえていえば

R[X, Y, …, その他ありとあらゆる変数…]

) です。

9.4.1. Dom::DistributedPolynomial.

R:=Dom::IntegerMod(18);
S:=Dom::DistributedPolynomial([X,Y],R);   // S=R[X,Y]
S(2*X+9*Y)*S(9*X+2*Y);   // S の元として (2X+9Y)(9X+2Y) を計算
                                 -5 X Y

面白いのは、 MuPAD の内部で poly(X,[X,Y],R) と S の元としての X とが異なることです。

R:=Dom::IntegerMod(18);
S:=Dom::DistributedPolynomial([X,Y],R);   // S=R[X,Y]
p:=poly(X,[X,Y],R);
p+S(X);
                                  FAIL    // p に S(X) は足せない。

 S(p)+S(X);                      // p にも S をつけてやれば成功する。
                                   2 X

9.4.2. Dom::Polynomial. Dom::Polynomial の使い方は Dom::DistributedPolynomial とほぼ同じです。

R:=Dom::IntegerMod(18);
S:=Dom::Polynomial(R);

9.5. イデアル (Dom::Ideal). 環 R にたいして、 R のイデアルを定義するには、 Dom::Ideal を使います。

R::=Dom::IntegerMod(18);
L:=Dom::Ideal(R);    // L は R のイデアル全体の集合 (Lattice)
J:=L({3,5});
                         <{3 mod 18, 5 mod 18}>

MuPAD はイデアルの和 (+), 積 (*), ベキなどを計算できますが、最良の生成元を求めるほど賢くはないようです。そういう方面ではグレブナ基底などを利用するのがいいでしょう。

9.6. 商体(Dom::Fraction). 整域 R に対して、その商体を MuPAD で使うには、 Dom::Fraction をつかいます。

Z:=Dom::Integer;
R:=Dom::DistributedPolynomial([X],Z);
S:=Dom::Fraction(R);
 S(X)/S(1+X);
                                    X
                                  -----
                                  X + 1

 S(X)/S(2);
                                    X
                                    -
                                    2

等々。

9.7. 体の代数拡大 (Dom::AlgebraicExtension). 有理数体 (Dom::Rational) に、代数的な元を付け加えて別の体を作るには Dom::AlgebraicExtension という命令を使います。例えば、

k = ℚ[z]/(z^{2} + z + 1)

を作るには、

k:=Dom::AlgebraicExtension(Dom::Rational, z^2+z+1 = 0, z)

のようにします。

9.7.1. トレース (conjtrace). 代数拡大体の元のトレースを求めるには次のようにします。

k:=Dom::AlgebraicExtension(Dom::Rational, z^2+z+1 = 0, z);
k::conjTrace (k(z));

                                   -1

MuPAD にはトレース以外にもいろいろな関数が準備されています。詳細は ? Dom::AlgebraicExtension してみてください。

9.8. 例:最小分解体の計算. ここでは ℚ 上の既約多項式 p = X^{3} + 5X + 1 の最小分解体を MuPAD に計算させてみましょう。まず、 p が ℚ 上既約であることを確認します。

p:=poly(X^3+5*X+1,Dom::Rational):
irreducible(p);

                                  TRUE

p の根の一つ a を ℚ に追加して新しい体 k = ℚ[a] を作ります。

k:=Dom::AlgebraicExtension(Dom::Rational, subs(p,X=a),a):
                                                     3
        Dom::AlgebraicExtension(Dom::Rational, 5 a + a  + 1 = 0, a)

今度は k[X] のなかで p を因数分解します。

p1:=poly(p,k):
S:=factor(p1);
[1, poly(X - a, [X], Dom::AlgebraicExtension(Dom::Rational,
          3                        2           2
   5 a + a  + 1 = 0, a)), 1, poly(X  + a X + (a  + 5), [X],
                                                3
   Dom::AlgebraicExtension(Dom::Rational, 5 a + a  + 1 = 0, a)), 1]
q:=S[4]; // S の第 4 成分を取り出す。
      2           2
poly(X  + a X + (a  + 5), [X], Dom::AlgebraicExtension(Dom::Rational,
          3
   5 a + a  + 1 = 0, a))

irreducible(q);

                                  TRUE

最後の行でわかるように q は既約なので、上と同様の操作で q の根 b を k に付け加えて L = k[b] を作ります。

 L:=Dom::AlgebraicExtension(k,subs(q,X=b),b);
Dom::AlgebraicExtension(Dom::AlgebraicExtension(Dom::Rational,
          3                     2    2
   5 a + a  + 1 = 0, a), a b + a  + b  + 5 = 0, b)

これで p を L 内で因数分解できるはずです。

p2:=poly(p,L):
factor(p2);
[1, poly(X + (a + b), [X], Dom::AlgebraicExtension(
                                                3
   Dom::AlgebraicExtension(Dom::Rational, 5 a + a  + 1 = 0, a),
          2    2
   a b + a  + b  + 5 = 0, b)), 1, poly(X - a, [X], Dom::AlgebraicExtension(
                                                3
   Dom::AlgebraicExtension(Dom::Rational, 5 a + a  + 1 = 0, a),
          2    2
   a b + a  + b  + 5 = 0, b)), 1, poly(X - b, [X], Dom::AlgebraicExtension(
                                                3
   Dom::AlgebraicExtension(Dom::Rational, 5 a + a  + 1 = 0, a),
          2    2
   a b + a  + b  + 5 = 0, b)), 1]

10. グレブナ基底

10.1. グレブナ基底 (groebner::gbasis). グレブナ基底を求めるには、 groebner::gbasis を使います。

f1:=poly(x-t^2-t^4,[t,x,y]);
f2:=poly(y-t^3-t^5,[t,x,y]);
groebner::gbasis([f1,f2]);

上の f1, f2 を定義するところで、 [t, x, y] の部分は monomial order を決定する際にも用いられています。同じものを何度もタイプするのは面倒ですから、

S:=[t,x,y];
f1:=poly(x-t^2-t^4,S);
f2:=poly(y-t^3-t^5,S);
groebner::gbasis([f1,f2]);

などとしても良いでしょう。

なお、次のようにして monomial order を変更することもできます。

S:=[t,x,y];
f1:=poly(x-t^2-t^4,S);
f2:=poly(y-t^3-t^5,S);
groebner::gbasis([f1,f2]);    // t>x>y の順序でグレブナ基底を計算。
T:=[x,y,t];
groebner::gbasis([poly(f1,T),poly(f2,T)]);//x>y>t の順序でグレブナ基底を計算。

順序を指定した方が確実でしょう。

groebner::gbasis([f1,f2],LexOrder); (辞書式順序)
groebner::gbasis([f1,f2],DegreeOrder); (次数つき辞書式順序)
groebner::gbasis([f1,f2],DegInvLexOrder); (次数つき逆辞書式順序)

10.2. 例題:楕円曲線の加法. //楕円曲線の足し算。

Ell:=(x,y)->y^2-x^3-p *x-q; //楕円曲線 E の定義方程式
//P1(x1,y1),P2(x2,y2) は E の点 (次の f1,f2 は 0)
f1:=Ell(x1,y1);
f2:=Ell(x2,y2);

// P1,P2 と同一直線上にある E の点を求めよう。

g:=Ell(x1+k*(x2-x1),y1+k*(y2-y1));
B:=groebner::gbasis([f1,f2]);
g1:=groebner::normalf(g,B);
g2:=collect(g1,VARS);

// g2 は k,k-1 を因子に持つ。それで割ったのが g3

g3:=normal(expand(g2/(k*(k-1))));

//g3 は k の一次式なので、その根は次のように見つけられる。

k1:=-coeff(g3,k,0)/coeff(g3,k,1);

// k1 を k に代入し、 y の符号を変えたのが P1 と P2 の和

x3:=(x1+k1*(x2-x1));

y3:=-(y1+k1*(y2-y1));

// 若干整理しておく

xx3:=normal(x3);
yy3:=normal(y3);

//実際に (xx3,yy3) が E の上に乗っているかチェック。

groebner::normalf(numer(Ell(xx3,yy3)),B);

//答え
//xx3:=
// -(3*q*x1-3*q*x2-2*x1*y1*y2+2*x2*y1*y2+p*x1^2-p*x2^2-x1*y2^2+x2*y1^2)
// /(p*x1-p*x2-y1^2+y2^2-3*x1*x2^2+3*x1^2*x2);
// yy3:=
// (3*q*y1-3*q*y2+p*x1*y1-2*p*x1*y2+2*p*x2*y1-p*x2*y2
// +y1*y2^2-y1^2*y2+3*x1*x2^2*y1-3*x1^2*x2*y2)
// / (p*x1 - p*x2 - y1^2 + y2^2 - 3*x1*x2^2 + 3*x1^2*x2)

11. 微積分

11.1. 微分 (diff). f(x) を x で微分する際には、

diff(f(x),x);

とやればよろしい。

diff(sin(x),x);
                                 cos(x)

diff(sin(x),x,x);     // x で sin(x) を二階微分
                                 -sin(x)

diff(sin(x*y),x,y);     // sin(xy) を x, y で一回ずつ微分
                         cos(x y) - x y sin(x y)

11.2. 積分 (int). f(x) を x で積分する際には、 int を使って、

int(f(x),x);

とやればよろしい。

int(x^3/(1+x^2),x);
                               2       2
                             x    ln(x  + 1)
                             -- - ----------
                              2        2

定積分もできます。例えば

∫_{−1}^{1} \frac{1}{x^{2} + 1}

を実行するには、

int (1/(x^2+1), x=-1..1);
                                   PI
                                   --
                                    2

などとすればよろしい。

11.3. 高階微分 (diff と＄との併用). 有限列を生成する＄記号と、 diff や int を組み合わせれば、高階微分や多重積分を簡単に計算させることができます。

 diff(x^100,x $ i=1..10);  // 10 階微分
                                              90
                         62815650955529472000 x

などなど。

12. 線型代数

12.1. 線型代数まわりの関数をエクスポートする (export(linalg);) 行列を扱うときには線型代数に使ういくつかの関数をあらかじめエクスポートしておいた方が便利です。いろいろなことをする前に忘れずに

export(linalg);

しておくとよいでしょう。

12.2. 行列の入力 (Dom::Matrix()). 行列を mupad に入力してやるには、 Dom::Matrix() を使います。

A:=Dom::Matrix()([[1,2],[3,4]]);
                               +-      -+
                               |  1, 2  |

                               |        |
                               |  3, 4  |
                               +-      -+

Dom::Matrix() を入力するのが面倒な場合には、これを適当な記号で定義しておくと便利です。平田さまのページ (http://www.ed.ehime-u.ac.jp/ hirata/MuPAD/index.html ) にならって

MAT:=Dom::Matrix();

と打ってみましょう。これ以後は

A:=MAT([[1,2],[3,4]]);

で行列が入力できるようになります。 Dom::Matrix() の”()” のなかには、実は係数環を指定することができます。

k:=Dom::AlgebraicExtension(Dom::Rational, z^2+z+1 = 0, z)
MAT:=Dom::Matrix(k);
A:=MAT([[1+z,2],[3,4]]);
                               +-        -+
                               |  z+1, 2  |
                               |          |
                               |  3,   4  |
                               +-        -+

などとやると、 k の元を成分に持つ行列 (M_{2}(k) の元) を与えることができるわけです。

(i, j)-成分を指定して行列を与えるには、 “->” をもちいます。

matrix(2,2,(i,j)->i);         //version 2.0 以降では matrix() が準備されている。

//旧バージョンでは matrix() の代わりに // 上の MAT() を使えばよい

                               +-      -+
                               |  1, 1  |
                               |        |
                               |  2, 2  |
                               +-      -+

行を表す変数を明示できるのでこの方が便利です。ただし旧バージョンとの互換性を保つためには行は i, 列は j を使っておくのが無難でしょう。

対角行列を与えるには”Diagonal” を最後に指定すると楽ができます。

En:=MAT(n,n,i->1,Diagonal): // 単位行列

(ただし、 E と I はそれぞれ自然対数の底 e と虚数単位 i とに割り当てられているので注意が必要です。 )

12.3. 行列の演算 (+,1,*,1/?, ＾ ).

四則演算

A+B    A と B の和
A-B    A と B の差
A*B    A と B の積
1/A    A の逆行列 (=A^(-1))
A^n A の n 乗

12.4. 行列の基本変形 (addRow,multRow,swapRow,addCol,multCol,swapCol). 基本変形

addRow(A,m,n,c)  (A の第 m 行) の c 倍を (A の第 n 行) に足した行列
multRow(A,m,c)   (A の第 m 行) を c 倍した行列
swapRow(A,m,n)   (A の第 m 行) と (A の第 n 行) を入れ替えた行列

(列については addCol, multCol, swapCol を用いればよい。 )

これらの関数は linalg パッケージに入っているので、もしあらかじめ export(linalg) していない場合には (たとえば trace ならば linalg::trace などのように)linalg:: を先頭にくっつけてやる必要があります。念のため。

12.5. 余因子行列 (adjoint) と転置行列 (transpose).

transpose(A) A の転置行列
adjoint(A) A の余因子行列

余因子行列は割算を用いないので逆行列の代わりに重宝します。 (A の逆行列は A の余因子行列を A の行列式で割ったもの. A の逆行列は A の行列式が可逆でないと意味を持たないが、 A の余因子行列にはそのような制限はない。 )

これらの関数は linalg パッケージに入っているので、もしあらかじめ export(linalg) していない場合には (たとえば trace ならば linalg::trace などのように)linalg:: を先頭にくっつけてやる必要があります。念のため。

12.6. 行列の諸量 (nrows,ncols,matdim,rank).

nrows(A)        A の行の数
ncols(A)        A の列の数
matdim(A)       =[nrows(A),ncols(A)]
rank(A) A のランク

これらの関数は linalg パッケージに入っているので、もしあらかじめ export(linalg) していない場合には (たとえば trace ならば linalg::trace などのように)linalg:: を先頭にくっつけてやる必要があります。念のため。

12.7. 正方行列の諸量 (det,tr,eigenVaules,eigenVectors).

det(A) A の行列式
tr (A) A のトレース
eigenValues(A)   A の固有値の集合
eigenVectors(A)  A の固有ベクトルの集合

これらの関数は linalg パッケージに入っているので、もしあらかじめ export(linalg) していない場合には (たとえば trace ならば linalg::trace などのように)linalg:: を先頭にくっつけてやる必要があります。念のため。

12.8. ブロック区分けされた行列の入力 (concatMatrix,stackMatrix). まず、いくつかの行列が次のように mupad に入力されているとします。

MAT:=Dom::Matrix();
A:=MAT([[0,1,0],[0,0,1],[1,0,0]]);
E3:=MAT(3,3,i->1,Diagonal);   //単位行列
Z3:=MAT(3,3);                      //零行列

このとき、

B = (\begin{matrix}A & A − E3 & 0 \\ 0 & A & A − E3 \\ 0 & 0 & A \end{matrix})

のような 9 × 9 行列を入力するには、つぎのように concatMatrix および stackMatrix を使うと便利です。

A1:=concatMatrix(A,A-E3,Z3);
A2:=concatMatrix(Z3,A,A-E3);
A3:=concatMatrix(Z3,Z3,A);
B:=stackMatrix(A1,A2,A3);

例えば A1 は次のような行列になります。

                    +-                              -+
                    |  0, 1, 0, -1,  1,  0, 0, 0, 0  |
                    |                                |
                    |  0, 0, 1,  0, -1,  1, 0, 0, 0  |
                    |                                |
                    |  1, 0, 0,  1,  0, -1, 0, 0, 0  |
                    +-                              -+

concatMatrix と stackMatrix を上のように何度も使うのは面倒ですね。じつは concatMatrix は ”.” (ピリオド記号) で代用できます。

A1:=A.(A-E3).Z3

この便法を使うと、次のようにお手軽にブロック区分けをされた行列を入力できます。

B:=stackMatrix(
A  . (A-E3) .  Z3    ,
Z3 .  A     . (A-E3) ,
Z3 .  Z3    .  A
);

(このように改行をいれて見やすくしておくといいでしょう。 )

これらの関数は linalg パッケージに入っているので、もしあらかじめ export(linalg) していない場合には (たとえば trace ならば linalg::trace などのように)linalg:: を先頭にくっつけてやる必要があります。念のため。 12.9. 行列の特定の行や列を取り出す (row,col).

linalg::row(A,i) A の第 i 行
linalg::col(A,j) B の第 j 列

12.10. 例題:行列のテンソル積. 行列のテンソル積が見当たらないので作ってみました。 concatMatrix と stackMatrix とを組み合わせるだけですから、簡単です。

//tensor product of A and v for a matrix A and a row vector v
tensor_vec:=proc(A,v)
local C;
local j;
begin
C:=A*v[1,1]:
for j from 2 to linalg::ncols(v) do
C:=C.(A*v[1,j]):
end_for: //j
end_proc:
//tensor product of A and B
tensor:=proc(A,B)
local C;
local i;
begin
C:=tensor_vec(A,linalg::row(B,1)):
for i from 2 to linalg::nrows(B) do
C:=linalg::stackMatrix(C,tensor_vec(A,linalg::row(B,i))):
end_for: //i
return(C);
end_proc:

13. もっと変数が欲しい

13.1. いっぱい変数を作る. text2expr と strprint を併用すれば、つぎのように秩序だって変数が作れます。

 text2expr("x".strprint(Unquoted,NoNL,i)) $i=0..10;
               x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10

13.2. 例:不定元を成分に持つ行列.

ntostr:=proc(n)
begin
return(strprint(Unquoted,NoNL,n));
end_proc;
matrix(3,3 , (i,j) -> text2expr("x".ntostr(i)."_".ntostr(j)));
                         +-                  -+

                         |  x1_1, x1_2, x1_3  |
                         |                    |
                         |  x2_1, x2_2, x2_3  |
                         |                    |
                         |  x3_1, x3_2, x3_3  |
                         +-                  -+

3x3 行列ぐらいなら、手で打っても同じですが、行列のサイズが大きいときには重宝するかも知れません。

14. グラフの描画

14.1. １変数関数のグラフ (plotfunc2d). 関数のグラフを描くには plotfunc2d を用います。

plotfunc2d(cos(x)) ;// cos(x) のグラフを描く。

たくさん描くこともできます。

plotfunc2d(sin(x),cos(x)); // sin(x) のグラフと cos(x) のグラフを重ねて描く。

＄記号を用いてたくさんのグラフを同時に重ねて描くことも可能です。

plotfunc2d(1/(cos(x)+i/5)  $i=-5..5) ;

描画する範囲 (変数 x と関数値 y = f(x) の範囲) を指定することもきます。

plotfunc2d(sin(x),cos(x),x=-5..5,y=-1.5..1.5); // sin(x) のグラフを描く。
plotfunc2d(sin(x),cos(x),x=-5..5,y=-1.5..1.5); // sin(x) のグラフと cos(x) の

グラフを重ねて描く。

上の例で、 x という変数名は sin(x), cos(x) のなかにも現れていますからすぐそれと分かりますが、関数値のほうの y という文字はべつに必須ではありません。

plotfunc2d(sin(x),cos(x),x=-5..5,u=-1.5..1.5); // sin(x) のグラフと cos(x) の

グラフを重ねて描く。

とやって違いを確かめてみて下さい。グラフの縦軸の変数名のところが少しかわるだけで、あとは同じであることが確認できるはずです。

見る領域を指定しつつ、たくさんのグラフを書くこともできます。例えば、 y = sin(x) + 0.1ie^{−5x} のグラフを i = −10, −9, −8, …, 8, 9, 10 まで 20 個書くには

plotfunc2d(sin(x)+0.1*i*E^(-5*x) $i=-10..10, x=-0.8..1.5,y=-1..2  );

とやればよろしい。範囲の指定のほうが後にくることに注意して下さい。一般的に書けば、

plotfunc2d(関数 1, 関数 2, 関数 3, ..., x の範囲 , y の範囲 );

という書式で関数 1, 関数 2,... のグラフを同時に描けることになります。

14.2. 陰関数のグラフ (plot::implicit). (注意: plot::implicit は (筆者の記憶が正しければ) 古いバージョンの MuPAD では命令が違ったはずです。そのような MuPAD をお持ちの場合には別途マニュアル等でご確認下さい。 )

陰関数を描くには、 plot::implicit という命令を用います。ただし、 plotfunc2d などと違って、 plot::implicit は画面にデータを書き出すのではなく、メモリ内に (多くの点の集まりとして) 「描く」ので、目でグラフをみるためにはメモリ内のそれらのデータを画面に「描く」操作 (plot) をする必要があります。

plot(plot::implicit(x^2+y^2-1,x=-2..2,y=-2..2)); // 円を描く

この例では、 x^{2} + y^{2} = 1 を満たす (x, y) を、 −2 ≤ x ≤ 2, −2 ≤ y ≤ 2 の範囲で見つけてきて、それを描画しています。 x, y の範囲を指定しないとエラーになってしまいますのでご注意を。

14.3. リストを折れ線グラフに描く (plot::data). リスト L=[10,20,30,50,-5] などを折れ線グラフに描くには、

plot(plot::data(L));

とすればよろしい。

14.4. 2 次元のグラフ (plot2d).

14.4.1. 曲線を書く (plot2d([Mode=Curve,[f(t),g(t)],t=[t0,t1])).

14.4.2. 折れ線 (多角形) を書く (polygon). 正方形を描いてみましょう。

shikaku:=polygon(point(0,0),point(1,0),point(1,1),point(0,1),Closed=TRUE);
plot2d([Mode=List,[shikaku]]);

point(a,b) は二次元の点 (a, b) をさし、上の例ではそれらを結んだ多角形として shikaku を定義しています。 shikaku を plot2d に噛ませれば四角形が表示されるわけです。

14.4.3. たくさんの曲線を同時に描く. plot2d の引数にたくさん曲線のデータを並べれば、それで曲線を複数同時に描くことができます。

plot2d([Mode=Curve,[k*cos(t),k*sin(t)],t=[0,2*PI]] $ k=1..10);

14.4.4. 描画する範囲を決める (ViewingBox=[xmin..xmax,ymin..ymax]). plot2d は、グラフのどこ ( xy 平面上のどの部分) を描画するかを自動的に決定しますが、それがうまくない場合には、 ViewingBox= なるオプションで指定します。

14.4.5. 縦横の縮尺比をそろえる／そろえない (Scaling=Constrained/UnConstrained). グラフの縦横の縮尺比をそろえるためには、 Scaling=Constrained なるオプションを指定します。円や、正方形などの縦横の比が大事なものについては指定したほうがよいでしょう。

14.4.6. 色, 線の太さなど. 描画の際、次のようなオプションを指定することができます。

LineStyle=DashedLines  //こう指定するとグラフが点線になる。
FontSize=24, //文字の大きさ
Labeling=FALSE, //座標軸に変数名を書くか否か
ViewingBox=[0,0.3,0,0.3], //どの範囲を描画するか

Axes=Origin, // こう指定すると「座標軸」を描く。 AxesOrigin=[0,0], // 「座標軸」のまじわるところをどこにするか。

LineWidth=50,    //線の太さ
Color=[Flat,[r,g,b]]    //色の指定。 r,g,b は [0,1] に収まらなければならない。

14.5. 3 次元のグラフ (plot3d).

14.5.1. 曲線を描く (plot3d([Mode=Curve,[f(t),g(t),h(t)],t=[t0,t1])).

14.5.2. 曲面を描く (plot3d([Mode=Surface,[f(t,u),g(t,u)],t=[t0,t1],u=[u0,u1])).

15. dirty tricks

この節では、 MuPAD を使っていてぶつかった問題のうち、「何だか知らないけれどこうすれば一応は計算できた。」という類のものについて書くことにします。 MuPAD のバージョンや計算する対象によっては通用しないかも知れません。つまり、正当な問題の不当な解き方、というわけです。まあ御役に立てるかどうかは定かではありませんがね。

15.1. Dom::Polynomial や Dom::DistributedPolynomial に代入する。 (expr). (注意: この小節は土基が未熟だったため書かれたもので、 expr を使えば dirty trick ではなく扱えます。 )

代入は subs で大丈夫と思っていたら、どういうわけか Dom::Polynomial などでは全くうまくいきません。

p:=3:
Zp:=Dom::IntegerMod(p):
VARS:=[X,Y,t,u]:    //変数
POLY:=Dom::DistributedPolynomial(VARS,Zp): // POLY=(Z/pZ)[X,Y]
subs(POLY(X),X=t);   // X に t を代入したい
                               (1 mod 3) X

//うーん。うまくいかない。

subs(collect(POLY(X),VARS),X=t);      //一旦 collect をかます。
                                    t

//うまくいった。 //場合によっては結果にもう一度 POLY をかぶせた方が良いこともあるでしょう。

... と思っていたのですが、このワザは新バージョンの mupad ではできなくなってました。というか、 expr というのがあったんですね。というわけで、正解は「 expr をつかいましょう。」でした。 kenpei さまのページにはちゃんと書いてありました。さすが。

p:=3:
Zp:=Dom::IntegerMod(p):
VARS:=[X,Y,t,u]:    //変数
POLY:=Dom::DistributedPolynomial(VARS,Zp): // POLY=(Z/pZ)[X,Y]
subs(POLY(X),X=t);   // X に t を代入したい
                               (1 mod 3) X

//うーん。うまくいかない。

subs(expr(POLY(X)),X=t);      //一旦 expr をかます。
                                    t

//うまくいった。 //場合によっては結果にもう一度 POLY をかぶせた方が良いこともあるでしょう。

もちろん、こういう場合にはグレブナ基底で扱うこともできるわけですが、わざわざそこまでしなくても、という時には便利ですね。

16. GNU Free Documentation License

GNU Free Documentation License
   Version 1.1, March 2000
 Copyright (C) 2000  Free Software Foundation, Inc.
     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

0. PREAMBLE
The purpose of this License is to make a manual, textbook, or other
written document "free" in the sense of freedom: to assure everyone
the effective freedom to copy and redistribute it, with or without
modifying it, either commercially or noncommercially.  Secondarily,
this License preserves for the author and publisher a way to get
credit for their work, while not being considered responsible for
modifications made by others.
This License is a kind of "copyleft", which means that derivative
works of the document must themselves be free in the same sense.  It

complements the GNU General Public License, which is a copyleft
license designed for free software.
We have designed this License in order to use it for manuals for free
software, because free software needs free documentation: a free
program should come with manuals providing the same freedoms that the
software does.  But this License is not limited to software manuals;
it can be used for any textual work, regardless of subject matter or
whether it is published as a printed book.  We recommend this License
principally for works whose purpose is instruction or reference.

1. APPLICABILITY AND DEFINITIONS
This License applies to any manual or other work that contains a
notice placed by the copyright holder saying it can be distributed
under the terms of this License.  The "Document", below, refers to any
such manual or work.  Any member of the public is a licensee, and is
addressed as "you".
A "Modified Version" of the Document means any work containing the
Document or a portion of it, either copied verbatim, or with
modifications and/or translated into another language.
A "Secondary Section" is a named appendix or a front-matter section of
the Document that deals exclusively with the relationship of the
publishers or authors of the Document to the Document's overall subject
(or to related matters) and contains nothing that could fall directly
within that overall subject.  (For example, if the Document is in part a
textbook of mathematics, a Secondary Section may not explain any
mathematics.)  The relationship could be a matter of historical
connection with the subject or with related matters, or of legal,
commercial, philosophical, ethical or political position regarding
them.
The "Invariant Sections" are certain Secondary Sections whose titles
are designated, as being those of Invariant Sections, in the notice
that says that the Document is released under this License.
The "Cover Texts" are certain short passages of text that are listed,
as Front-Cover Texts or Back-Cover Texts, in the notice that says that
the Document is released under this License.
A "Transparent" copy of the Document means a machine-readable copy,
represented in a format whose specification is available to the
general public, whose contents can be viewed and edited directly and
straightforwardly with generic text editors or (for images composed of

pixels) generic paint programs or (for drawings) some widely available
drawing editor, and that is suitable for input to text formatters or
for automatic translation to a variety of formats suitable for input
to text formatters.  A copy made in an otherwise Transparent file
format whose markup has been designed to thwart or discourage
subsequent modification by readers is not Transparent.  A copy that is
not "Transparent" is called "Opaque".
Examples of suitable formats for Transparent copies include plain
ASCII without markup, Texinfo input format, LaTeX input format, SGML
or XML using a publicly available DTD, and standard-conforming simple
HTML designed for human modification.  Opaque formats include
PostScript, PDF, proprietary formats that can be read and edited only
by proprietary word processors, SGML or XML for which the DTD and/or
processing tools are not generally available, and the
machine-generated HTML produced by some word processors for output
purposes only.
The "Title Page" means, for a printed book, the title page itself,
plus such following pages as are needed to hold, legibly, the material
this License requires to appear in the title page.  For works in
formats which do not have any title page as such, "Title Page" means
the text near the most prominent appearance of the work's title,
preceding the beginning of the body of the text.

2. VERBATIM COPYING
You may copy and distribute the Document in any medium, either
commercially or noncommercially, provided that this License, the
copyright notices, and the license notice saying this License applies
to the Document are reproduced in all copies, and that you add no other
conditions whatsoever to those of this License.  You may not use
technical measures to obstruct or control the reading or further
copying of the copies you make or distribute.  However, you may accept
compensation in exchange for copies.  If you distribute a large enough
number of copies you must also follow the conditions in section 3.
You may also lend copies, under the same conditions stated above, and
you may publicly display copies.

3. COPYING IN QUANTITY
If you publish printed copies of the Document numbering more than 100,
and the Document's license notice requires Cover Texts, you must enclose
the copies in covers that carry, clearly and legibly, all these Cover

Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
the back cover.  Both covers must also clearly and legibly identify
you as the publisher of these copies.  The front cover must present
the full title with all words of the title equally prominent and
visible.  You may add other material on the covers in addition.
Copying with changes limited to the covers, as long as they preserve
the title of the Document and satisfy these conditions, can be treated
as verbatim copying in other respects.
If the required texts for either cover are too voluminous to fit
legibly, you should put the first ones listed (as many as fit
reasonably) on the actual cover, and continue the rest onto adjacent
pages.
If you publish or distribute Opaque copies of the Document numbering
more than 100, you must either include a machine-readable Transparent
copy along with each Opaque copy, or state in or with each Opaque copy
a publicly-accessible computer-network location containing a complete
Transparent copy of the Document, free of added material, which the
general network-using public has access to download anonymously at no
charge using public-standard network protocols.  If you use the latter
option, you must take reasonably prudent steps, when you begin
distribution of Opaque copies in quantity, to ensure that this
Transparent copy will remain thus accessible at the stated location
until at least one year after the last time you distribute an Opaque
copy (directly or through your agents or retailers) of that edition to
the public.
It is requested, but not required, that you contact the authors of the
Document well before redistributing any large number of copies, to give
them a chance to provide you with an updated version of the Document.

4. MODIFICATIONS
You may copy and distribute a Modified Version of the Document under
the conditions of sections 2 and 3 above, provided that you release
the Modified Version under precisely this License, with the Modified
Version filling the role of the Document, thus licensing distribution
and modification of the Modified Version to whoever possesses a copy
of it.  In addition, you must do these things in the Modified Version:
A. Use in the Title Page (and on the covers, if any) a title distinct
   from that of the Document, and from those of previous versions
   (which should, if there were any, be listed in the History section
   of the Document).  You may use the same title as a previous version
   if the original publisher of that version gives permission.

B. List on the Title Page, as authors, one or more persons or entities
responsible for authorship of the modifications in the Modified
Version, together with at least five of the principal authors of the
Document (all of its principal authors, if it has less than five).
C. State on the Title page the name of the publisher of the
Modified Version, as the publisher.
D. Preserve all the copyright notices of the Document.
E. Add an appropriate copyright notice for your modifications
adjacent to the other copyright notices.
F. Include, immediately after the copyright notices, a license notice
giving the public permission to use the Modified Version under the
terms of this License, in the form shown in the Addendum below.
G. Preserve in that license notice the full lists of Invariant Sections
and required Cover Texts given in the Document's license notice.
H. Include an unaltered copy of this License.
I. Preserve the section entitled "History", and its title, and add to
it an item stating at least the title, year, new authors, and
publisher of the Modified Version as given on the Title Page.  If
there is no section entitled "History" in the Document, create one
stating the title, year, authors, and publisher of the Document as
given on its Title Page, then add an item describing the Modified
Version as stated in the previous sentence.
J. Preserve the network location, if any, given in the Document for
public access to a Transparent copy of the Document, and likewise
the network locations given in the Document for previous versions
it was based on.  These may be placed in the "History" section.
You may omit a network location for a work that was published at
least four years before the Document itself, or if the original
publisher of the version it refers to gives permission.
K. In any section entitled "Acknowledgements" or "Dedications",
preserve the section's title, and preserve in the section all the
substance and tone of each of the contributor acknowledgements
and/or dedications given therein.
L. Preserve all the Invariant Sections of the Document,
unaltered in their text and in their titles.  Section numbers
or the equivalent are not considered part of the section titles.
M. Delete any section entitled "Endorsements".  Such a section
may not be included in the Modified Version.
N. Do not retitle any existing section as "Endorsements"
or to conflict in title with any Invariant Section.
If the Modified Version includes new front-matter sections or
appendices that qualify as Secondary Sections and contain no material
copied from the Document, you may at your option designate some or all
of these sections as invariant.  To do this, add their titles to the
list of Invariant Sections in the Modified Version's license notice.
These titles must be distinct from any other section titles.

You may add a section entitled "Endorsements", provided it contains
nothing but endorsements of your Modified Version by various
parties--for example, statements of peer review or that the text has
been approved by an organization as the authoritative definition of a
standard.
You may add a passage of up to five words as a Front-Cover Text, and a
passage of up to 25 words as a Back-Cover Text, to the end of the list
of Cover Texts in the Modified Version.  Only one passage of
Front-Cover Text and one of Back-Cover Text may be added by (or
through arrangements made by) any one entity.  If the Document already
includes a cover text for the same cover, previously added by you or
by arrangement made by the same entity you are acting on behalf of,
you may not add another; but you may replace the old one, on explicit
permission from the previous publisher that added the old one.
The author(s) and publisher(s) of the Document do not by this License
give permission to use their names for publicity for or to assert or
imply endorsement of any Modified Version.

5. COMBINING DOCUMENTS
You may combine the Document with other documents released under this
License, under the terms defined in section 4 above for modified
versions, provided that you include in the combination all of the
Invariant Sections of all of the original documents, unmodified, and
list them all as Invariant Sections of your combined work in its
license notice.
The combined work need only contain one copy of this License, and
multiple identical Invariant Sections may be replaced with a single
copy.  If there are multiple Invariant Sections with the same name but
different contents, make the title of each such section unique by
adding at the end of it, in parentheses, the name of the original
author or publisher of that section if known, or else a unique number.
Make the same adjustment to the section titles in the list of
Invariant Sections in the license notice of the combined work.
In the combination, you must combine any sections entitled "History"
in the various original documents, forming one section entitled
"History"; likewise combine any sections entitled "Acknowledgements",
and any sections entitled "Dedications".  You must delete all sections
entitled "Endorsements."

6. COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and other documents
released under this License, and replace the individual copies of this
License in the various documents with a single copy that is included in
the collection, provided that you follow the rules of this License for
verbatim copying of each of the documents in all other respects.
You may extract a single document from such a collection, and distribute
it individually under this License, provided you insert a copy of this
License into the extracted document, and follow this License in all
other respects regarding verbatim copying of that document.

7. AGGREGATION WITH INDEPENDENT WORKS
A compilation of the Document or its derivatives with other separate
and independent documents or works, in or on a volume of a storage or
distribution medium, does not as a whole count as a Modified Version
of the Document, provided no compilation copyright is claimed for the
compilation.  Such a compilation is called an "aggregate", and this
License does not apply to the other self-contained works thus compiled
with the Document, on account of their being thus compiled, if they
are not themselves derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these
copies of the Document, then if the Document is less than one quarter
of the entire aggregate, the Document's Cover Texts may be placed on
covers that surround only the Document within the aggregate.
Otherwise they must appear on covers around the whole aggregate.

8. TRANSLATION
Translation is considered a kind of modification, so you may
distribute translations of the Document under the terms of section 4.
Replacing Invariant Sections with translations requires special
permission from their copyright holders, but you may include
translations of some or all Invariant Sections in addition to the
original versions of these Invariant Sections.  You may include a
translation of this License provided that you also include the
original English version of this License.  In case of a disagreement
between the translation and the original English version of this
License, the original English version will prevail.

9. TERMINATION

You may not copy, modify, sublicense, or distribute the Document except
as expressly provided for under this License.  Any other attempt to
copy, modify, sublicense or distribute the Document is void, and will
automatically terminate your rights under this License.  However,
parties who have received copies, or rights, from you under this
License will not have their licenses terminated so long as such
parties remain in full compliance.

10. FUTURE REVISIONS OF THIS LICENSE
The Free Software Foundation may publish new, revised versions
of the GNU Free Documentation License from time to time.  Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.  See
http://www.gnu.org/copyleft/.
Each version of the License is given a distinguishing version number.
If the Document specifies that a particular numbered version of this
License "or any later version" applies to it, you have the option of
following the terms and conditions either of that specified version or
of any later version that has been published (not as a draft) by the
Free Software Foundation.  If the Document does not specify a version
number of this License, you may choose any version ever published (not
as a draft) by the Free Software Foundation.

ADDENDUM: How to use this License for your documents
To use this License in a document you have written, include a copy of
the License in the document and put the following copyright and
license notices just after the title page:
      Copyright (c)  YEAR  YOUR NAME.
      Permission is granted to copy, distribute and/or modify this document
      under the terms of the GNU Free Documentation License, Version 1.1
      or any later version published by the Free Software Foundation;
      with the Invariant Sections being LIST THEIR TITLES, with the
      Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
      A copy of the license is included in the section entitled "GNU
      Free Documentation License".
If you have no Invariant Sections, write "with no Invariant Sections"
instead of saying which ones are invariant.  If you have no
Front-Cover Texts, write "no Front-Cover Texts" instead of
"Front-Cover Texts being LIST"; likewise for Back-Cover Texts.

If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of
free software license, such as the GNU General Public License,
to permit their use in free software.

17. Changes

2008/11/15 (version 0.3.4)

* 行列の tensor 積のサンプルコードがずっと間違ったままでした。 (すみません。 ) ようやくなおしました。

2003/10/29 (version 0.3.2)

* cases のところに fall through の説明を書き足す。 2003/10/17 (version 0.3.1)

* Changes を真面目につけることにする。 (多分)

* plotfunc2d の項を書く。

* 積分の項を少し書き足す。