自己同型検定を一晩走らせてA4同型写像24個を出力した

A4の自己同型検定を一晩走らせて,恒等写像を含めて24個の同型写像が出力されたが,完了までにはほど遠い.停止させてチェックしたところ「i」までは進んでいたので,半分くらいこなしたというところだろうか?少なくともS5くらいまでは計算できるようにしたいのだがほど遠い話だ.ELSIEは一般の行列の同型判定プログラムだが,準同型検定CSは本来群の検定を目的としたものであるから,単位元の存在は仮定してよいはずだ.従って,全置換のうち,先頭がaであるものだけを検査するというのでよいのではないだろうか?これならほどほどの時間で完了できる.A4なら10分も掛からないのではないだろうか?S5となるとそれでもほぼ不可能だが,S4なら何とかなるかもしれない.

どう改造すればよいか?ArrayList Createで渡す配列を最初から短くしておくのが一番手っ取り早い.Permutation.Printでリストを生成するときに書き戻せばよいのではないか?いや,それより確実なのは,全単射の生成で置換リストを生成するときに付け加える方が分かり易い.⇒しかし,この場合は全置換リストを生成する必要があるのではないか?対称群を生成するときなどは完全な置換リストが必要になる.

「置換リストを使う」設定で,自己同型検定→群同型判定で例外が発生する.⇒全単射の生成で落ちる.置換リスト = new string[m, n];で墜ちている.m=479001600, n=12だ.sizeof(string)は取れないので,sizeof(long)で代用すると,18,446,744,072,449,064,960で到底カバーできる数字ではない.

「置換リストを使う」設定のときの論理は現行のママとし,使わないときには Permutation.Creatの引数で調整することにする.⇒実装した.A4でテストしてみる.⇒最初の3つまではすぐに出たが,その後が続かない.相当な時間が掛かりそうだ.13:10開始ということにして時間を測ってみることにする.⇒完了した.所要時間は1時間半.まぁまぁの成績と言ってよいだろう.

#1 Permute 自己同型:b,c,d,e,f,g,h,i,j,k,l,
#2 Permute 自己同型:b,c,i,h,g,k,j,l,e,f,d,
#3 Permute 自己同型:b,c,l,j,k,f,e,d,h,g,i,
#4 Permute 自己同型:c,b,d,f,e,j,k,l,g,h,i,
#5 Permute 自己同型:c,b,i,g,h,e,f,d,k,j,l,
#6 Permute 自己同型:c,b,l,k,j,h,g,i,f,e,d,
#7 Permute 自己同型:e,g,d,k,c,h,f,l,b,j,i,
#8 Permute 自己同型:e,g,i,b,j,c,k,d,f,h,l,
#9 Permute 自己同型:e,g,l,f,h,j,b,i,k,c,d,
#10 Permute 自己同型:f,j,d,h,b,k,e,i,c,g,l,
#11 Permute 自己同型:f,j,i,e,k,g,c,l,h,b,d,
#12 Permute 自己同型:f,j,l,c,g,b,h,d,e,k,i,
#13 Permute 自己同型:g,e,d,c,k,b,j,i,h,f,l,
#14 Permute 自己同型:g,e,i,j,b,f,h,l,c,k,d,
#15 Permute 自己同型:g,e,l,h,f,k,c,d,j,b,i,
#16 Permute 自己同型:h,k,d,g,j,e,b,l,f,c,i,
#17 Permute 自己同型:h,k,i,f,c,j,g,d,b,e,l,
#18 Permute 自己同型:h,k,l,b,e,c,f,i,g,j,d,
#19 Permute 自己同型:j,f,d,b,h,c,g,l,k,e,i,
#20 Permute 自己同型:j,f,i,k,e,h,b,d,g,c,l,
#21 Permute 自己同型:j,f,l,g,c,e,k,i,b,h,d,
#22 Permute 自己同型:k,h,d,j,g,f,c,i,e,b,l,
#23 Permute 自己同型:k,h,i,c,f,b,e,l,j,g,d,
#24 Permute 自己同型:k,h,l,e,b,g,j,d,c,f,i,

いよいよ,ELSIEの登場ではないだろうか?ELSIEはプロジェクトとしてはすでに組み込まれているのだが,C#からどう呼び出せばよいのだろうか?マネージドからアンマネージドなので何かラッパーのようなものが必要になるのではないかと思うのだが… ⇒そもそも,#include プリプロセッサディレクティブがない.⇒少なくとも,下記のような仕掛けが必要なようだ.

extern “C”             //No name mangling
__declspec(dllexport)  //Tells the compiler to export the function
int                    //Function return type    
__cdecl                //Specifies calling convention, cdelc is default,
                        //so this can be omitted
test(int number){
     return number + 1;
}

ゼルコバの木ではどんなことをやっていたのか見てみよう.ExporoClasses.hというヘッダファイルがある.冒頭で,

#if defined(ZELKOVA_EXPORTS)
#define _EXPORTCLASS __declspec(dllexport)
#else
#define _EXPORTCLASS __declspec(dllimport)
#endif /* ZELKOVA_EXPORTS */

でEXPORTCLASS を定義している.ZELKOVA_EXPORTSを使って,dllexportとdllimportを切り分けている.どういう使い方をするのかは,いまいち分からない.ZELKOVA_EXPORTSは comdebug.h で定義されている.コメントに「COMDEBUG: _EXPORTCLASSの出入りの方向を決める:この行はExportClasses.hの前に置かなくてはならない!」とある.ExporoClasses.hには外部インタフェース用のクラスが各種定義されている.すべて,class _EXPORTCLASS PERSONAL のようにEXPORTCLASS として立てられている.

もうひとつ,ZelkovaExports.hというヘッダファイルがある.ここでも同種のマクロが定義されている.

#if defined(ZELKOVA_EXPORTS)
#define _EXPORT extern “C” __declspec(dllexport)
#else
#define _EXPORT extern “C” __declspec(dllimport)
#endif // ZELKOVA_EXPORTS

このヘッダファイルには,

_EXPORT long __stdcall GetViewRect(CRect *viewrect);

のような形式でDLLインタフェース関数が列挙されている.この関数の実装は,KeizuDLL.cppにあり,

long __stdcall GetViewRect(CRect *viewrect)
{
     AFX_MANAGE_STATE(AfxGetStaticModuleState());
     probe(GetViewRect)
     ASSERT_NEVER (!TreeView)
     *viewrect = TreeView->ViewRect();
     return 0;
}

のようなややこしいことをしている.なぜか,AFX_MANAGE_STATE(AfxGetStaticModuleState());のようなお呪いが必要とされている.このような宣言はextern “C” {}というブロックの中で行われているという点もポイントだ.

ZelkovaGC.hでは,namespace ZelkovaBetaというのが定義されている.このヘッダファイルにはExportClasses.hとZelkovaExports.hが#include されていて,参照できるようになっている.namespace ZelkovaBetaの中にはVBから参照されるクラスが定義されている.VBとC#はほぼ同等なので,ここまでやらなくてはならないのではないか?DLL内の関数名などをどう参照すればよいのか?DLLをリンクするだけで参照できるようになるのだろうか?namespace はC++で宣言できる.これだけで済むのなら好都合なのだが…

もう一つ問題がある.matrixはhugenumの行列になっている.これをcpp_intに切り替えるか,ないしC#に持ち出してBigIntegerが使えるようにしなくてはならない.ELSIEは4つのC++ファイルからなっている.これをまるごとC#に移すというのはちょっと二の足を踏んでしまう.まず,最初にこれをcpp_intに置き換えるところから始めた方がよいのではないか?仮に最終的にC#に持ち出すことになったとしても,そこまでやってあれば,かなり対応し易くなるはずだ.しかし,そもそもmatrixをhugenumにする必要が本当にあるのだろうか?PSI数などが大きくなるのは当然であるとしても,行列本体に巨大数を格納するというのは必要なのだろうか?

matrixとarrayはhugenumだが,それと別にMatとVectというのがある.これらはintの配列だ.ISOMORPHというクラスにはarrayが3つ,matrixが3つも含まれている.ISOMORPHのinitializeでは最初に引数で渡されたMatを内部のMatメンバーにコピーしている.つまり,検体となる行列は本来 int 配列なのだろう.従って,外部とのインターフェースはこの行列を渡せばよいということになるのではないか?⇒とりあえず,外部から2つのMatデータを与えられればMatrixComparisonと同等の検査を実行できそうだ.とりあえず,ELSIEの持っている6つの処理をC#から実行できるようにすればよいのではないか?

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA