トップページ Maxima とは リンク集 関数と変数 ちっぷす imaxima 数独
Maxima ..... Tips(FAQ とも言う)

【三角関数を含む方程式を解く】 ..... to_poly_solver.mac

三角関数を含む方程式に関数 solve を適用しても、全ての解を求めることは出来ない。

(%i1) solve(sin(2*x - %pi/6) = 1/2, x);

solve: using arc-trig functions to get a solution.
Some solutions will be lost.
                                        %pi
(%o1)                              [x = ---]
                                         6
to_poly_solver.mac で定義されている関数 %solve(= to_poly_solve) を適用すると、全ての解を求めることが出来る(当然のことながら、全ての方程式を解けるわけではありません)。
(%i2) load("to_poly_solver")$

(%i3) %solve(sin(2*x - %pi/6) = 1/2, x, 'simpfuncs = ['ratexpand]);
                                     %pi                  %pi
(%o3)          %union([x = %pi %z2 + ---], [x = %pi %z3 + ---])
                                      2                    6
ここで、%z2%z3 は任意の整数を表している。

【カレント・ディレクトリを変更する】 ..... ?xchdir

カレント・ディレクトリ(フォルダ)を変更するには、Lisp で定義されている関数 xchdir を Maxima から呼び出して利用します。

(%i1) system("cd")$
C:\Documents and Settings\ハルヒ

(%i2) ?xchdir("C:\\Documents and Settings")$

(%i3) system("cd")$
C:\Documents and Settings
上記のように、Windows ではディレクトリ(フォルダ)の区切りを「\\」とするところがポイントです。なお、:lisp(system:chdir "My Documents") のように実行することも出来ますが、この方法では Lisp 依存になってしまいます(SBCL の場合は system:chdir ではなく sb-posix:chdir とする必要があります)。

【グラフをファイルに保存する】 ..... gnuplot_term、gnuplot_out_file

最近の Maxima は(標準では)gnuplot を使ってグラフを描いている。そのグラフをファイルに保存するには、plot2d や plot3d の場合は、

(%i1) plot2d(x^2, [x, -1, 1],
             [gnuplot_term, "pdf"], [gnuplot_out_file, "filename.pdf"]);
のように実行する。変数 gnuplot_term の値は、そのまま gnuplot に(「set term 値」として)渡される。従って、カラーの EPS で保存するなら、[gnuplot_term, "postscript eps color"] とすればよい。draw パッケージ(draw2d や draw3d)の場合は
(%i1) draw2d(terminal=eps_color, file_name="filename",
             explicit(x^2, x, -1, 1));
のように実行する。この場合、ファイル名の拡張子(.eps や .pdf など)は、変数 terminal の値に合わせて自動的に付与されるため、不要(というより付けてはいけない)。

【出力順序を変更する】 ..... ordergreat、orderless

Maxima の出力結果は、多くの場合我々が慣れている表現とは異なる順番で表示される。

(%i1) expand((x + y)^4);

                       4        3      2  2      3      4
(%o1)                 y  + 4 x y  + 6 x  y  + 4 x  y + x

(%i2) factor(x^2 - y^2);

(%o2)                          - (y - x) (y + x)
上記の例はいずれも y について整理された形になっている。これを x について整理した形に変更するには、関数 orderless や ordergreat を用いる。
(%i3) ordergreat(x, y);

(%o3)                                done

(%i4) expand((x + y)^4);

                       4        3      2  2      3      4
(%o4)                 x  + 4 y x  + 6 y  x  + 4 y  x + y

(%i5) factor(x^2 - y^2);

(%o5)                           (x - y) (x + y)
元の状態に戻すには unorder を実行する。
(%i6) unorder();

(%o6)                               [y, x]

補遺(2010/02/18) 変数 powerdisp に true を代入しておく方法でも似たような効果が得られます。

【tan(x) の導関数を 1/cos(x)^2 にする】 ..... gradef

標準状態の Maxima では、tan(x) を微分すると sec(x)^2 を返す。これを 1/cos(x)^2 に変更するには、関数 gradef を用いる。

(%i1) diff(tan(x), x);

                                       2
(%o1)                               sec (x)


(%i2) gradef(tan(x), 1 / cos(x)^2);

(%o2)                               tan(x)


(%i3) diff(tan(x), x);

                                       1
(%o3)                               -------
                                       2
                                    cos (x)

【乱数を発生させる】 ..... make_random_state、set_random_state

関数 random はデフォルトでは毎回同じ乱数列を発生させる。これを変更するには、次のようにして、「現在の時刻」を利用した種を用いるようにすればよい。

(%i1) s: make_random_state(true)$

(%i2) set_random_state(s)$

【分母を有理化する】 ..... algebraic: ture

(分母を)有理化するには algebraic を ture にした上で関数 rat(や ratsimp)を実行する。

(%i1) 1/(1+sqrt(3));

                                       1
(%o1)                             -----------
                                  sqrt(3) + 1


(%i2) ratsimp(%), algebraic: ture;

                                  sqrt(3) - 1
(%o2)                             -----------
                                       2

【多項式を整理する】 ..... rat or collectterms

多変数多項式 f(x, y, z, ...) を 1 つの変数について整理するには関数 rat(や ratsimp)もしくは collectterms を使う。

(%i1) expand((y-1)*(y+1)*x^2+(y-1)*x+y-1);

                          2  2              2
(%o1)                    x  y  + x y + y - x  - x - 1


(%i2) rat(%,x);

                          2       2
(%o2)/R/                (y  - 1) x  + (y - 1) x + y - 1
factorout を使っても似たようなことは出来る。

【陰関数微分】 ..... depends

普通に diff(式, x) を実行すると「式」に含まれる x 以外の変数は全て定数とみなされる。例えば、変数 y を x の関数とみなして微分するには depends(y, x) を実行すればよい。

(%i1) diff(x^2*y+y,x);

(%o1)                                2 x y


(%i2) depends(y,x);

(%o2)                               [y(x)]


(%i3) diff(x^2*y+y,x);

                               2 dy   dy
(%o3)                         x  -- + -- + 2 x y
                                 dx   dx


(%i4) solve(%,diff(y,x));

                                 dy     2 x y
(%o4)                           [-- = - ------]
                                 dx      2
                                        x  + 1
依存関係を解除するには remove(y, dependency) を実行する。

【小数点の精度を変更する】 ..... fpprec(デフォルトは 16)

関数 bfloat を用いると、標準では 16 桁の精度で小数値を出力する。桁数の変更には変数 fpprec を用いる。

(%i1) bfloat(%pi);

(%o1)                         3.141592653589793B0


(%i2) fpprec:100;

(%o2)                                 100


(%i3) bfloat(%pi);

(%o3) 3.141592653589793238462643383279502884197169399375
105820974944592307816406286208998628034825342117068B0

【出力幅を変更する】 ..... linel(デフォルトは 79)

出力幅(行の長さ)はターミナルウィンドウの幅に合わせて適宜変更する必要がある。そのための変数が linel である。

(%i1) linel:30;

(%o1)         30


(%i2) bfloat(%pi),fpprec:100;

(%o2) 3.141592653589793238462#
64338327950288419716939937510#
58209749445923078164062862089#
98628034825342117068B0

【関数を定義する】 ..... define と :=

普通は := を用いて、f(x):=sin(x) のようにすればよいが、この方法では右辺に例えば diff のような演算子を含めることが出来ない。そのような場合は代わりに関数 define を用いる。

(%i1) f(x):=diff(sin(x),x); ←失敗する

(%o1)                       f(x) := diff(sin(x), x)


(%i2) f(%pi);

(%o2)                                  0 ←間違い


(%i3) define(f(x),diff(sin(x),x));

(%o3)                           f(x) := cos(x)


(%i4) f(%pi);

(%o4)                                - 1

【ローカル変数を使用する】 ..... block

block([変数1, 変数2, ...], 処理1, 処理2, ...) のように使用する。次の例は、x に s=1 を加える関数です(無意味な例です)。

(%i1) f(x):=block([s],s:1,x+s);

(%o1)                  f(x) := block([s], s : 1, x + s)


(%i2) f(3);

(%o2)                                  4


(%i3) s;

(%o3)                                  s

【四捨五入】 ..... cf. ?round

Maxima には四捨五入をする関数が存在しないようなので、作る!。まず、ガウス記号に相当する関数 fix を用いて、小数第 1 位を四捨五入する関数 rnd を定義する。

(%i1) rnd(x):=fix(x+0.5)$


(%i2) rnd(123.49);

(%o2)                                  123


(%i3) rnd(123.5);

(%o3)                                  124
この関数 rnd を用いて、実数 x を小数第 n 位で四捨五入する関数 round を定義する(高校で学ぶように、10^(n-1) 倍(四捨五入したい位の数を小数第 1 位に移動)してから四捨五入を実行し、その後 10^(n-1) で割れば良い)。
(%i4) round(x,n):=block([t],t:x*10^(n-1),float(rnd(t)/10^(n-1)))$


(%i5) round(2.345,2);

(%o5)                                  2.3
負の数でも大丈夫かな?

【多項式の次数】

Maxima には多項式の次数を求める関数が存在しないようなので、作る!。多項式 f を変数 x で割って、商 q を求める。商 q を変数 x で割って、商を求める。以下商が 0 になるまでこの操作を繰り返し、繰り返し回数を数える。

degree(f,x):=block([q,i,j],
        q:f,
        for i:0 while (q # 0 ) do (j:i,q:quotient(q,x)),
        j
);
上記 5 行を maxima-init.mac に書いておき、ホームディレクトリに置いておく。
(%i1) degree(2*x^3-5*x^2+x+9, x);

(%o1)                                  3
powers.lisp を load して、max(powers(式, 変数)[1]) とする案も。もっと上手い方法がありそう。

補遺(2006/08/21) hipow が一応次数を求める関数のようです。

【行列の基本変形】

Maxima には行列の基本変形を実行する関数が存在しないようなので、作る!。ファイル maxima-init.mac をダウンロードしてホームディレクトリに置いておくと、maxima 起動時に自動的に読み込まれ、以下 6 個の関数が使えるようになる:

rowmult(A, n, c) 第 n 行を c 倍する
rowadd(A, n, m, c) 第 n 行に第 m 行の c 倍を加える
rowch(X, m, n) 第 n 行と第 m 行を入れ替える
colmult(A, n, c) 第 n 列を c 倍する
coladd(A, n, m, c) 第 n 列に第 m 列の c 倍を加える
colch(X, m, n) 第 n 列と第 m 列を入れ替える

(%i1) A:matrix([1,2],[3,4]);

                                   [ 1  2 ]
(%o1)                              [      ]
                                   [ 3  4 ]


(%i2) rowmult(A,1,10);

                                  [ 10  20 ]
(%o2)                             [        ]
                                  [ 3   4  ]


(%i3) coladd(A,1,2,10);

                                   [ 21  2 ]
(%o3)                              [       ]
                                   [ 43  4 ]

【随伴行列を求める】

Maxima には随伴行列を返す関数が存在しないらしい(関数 adjoint は余因子行列を返す関数であることに注意)。随伴行列とは転置行列の各成分を共役複素数で置き換えた行列のことだから、転置行列を返す関数 transpose と全ての成分を共役複素数で置き換えた行列を返す関数 CONJUGATE(eigen パッケージ)を組み合わせればよい。

(%i1) M:matrix([1+%i,2+%i],[3+%i,4+%i]);

                              [ %i + 1  %i + 2 ]
(%o1)                         [                ]
                              [ %i + 3  %i + 4 ]


(%i2) load("eigen");

(%o2)        /usr/local/share/maxima/5.9.2/share/matrix/eigen.mac


(%i3) transpose(conjugate(M));

                              [ 1 - %i  3 - %i ]
(%o3)                         [                ]
                              [ 2 - %i  4 - %i ]
なお、バージョン(5.9.1 辺り)によっては大文字 CONJUGATE でないと機能しないかもしれない。

【1/x を正しく不定積分する】 ..... logabs

普通に integrate(1/x, x) を実行すると、正しい答え log|x| が得られず、log(x) となる。変数 logabs を true に設定すれば正しい答えが得られる。(定積分の場合はデフォルトで logabs が true の状態で計算するため、誤った答えになることはないそうです。)

(%i1) integrate(1/x,x);

(%o1)                               log(x)


(%i2) logabs:true;

(%o2)                                true


(%i3) integrate(1/x,x);

(%o3)                             log(abs(x))

【出力を一次元表示にする】 ..... display2d

アスキーアートのような複数行を使った出力をやめて、 一次元表示に切り替えるには、変数 display2d を false にする(デフォルトは true):

(%i1) x*x+y*y;

                                     2    2
(%o1)                               y  + x


(%i2) display2d:false;

(%o2) false


(%i3) x*x+y*y;


(%o3) y^2+x^2
一時的に一次元表示に切り替えるには、関数 disp を併用すれば良い:
(%i4) display2d:true;

(%o4)                                true


(%i5) disp(x*x+y*y), display2d:false;

y^2+x^2

(%o5)                                done

【TeX 出力を改善する】 ..... mactex-utilities.lisp

関数 tex を使うと、plain TeX 形式で出力される。次の例を参照。

(%i1) f(x):=1/x;

                                           1
(%o1)                              f(x) := -
                                           x


(%i2) tex(f(x));

$${{1}\over{x}}$$

(%o2)                                false

(%i3) M: matrix([1,2],[3,4]);

                                   [ 1  2 ]
(%o3)                              [      ]
                                   [ 3  4 ]


(%i4) tex(M);

$$\pmatrix{1&2\cr 3&4\cr }$$

(%o4)                                false
mactex-utilities.lisp を load すると、標準的な LaTeX 形式の出力になる。
(%i6) load("mactex-utilities.lisp")$


(%i7) tex(f(x));

$$\frac{1}{x}$$

(%o7)                                false


(%i8) tex(M);

$$\begin{pmatrix}1 & 2 \\ 3 & 4 \\ \end{pmatrix}$$

(%o8)                                false

【非対話モード】 ..... noninteractive mode

Maxima にはプロンプト (%i1) から命令を実行する代わりに、 maxima コマンドに直接命令を食わせる「非対話モード」も用意されています。 例えば、ターミナルで

maxima --batch-string="factor(1000);"
を実行すると、maxima は 1000 を素因数分解した結果を表示した後終了します:
[~]> maxima --batch-string="factor(1000);"

Maxima 5.9.2.19cvs http://maxima.sourceforge.net
Using Lisp SBCL 0.9.9
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
This is a development version of Maxima. The function bug_report()
provides bug reporting information.

(%i1)                            factor(1000)

                                      3  3
(%o1)                                2  5
また、factor(1000); のような Maxima の命令がファイル happy.mac に記入してある場合は maxima --batch-lisp=happy.mac もしくは maxima -b happy.mac を実行することで、やはり、Maxima は結果を出力した後終了する非対話モードで動作します。