トップ «前の日記(2008-03-24) 最新 次の日記(2008-03-26)» 編集

Orz日記 by Akio Morita

ToDo:

  • 15 SAD Fit[]回りの障害事例の解析
  • 10 smart pointer版PEGクラスの再実装(Left Recursionまわり)
2006|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|06|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|07|08|09|10|11|12|
2013|01|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|06|07|08|10|12|
2016|01|02|03|05|06|08|10|11|
2017|01|02|03|04|05|06|07|09|10|11|12|
2018|01|02|03|04|06|07|08|09|10|11|12|
2019|01|03|04|05|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|06|07|08|09|

2008-03-24 [長年日記]

_ [SAD]SpaceCharge/Scheffの高速化

Scheff.n内の ScheffDecoup[], ScheffGenerator2[]を C moduleで再実装。 さらに、ScheffGenerator2[]を使った StepSigmaMatrix[]を StepSigmaMatrix2[]という名前で C moduleで再実装。 (もちろん、内部的なScheffGenerator2[]の呼び出しは C module内の 内部API経由)

これで、Revision 1569の実装に対して約 6倍に高速化(オリジナルからだと約 33倍)

SADScriptでのマトリクス演算が意外と遅いので(内部的に二重リストと Fortran配列間を相互変換するオーバーヘッドが大きいと思われる)、 ScheffPropElem[]も C moduleで実装すればもう少し速くなると 思われるが、可変刻みドライバーコードは変更容易性のために SADScriptのままにしておいた方が良いと思われるので、 手を付けずに残しておく。

_ [KEKB]停電からの復旧に20時間らしぃ

瞬停が原因でいろいろ止まったらしく、Belleの冷凍器が停止して 液体ヘリウムが飛んだらしく運転再開まで20時間ぐらいかかるそうだ

_ [SAD]スロット演算子

先日、スロットの罠で、スロット演算子#が 実数へ右結合するという書き方をしたが、どうやら本当に演算子らしいです。 { 2 3 } &は、二つの実数間に暗黙の積演算子が存在すると見做され {Times[2,3]}& -> ({6}&)と簡約されます。

それに対して、{ # 3 } &は、直感的には{Times[#, 3]}&と 解釈されそうな所なのですが、({#3}&)と簡約されます。

つまり、スロット演算子#は字句解析レベルでは独立したトークンであり、 構文解析レベルで右結合な演算子なのです。 つまり、字句解析レベルでは、#2という第2スロットを示す表現は、 スロット演算子#と実数リテラル2の2トークンだったのです。

さらに、スロット演算子の優先順位は暗黙の積演算子より高いことが分かります。

すると、次の疑問が沸き起こります。 スロット演算子と右結合したオペランドが実数リテラル以外の場合、何が起こる?

 In[1]:= f = {# a}&
Out[1]:= ({#a}&)
 In[2]:= a = 1
Out[2]:= 1
 In[3]:= g = {# a}&
Out[3]:= ({#a}&)
 In[4]:= f[1,2,3]
???FFS::undef:  Undefined element in ({#a}&)[1,2,3]
???General::abort:  Aborted:
f[1,2,3]
        ^
 ???-FFS-Error-?Undefined command or element: F[1
 In[4]:= g[1,2,3]
???FFS::undef:  Undefined element in ({#a}&)[1,2,3]
???General::abort:  Aborted:
g[1,2,3]
        ^
 ???-FFS-Error-?Undefined command or element: G[1
 In[4]:=

なんと、シンボルaと右結合するではありませんか!(fの拘束結果) これだけ見ると、純関数の参照するスロット番号を変数としてパラメータ化 出来そうなのですが、SADの実装ではそうは問屋が下ろしません。 不思議なことに実数1に拘束されたシンボルaに 右結合したスロット演算子の簡約結果が奇妙なことになっています(gの拘束結果)

つまり、スロット演算子#は右結合かつ Hold属性を 持っているようです。

ただ、fgを作用させた結果は、何とも味気ないものになっていまが、 発生しているエラーはUndefined Slotでは無いのでまだまな謎は尽きません。

怪しい構文定義

こうなってくると、スロット演算子##の動作です。 {## 2}&{## a}&は予想に違わず ({##2}&)({##a}&)に簡約されます。

さて、トークンレベルではどうなっているのでしょう?

{ # # }&の評価結果は、なんと({#}&)になります。 解釈に悩みますが、この挙動から

  • ##は字句解析レベルで一個の独立したトークンである
  • 2つのスロット演算子#の内、どちらかが構文解析で無視された

ことが分かります。 スロット演算子は、右結合かつオペランドが無い場合は暗黙のうちに 1をオペランドとするので、これまでの見てきた動作との 一貫性を優先するなら({#(#1)}&)のように評価されるべきところ だと思われます。少なくとも、勝手にトークンが失われるのは反則でしょう。

ここで、二つ目の#をカッコで括ったさらに怪しい構文を試してみます。

 In[1]:= f1 = { # (#) } &
Out[1]:= ({##}&)
 In[2]:= f2 = { ## }&
Out[2]:= ({##}&)
 In[3]:= f1@@Range[10]
???General::wrongtype:  Argument must be Number or symbol in ({##}&)[1,2,3,4,5,6,7,8,9,10]
???General::abort:  Aborted:
f1@@Range[10]
             ^
 ???-FFS-Error-?Undefined command or element: F1@@RANGE[10]
 In[3]:= f2@@Range[10]
Out[3]:= {1,2,3,4,5,6,7,8,9,10}
 In[4]:= f1===f2
Out[4]:= 0
 In[5]:=

すごく謎な挙動です、f2に拘束している純関数は、 すべての引数のリストを返す演算子で普通に動作していますが。 無理やりスロット演算子にスロット演算子を結合させた純関数(f1)は まともに動きません。

SameQは、f1f2の違いを認識しているようですが、 表示上区別が付きません。もしやと思い、ToString[]を試してみると...

 In[1]:= f1 = { # (#) }&
Out[1]:= ({##}&)
 In[2]:= f2 = { ## }&
Out[2]:= ({##}&)
 In[3]:= ToString[f1]
Out[3]:= "({##}&)"
 In[4]:= ToString[f2]
Out[4]:= "({##}&)"

これは、もはや笑うしか有りません。 つまり、環境と結合の無い純関数の定義を ToStringで シリアライズしたものをToExpressionで元通りに復元不能と 言うことです。


カテゴリー: Admin | Emacs | EPICS | Fortran | FreeBSD | GCC | hgsubversion | IPv6 | KEKB | LHC | Lisp | LLVM | MADX | Ryzen | SAD | samba | tDiary | unix | WWW | YaSAI | お仕事 | イベント | 出張 | 宴会 | 数学 | 艦これ | 買いもの | 追記 | 雑記