GNU Octave 2.1.x 日本語マニュアル/式

Octave において,式は,ステートメント(文)の基本的な構成要素です。ある式は値へと評価され, 表示,テスト,変数への格納,関数への受け渡し,あるいは代入演算子を用いて変数へ新しい値を割り当てたりすることができます。 ある式は,それ自身をステートメントとして提供することができます。 大部分のその他のステートメントは,操作しようとするデータを指定する1つ以上の式を含んでいます。 他の言語と同様に,Octave における式は,変数,配列,定数および関数呼び出し,さらにはそれらを様々な演算子で結びつけたものを含みます。
インデックス式を用いると,行列やベクトルの選択した要素を参照したり,抜き出したりできるようになります。 インデックスは,スカラ,ベクトル,範囲あるいは特殊な演算子‘:’ をとることができます。 この演算子は,全体の行あるいは列を選択するために使うことになるでしょう。 ベクトルは,単一の式を使用することによりインデックス化できます。 行列は,1つまたは2つのインデックスを使用することによりインデックス化できます (もし組み込み変数warn_fortran_indexingの値がゼロでないならば,1つのインデックスを指定したときに警告が発生します)。
[Built-in Variable]
もしwarn_fortran_indexingの値がゼロでなければ,単一のインデックスを用いて2次元行列の要素を選択する式に対して,警告を表示します。 標準状態では0である以下の行列について,
以下の式は,どれも同じ意味です。
これらは,行列の最初の行を選択しています。 1 を含むベクトルでスカラをインデックス化すると,各要素がもとのスカラの値に等しく,インデッ クスベクトルと同じサイズのベクトルを生成することができます。たとえば,以下の式は,
4 つの要素がすべて13 であるベクトルを生成します。 同様に,1を含む2つのベクトルでスカラをインデックス化すると,行列を生成することができます。 たとえば,以下の式は,
すべての要素が13 であって,2 行3 列の行列を生成します。 これは分かりにくい表記であって,避けるべきです。すべての要素が1 である適切な大きさの行列 を生成するためにones関数を使用し,望む結果を生み出すためにそれをスケール化する方がよいの です。Section 18.3 [Special Utility Matrices]を参照してください。
[Built-in Variable]
もしwarn_resize_on_range_errorがゼロでないならば,行列の添え字の範囲を超えたイ ンデックスを割り当ててサイズ変更するときに警告を表示します。標準状態では0 です。 上の例で示した式のように,ループを使用してベクトルを生成することは,完全に非効率です。こ のような場面では,以下のような式を使用することが,ずっと効率的です。
この式は,完全にループを避けています。それでもループが必要となる場面,あるいは,値の数が大き な行列を形成するために結びつけられなければならない場面においては,最初に行列のサイズをセッ トし,その後にインデックスコマンドを用いて要素を挿入する方がずっと高速です。たとえば,行列 aが与えられているとして,
この式は,特に大きな行列において以下の式よりもかなり高速です。
なぜならば,Octave は,結果を繰り返しサイズ変更する必要がないためです。
関数は,特定の計算手順に対する名称です。関数には名前がついているので,プログラムの任意の場 所でそれを呼び出すことができます。たとえば,sqrt関数は,ある数の平方根を計算します。 あらかじめ用意されている関数群は,組み込み関数です。これは,どのOctave プログラムにおい ても利用可能であることを意味します。sqrt 関数は,組み込み関数のひとつです。さらに,あなた独 自の関数を定義することもできます。これを実行するためのさらなる情報は,Chapter 13 [Functions and Scripts]を参照してください。 関数を使用するための方法は,関数呼び出し式を使うことです。この式は,関数名と,それに続く かっこでくくられた引数のリストから構成されます。その引数は,関数が実行する計算に用いる生の 対象物を与える式です。1 つ以上の引数があるとき,それらはカンマで区切ります。もし引数がなけ れば,カッコを省略することができます。しかし,関数の呼び出しを行ったということを明確にする ため,いつでもカッコを使うことがよい考えです。いくつかの例を挙げます。
各々の関数ごとに,とるべき引数の数が決まっています。たとえばsqrt関数は,1個の引数(平方根をとるべき数)をつけて呼び出さなければなりません。
組み込み関数の中には,特定の利用法に応じて引数の数を変えるものがあります。 また,その関数の挙動は,与えた引数の数によって異なります。 他の式と同じように,関数の呼び出しは値です。 これは与えた引数に基づいて,その関数により計算されたものです。 この例において,sqrt (argument)の値は,引数の平方根です。 関数は,ある変数に値を代入したり,入出力を実行したりするような使い方もできます。 大部分の言語とは異なり,Octave における関数は,複数の値を返すことがあります。たとえば,
この式は,行列aの特異値分解を計算し,3 つの計算結果の行列をu,sおよびvに代入します。 複数の代入式の左辺は,それ自体が式になっており,変数名やインデックス式のリストをとるこ とができます。Section 10.1 [Index Expressions]およびSection 10.6 [Assignment Ops]も参照してください。
Octave では,Fortran とは異なり,関数の引数は値として渡されます。これは,関数呼び出しにおけ る各々の引数は,関数に渡される前に評価され,メモリの一時領域に割り当てられます。現在のとこ ろ,引数を値ではなく参照渡しとするように指定する方法はありません。これは,関数呼び出しにお いて,引数の値を直接変更することは不可能だということです。関数内では,一時的にコピーされた 値のみを変更することはできます。たとえば,以下の関数があります。
この関数は,1 番めの引数の値をn 回繰り返して表示するものです。この関数において,変数n は, その値が関数の呼び出し元で変更されることを心配する必要なく,一時変数として使用されています。 その関数が引数を修正しようとしないことを最初に決定する必要なく,どの引数に対しても定数とし て渡すことが常に可能となるため,値渡しは役に立ちます。 呼び出す側は,引数に対する式として変数を使用するでしょうが,呼び出される関数はこれを知り ません。ただ引数のもつ値だけを知るのです。たとえば,以下のように呼び出される関数があるとし ます。
あなたは,引数が「fooという変数」であると考えるべきではありません。 かわりに,引数が"bar"という文字列値であると考えるべきです。 Octave は,関数の引数に値渡しを使用していますが,値は必要のない時にはコピーされません。 たとえば,
この例では,もし関数fがその引数の値を変更しないのであれば,2 つの1000 行1000 列の行列を,実際には存在しないようにします。 ですから,Octaveは関数fの範囲外で値を変更することを避けるためにコピーを作らなければなりません。 そうでないとすれば,定数または一時的な結果の値を修正しようとします(そして失敗します)。
いくつかの制限はありますが,関数の再帰呼び出しが許されています。再帰関数は,直接・間接にそ れ自身を呼び出す関数のことです。たとえば,与えられた整数の階乗を計算する非効率な2例を示し ます。
この関数は,それ自身を直接呼び出す再帰的関数です。 この関数は,自分自身を呼び出すたびに,以前の呼び出しで用いた値よりも1だけ小さい引数を使用しているので,最終的には終了します。 い ちど引数がゼロ以下になれば,この関数は自分自身を呼び出さずに,再帰は終了します。 組み込み変数max_recursion_depthは,再帰の深さの限界を指定し,Octave が無限回の再帰 にはまることを回避します。
[Built-in Variable]
関数が再帰的に呼び出される回数の限界を決定します。 もし限界を超えるならば,エラーメッセージを表示し,トップレベルに制御を戻す。 初期値では256 です。
Octaveの関数の中には,再帰的に呼び出すことのできない関数として実装されているものがあります。 たとえば,ODEソルバlsodeは,結局のところ,再帰呼び出しのできないFortranサブルーチンで実装されています。 したがって,lsodeを必要とするユーザ提供関数を,その内部から直接・間接を問わず呼び出すべきではありません。 そのようなことを行うと,予期しない挙動を起こします。
以下の算術演算子が利用でき,スカラと行列に対して動作します。
加算します。
もし両方のオペランドが行列ならば,行と列の数の両方とも一致していなければなりません。 もし片方のオペランドがスカラならば,その値を他方のオペランドの全要素に加算します。
要素どうしの加算です。
この演算子は+と等価です。
減算します。
もし両方のオペランドが行列ならば,行数と列数の両方とも一致していなければなりません。
要素どうしの減算です。
この演算子は-と等価です。
行列の乗算です。
x の列数は,y の行数と一致していなければなりません。
要素どうしの乗算です。
もし両方のオペランドとも行列ならば,行数と列数の両方とも一致していなければなりません。,
右除算です。
これは,概念的には,以下の式と等価です。
しかし,この演算子はy’ の逆数(逆行列)を形成することなく計算します。 もし方程式が正方でない,あるいは係数行列が特異ならば,最小ノルム解を計算します。
要素ごとの除算です。
左除算です。
これは,概念的には,以下の式と等価です。
しかし,この演算子はx’ の逆数(逆行列)を形成することなく計算します。 もし方程式が正方でない,あるいは係数行列が特異ならば,最小ノルム解を計算します。
要素ごとの左除算です。y の各々の要素を,x の各々の対応する要素で割ります。
ベキ乗の演算子です。
もしxとyの両方ともスカラならば,この演算子はx のy 乗を返します。 もしxがスカラであり,yが正方行列ならば,その結果は固有値展開を用いて計算されます。 もしx が正方行列ならば,y が整数のときにはrepeated multiplication によって,yが整数でないときには固有値展開によって計算します。 xとyの両方とも行列ならば,エラーとなります。 この演算子の実装は,改善される必要があります。
要素ごとのベキ乗演算子です。
もし両方のオペランドとも行列ならば,その行数と列数が一致していなければなりません。
負値です。
正値です。この演算子は,オペランドに何もしません。
複素共役転置です。実数の引数に対しては,この演算子は転置演算子と同じです。
複素数の引数に対しては,この演算子は式
conj (x.')
と等価です。
転置です。
Octave の要素ごとの演算子は,‘.’から始まるので,以下のような式はあいまいになる可能性があることに注意してください。
1./m
なぜならば,ピリオドは,定数の一部あるいは演算子の一部のどちらにも解釈できるためです。 この衝突を避けるために,Octave は,型を持っているかのように式を扱います。 つまり,
(1) ./ m
であって,
(1.) / m
ではありません。 これはOctave の文法解釈の普通の挙動,すなわち,通常はある与えられた点にお いて最も長くマッチするように入力をトークンに分割すること,とは相容れないのですが,この場合 には上記の解釈の方が役に立ちます。
[Built-in Variable]
もしwarn_divide_by_zeroが0 でないならば,Octave がゼロで除算したときに警告が発生 します。 もしこの値が0 ならば,警告を省略します。 標準状態は1 です。
比較演算子は,(たとえば等しいというような)数値の関係を比較します。 これらは関係演算子を用いて書かれています。 Octave のすべての比較演算子は,比較が真であれば1 を,偽であれば0 を返します。 行列の値について,これらは要素ごとに基づいて動作します。 たとえば,以下のようになります。
もし片方のオペランドがスカラであり,他方が行列ならば,このスカラを行列の各々の要素と順に 比較して,結果はその行列と同じサイズになります。
x がy よりも小さいならば真です。
x がy と同じか小さい(以下)ならば真です。
x がy と等しいならば真です。
x がy と同じか大きい(以上)ならば真です。
x がy よりも大きいならば真です。
x がy と等しくないならば真です。
文字列の比較は,上で示した比較演算子ではなく,strcmp関数により実行することができます。 Chapter 5 [Strings]を参照してください。
要素ごとの論理(ブール)式は,ブール演算子“or”(‘|’),“and”(‘&’)および“not”(‘!’)と,入 れ子をコントロールするための括弧を用いた比較式の組み合わせです。 ブール式の真理値は,成分式 の対応する要素の真理値の組み合わせによって計算されます。 ある値がゼロならば偽であり,それ以 外は真であると見なします。
要素ごとのブール式は,使用できる比較式であれば,何でも使えます。 これらは,ifおよびwhileステートメントにおいても利用できます。 しかし,もしifまたはwhileステートメントにおいて条件として行列を使用するならば,その要素のすべてがゼロでないときに限り真になります。
比較演算子のように,要素どうしのブール式の各々の要素は数値を持ちます(真ならば1,偽ならば0)。 これは,ブール式の結果が変数に格納されたときには,数値になり,ふつうの値として使用さ れます。 要素どうしのブール演算子についての解説です。
もしboolean1 とboolean2 の対応する要素の両方が真ならば,結果の要素は真となります。
もしboolean1 とboolean2 の対応する要素のどちらかが真ならば,結果の要素は真と なります。
もしboolean の要素が偽ならば,結果の要素は真となります。 オペランドに行列を指定したとき,これらの演算子は要素ごとに働きます。 たとえば,
この式は,2 行2 列の単位行列を返します。 二項演算子に対して,両方のオペランドが行列ならば,オペランドの次元はそろっていなければなりません。 もしオペランドの片方がスカラであり,もう片方が行列ならば,この演算子は行列の各要素にスカラを適用します。
要素ごとの二項ブール演算子について,式boolean1 とboolean2 の両方とも,結果を計算する前に評価されます。 このことは,その式が別の効果をもつときに異なる結果を生むことになります。 たとえば,
この式は,たとえ変数a がゼロであっても,b はインクリメントされます。 この挙動は,ブール演算子が,行列のオペランドで説明したように動作するために必要なことです。
ifおよびwhileの条件において,スカラへの暗黙的な変換と結合して,Octave の要素ごとのブール 演算子は,しばしば大部分の論理演算子を実行するには十分です。 しかし,全体の真理値を決定する ことができた時点で,ただちにブール式の評価をやめることが望ましいことがあります。 Octave の短絡回路ブール演算子は,そのように動作します。
all(all (boolean1))と等価な操作を利用して,式boolean1 は評価され,スカラに変換されます。 もしそれが偽ならば,式全体は0 という結果になります。 もしそれが真ならば,all (all (boolean2))と等価な操作を利用して,式boolean2 は評価され,スカラに変換されます。 もしこれが真ならば,式全体の結果は1 であり,そうでなければ全体の式の結果は0 になります。
all (all (boolean1))と等価な操作を利用して,式boolean1 は評価され,スカラに変換されます。 もしそれが真ならば,式全体は1 という結果になります。 もしそれが偽ならば,all (all (boolean2))と等価な操作を利用して,式boolean2は評価され,スカラに変換されます。 もしこれが真ならば,全体の式の結果は1 であり,そうでなければ式全体の結果は0になります。
両方のオペランドが,式の全体の真理値を決定する前に評価されないことがあるという事実は,重要に成り得ます。 たとえば,
a && b++
この式は,変数b の値は,変数a がゼロでないときにだけインクリメントされます。
これは,いくぶん簡潔なコードを書くのに使えるでしょう。 たとえば,
このコードは,存在しない引数を評価しようとするのを避けるために,2つのifステートメントを使わねばならないところに使うことができます。 たとえば,短絡回路機能を使わないとすれば,以下のように書く必要があります。
以下のコード
は,fを1 個または2 個の引数をつけて呼び出すと,エラーになります。 なぜならば,Octave は,演算子‘&’に関する2 つのオペランドを両方とも評価しようとするからです。
代入は,ある新たな値をある変数に格納する式です。 たとえば,以下の式は,1 という値を変数zに代入します。
この式を実行した後,変数zは値1 を持ちます。 zが代入の前に持っていた古い値は,どんなものも忘れてしまいます。 イコール‘=’記号は,代入演算子と呼ばれています。
文字列値も代入することができます。 たとえば,以下の式は,変数message に"this food is good"という値を格納することになります。
(これは,文字列の連結を示してもいます) 大部分の演算子(加算や連結など)は,値を計算すること以外の作用はありません。 もしその計算結果を無視するなら,演算子を使うことはないでしょう。 でも,代入演算子は違います。 これは値を生み出しますが,たとえその値を無視したとしても,代入は,値の改変を通して関知されています。
これを副作用と読んでいます。
代入の左辺オペランドは,変数(Chapter 9 [Variables]参照)である必要はありません。 これには,行列の要素(Section 10.1 [Index Expressions]参照)あるいは返り値のリスト(Section 10.2 [Calling Functions])をとることができます。 これらはすべてlvalues と呼ばれており,代入演算子の左辺に現れることを意味しています。 右辺のオペランドは,どのような式にもなります。 これは特定の変数や行列,戻り値のリストに格納される新しい値を生み出します。
変数は,もともとの型を持っていないことに注意することは重要です。 変数の型は,単にその時点に保持することになったどんな値の型をも取ります。 以下のプログラムの一部分において,変数fooは,最初は数値をもち,その後は文字列値をもちます。
2番めの代入によってfooに文字列を与えるとき,以前に数値を持っていたということを忘れてしまいます。
インデックス付き行列にスカラを代入すると,インデックスで参照した要素のすべてにスカラが セットされます。 たとえば,もしaが少なくとも2 つの列をもつ行列であるならば,
この式は,aの2 列めのすべての要素に5 をセットします。 空行列‘[]’ を代入することは,大部分の場面において,行列またはベクトルの行あるいは列を削除できるように動作します。 Section 4.1.1 [Empty Matrices]を参照してください。 たとえば,4 行5 列の行列A が与えられるとき,
この代入式は,A の3 行めを削除します。 また,
この代入文は,1列め,2列めおよび5列めを削除します。
代入は式ですから,値をもちます。 したがって,式としてのz = 1は,値1 をもちます。 この結果にひとつとして,複数の代入式を一度に書くことができます。
この式は,すべての3 つの変数に値0 を格納します。 この動作になるのは,z = 0の値は0 であり,これをyに代入し,さらにy = z = 0 の値0 がxに代入されるためです。
このことは,値のリストを代入するときにも当てはまります。 ですから,以下の式は妥当です。
これは,以下の式と完全に等価です。
このような表記において,式の各部分の値の数はそろえる必要がありません。 たとえば,
この式は,変数‘d’の値は変化しないままであることを除いて,上の式と等価です。 また,
この式は,以下の式と等価です。
式を呼び出したどこの場所でも,代入文を使用することができます。 たとえば,yに1 をセットした後でxが1 に等しいかどうかをテストするために,x != (y = 1)と書くことは妥当です。 しかし,この書き方は,プログラムを読みづらくします。 使い捨てのプログラムを除き,このような代入の入れ子を排除するように書き換えるべきです。 これは決して難しいことではありません。
[Built-in Variable]
もしこの変数の値がゼロでないならば,Octave は,代入後に左辺の値を表示する代わりに,代入式の右辺の値を表示するようになります。
インクリメント演算子は,ある変数の値を1 だけ増やしたり減らしたりします。 変数をインクリメン トする(1 だけ増やす)ための演算子は‘++’と書きます。 この演算子は,その値を参照する前または 後に変数をインクリメントするために使用できます。
たとえば,変数x を参照する前にインクリメントするには,++x と書きます。 これは,x に1 を 加え,その後で式の結果としてx の新しい値を返します。 これは,式x = x + 1と全く同じです。
変数x を参照後にインクリメントするためには,x++と書くことになります。 これは変数x に1 を加えますが,x をインクリメントする前の値を返します。 たとえば,もしx が2 に等しいならば, 式x++の結果は2 であり,x の新しい値は3 です。
行列またはベクトルを引数にすると,インクリメントおよびデクリメント(1 だけ減らす)は,オ ペランドの各々の要素に対して作用します。
すべてのインクリメントおよびデクリメント式のリストを示します。
この式は,変数x をインクリメントします。 この式の値は,x の新しい値です。 これは,
x = x + 1
と等価です。
この式は,変数x をデクリメントします。 この式の値は,x の新しい値です。 これは,
x= x - 1 と等価です。
この式は,変数x をインクリメントします。 この式の値は,x の元の値です。
この式は,変数x をデクリメントします。 この式の値は,x の元の値です。 インデックス式をインクリメントすることは,現在のところ可能ではありません。 たとえば,式
v(4)++
は,ベクトルvの4番めの要素をインクリメントすることを期待するでしょう。 しかし,かわりにパースエラーを起こします。 この問題は,Octave の将来のリリースにおいて修正されるでしょう。
演算子の優先順位は,1 つの式の中にさまざまな演算子が近い位置に現れたとき,どのように演算子 をグループにするかを決定します。 たとえば,‘*’ は‘+’よりも高い順位です。 ですから,式a + b * cは,bとcを掛けて,その後でaを加えることを意味します(つまり,a + (b * c))。
かっこを使用することによって,演算子の順序を覆すことができます。 優先順位とは,かっこ自身を書かないときに,かっこを仮定する位置であると言えると思ってください。 事実,あまり使わない演算子の組み合わせをとるところでは,いつでもかっこを使うことが賢明です。 なぜならば,そのプログラムを読む人々は,その場合の計算順位を覚えていないかもしれないからです。 完全に忘れてしまえば,間違いを起こすことになります。 かっこを明記することは,このようなミスを抑える助けになるでしょう。
同じ優先順位の演算子をともに使用するとき,最も左の演算子は,代入とベキ乗演算子(これらは逆向きにグループ化します)を除いて, 最初にグループを作ります。 ですから,式
は,
のようにグループ化しますが,式
は,
のようにグループ化します。
前置する単項演算子の順位は,別の演算子がオペランドの後ろに来るときに重要です。たとえば,
は
という意味になります。なぜならば,‘-’は‘^’よりも順位が低いためです。
Octave における演算子の表を示します。 下に行くほど順位が高くなるようになっています。
ステートメント演算子