sf は 数式での計算もできる、コンソール上で使う電卓です。下のように、文字変数を含む数式を計算できます。
> sf "x=4.8, y=2.1, z = x^-2 + 2 + !exp(3x^2) y " < 2.19106e+030 >x,y などの文字変数には、複素数・行列・ベクタを割り当てられます。x, y, z などの左辺値変数は、変数ファイルとして残ります。別の数式の記述に再利用できます。リピート構文も組み込んであり、数列もベクタ変数として記述できます。ベクタ変数を関数表現に対応させることで、微分・積分関数を計算することもできます。gnuplot などの画像化ソフトと組みわせることでグラフ表示もできます。
sf "3+4" < 7 > sf "3-4" < -1 > sf "3*4" < 12 > sf "1+3/4" < 1.75 > sf "(1+3)/4" < 1 > sf "2*3^4" < 162 >のような具合です。演算記号の優先順位で、べき乗が最優先され、乗除算が次に優先されること、優先順位を変更するには括弧を使うことも普通の数式と同じです。
# 下の計算は二重引用符がないので sf "2*34" の意味になってしまいます。 sf 2*3^4 < 68 >
sf "r=1+0.05" sf "g=9.8"sf の変数ファイルは、下のようなテキスト・ファイルです。人間が参照・変更できます。Perl などで処理できます。
type g.val % BaseDouble 1 < 9.800000000000001 > type r.val % BaseDouble 1 < 1.05 >sf の一番の特徴は、このように計算結果を変数ファイルに残せることです。この変数ファイルを sf で計算させる数式中に記述できることです。下のような式による計算がが可能です。
# 5 % の消費税率のレート r=1.05 を使えば、 1050 円の商品の消費税込みの価格を下の様に計算できます sf 1050 r < 1102.5 > #重力加速度定数 g=9.8 を使えば、4.5 秒後の落下距離は下のように計算できます sf "(1/2) g 4.5^2 < 99.225 >多くの数値から構成される行列やベクタのこのような文字列変数による代数記述することで、行列やベクタを含んだ計算式を簡便に記述できるようになります。
type _dt.val < 99.22500000000001 > # inch 換算の距離を求める sf "_dt*2.54" < 258.483 >配布の sf には組み込み文字列変数として、π 円周率、 真空の誘電率 ε0 などが既に定義してあります。これらを使えば下のような計算ができます。
sf "(1/(4 π ε0)) /g" < 9.17097e+008 >これは、1 メータの距離にある1 クーロンの電荷の間には 9.17 億トンの重さに相当する力が働くことを意味する計算式です。教科書に書かれている数式は実際の数値を計算してみないと、その数式が持つ意味を理解できません。それが判っていても、電卓などで数値を代入して計算する手間と時間を惜しんでしまい、実際の計算を端折ってしまいます。大部分の電気系の技術者が、上の電磁気学の初歩的な計算結果を意外に大きな数値だと思うはずです。sf を活用して、教科書の数式を、より深く理解してくださることを希望します。
sf 2π < 6.28319 > # パウリ行列を使った計算 sf "σx^-3" < 0, 1 > < 1, 0 >なお、下のような = の使い方は、代入させる変数ファイルが作れないのでエラーになります。
sf "3=4" <-- error Regular Pattern match is not detected for "=4"
# t @=2.5 はテンポラリ変数 t を宣言して、2.5 に初期化することを意味します sf "t @=2.5, (1/2) g t^2" < 30.625 >上の計算式で、コロン "," は複数の式を一行に記述するときに使います。C 言語の "," と同じです。
sf 1200 451 311.23 43500 31000 < 76462.2 >のように数値を打ち込むだけで合計を計算できます。ブラインド・タッチができるならば、sf は、ソロバンの有段者以上の計算力をもたらします。読み上げ程度は朝飯前です。人に読み上げてもらう必要がないぶん sf のほうがソロバンよりすぐれています。数値入力だけならば右手だけで十分であり、左手で伝票を捲ることができますから。
sf _dt 1345 212.43 < 78019.7 > sf 1000 _dt < 79019.7 > sf total = 2312 _dt < 81331.7 > sf total * 1.05 + 100 < 85498.2 > sf total < 81331.7 > sf total 2 < 162663 >デフォルトの _dt 変数ではなく totol などの指定した変数ファイルに結果を残したいときは、" 変数名= " によって指定します。このように指定した変数は、sf の計算式で total などの変数名のまま使えます。でも tatal のように数字とスペース以外の文字が入ると、通常の数学のように、スペースは * 演算の意味になります。
sf "(1+2i + 3+4i)" < 4+6i > sf "(1+2i)(3+4i)" < -5+10i > sf "(1+2i)/(3+4i)" < 0.44+0.08i > # sf への組み込み関数は ! で始まります sf "!exp(3+4i)" < -13.1288-15.2008i >なを C++ の標準ライブラリで組み込まれている複素数関数は sf でも扱えます。下のような複素数計算も可能です
sf "!sin(-1+2i)" < -3.16578+1.9596i > sf "!log(-1+2i)" < 0.804719+2.03444i > sf "(-1+2i)^(3+4i)" < -0.00325069+0.000334598i >
# light velosity m/s cL @= 2.99792458e+8 # π 円周率 π @= 3.141592653589793 # プランク定数 h/2π 1.05457266(63)×10-34 J s h` @= 1.05457266e-34 hP @= h` 2 π #ボルツマン定数 J K^-1 K は絶対温度の単位です。Kg ではありません kB @= 1.380662e-23 # Joule/ degree #万有引力定数 G = 6.672 ×10-11 N m^2 kg^-2 cG @= 6.672e-11 #重力加速度 g = 9.80665 m s-2 cg @= 9.80665 #素電荷 e = 1.6021892 ×10-19 C qE @= 1.6021892e-19 ・ ・ # 真空の誘電率 ε0 クーロン**2 / (Newton * M ** 2) ε0 @= 8.854187816e-12上のような sf.ini ファイルが定義されていれば、下の微細構造定数が、数式どおりに計算できてしまいます。
sf "4 π ε0 h` cL / qE^2" < 137.034 >
sf "a @= 2, a<1,4,3> - <2,2,2>/a" < 1, 7, 5 >長いベクトルの要素が等差級数のときは << start, size, stride >> のように簡便に記述できます。start は初期値、size はベクトルの長さ、stride は隣り合う要素の差分値です。ベクタ要素の値が全て 0 のときは << size >> と、より単純に記述できます。
sf "<<0,15,3>>" < 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42 > sf "<<15>>" < 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 >のように、等差級数値を持つ、また要素が 0 の長さ 15 のベクタを簡便に記述できます。
sf <<start, size, stride @tempVar| expression with tempVar>>例えば、下のように、(1+1/n)^n n=1,2,... の数列ベクタ記述できます。ここで、N を大きくしていくと、この数列は常用対数に近づいていきます。
sf "N@=6,<<1,N,1@t|(1+1/t)^t>>" < 2, 2.25, 2.37037, 2.44141, 2.48832, 2.52163 >下のように、(1+1/n)^n n=1,2,.. の収束があまり良くないことまで簡単に分かります
sf "N@=100,<<1,N,1@t|(1+1/t)^t>>" loop count:_n 0 mtrxCommand argment: (1+1/t)^t ・ ・ loop count:_n 99 mtrxCommand argment: (1+1/t)^t < 2, 2.25, 2.37037, 2.44141, 2.48832, 2.52163, 2.5465, 2.56578, ・・ ・ ・ ・・・・ 2.70396, 2.70411, 2.70426, 2.7044, 2.70454, 2.70468, 2.70481 >
# 下の式では t 変数はダミー変数になってしまいます。計算には使っていません。 sf "N@=16, F=<<N>>, F[0]=1,F[1]=1, <<0,N-2,1 @t| F[_n+2] = F[_n+1] + F[_n]>>,F" sf "N@=16, F=<<N>>, F[0]=1,F[1]=1, <<0,N-2,1 @t| F[_n+2] = F[_n+1] + F[_n]>>,F" loop count:_n 0 mtrxCommand argment: F[_n+2]= F[_n+1]+ F[_n] ・ ・ loop count:_n 13 mtrxCommand argment: F[_n+2]= F[_n+1]+ F[_n] < 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987 > sf "N@=100, F=<<N>>, F[0]=1,F[1]=1, <<0,N-2,1 @t| F[_n+2] = F[_n+1] + F[_n]>>,F" loop count:_n 0 mtrxCommand argment: F[_n+2]= F[_n+1]+ F[_n] ・ ・ loop count:_n 97 mtrxCommand argment: F[_n+2]= F[_n+1]+ F[_n] < 1, 1, 2, 3, 5,・・ ・ ・ ・・, 5.16807e+019, 8.36211e+019, 1.35302e+020, 2.18923e+020, 3.54225e+020 >ここで、sf が繰り返し構文のためにデフォルトで用意している、インデックス・テンポラリ変数 _n を使っています。_n は 0,1,...size-1 と変化するインデックス変数です。行列やベクタなどの要素を簡単にアクセスするために設けています。
sf "N=8, vector=<<0,N,2 π/N @t| !sin(t)>>" < 0, 0.707107, 1, 0.707107, 1.22461e-016,-0.707107, -1,-0.70710 >この式は π/N の等差級数により定まる sin(t) の値を要素とするベクトルを意味します。。N の値を 100 とか 256 とかの値にしてプロット数を多くしてやると、コンピュータでグラフ表示したとき sin 関数の形になります。
sf "N=100, π/N !sum(<<0,N,2 π/N @t| !sin(t)>>)" < -5.03299e-015 > sf "N=100, 0.5π/N !sum(<<0,N,0.5π/N @t| !sin(t)>>)" < 0.992125 > < 1.99984 >
//@@ # sin(.) 関数を [0, π) の区間で、台形公式を使って定積分する N @= 100 vect @= <<0,N,0.5π/N @t| !sin(t)>> vect2 @= vect #下の二行は、最初に私が犯した誤り #vect2 @= !shift(vect) #vect[N-1]=0 #左端をなくして右端を追加する vect2[0] = !sin(0.5π) 0.5π/N !sum(vect + vect2) /2 //@@@ //copy \#####.### temp.se /y //sf @@temp < 0.999979 >ここで、//@@, //@@@ の記号がでてきます。これは 「//@@ から //@@@ までの間の文字列を内容とする \#####.### の名前のファイル作成する」 との意味に解釈してください。。そして //@@@ に続く、先頭が // であるコマンド行 copy \#####.### temp.se /y と sf @@temp を続けて実行させていると解釈してください。以後何度も、この略記法を使います
//@@ # -ΔT/2 から ΔT/2 までを計算する ΔT @= 1 ωs @= 2 π/ΔT func = <<100>> <<0,10,1 @n| func = func + <<-ΔT/2, 100, ΔT/100 @t| !exp(i n ωs t)>> >> func = !abs(func) func = !print(plot "-" using 1:2) //@@@ //copy \#####.### temp.se /y //sf @@temp //gnpltDt.exe func.val > gnuplot.ini //start \ap\gnuplot\wgnupl32.exeこのsf 計算例は exp(i n ωt) の関数を n=0,1,... で足しあわせてやるとδ関数に近づいていく様子をシミュレーションしています。sf の !print(...) コマンドは、下のような #g に !print(...) の引数を加えたコメント文字列をを func.val ファイル変数に追加します。
type func.val #g plot "-" using 1:2 % BaseDouble 100 < 6.123031769111885e-016, 0.3091695508850632, ・・・, 0.3091695508850451 >添付の gnpltDt.exe プログラムは、sf のベクタ・ファイル変数テキスト・ファイルをしたのように変換します。#g plot "-" using 1:2 部分は #g を取り去って gnuplot 側に渡されます。
type gnuplot.ini plot "-" using 1:2 0 6.123031769111885e-016 0 1 0.3091695508850632 0 2 0.5889474054649219 0 ・ ・ 99 0.3091695508850451 0Excel でグラフ表示させたいときには、ベクタ・ファイル変数テキスト・ファイルを CSV 形式のテキスト・ファイルに変換してやれば良いはずだと考えます。(実際には行っていません。Excel を使ったいると胃が痛くなるほど Excel が嫌いなので許してください。)
type Poisson.sf _rt = _prm1 _prm2 - _prm2 _prm1 sf @Poisson(σx, σy) < 2i, 0 > < 0, -2i > sf @Poisson(σx σz, σy) < 0, 0 > < 0, 0 > # Pauli 行列 σx,σy,σz は sf.ini に定義してあります sf σx < 0, 1 > < 1, 0 > sf σx < 0, 1 > < 1, 0 > sf σz < 1, 0 > < 0, -1 >sf のサブルーチン・ファイルをユーザーが自分で記述するとき _rt に戻り値を設定することを忘れないで下さい。戻り値がなくなってしまいます。
# サイズ 3 の 0 要素ベクタ変数 vector.val を生成します sf "vector = <<3>>" < 0, 0, 0 > # ベクタ最後の要素を 1 にする sf ”vector[2] = 1" < 0, 0, 1 > # 3x3 の 0 要素行列(変数ファイル)を生成する sf "Matrix = [[3]]" < 0, 0, 0 > < 0, 0, 0 > < 0, 0, 0 > # 最初の列を <1,2,3> にする sf "Matrix[*,0] = <1,2,3>" < 1, 0, 0 > < 2, 0, 0 > < 3, 0, 0 > # 最初の行を <3,4,5> にする sf "Matrix[2,*] = <3,4,5>" < 1, 0, 0 > < 2, 0, 0 > < 3, 4, 5 > # 儀容列の対角要素を <6,7,8> にする sf "Matrix[*,*] = <6,7,8>" < 6, 0, 0 > < 2, 7, 0 > < 3, 4, 8 > # 行列をベクタにを作用させる sf Matrix vector < 0, 0, 5 > # 3x4 の 0 要素行列(変数ファイル)を生成する sf "Matrix = [[3,4]]" < 0, 0, 0, 0 > < 0, 0, 0, 0 > < 0, 0, 0, 0 >
sf "temp = <<3>>" sf "temp[0] = 1" < 1, 0, 0 > sf "temp[1] = !exp(2)" < 1, 7.38906, 0 >なお、sf のベクタや行列のインデックスは 0 から始まるものとしています。 C 言語の配列と同じです。
vector[ベクタのインデックスを start から初めて、stride ずつ size 回だけ増やしていき、そのインデックス値群により定まる部分ベクタを指定します。例えば、長さ 10 のベクタの 1,3,5,7 要素に、1,2,3,4 の数値を代入する操作は下の様に行えます。さらに続けて 0,4,8 要素に 5,6,7 の数値を代入します。]
sf "vector = <<10>>" < 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 > sf "vector[<1,4,2>] = <1,2,3,4>" < 0, 1, 0, 2, 0, 3, 0, 4, 0, 0 > sf "vector[<0,3,4>] = <5,6,7>" < 5, 1, 0, 2, 6, 3, 0, 4, 7, 0 >このベクタの三番目から七番目まで 5 この要素をを連続して読み出したければ、stride を 1 にして、したのように記述します。
sf "vector[<2,5,1>]" < 0, 2, 6, 3, 0 >インデックスは 0 から始まるので三番目の要素はインデックス 2 で指定されます。なれるまでは判りにくいと思います。自分で上の数値を変えがら、上の操作を色々と行うってみることで判るはずです。
sf Matrix = [[5]] < 0, 0, 0, 0, 0 > < 0, 0, 0, 0, 0 > < 0, 0, 0, 0, 0 > < 0, 0, 0, 0, 0 > < 0, 0, 0, 0, 0 > # 対角要素の最初の四つを 1,2,3,4 にする sf "Matrix[<0,4,5+1>] = <1,2,3,4>" < 1, 0, 0, 0, 0 > < 0, 2, 0, 0, 0 > < 0, 0, 3, 0, 0 > < 0, 0, 0, 4, 0 > < 0, 0, 0, 0, 0 > # 対角要素から一つ右上の四つ斜め要素を 5,6,7,8 にする sf "Matrix[<1,4,5+1>] = <5,6,7,8>" < 1, 5, 0, 0, 0 > < 0, 2, 6, 0, 0 > < 0, 0, 3, 7, 0 > < 0, 0, 0, 4, 8 > < 0, 0, 0, 0, 0 > # 右上から左下への対角要素を 11,12,13,14,15 にする sf "Matrix[<4,5,5-1>] = <11,12,13,14,15>" < 1, 5, 0, 0, 11 > < 0, 2, 6, 12, 0 > < 0, 0, 13, 7, 0 > < 0, 14, 0, 4, 8 > < 15, 0, 0, 0, 0 > # 5 行目の 2 列目以降の連続する三つの要素を 21,22,23 にする sf "Matrix[<5*(5-1)+3-1,3,1>] = <21,22,23>" < 1, 5, 0, 0, 11 > < 0, 2, 6, 12, 0 > < 0, 0, 13, 7, 0 > < 0, 14, 0, 4, 8 > < 15, 0, 21, 22, 23 > # 行列の 2 列目と 3 列目の二つより長さ 10 のベクトルを取り出す sf "Matrix[<(2-1)*5,10,1>]" < 0, 2, 6, 12, 0, 0, 0, 13, 7, 0 >行列部分要素を slice array を使ってアクセスすることは、ベクタのときより、判りにくいとも思います。上の例で様々の数値を入れて納得するまで操作してみてください。slice array に慣れれば、規則性のある部分行列要素へのアクセスを簡単に記述できますから。
# binary 表記 0b ..._... で、人間が分かり易くするため 1 と 0 の羅列の間に '_' を自由に配置できる。 sf 0x = 0x24 + 12 + 0b1011_1100 0xec 図 1.3:2計算結果は履歴も含め、無限にスクロールできる黒板であるコンソールに残っています。一々計算結果をメモに写す必要もありません。
sf では行列要素のアクセスに、プログラマーにはなじみやすい slice array の考え方を使えます。STL の valarray で定義されている slice_array です。Vector/Matrix[<start, size, stride>] によって、行列要素を valarray ベクトルとして一列に並べたときの要素から、start から始まる stride ごとの size 分の要素を指定します。
vector[<1,4,2>] ○ ● ○ ● ○ ● ○ ● ○ start │ ↑ │<-- stride -->│ size 四個目 sf "vector =<0,1,2,3,4,5,6,7,8>" # 要素が 0...8 のvector 変数 < 0, 1, 2, 3, 4, 5, 6, 7, 8 > sf "vector[<1,4,2>] =<10,11,12,13>" < 0, 10, 2, 11, 4, 12, 6, 13, 8 > 図 1.3:3slice array を使った記述は、多くの 0 要素を持つ行列のときに威力を発揮します。
sf "Matrix = [[4]]" < 0, 0, 0, 0 > < 0, 0, 0, 0 > < 0, 0, 0, 0 > < 0, 0, 0, 0 > sf "Matrix[*,*] = <1,2,3,4>" # 正方行列の対角成分は Matrix[*,*] で指定できる < 1, 0, 0, 0 > # 4x4 行列ではsf Matrix[0,4,5] としても Matrix[*,*]と同じ < 0, 2, 0, 0 > # 対角成分を <1,2,3,4> ベクトルで置き換える < 0, 0, 3, 0 > < 0, 0, 0, 4 > sf "Matrix[<1,3,5>] = <7,8,9>" # 対角成分の一つ上側の斜め列を <7,8,9> ベクトルで置き換える < 1, 7, 0, 0 > < 0, 2, 8, 0 > < 0, 0, 3, 9 > < 0, 0, 0, 4 > 図 1.3:4slice array の考え方は少し複雑ですが、多くの規則性の有るスパーシティの高い行列要素操作するときには威力のある記述法です。
>type matrix.val % BaseDoubleMatrix 4, 4 < 1, 7, 0, 0 > < 0, 2, 8, 0 > < 0, 0, 3, 9 > < 0, 0, 0, 4 > 図 1.3:4計算結果が、このようなテキスト・ファイですから、プログラマーであれば自由に細工できます。計算結果入ったベクタ・テキスト・ファイルを gnuplot で表示するようなフィルタ・プログラムは簡単に作れます。そのフィルタ・プログラムも作ってありますが、自分で Exel でのグラフ表示に適した向きのフィルタ・プログラムを作ることも容易なはずです。
//@@ m @= 0.55 η @= 3787073 <<0,200,10000@t| 1- !exp(-(t/η)^m) >> !print(plot "-" using 1:2) //@@@ //sf @\#####.### //\gnpltDt.exe _dt.val > gnuplot.ini //start \ap\gnuplot\wgnupl32.exe上のように、指数関数を !exp で表し、m と ηの値を指定してことでワイブル分布関数のグラフを見ることができます。m < 1 ならば、初期故障が発生しやすい装置の故障分布であることが分かります。上の式はハード・ディスクの累積故障率のワイブル分布です。理系の教科書を読んでいるとき、数式の洪水に飲み込まれて分からなくなってしまうことが多くあります。このように実際の数値を代入し計算して具体例を補ってやることで、書かれている内容をより的確に読み取れるようになります。
T=1, z=1 T/2(1+z^-1)/(1-z^-1) = T/2 (1 + 2z^-1/(1-z^-1)上の左右の式が同じ値になることを sf で確認すれば、式の変形に間違いが入りこまなかったと自身を持てます。また逆に誤りが入り込んだ式を特定できます。
float(sin(2.1*%pi)); at Maxima のように余分な float を叩く必要はありません
Boltzman constarnt Dirack constanc, 誘電率 exe ファイルは visual C で作る必要はありません。gcc でも intel C++ fortran でもかまいません。 sf はMathamatica などのソフトを使っていらっしゃる方にも有用なはずです。sf は数値計算ソフトでの perl や 1 liner gnuplot などのグラフ表示ソフトと組み合わせれば計算結果をグラフとしても表示できます。行列サイズは、コンピュータのメモリによる制限できまります。、仮想メモリを含みます。とくに、ソフト上は制限もチェックもしておりません。tensor や行列の行列なども indexed file により扱えます。sf で十数行までの script を記述して使います。perl などと同じに考えてください。<-- 100 行を超える sf script は避けるべき。C++/Matrix library で記述すべきです。console からユーザーが interruptive に操作して使っていくものです。 <-- 100 行を超えるときは、真剣に C++ で記述することを検討してください。 reduce などの数式処理言語は実際に使っていらっしゃるのは限られるでしょう。日常の単純な数式変形でも sf を活用できます。数式を実行させて同じ値であることを確認すれば良いのですから。sf は単なるコマンド実行プログラムです。コマンド引数に計算式を記述します。計算結果はコンソールに出力されると同時に"変数名.val"ファイルにも記録されます。そのファイルを変数とする演算もできるので、組み合わせにより複雑な計算式や、状態を持った計算が実行可能です。変数ファイルはテキスト・ファイルですから、他のソフトと自由に組み合わせられます。gnuplot などと組み合わせればグラフ表示も可能です。kVerifier のテストを適用した実用例でもあり、テストも含めてソースも公開しております。テスト付ですので、プログラムの素養のある方でしたら、自分専用に sf.exe をカスタマイズできます。
sf.exe はプログラマーや理系の研究者・技術者向けの計算ツールです。日常的にコンソールからコンピューター操作をしている方のための計算ツールです。sf !log(3) などとコマンドを打ち込むだけで実行できます。マウス・クリックなどにより統合環境を立ち上げる必要はありません。電卓を一々取り出す必要もありません。パスの切ってあるディレクトリに sf.exe を置いておくだけです。
ただし、sf は kVeriifer の advertizing software であり、VcVrfyMDdLt08.zip ファイルを sf.exe と同じディレクトリに置いてあるときのみ動作するように作ってあります。VcVrfyMDdLt08.zip も解凍して読んでくださることを希望します。
sf は数値だけではなく変数も計算の対象にできます。下のような光速や円周率を表す c.val/π.val 変数ファイルを作っておけば、それらの文字を使った演算式での計算が可能です。
>type c.val % BaseDouble 1 # 光速 c = 2.99792458 ×108 m s-1 <2.99792458e8> >type π.val % BaseDouble 1 # π 円周率 < 3.141592653589793 >次のように変数を使った計算を行なわせられます
>sf 2π c**2 < 5.64705e+017 > >sf rs=!sin(π/4) < 0.707107 >上の計算式では sf の計算結果は rs.val に 16 桁精度の整数として残ります。デファルとの 6 桁以上の精度で数値を見たいときには、rs.val を type します。
計算式に左値 "rs=" がないときには、デフォルト左値 _dt.val に計算結果が残ります。_dt を計算式中に入れることで、直前の計算結果を取り込んだ計算が可能です。なお、_dt.val が変更されるのは = を含まない計算式のときに限られます。
計算頻度の多い足し算については「数字とスペースのみからなる数式はスペースを足し算と見なす」便法を設けています。」変数や関数が含まれる式は通常どおりスペースは積と見なされます。
>sf 1 2 3 4 5 6 7 8 9 10 < 55 >上の便法は、より厳密には「数字とスペースのみからなる数式(数式の最初、または最後には _dtをおくこともできる)はスペースを足し算と見なす」便法を設けています。」となります。_dt を追加することで、前回の計算結果に足し算を追加した総計を計算することが可能になります。
>sf 11 12 _dt < 78 >プログラマーが良く使う 16 進数は 0x で始めることで記述します。C 言語とおなじです。計算結果を 16 進数にしたいときは、左値を 0x = にします。
>sf 0x10 + 0x20 < 48 > >sf 0x = 0x20 + 16 0x30sf はベクトルや行列も扱えます。ベクトルは < > で囲って表現します。下のようにベクトル演算を行ないます。< のような文字が入ってくると、そのままではコマンドラインのリダイレクトと解釈されるので "..." と引用筆で囲みます
>sf "a = <1,3, 5>" # 変数 a を三次元ベクトル値 1,3,5 を持つベクトルにします < 1, 3, 5 > >sf "b = 2 a" # < 2, 6, 10 > >sf "<a ¦ b>" # 内積演算です < 70 > >sf "<a ¦ Matrix ¦ b>" # 行列をはさんだ内積演算です行列についてはコマンドラインから扱えるのは 0 初期値での行列の生成、i 行、j 列, 、i,j 要素、slice array のような start, size, stride 三要素によるアクセスに限定されます。以下のような操作になります。
>sf "test = [[4,3]]" # 4 x 3 行列を生成し 0 に初期化する < 0, 0, 0 > < 0, 0, 0 > < 0, 0, 0 > < 0, 0, 0 > > >sf " test[*,2] = <4,4,4,4>>" # 2 列目に <4,4,4,4> を代入する < 0, 0, 4 > < 0, 0, 4 > < 0, 0, 4 > < 0, 0, 4 > #<<5,3,1>> は slice array と同様に 5:start, 3:size, 1:stride を意味します。<<5,3,1>> == <5,6,7> です。 >sf " test[2,*] = <<5,3,1>>" # 3 行目に <5,6,7> を代入する < 0, 0, 4 > < 0, 0, 4 > < 5, 6, 7 > < 0, 0, 4 > >sf " test[1,1] = 10" # 1,1 要素に 10 を代入する < 0, 0, 4 > < 0, 10, 4 > < 5, 6, 7 > < 0, 0, 4 > >sf test b < 40, 100, 116, 40 > # 行列 test.val と前に作ったベクタ b.val を掛ける
行列が C に言語にあわせて 0,0 から始っています。1,1 からではありません。Fortran に慣れた人には違和感があるかもしれません。C/C++ プログラムに適用する kVeriier の advetising software であり、C/C++ 記述方法を優先します。
二項演算子 real op real = real, real op complex == complex first │scalar scalar scalar vector vector vector matrix matrix matrix second│scalar vector matrix scalar vector matrix scalar vector matrix ──────────────────────────────────── + │ ○ × × × ○a × × × ○a - │ ○ × × × ○a × × × ○a * │ ○ ○ ○ ○ ○a × ○ ○b ○a / │ ○ × × ○ × × ○ × × ^ │ ○ × × × × × ○d × × <v|w> │ × × × × ○a × × × × <|M|v>│ × × × × × × × ○b × 但し書き a same vector size, same column/row size b restricted to vector size = matrix row size a square matrix に限る d only sqaure,power 値は整数に変換される。負の power 値は逆行列がある
○ 単項関数 │real │complex │ │scalar vector matrix│scalar vector matrix│備考 ───┼──────────┼──────────┼────────── !abs │ ○ ○ ○ │ ○ ○ ○ │real の非負値になる !det │ × × ○a │ × × ○a │ !sin │ ○ ○ ○ │ ○ ○ ○ │ !cos │ ○ ○ ○ │ ○ ○ ○ │ !tan │ ○ ○ ○ │ ○ ○ ○ │ !sinh │ ○ ○ ○ │ ○ ○ ○ │ !cosh │ ○ ○ ○ │ ○ ○ ○ │ !tanh │ ○ ○ ○ │ ○ ○ ○ │ !exp │ ○ ○ ○ │ ○ ○ ○ │ !log │ ○ ○ ○ │ ○ ○ ○ │minus 引数は複素数を返す !asin │ ○ ○ ○ │ ○ ○ ○ │ !acos │ ○ ○ ○ │ ○ ○ ○ │ !atan │ ○ ○ ○ │ ○ ○ ○ │ !log10│ ○ ○ ○ │ ○ ○ ○ │minus 引数は複素数を返す !norm │ ○ ○ ○ │ ○ ○ ○ │vector, 行列を real 非負値にする !fft │ ○ ○ ○ │ ○ ○ ○ │行列は横ベクトルごとに fft を施す !rft │ ○ ○ ○ │ ○ ○ ○ │行列は横ベクトルごとに rft を施す !shift│ ○ ○ ○ │ ○ ○ ○ │行列は横ベクトルごとに shift を施す !dggr │ ○b1 ○b1 ○b2│ ○b3 ○b3 ○ │ !realr│ ○ ○ ○ │ ○ ○ ○ │ !image│ ○ ○ ○ │ ○ ○ ○ │ !size │ ○ ○ ○ │ ○ ○ ○ │ !floor│ ○ ○ ○ │ ○ ○ ○ │ !sign │ ○ ○ ○ │ ○ ○ ○ │ !sqrt │ ○ ○ ○ │ ○ ○ ○ │ !sum │ ○ ○ ○ │ ○ ○ ○ │ !prdct│ ○ ○ ○ │ ○ ○ ○ │ a square matrix に限る b 1 no nopration 2 only transpose 3 only conjugate
sf "matrx=[[5]]" sf "matrx[*,*]=<1,2,3,4,5>"と
sf "matrx=[[5]]"matrx[*,*]=<1,2,3,4,5>"は同じ計算を行います。きまった計算手順は一行で書いておいたほうが、エディタで一行コピーしたあとに、式を変形する時間を短くできます。でも、これより複雑な C 言語での for loop のような記述をしたくなりことが多くあります。これは index 変数による記述を導入することで実現します。、サイズの大きなベクタは短い式で記述することが望まれます。slice array で記述できるような規則性を持ったベクタは << , , >> 記述により表現できます。
sf "temp = <<1,10,2>>" sf "temp = < 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 >の二つの式は、同じ計算式です。
sf "temp=!log10(<<1,5,2>>)" sf "temp=< !log10(1), !log10(3), !log10(5), !log10(7), !log10(9) >"の二つの式も、同じ計算式です。でも、使える関数は sf にビルト・インされた基本関数に限られてしまいます。temporary 変数を導入することで、任意関数のベクトル表現を可能にしています。
sf "vector=<<5>>;n@@<0,1,2,3,4>;vector[n] = n^2" < 0, 0, 0, 0, 0 > loopCount:1 n.val: 0 < 0, 0, 4, 0, 0 > loopCount:2 n.val: 1 < 0, 0, 4, 0, 0 > loopCount:3 n.val: 2 < 0, 0, 4, 0, 0 > loopCount:4 n.val: 3 < 0, 0, 4, 0, 0 > loopCount:5 n.val: 4 < 0, 0, 4, 0, 0 >上の計算式は n^2 の 要素をもつベクトルを作っています。同じ処理を下のようにも記述できます。
sf "vector=<<5>>;n@@<<0,5,1>>;vector[n] = n^2"計算式を複数書いたり、index ループをネスティングさせることも可能です。下のようにも記述できます。
sf "matrix=[[4]];j@@<<0,4,1>>;k@@<<0,4,1>>;matrix[j,k] = j^2 + k"なお、インデックスとして i 変数は使わないでください。sf では i は複素数を意味してしまうからです。i0 のような変数名ならば使えます。この例で使われたインデックス変数 n や j,kは、実際に変数ファイル n.val として生成されます。繰り返しのたびに、実際に書き込み、また読み出されます。繰り返しの数が多くなると、ファイルの読み書きの時間が重くなってきます。
@<< start, size, stride @ _t |計算式 >>の記述を容易しています。例を示します。下は sinc() 関数のベクタを生成しています。
sf "<<0.01,100,0.01 @ _t | !sin( _t) / _t>>現在のところ temporary 変数としては _t しか使えません。これでも多くの用途で使えるはずです。なお、temporay 変数はファイル _t.val は生成されません。index ループより高速に動作します。
sf では上に述べた繰り返し記述をサポートしていますが if then else のような条件判断を伴う構文はサポートしていません。sf は計算式処理を容易にすることを目指していますが、計算式プログラミングは目指していません。条件判断をさせるプログラム構文で記述したいときは C++ プログラムを使うべきと考えています。valarray<.> や、数値計算ライブラリを使えば C++ でも行列やベクタを容易に扱えると考えます。If then else が入るような複雑な処理のためには、デバッグ環境が必要になります。そのためには C/C++ のデバッグ環境を使うことが効率的です。新しいデバッグ環境を勉強する時間、環境を開発する時間は無駄だと考えます。
sf はデバッグ作業を必要としないような単純な計算を容易にするためのツールを目指しています。実際の計算では、そのようなものの方が多いはずです。
>type ExpMt.bat sf "I=(%1)^0; _rs = I +%1(I+%1/2(I+%1/3(I+%1/4(I+%1/5(I+%1/6(I+%1/7(I+%1/8 (I+%1/9(I+%1/10(I+%1/11(I+%1/12(I+%1/13(I+%1/14(I+%1/15(I+%1/16(I+%1/17 (I+%1/18(I+%1/19(I+%1/20)))))))))))))))))))" (実際に使うときは CR を取り一行にして下さい)下のように使えます。
sf "X=[[2]];X[<0,4,1>] = < i, -3, 3, -i>" sf XU = ~ExpMt.bat(X) < -0.999786-0.00654071i, 0.0196221 > < -0.0196221, -0.999786+0.00654071i > # 確認 sf !dggr(XU) XU < 1, 0 > < 0, 1 >sf での変数ファイルは文字列です。_rs.val に値を返せならば UserFunction は何で記述されていてもかまいません。 <-- _rs は ファイル変数 <-- nexting による変数の _rs 変数の書き換えがある。 <-- nexting による変数の _rs の temporay 変数へのコピーするか否かはユーザーの選択です
----------------- 未定トピックス -----------------------
1e+3 <-- 2e3 は 2* e3.val variable の意味になる
ちなみに h`.val があれば >sf 3 h`.val のようにも記述できる。意味は無いでしょうが。
sf z@, のような temporary 変数のみを宣言することも許す
//sf z@, z = 3, z + 4 でも 7 となるし、z.val file は壊れない
..sf doc c、ε0, μ0, h` (h bar) G 万有引力乗数などの物理乗数ファイルを、作業ディレクトリごとに作っておけば、公式のまま物理値を計算できます。
..sf doc sf はユーザーがお使いのエディターで数式を記述することを前提としています。エディタをキーボードのホームポジションから操作されているならば、そのまま sf の数式を記述するときにも使えます。数式記述モードや、ファンクションキー、マウスなどの使用を強制することはありません。
..sf doc sf がテキスト入力であるため、行列のように多くのデーターが必要なときは、ユーザーが入力手段を選択できます。cut and paste, perl filter などが使えます。
..sf doc スペースで積の演算にできるだけでも重宝します。変数の最後に ',` を追加できます。Windows では temporary 変数に限りますが、大文字、小文字を区別します。日本語(Windows では Shift JIS)に限りますが 先頭の一文字にはギリシャ文字を使用できます。
..sf doc sf では再利用される結果は"変数.val"ファイルとして残ります。プロジェクト・ファイルではありません。"変数.val" を別のディレクトリにコピーするだけで、再計算することなく、以前に計算結果を再利用できます。ファイルとして残ることは、OS のファイル操作コマンドを利用できることを意味します。"変数.val" に Read only 属性を持たせれば、通常の操作では壊れなくなります。上書きされることはなくなります。"変数.val" を別の名前に rename するだけで、前の計算結果との衝突なく新しい結果を残せます。これらの操作を普通のファイル操作として実行できます。これらの操作のために新たなコマンドを覚える必要はありません。使い慣れたファイラーによる操作も可能です。
..sf doc 計算速度が不満だったら、se2 を活用する、または複数のコンピュータで並列して計算するような exe file を作り、そちらで計算させられます。
..sf doc 理系の教科書や論文では数式が多く出てきます。書くほうにとって、文章では説明しきれないことを数式で表現します。読むほうも、冗長な文章の変わりに数式で理解する必要があります。でも単純な数式ばかりではありません。少し複雑なものになると、著者が言おうとしている数式の一部しか読み取れなくなります。それが積み重なったとき、何を言っているかわからなくなります。理系の多くの教科書、論文が読んでも理解できないときの多くは数式の理解が不十分なためです。
量子力学でのように数式が解っても概念が理解できないものもありますが、このようなことは少数です。量子理化学ほど、概念把握が難しいものを作り上げるような頭の良い学者は全世界合わせても限られてしまいますから。
..sf doc 自分で c/c++ プログラムが書けるならば、mathematica 以上のことができる
start c:\job\vrfy\doc\exprt\sf.htm