■■ sf: scientific formula calculator ■■

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 は素早く結果を得られるように作ってあります。コマンド引数自体に数式を記述します。コンソールをホワイト・ボードのように使い、数式を書きあげ、コンピュータに計算させます。sf 専用のインターフェース・ウィンドウを立ち上げることはありません。計算のたびに入力インターフェース・ウィンドウを立ち上げていたのでは、その時間は思考の妨げでしかありません。

単純に16/10/2 進数の加減乗除算を "sf 0x=0x324 + 15 - 0b1101_0010" (この計算を行わせる 0x261 をコンソールに表示します)などとキーボードからタイピングするだけで行えることだけでも、sf が有用なことを理解してもらえるはずです。

自分でプログラムできる方ならば、sf 向けの実行ファイルを作成できます。 LAPACK などの行列ライブラリから sf 向けの実行ファイルを作ることで、sf に自由に行列計算パッケージを組み込みことが可能です。

残念なことですが sf を使いこなすには、コンソール操作の壁があります。誰でも扱える GUI マウス操作ではありません。でも、sf のコンソール操作に壁を感じたとしても、少し我慢をして挑戦してくださることを希望します。タッチ・タイプができればコンソール操作は難しいものではありません。慣れてしまえば、マウス操作が煩わしくなるほどに便利なものです。sf のような計算ソフトでは CUI が適していることを体得できると思います。Windows のアクセサリとして標準で備わっている GUI 電卓ソフトが、計算を効率的に行うには不合理だと納得できるはずです。そこで得た CUI 操作は、sf 以外のソフトを使うときにも、コンピュータ操作を簡単にしてくれます。

sf は kVerifier の例題に使う宣伝用ソフトとしてソースと共に公開しますが、登録料 5000 円の有償ソフトとします。(高級電卓代金だと思ってください。) sf だけでも、有償とする価値のある計算ツールにできたと自負しています。GPL で配布されている Maxima と組み合わせて使えば、Mathematica や Matlab 同等以上のことが可能です。


■ sf 速習 ■

△加減乗除演算
sf での加減上除算は普通の数式と同様に +, -, *, / 記号を使います。べき乗は ^ 記号を使います。コマンドライン引数に計算式の文字列を与えて、sf.exe を実行させることで計算を行わせます。コマンド・プロンプト上で下のように実行させます
    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 >
のような具合です。演算記号の優先順位で、べき乗が最優先され、乗除算が次に優先されること、優先順位を変更するには括弧を使うことも普通の数式と同じです。
二重引用符の記号は省略できることも多いのですが、Windows のコマンドラインでは二重引用符がないと意味が変わってしまうことが多くあるので、慣れないうちは、無条件に引数の最初と最後に二重引用符を付けることを勧めます。

例えば Windows では二重引用符がないとき、コマンドラインに記述された ^ 記号は消されてしまいます。
    # 下の計算は二重引用符がないので sf "2*34" の意味になってしまいます。
    sf 2*3^4
    < 68 >
△ファイル文字変数
sf では = を文字変数ファイルへの代入演算子として扱います。下のように sf を実行すると、g.val と r.val の名前の変数ファイルがカレント・ディレクトリに生成されます。既に、ファイルが既に存在するときは、その値部分が変更されます。
   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 >
多くの数値から構成される行列やベクタのこのような文字列変数による代数記述することで、行列やベクタを含んだ計算式を簡便に記述できるようになります。

なお sf では = を含まない計算式のときは、_dt = があるものと暗黙のうちに仮定します。上の sf "(1/2) g 4.5^2" を計算させると、下の _dt.val 変数ファイルができています。もちろん、この _dt ファイル変数は sf の計算式の中に記述できます。
    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.ini テキスト・ファイルに宣言・定義してある変数であり、ユーザ側で自由に追加・修正できます。

日本語 OS のユーザーに限られますが、変数文字列の先頭一文字だけはギリシャ文字を使えます。下の様に、日常で使う数式の記述により近い形式で、計算式を記述できます。
    sf 2π
    < 6.28319 >

    # パウリ行列を使った計算
    sf "σx^-3"
    < 0, 1 >
    < 1, 0 >
なお、下のような = の使い方は、代入させる変数ファイルが作れないのでエラーになります。
    sf "3=4"
    <-- error
    Regular Pattern match is not detected 
        for "=4"

△テンポラリ文字変数
一時的にしか使わない変数のためにテンポラリ変数を用意してあります。HDD のカレント・ディレクトリに設けられるファイル変数とは異なり、コンピュータのヒープ・メモリ上にダイナミックに設けられる変数です。HDD 上に不必要なファイル変数を残しません。 下のようにテンポラリ変数を使うと、より公式に近い数式を使って、計算することができます。 @= がテンポラリ変数を宣言・定義する構文です。
    # t @=2.5 はテンポラリ変数 t を宣言して、2.5 に初期化することを意味します
    sf "t @=2.5, (1/2) g t^2"
    < 30.625 >
上の計算式で、コロン "," は複数の式を一行に記述するときに使います。C 言語の "," と同じです。
テンポラリ変数を使えば、大文字と小文字を区別できるようになるメリットもあります。Window OS では大文字と小文字の区別ができないため、ファイル変数は大文字・小文字による変数の区別はできません。
△足し算の特別ルール
sf では、数式を記述するときと同様に演算子を省略したときは積の * 演算子を自動的に挿入します。でも足し算だけの数値計算のとき、スペースを + 演算子とみなす便法を適用します。合計数値を求めて、足し算だけを多く行うときのためです。
    sf 1200 451 311.23 43500 31000
    < 76462.2 >
のように数値を打ち込むだけで合計を計算できます。ブラインド・タッチができるならば、sf は、ソロバンの有段者以上の計算力をもたらします。読み上げ程度は朝飯前です。人に読み上げてもらう必要がないぶん sf のほうがソロバンよりすぐれています。数値入力だけならば右手だけで十分であり、左手で伝票を捲ることができますから。
sf の数値入力はコマンド・ラインから行います。数値入力データーの履歴はコンソール画面に残っています。入力数値に誤りがなかったか、後で再確認ができます。

sf では、デフォルトの結果は _dt.val 変数に入ります。_dt が最初、または最後にあるときに限って、その他の入力が数字とスペースに限られていれば、スペースを + 演算してみなします。前回の足し算の結果に追加していくことができます。
    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 を使って日常の業務を効率的に、気持ちよく済ませてください。

△複素数
sf では数学での記述と同様に記号 'i' を使って複素数を記述できます。関数の引数にも複素数を使えます。
    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 >

△sf.ini ファイルとデフォルト・テンポラリ変数
πなどの何時も使う変数は、カレント・ディレクトリのテキスト・ファイル sf.ini に、あらかじめテンポラリ変数として宣言しておけます。sf が動作を開始するとき、最初に sf.ini を読み取り、テンポラリ変数を宣言・定義します。
    # 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 では <1,4,3> のように < と > で数値列を囲むことで、ベクトル値を表現します。ベクトル同士の加減算、ベクトルとスカラー変数との乗除算も可能です。
    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 >
△アルゴリズムにより定まる数列ベクタ
sf の繰り返し構文を使えば、アルゴリズムにより定まる数列ベクタも簡便に記述できます。F[n+2] = F[n+1] + F[n] のような漸化式でアルゴリズムで表現されるフィボナッチ数列のベクタも、下のように簡単に記述できます。C 言語などを持ち出すまでもありません。
    # 下の式では 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 の繰り返し構文 sf <<start, size, stride @tempVar| expression with tempVar>> の expression には sf で計算可能な任意の数式・関数を記述できます。これを利用して、任意の関数をベクタ数値列として表現できます。
    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 はベクタ要素全部を足し合わせるの !sum(.) 関数があります。これを利用すれば、関数の定積分の近似値を求められます
    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 >
△ブロック実行ファイル
sf は、計算式の数が多い、コメントを書いておきたいなどのために、テキスト・ファイルに計算式を複数行書いておき、連続して実行する機能を持っています。

先の sin(.) 関数の定積分を台形公式を使うことで精度を上げてみます。改行とコメントを入れることができるため、式の意味が分かり易くなります。
//@@
    # 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 を続けて実行させていると解釈してください。以後何度も、この略記法を使います

この作業をマニュアルで実際に行ってもかまいませんが、お使いのエディタに、このようなマクロを組み込んでしまうことを強く勧めます。私自身は WZ エディタのマクロでこれを実現しています。詳細はコンソール操作の勧めを参照願います。

ブロック実行ファイルのデフォルトの拡張子は se です。sf @@temp のように拡張子が無いファイルを指定されたときは、自動的に se 拡張子を補って temp.se ファイルを探し実行します。se 以外の拡張子を使うときは、ユーザーが明示的に記述します

具体例を作って実際に計算させてみると、教科書を読んでいるだけでは見逃してしまう、本質的な点に気づかされます。sf は、この計算作業を簡単に実行できるようにします。上の台形公式による定積分の計算を C 言語などでやろうとすると、プログラムのデバッグ作業という、余分な作業が入りこんでしまいます。本来の数学を理解することから離れた作業を強いられます。sf を使うと数学での作業だけで済みます。

この台形公式を使った積分では、新規に右端の値を追加することが精度を上げるために必要であることに気づかされました。最初は単純に vect をシフトしたものを vect2 としたため、単純な区分求積方より精度の悪い結果となりました。台形公式による積分を誤って理解していた気づかされました。
△関数グラフ表示
sf での計算結果は、拡張子が val である、テキスト・ファイルであるファイル変数に書かれた数値の集まりとして残ります。その数値の集まりを gnuplot や Excel などのグラフ表示可能なデータに変形してやればグラフ表示が可能になります。

表示可能なデータへの変形は Perl, Ruby など、お好きなフィルタ言語が使えます。sf での計算結果はテキスト・ファイルであるファイル変数ですから。私自身は、多くの場合、自分の kreg C++ 正規表現ライブラリを使っています。sf のベクタ変数テキスト・ファイルを gnuplot で扱えるデータの形式に変換する gnpltDt.cpp/gnpltDt.exe ファイルを添付します。

下に、gnuplot データへの変換例を例示します。gnuplot では gnuplot.ini テキスト・ファイルに表示データを書いてやれば、gnuplot を走らせるだけでグラフを表示させられます。グラフ表示のために必要な gnuplot コマンド文字列は sf の !print(...) コマンドによってファイル変数テキスト・ファイルに出力されます。
//@@
    # -Δ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    0
Excel でグラフ表示させたいときには、ベクタ・ファイル変数テキスト・ファイルを CSV 形式のテキスト・ファイルに変換してやれば良いはずだと考えます。(実際には行っていません。Excel を使ったいると胃が痛くなるほど Excel が嫌いなので許してください。)
△サブルーチン・ファイル
sf では何度も繰り返して行われる計算作業を一行で記述できるようにする、サブルーチン・ファイルの機能を設けています。ブロック実行ファイルに似ていますが、下の点で異なります。
  1. @subFile(,,) の形式で呼び出される
  2. 呼び出すとき、引数 _prm1, _prm2, ,... の名前のテンポラリ変数に引数値を渡す
  3. _rt テンポラリ変数に戻り値を記述する
  4. デフォルトの拡張子が sf である
下のような行列のポアソン・ブラケット演算を行わせる Poisson.sf を作っておけば、それを sf の計算式の中から呼び出し、実行させられます
    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 に戻り値を設定することを忘れないで下さい。戻り値がなくなってしまいます。

行列
sf では行列計算もできます。sf では <<N>> で 0 要素からなるサイズ N のベクタを意味しましたが。[[N]] で 0 要素からなるサイズ N x N の行列を意味します。[[N,M]] で 0 要素からなるサイズ N x 3 の行列を意味します。Matrx[n,*] で行列の n 行を表します。Matirx[*,m] は行列の m 列を表します。Matrix[*,*] は正方行列の対角要素を表します。正方行列でないときは Matrix[*,*] はエラーになります。
    # サイズ 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 >
△ベクタ・行列の部分要素
ベクタ要素は [index] により指定できます。下のように index 0 要素に値を設定できます。
    sf "temp = <<3>>"
    sf "temp[0] = 1"
    < 1, 0, 0 >
    sf "temp[1] = !exp(2)"
    <       1, 7.38906,       0 >
なお、sf のベクタや行列のインデックスは 0 から始まるものとしています。 C 言語の配列と同じです。

sf では、ベクタや行列の部分要素を、C++ 言語の slice array の形式を使って、まとめて扱えるようにしています。slice array を理解していないと判りにくいとも思います。sf で最も難しい部分だと思います。でも C++ 言語で数値計算をするときには使う考え方であり、ここで苦労しても損にはならないはずです。

ベクタの部分要素を [...] のなかに start, size, stride の三要素から鳴るベクタを指定することで、ベクタの部分要素を指定します。ここで start, size, stride は全て正の整数です。
 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 で指定されます。なれるまでは判りにくいと思います。自分で上の数値を変えがら、上の操作を色々と行うってみることで判るはずです。

このような一見わかりにくい slice array を使うのは、行列要素の部分要素を簡単にアクセスするためです。行列を一列に並べなおしたベクタとみなして、そのベクタの部分ベクタにアクセスするためです。

5x5 行列を例に slice array にある行列要素の一括指定の例を幾つか示します。
    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 に慣れれば、規則性のある部分行列要素へのアクセスを簡単に記述できますから。
△ユーザー関数を使っての拡張
sf の計算機能を、ユーザーが C/C++ 言語を使って拡張できます。 ~で始めます デフォルト拡張子 exe については省略できます 引数は _arg1.val,_arg2.val, ... argN.val ファイル変数に残されます 戻り値は _rs.val ファイル変数に記述する expM 正方行列の exponetial random Jacobi エルミート行列の対角化 sfMtrx.lib を利用することで、用意に sf のファイル変数として読み書きできるます。LPACK などの既存の C/C++ 行列パッケージなどを sf に取り込むことが可能です。

■ 2 どんな分野、どんなユーザーに役立つか ■

sf は計算を頻繁に行うユーザー全てに役立ちます。コンピュータを使いながら電卓を使っているような方に便利です。コンピュータを使っていながら、その横で電卓を使って計算しているなんておかしいと思いませんか?

Windows のアクセサリに電卓があります。でも、それで満足ですか?直ぐには使えません。ソフトを立ち上げるために、スタートボタンから始まる面倒な操作が必要です。また複素数は扱えません。行列・ベクタは扱えません。関数は不十分ですし、マウスで操作せねばなりません。メモリできる定数は一つだけです。ユーザーによる拡張など不可能です。sf ならば、これらの問題はありません。

多くの場面で、sf は既存の計算ソフトより便利なはずです。unix や cygwin を使っているような方ならば、計算ソフト bc や dc を使えます。Maxima のような高機能なソフトさえ GNU GPL で配布されています。でも、多くの場合 sf のほうが便利です。より少ないキータイプ回数で計算させられます。コマンド・ラインの引数に計算式を書くだけですから。パイプや echo などを使う必要がありませんから。

sf.ini ファイルに、消費税などの頻繁に使う計算定数(例えば r @=1.05) を書いておけば "sf 135 r" とコマンドラインからタイプするだけで、消費税込みの値段を計算できます。エディタ上で数式をメモ書きしているときに、その計算結果が欲しくなったら、その数式をコマンドラインにコピー&ペーストするだけで計算できてしまいます。エディタのマクロを上手く作れば、一つのキー操作だけで、数十行の操作が必要な計算式の結果を得られます。(WZ エディタ使いの方ならば、ブロック・ライン実行 shell マクロも参照ください)これらが複素数の行列計算まで可能です。

□□ 1.1 高校生に □□

高校の数学や物理の勉強で、多くの計算がでてきます。公式がでてきます。それらの大部分は sf で計算できます。

普段の勉強では、公式を丸暗記するのではなく sf を使って納得できるまで様々の数値実験を行って見てください。単純な計算作業は sf にやらせて、数学や物理の本質を勉強してください。


□□ 1-3 プログラマーに □□

sf は単純なコンソール exe プログラムです。sf は普段使っているコンソールから、引数に計算式を打ち込むだけで計算できます。下のようにコンソールから入力するだけで 0xec と答えが返ってくる便利さはプログラマーならば理解してもらえるはずです。マウスを使う必要はありません。
    # 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:3
slice 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:4
slice array の考え方は少し複雑ですが、多くの規則性の有るスパーシティの高い行列要素操作するときには威力のある記述法です。

sf での変数は拡張子が "val" のテキスト・ファイルです。実際「図 1.3」で作った Matrix 変数をは下に示します。
    >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 でのグラフ表示に適した向きのフィルタ・プログラムを作ることも容易なはずです。
複数の sf を平行して走らせることも可能です。
sf はプログラムのソースも公開しています。ユーザーが自分で作成した exe ファイルの呼び出しもできます。備わっています。 sf は 10 進数だけではなく、16進数、2 進数も計算できます。その計算入力値と計算結果や結果はコンソールに残ります。 sf 自体はは parser です。数値計算は付録です ..sf doc sf は数値計算プログラムではなく perser ライブラリです。数値計算をする部分はわずかです。 <-- FFT/行列以外の数値計算は C++ の標準に備わっているものを使っているだけです。 <-- 行列などの数値計算の拡張は User 関数(exe file) によって行います <-- 2.0のバージョンでは大部分を template ライブラリとして実装する予定です <-- double/float 以外の無限精度実数クラスや有限体クラスなどを組み合わせてコンパイルしなおす ことで、任意精度の数値や、GF(2^8) などでのガロア体の行列計算も可能にします

□□ 理系のエンジニア、研究者、学生に □□

数式での計算、および、行列やベクトルの計算を行う必要のある方に sf を勧めます。

sf は数式のチェックに使えます。通常の数式記述と殆ど同じ、文字式のまま計算できるからです。累積故障率を表すワイブル分布関数 F(t) = 1- exp(-(t/η)^m) が教科書に出てきたとします。
    //@@
    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 ならば、初期故障が発生しやすい装置の故障分布であることが分かります。上の式はハード・ディスクの累積故障率のワイブル分布です。理系の教科書を読んでいるとき、数式の洪水に飲み込まれて分からなくなってしまうことが多くあります。このように実際の数値を代入し計算して具体例を補ってやることで、書かれている内容をより的確に読み取れるようになります。

公式に則して具体的な適用例への確認計算をしていくとき、真空の誘電率、プランク定数などといった式に良く出てくる数値は sf はユーザーがセットした ε0 や h` といったファイル変数で扱えるので、文献の数式と殆ど同じ式を使って計算していけます

sf 式の変形に誤りが入り込んだことの確認にも使えます。式の変形には誤りが簡単に入り込んでしまいます。誤った式を前提として何週間も論理展開した後に式の誤りに気づくなんてことも珍しくありません。同僚が確認検算をしてくれれば良いのでしょうが、そんな恵まれた環境にいる人は少数派でしょう。sf を使えば変形した式が変形前の式と同じ値になるかを確認することで、自分で式の誤りが入り込んだことを確認できます。
    T=1, z=1
    T/2(1+z^-1)/(1-z^-1) = T/2 (1 + 2z^-1/(1-z^-1)
上の左右の式が同じ値になることを sf で確認すれば、式の変形に間違いが入りこまなかったと自身を持てます。また逆に誤りが入り込んだ式を特定できます。

sf では、スカラー値・ベクタ値・行列値の変数ファイルを sf 計算式の対象にできます。 行列、ベクタを含んだ計算式を単純に記述できます。 ギリシャ文字をつかえます。 文字の最後に ' と ` を使えます。 temporary 変数--大文字と小文字の区別 -- 高速アクセス -- ディレクトリ中のファイルを壊さない {number[,number...]} による index 付の変数ファイル名を使えます
index には変数を使うことができます。 interger に限られます。マイナス値も取れます !sin,cos, tan... 複素数 π表記

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 doc for programmer LAPAC など、他のライブラリと組み合わせて利用することが一番簡単なのは sf だと自負しています。C/C++ のライブラリとリンクするには、sf への .val ファイルの変数フォーマットに変換するだけですから。そのフォーマットとの交互変換は、sf.lib が備えていますから。この変換を利用したインターフェースをユーザーが自分でつくれば、Fortran、そのほかの数値計算ライブラリとも組み合わせて exe 実行ファイルを作れば、sf と組み合わせて利用できますから。

□□ Mathematic, MatLab などのユーザーに □□

・タッチ・タイピングができて ・コンピュータがあるにもかかわらず電卓を使っている 人に使って欲しいソフトです。 方程式が正しく変形されているか否かは、具体的な数値を二回も当たれば、多くのばあい正しいとみなせます >sf a=1.4 >sf "!sin(a/2) - !sqrt(1-!cos(a))/!sqrt(2)" mtrxCommand argment: !sin(a/2)- !sqrt(1-!cos(a))/!sqrt(2) < 0 > >sf a=0.034 >sf "!sin(a/2) - !sqrt(1-!cos(a))/!sqrt(2)" mtrxCommand argment: !sin(a/2)- !sqrt(1-!cos(a))/!sqrt(2) < 1.52656e-016 > 計算式の変形の連鎖で誤りがないことの憲章にも使えます。

sf は単なるコマンド実行プログラムです。コマンド引数に計算式を記述します。計算結果はコンソールに出力されると同時に"変数名.val"ファイルにも記録されます。そのファイルを変数とする演算もできるので、組み合わせにより複雑な計算式や、状態を持った計算が実行可能です。変数ファイルはテキスト・ファイルですから、他のソフトと自由に組み合わせられます。gnuplot などと組み合わせればグラフ表示も可能です。kVerifier のテストを適用した実用例でもあり、テストも含めてソースも公開しております。テスト付ですので、プログラムの素養のある方でしたら、自分専用に sf.exe をカスタマイズできます。

■sf の機能概観

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
    0x30
sf はベクトルや行列も扱えます。ベクトルは < > で囲って表現します。下のようにベクトル演算を行ないます。< のような文字が入ってくると、そのままではコマンドラインのリダイレクトと解釈されるので "..." と引用筆で囲みます
    >sf "a = <1,3, 5>"  # 変数 a を三次元ベクトル値 1,3,5 を持つベクトルにします
    < 1, 3, 5 >
    >sf "b = 2 a"       # 
    < 2, 6, 10 >
    >sf "<a &brvbar; b>"        # 内積演算です
    < 70 >
    >sf "<a &brvbar; Matrix &brvbar; 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++ 記述方法を優先します。

■ sf の変数

△ 変数名
△ 先頭ギリシャ文字、末尾 ' ` 記号
△テンポラリ変数
sf では、ヒープ・メモリのスタック・リスト上に設けられるテンポラリ変数が使えます。
  1. tempVar @= 3.142 のように @= で初期値と共に、テンポラリ変数であることを宣言します。(fileVar = 3.142 のように記述すると、ファイル変数となり、HDD 上に変数ファイルが作られます。)
  2. テンポラリ変数は大文字/小文字を区別できます。(Windows のファイルは case sensitive ではない制約により、sf のファイル変数は大文字/小文字の区別ができません。)
  3. テンポラリ変数はスタック上にダイナミックに設けられるので、ループ・ブロックやサブルーチン・ファイルなどスコープが異なれば、同じ名前の変数を使えます。変数名の衝突を避けられます。HDD 上に作られるファイル変数は、一つの変数名文字列に一つのファイル変数のみしか存在できません。変数名の衝突が発生します。
  4. テンポラリ変数とファイル変数の両方が同時に存在したとき、テンポラリ変数が優先します。
△ temporary 変数と case sensitive ファイル変数より優先
△ sf の複素数記述
△ sf の浮動小数点記述
△ インデックス・ファイル

■ @fileName.sf ブロック実行ファイル

▲ 式の要素
▲ 戻り値
▲ 引数
▲ @@subFile サブルーチン・ブロック
△ _prm1,prm2,.. 引数

● sf.ini 初期設定ファイル

current directory に限定する

● 出力数値フォーマットと制御

△ 表示桁数の設定 △ 0 表示設定

■ 可能な演算の組み合わせ

scalar, vector, matrix で加減乗除算ができるもの、できないものがあります。その一覧表を下に示します。
二項演算子 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 値は逆行列がある

■サポートしている関数

scalar, vector, matrix で適用できる関数が異なってきます。その一覧表を下に示します。
○
単項関数
      │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 における繰り返し

sf では ',' 区切ることにより複数の計算式を一行のコマンド引数内で記述させることができます。
    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 変数を導入することで、任意関数のベクトル表現を可能にしています。

■index 変数による繰り返し

index@@<< first, size, stride>> 計算式、または index@@< , , ... , > 計算式により C 言語の for loop のような計算式の記述を可能にしています。
    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 として生成されます。繰り返しのたびに、実際に書き込み、また読み出されます。繰り返しの数が多くなると、ファイルの読み書きの時間が重くなってきます。

■temporary 変数による繰り返し

sf では関数をベクタとして表現して処理することを想定しています。関数を有限次元の Hirbert 空間として扱うことをイメージしています。!shift(ベクタ/行列変数) との差分により、微分関数を扱うことを想定しています。このため、任意関数をベクタとして表現できる
    @<< 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 はデバッグ作業を必要としないような単純な計算を容易にするためのツールを目指しています。実際の計算では、そのようなものの方が多いはずです。

■関数、微分、積分

..Hilbert 空間演算

●ユーザーによる計算機能の拡張

■サブ・ファイル関数

<-- _ で始まってはならない。'`,{} などを加えられない <-- secondory name がなければ .sf だと見なす <-- current directory に限定する 引数は _prm1,_prm2,... 戻り値は _rt <-- rt は temporary 変数 <-- nexting による変数の _rt 変数の書き換えはない

■ユーザー関数

引数は _arg1,_arg2,... 戻り値は _rs sf はユーザーが記述した関数を ~UserFunction(string) の '~' を付けることで呼び出せるようにしています。戻り値は _rs.val に入っていることを前提としています。UserFunction は bat ファイルでも exe ファイルでも実行ファイルならばなんでもかまいません。渡される引数は、計算式中に書かれた ~UserFucntion(.) 引数文字列そのものです。正方行列の exponential を下のような ExpMt.bat バッチ・ファイルで近似できます。
>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 変数へのコピーするか否かはユーザーの選択です

■ToDo

  1. temporary 変数を _t だけに限定しない。普通の変数名を使えるようにする
  2. 計算結果の途中の行列、ベクタにも[..] を使えるようにする。exmaple (mat1 + mat2)[1,2] * 3
  3. 変数名ファイルに index を付けられるようにする。これにより多次元行列や、行列要素が行列にしたりできる。
..sf doc for programmer version 2.x では sf を template library として実装するつもりです。幾つかの関数を備えていれば任意の演算クラスを扱えるようにします。すでに fft や LU 分解は template として実装しています。sfMtrx.cpp のソースは string の parse に徹するように変更するつもりです。

■Tips

..sf doc tips 2.99e8 と書いてはいけません。2.99e+8 と書きます。2.99e8 は 2.99 * e8 の意味になります % BaseVarDouble 1 # 光速 c = 2.99792458 ×10^8 m s-1 <2.99792458e+8>
..sf doc tips >sf "<<0,100,0.01 @t|!exp(-t^2)>>, !print(plot \"-\" using 1:2)" <-- コマンド・ラインからは \" が必要です
..<-- sf tips doc 下が complex になる sf "x@=-1, x^3" <-- x^3 の整数乗とは計算していません。flot 乗です。-1 の float 乗算は複素数だからです <-- 行列、ベクトルの index を求めるときだけが integer 数値に変換されます <-- <<1,100,@t|vector[t]>> ではなく <<1,100,@t|vector[_n+1]>> と default index _n を使うべきです
command line で user 関数を呼び出すとき、引数は '...' の single quot を使います。double quot はコマンド記述側と衝突するからです ----------------- 未定トピックス ----------------------- 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