• 検索結果がありません。

1.3 属性の宣言と属性値

1.3.5 atvalue 函数による函数値の設定

(%i9) properties(mike);

(%o9) [value, [user properties, value_check], special]

(%i10) mike:15;

(%o10) 15

(%i10) :lisp (get ’$mike ’assign) NIL

(%i10) :lisp (put ’$mike ’assign-mode-check ’assign) ASSIGN-MODE-CHECK

(%i10) mike:15;

15 is not prime!!

#0: ptest(y=15)

-- an error. Quitting. To debug this try debugmode(true);

この例では,最初に素数でなければエラーを返す述語函数ptestを定義し,それから, define variable 函数で大域変数tamaに初期値5を与えて整数変数として宣言します.それから,qput函数を用い てcheck value属性にptestを与えます.この時, 変数mikeに15を設定しようとすれば,15は素数 ではないのでエラーになっています.

ここまでの動作をもう少し詳しく解説しましょう.先ず,define variable函数による宣言で,変数 の型をintegerと宣言しています.define variable函数は, 変数の型をany以外に指定していれば, 宣言する大域変数のassign属性に内部函数のassign-mode-check函数を割当てます.この内部函数

は変数のvalue check属性に設定された函数を用いて変数の評価を実行する函数です.次に,この

value check属性の設定でqput函数を用いています.ここでの例では,大域変数tamaのvalue check

属性にptest函数を割当てていますね.すると,大域変数tama

に値を割当てる時に,assign-mode-check函数が,大域変数tamaのcheck value属性に割当てられた述語函数で割当てようとする値を

評価します.この例では,ptest函数に15が引渡されます.この例では15が素数でない為にfalseと なり,変数に15が割当てられません.

次の例では, 大域変数mikeの型を any とした場合です. この場合,変数 mikeの value check 属性に値を設定しても,先程の様にmike:15を実行した場合にエラーも何も出ません.この場合, 大域変数mikeのassign属性にassign-mode-checkが設定されていない為です.これはLISPで

(get ’$mike ’assign) を実行すれば, NILが返されるので判ります.

そこで, :lisp (put ’$mike ’assign-mode-check ’assign) として見ましょう.これによって,属性 as-signの値としてassign-mode-checkを設定されます.すると,割当の際に検証が実行される様になり ます.

atvalue函数

³

atvalue(,点リスト,境界値) at(,点リスト)

µ ´

atvalue函数による境界値の設定では,函数や式に対して点をリストで指定し,そのリストに対応

する境界値を設定します.

このatvalue函数で値を指定すると,atvalue属性に座標と函数値が対応付けられ,の prop-ertiesリストにatvalue属性が追加されます.

尚,引数のには函数f(⟨v1,· · ·,⟨vn)やその微分が指定可能ですが,その場合には変数の 従属性が明確になる様に指定しなければなりません.

リスト変数1=の様に変数と値を演算子=で繋ぎ合せた式のリストになります.

atvalue(f(x),x=xˆ2+x+1,0)とした場合,x=xˆ2+x+1の左辺は函数f(x)で用いた疑似変数であ り,=も方程式で用いる演算子=とは意味が異なっています. その為,xˆ2+x+1で用いている変数x とは関係ありません.この事から,x2+ 1 = 0の解x=±iを函数f に代入しても函数f は零にな らない事に注意して下さい.函数f が零になるのはf(x2+x+ 1)の時です.

(%i1) atvalue(f(x),x=x^2+x+1,0);

(%o1) 0

(%i2) f(x^2+1);

2

(%o2) f(x + 1)

(%i3) f(x^2+x+1);

(%o3) 0

atvalue函数で設定された値をprintprops函数を使って表示する際に,函数の疑似変数を表記す

る為に,記号@1,@2,· · · が用いられます.

(%i35) atvalue(h(x,y,z),[x=1,y=0,z=0],10);

(%o35) 10

(%i36) atvalue(diff(h(x,y,w),w),[x=1,y=0,w=0],0);

(%o36) 0

(%i37) printprops(h,atvalue);

!

d !

--- (h(@1, @2, @3))! = 0

d@3 !

!@1 = 1, @2 = 0, @3 = 0

h(1, 0, 0) = 10

但し,atvalue函数で設定した函数の値はget函数で取出せず,削除もrem函数では出来ません.

(%i1) put(f,C-inf,type);

(%o1) C - inf

(%i2) atvalue(f(x),x=0,0);

(%o2) 0

(%i3) properties(f);

(%o3) [atvalue, [user properties, type]]

(%i4) get(f,type);

(%o4) C - inf

(%i5) rem(f,atvalue);

(%o5) false

(%i6) remove(f,atvalue);

(%o6) done

(%i7) properties(f);

(%o7) [[user properties, type]]

しかし,atvalueで設定した属性値は他のものと同様にprintprops函数で函数名と属性を指定す る事で表示されます.

(%i19) atvalue(f(x),x=0,0);

(%o19) 0

(%i20) atvalue(g(x),x=0,1);

(%o20) 1

(%i21) atvalue(g(x),x=1,2);

(%o21) 2

(%i22) printprops(all,atvalue);

f(0) = 0

g(0) = 1

g(1) = 2

(%o22) done

次のat函数はatvalue函数と対で用います. をatvalue函数に対して与えられるものと同 じ方程式のリスト,方程式中に含まれる変数に対し, atvalue函数で指定した値を入れて評価します.

部分式がatvalue函数で指定された値を持たない為に,評価出来ない場合,その部分式に作用する

at函数の名詞型が返されます.又,その部分式は二次元的書式で表示されます.

勾配と従属性の設定

³

gradef(函数名(変数1,· · ·,変数m),1,· · ·,n) gradef(アトム,変数,)

depends(函数,変数1,· · ·, 函数n,変数n)

µ ´

gradef函数は 函数のn個の引数に対する微分を ddxf

i =iで定めます. 尚,gradef函数 で勾配を定義すると,大域変数gradefsに函数名が蓄えられます.更に,指定した函数にはgradef属 性が付与されます.

引数が変数の総数m ·n個の勾配nよりも少ない場合,最初の函数のi番目の引数が参照さ れます.xi は函数定義で用いる疑似変数と同類で,函数函数i番目の変数を指定する為に用 います.

最初の引数を除く全てのgradef函数の引数はが定義された函数ならばその函数が呼出さ れて結果が用いられます.勾配は函数が第一階微分を除いて正確に判らない場合で,より高階の微 分を得たい時に必要となります.

gradef(アトム,変数,)で変数 変数による函数の微分がとなる事を宣 言します.この場合,大域変数gradefsには登録されず,属性もatomgrad属性になります.

この時, depends(⟨f⟩,⟨x⟩)も実行されるので, depends函数によって属性dependencyが付加さ れ, 同時に大域変数dependenciesにも函数が追加されます.

gradef函数はMaximaの既に定義された函数の微分を再定義する事にも使えますが,添字された

函数に対してgradef函数は使えません.

depends函数で,函数の変数に対する従属を宣言します.例えば, depends(f,x) で函数fが変数x に従属する性質を付加します.尚,depends函数による従属性の宣言にて,函数自体を予め定義する 必要はありません.

(%i41) depends(neko,[tama,mike]);

(%o41) [neko(tama, mike)]

(%i42) diff(neko,tama);

dneko

(%o42)

---dtama (%i43) diff(diff(neko,tama),tama);

2 d neko

(%o43)

---2 dtama (%i44) depends([rat1,rat2],[cheese,milk]);

(%o44) [rat1(cheese, milk), rat2(cheese, milk)]

(%i45) depends([rat1,rat2],[cheese,milk],neko,[tama,mike]);

(%o45) [rat1(cheese, milk), rat2(cheese, milk), neko(tama, mike)]

勿論,depends函数を実行していなければ,diff函数を実行した時点で0になります. depends函数 でnekoが変数tamaとmikeに従属する函数と宣言した為に,微分を行っても零になりません.最 初の例では函数nekoが1成分しかない為に,リストの大括弧を外しています.

函数の変数に対する従属性は大域変数dependenciesに登録された函数の情報から調べられます.

gradefとdependsに関連する大域変数

³

変数名 初期値 概要

gradefs [] 勾配を定義された函数名リスト

dependencies [] 従属性を宣言された函数名リスト

µ ´

gradef函数で勾配を定義すると,大域変数gradefsに函数名が蓄えられます.

大域変数dependenciesには,dependsやgradefで指定された函数名が蓄えられます.

これらの変数は共にデフォルト値が空のリスト[]です.

(%i4) gradef(f(x,y),y,x);

(%o4) f(x, y)

(%i5) gradefs;

(%o5) [f(x, y)]

(%i6) diff(f(x,y),x);

(%o6) y

(%i7) diff(f(x,y),y);

(%o7) x

(%i8) dependencies;

(%o8) []

(%i9) depends(g,x,y,z);

(%o9) [g(x), y(z)]

(%i10) dependencies;

(%o10) [g(x), y(z)]

(%i11) gradefs;

(%o11) [f(x, y)]

(%i12) gradef(h,x,x^2);

(%o12) h

(%i13) dependencies;

(%o13) [g(x), y(z), h(x)]

この例で示す様に,gradefやdepends函数を用いる事で,gradefsやdependenciesに函数名が蓄積 されます.尚,gradefを用いてdependenciesに函数を追加する為には, gradef(アトム ,変数 ,)の形式に限定されます.