VB.NETのコードをC++に移植する

C++にboostを組み込んで,cpp_int(巨大整数)を扱うことができるようになった.さて,ここからどちらの方向に進めばよいのだろう?ELSIEは行列同型判定アプリなので,現在VBで開発している準同型検定とリンクさせることが目標ではあるが,どこをプラットフォームとすればよいのかが問題だ.ELSIEをVBから呼び出さるように作り込むという方向と,準同型検定をC++に移植するという2つの方向が考えられる.究極の目標が,NODULEを基底クラスとする統合的な処理系を作り上げることにあるとすれば,そのもっとも現実的な方向はVBを捨ててC++に乗り換えることではないか?

boostにはグラフ理論周りの関数もかなり整備されているので,うまくゆけばこれらをそっくり利用することも考えられる.準同型検定のソースは現在1200行くらいなので,移植するというプランの現実性は十分ある.VB,BETとC#の相互変換ツールというのがある.VS 2008には実装されていたようだが,すでに廃止されているが,それに替わるものがオンラインで使える可能性がある.

Telerik Code Converter
http://converter.telerik.com/

SharpDevelopというツールもある.ただし,これも新しい版では廃止されてしまっているようだ.また,対象となるプロジェクトもVS 2015までのようだ.Language Convertプラグインというのもある.これはVSのプラグインだろうか?dnSpyというツールは双方向の変換ができるようだ.IL Spyというのもあるらしい.先頭のTelerik Code Converterというのをオンラインで試してみた.ファイル1本分を黙って変換してくれた.ただし,一部に変換に失敗したところもあるようだが… 十分間に合うのではないだろうか?

C#のプロジェクトには大別して3種ある.①Windows フォームアプリケーション,②Windows フォームアプリ,③WPFアプリケーション.①t②の相違点は.NET Frameworkを使うか?.NET Core を使うかという違いだ..NET Frameworkは4.8で終了ということになっているので,将来的な問題がある.②の場合には,.NET CoreがWindowsに標準装備されていないという問題がある.③のWPFというのは最新のテクノロジーでGUIとロジックが完全に分離したものになる.

ただし,これまでのようにツールボックスからコントロールからドラッグ&ペーストなどのことができなくなり,すべてXAMLで記述しなくてはならない.③ではGDIではなくDirect 3Dが使われているので,描画はより強力なものになることが期待できる.将来的にはWindows App SDKを使うという方向性が出されており,今後どうなるかは今のところ未定である.とりあえず,①のWindows フォームアプリケーションでゆくしなかいのではないだろうか?⇒初めてのC#プロジェクトを立ち上げてみた.何とかなりそうな気配ではある.

ArrayListというクラスが未定義になった.⇒C#にもArrayListというクラスはある.⇒using System.Collections;で解消した.

private var S4の置換 = new 置換(“S4の置換”, 4);で「キーワード ‘var’ は、ローカル変数宣言内またはスクリプト コード内でのみ有効です」⇒var→置換で解消した.

「’共役変換検定’ は ‘メソッド グループ’ であるため、これに割り当てることはできません」⇒VBではファンクション名に値を代入して返すようになっているが,この方法は通用しない.C#では明示的に戻り値を返す必要がある.⇒対処した.

public static string KeyIndex(ref string[] map, string key)の戻り値がstringになっている.⇒KeyIndexには2つある.写像クラスと群クラスのものだ.Public Function KeyIndex(key As String) As Integerは群で,Shared Function KeyIndex(ByRef map() As String, key As String) As Stringは写像クラスだ.共役変換検定の中では写像クラスの関数を呼び出している.明らかにこれは誤りだ.というか,多分戻り値をintで取り出しているのが誤りなのだろう.VBのソースコードを修正しておこう.⇒いや,違う.関数定義の方が間違っている.実際のコードでは整数を返している.⇒対処した.

▲public static void Fact(object n) この関数はbigIntegerを返すものであるはずだ.⇒この関数はどこかから拾ってきたものではなかったろうか?引数も戻り値も型なしだ.とりあえず,intを引数としてintを返すものとしておく.ただし,これは巨大数になる可能性があるので,BigIntegerとした方が無難かもしれない.60!で10進81桁になる.しかし,この値は置換クラスの変数mに格納されるものなので,そこまで大きくなることを想定していないのではないか?⇒これは後で見直すことにして,ここでは保留としておく.

string[] listtop = list(0);でエラーになる.⇒list[0]なのではないか?⇒そのようだ.修正して解消した.

public void リストに登録あり(string[] list, string key)⇒戻り値の型指定なし⇒ブール値を返すように修正.

配列の初期化でエラーが出ている.string の2次元配列だ.「配列初期化子は変数かフィールド初期化子の中でのみ使用できます。new 式を使用してください。」以下のような式が通らない.

private 群 S2 = new 群(“S2”, 2, new[] { “1”, “-1” }, new[] { { “1”, “-1” }, { “-1”, “1” } });⇒new[] →new[,]として解消した.

型 ‘int’ を ‘bool’ に暗黙的に変換できません→対処した.

int rows = Information.UBound(table, 1); のような変な構文が出てきた.C#にはUBoundという関数はないのだろうか?⇒GetLength
で代用する.⇒UBoundの次元は1発進だが,GetLengthでは0発進.

「現在のコンテキストに ‘Strings’ という名前は存在しません」⇒Strings.Format→String.Format

C#ではMsgBoxがMessageBoxになる.⇒MessageBox.Showを使う.⇒エラーメッセージはe.Messageで取り出す.

エラー処理を除いてすべてのコンパイルエラーが消えた.⇒とりあえず,画面を整備して動かし始めた.

▲Permutation::Createで例外が発生する.⇒配列サイズが制限を超えている.array.Length=24となっているが,制限は13までだ.S4の乗積表を生成しようとしているのだが,S4の元は24個あるので,24!=620,448,401,733,239,439,360,000にもなり,到底カバーできない.しかし,群S4はこれまでにも生成したことはあったのではないだろうか?⇒いや,おそらくやっていないと思う.A4の群検査でハング状態になっている.A4くらいまではこなしていたような気もするのだが…

準同型検定ではほとんどログを取っていないので,進行状況がほとんど分からない.多少のところはFBに投稿していたかもしれないが… コストが掛かっているのは自己同型検定なので,もしかすると,これまでは止めてあったのかもしれない.いや,おそらくそういうことだったのではないか?ELSIEを引っ張りだしてきたのは,到底カバーできないというのが発端だったはずだ.従って,この問題を解決するには,ELSIEを整備して実用化するしかないと思う.

これで目標が定まったと言えるのではないか?

ELSIEのグラフ同型判定機能

ELSIEの6番目のオプションである Random matrices を実行して例外が発生している.⇒CriticalStateで例外をthrowしている. この関数では例外なく例外をスローしてトラップから出るようになっている.暫定的に平常時の脱出口を設けた.コンソールで0を入力すると処理を中断するようになっているが,エラーが発生する.USERABORT –1023 だ.⇒ゼロ復帰するように修正した.

昨日のログでは「Mirroring Methodというのは,MATRIXINVARIANTが定義されていないときに実行されるアルゴリズムと見られる」としているが,その反対ではないか?いや,間違ってはいない.現行ソースではMATRIXINVARIANTはオフになっている.動作チェックするために,暫定的にオンにしてみたのではなかったろうか?

NARCISSUSというマクロもある.多分,グラフ同型判定用と思われる.このリテラルがオンになっているとCallNautyという関数が呼ばれるようになっている.この関数の実装は含まれていないが,多分Nautyを呼び出しているのだろう.Nautyというのは確か,オーストラリアの先生が書いた最速のグラフ同型判定プログラムだ.

グラフのサンプルファイルは以下のような書式になっている.

===================================================================================
Graph Isomorphism : Counter Example  Sun Sep 10 15:47:11 2023
===================================================================================
#1 > 1 3 4 5 6 7 8 9 10 11 12
#2 > 2 4 5 6 7 8 9 10 11 12
#3 > 1 2 4 6 7 8 12
#4 > 2 3 4 5 6 9 10
#5 > 2 3 5 6 7 8 9 10 11 12
#6 > 2 3 6 8 9 11
#7 > 3 6 7 8 9 10 11 12
#8 > 2 5 6 9 10
#9 > 1 5 9 10 11 12
#10 > 1 2 3 4 5 6 9 10 11
#11 > 1 3 4 5 6 8 9 10 11
#12 > 2 4 6 7 9 10 11 12

これはおそらく,隣接行列というより,隣接リストと呼ばれるべきものだろう.実際,このリストは変換されて以下のような隣接行列として出力される.

    1  2  3  4  5  6  7  8  9  0  1  2
  1:  1  0  1  1  1  1  1  1  1  1  1  1
  2:  0  1  0  1  1  1  1  1  1  1  1  1
  3:  1  1  0  1  0  1  1  1  0  0  0  1
  4:  0  1  1  1  1  1  0  0  1  1  0  0
  5:  0  1  1  0  1  1  1  1  1  1  1  1
  6:  0  1  1  0  0  1  0  1  1  0  1  0
  7:  0  0  1  0  0  1  1  1  1  1  1  1
  8:  0  1  0  0  1  1  0  0  1  1  0  0
  9:  1  0  0  0  1  0  0  0  1  1  1  1
10:  1  1  1  1  1  1  0  0  1  1  1  0
11:  1  0  1  1  1  1  0  1  1  1  1  0
12:  0  1  0  1  0  1  1  0  1  1  1  1

グラフ同型判定でサンプルを自動生成しているが,まったく同型なサンプルが作れていない.⇒元のグラフの隣接行列をシャッフルしているが,行の入れ替えしかやっていないため,ノーマルなグラフの形が崩れてしまっている.グラフの場合は,行と列は完全に対応していなくてはならない.つまり,行ヘッダと列ヘッダは完全に一致する必要がある.(実際には行ヘッダ/列ヘッダのようなものは持っていないが)⇒Shuffleを書き換えて,行と列を完全に同期するようにした.

グラフが有向か無向かのチェックを行っているが,そのあと,有向グラフを弾いている.⇒有向グラフも検定の対象となるように修正した.また,有向枝のダンプも止めた.

コンソールで0を入力すると処理を打ち切って,メニューに戻れるようにした.これでグラフ同型検定はある程度使い物になるようになった.

boost のインストールに成功した!

boostをインストールしてみたのだが,どうしても include path が通らないので,vcpkg というツールを使ってみた.これは,多分マイクロソフトの製品ではないかと思われるが,サードパーティ製の規模の大きいパッケージをインストールするためのツールで,これを使えば整合的なインストールができるというのが謳い文句だ.vcpkg を使うためにはまず,git にアクセスできる必要があるので,git をダウンロードしてインストールした.https://git-scm.com/ この後,git を起動してコマンドラインから以下を実行して,vcpkg をインストールする.

>git clone https://github.com/Microsoft/vcpkg.git

ついで,以下を実行してvcpkgをビルドする.

>.\vcpkg\bootstrap-vcpkg.bat

これで vcpkg がインストールできたので,以下を実行して boost をインストールした.

>vcpkg install boost

これだけで boost のインストールが始まったので,おそらく git ないし vcpkg は boost のパッケージがどこに置いてあるかを知っているのだろう.というか,多分 boost は git のプロジェクトの一部なのだろう.インストールには1.1時間掛かっているので,かなりのボリュームだ.ただし,boost がどこにインストールされているのか分からないので,探し回ったところ,以下のフォルダに格納されていた.

C:\Users\babalabo\vcpkg\installed\x86-windows\include

多分ここを指定すればよいのではないかと思う.このフォルダの下にある boost にはすべての hpp ファイルが入っている.(boostのヘッダファイルは*.hではなく,*.hppという拡張子が付いている)DLL は vcpkg\installed\x86-windows\bin に,LIB はvcpkg\installed\x86-windows\lib にある.⇒expample というプロジェクトで試してみたが,ダメだ.どういうことだろう?もしかすると,もうひとつ実行する必要があるのかもしれない.これをやってみよう.

>.\vcpkg\vcpkg integrate install 

これを実行して,以下が表示された.

C:\Users\babalabo>.\vcpkg\vcpkg integrate install
Applied user-wide integration for this vcpkg root.
CMake projects should use: “-DCMAKE_TOOLCHAIN_FILE=C:/Users/babalabo/vcpkg/scripts/buildsystems/vcpkg.cmake”

All MSBuild C++ projects can now #include any installed libraries. Linking will be handled automatically. Installing new libraries will make them instantly available.

多分,この効果は新しく作ったプロジェクトにしか効かないのではないかと思う.VS2017のC++によるデスクトップ開発というパッケージには,Boost.Testのテストアダプターというのが含まれている.つまり,Boost はVS2017にすでに含まれている可能性がある.

https://learn.microsoft.com/ja-jp/visualstudio/test/how-to-use-boost-test-for-cpp?view=vs-2022

Boost.Testというのは,テストのための特製のプロジェクトを立てるということのようで,ここではとりあえずは関係ないようだ.

プロジェクトを作り直した.今回は何も設定することなく完璧に動いた.さて,問題はBigIntが使えるかどうかだ.boostではこれをcpp_intと呼んでいるようだが… ⇒簡単に動いた.

#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>
namespace mp = boost::multiprecision;

int main()
{
     mp::cpp_int x = 1;
    for (unsigned int i = 1; i <= 100; ++i)
         x *= i;
        std::cout << x << std::endl;
}

これで準備は整った.いよいよELSIEの再生だ!

Boost C++ Libraries をインストールした

どうもいまいち,ELSIEの動作が分からない.オプション4のRead a matrix data fileでサンプルを読み込ませた場合でも,

p0:EchoingMethod: ._NORMAL_ (12,12,12)
orbits=FIXED POINTS

p1:EchoingMethod: ._NORMAL_ (12,12,12)
orbits=FIXED POINTS

O0: 6 8 1 9 3 12 5 2 4 10 11 7
O1: 5 12 1 10 3 11 7 6 9 8 2 4

Matrices are isomorphic: Required time=722449:06:01, N=12, M=48, axes=0, crack=0
Psi0=(4.3189128850862000E+13:43189128850862)
Psi1=(4.3189128850862000E+13:43189128850862)
#001 The experiment complete! expo=2, X=4, Y=4, type=NORMAL

のようなダンプが出る.2つの行列を扱っているようだが,p0, p1はどう違うのだろう?⇒2つ目の行列はShuffleで生成されたものだ.おそらく,これは行と列をランダムに入れ替えることに相当する操作と思われる.従って,2つの行列は当然同型と判定されなくてはならない.

方式はよく分からないが,ともかく与えられた行列からある種の不変量を計算し,それを比較することによって同型か否かを判定しているものと見られる.この不変量は巨大数となるので,hugenumというデータ型を自作して対応しているというのが現状のようだ.hugenumというのは倍倍精度実数と長長整数を組み合わせたもので,誤差が発生するのは避けられない.FIXED POINTS(固定小数点数)というのはおそらく,誤差が発生していないということを意味するのだろう.

この実装では「Echoing Method」というアルゴリズムが実装され,A1という記号が振られているが,A2は存在しない.Mirroring Methodというのは,MATRIXINVARIANTが定義されていないときに実行されるアルゴリズムと見られるので,不変量の計算を行わない別法と考えられるが,現状ではEchoing Methodに固定されているものと見られる.

ただし,Mirroring Methodの実装は残っていて,切り替えは可能な状態になっている.MATRIXINVARIANTをオフにすると,上記のプサイ数の計算は実行されないが結果は同じになるので,一応動いているものと見られる.⇒いや,プサイ数の計算は実行されているようだ.ダンプに含まれないだけではないか?2つの手法の相違点はよくわからないが,それほど大きく異なるものではないような気がする.

フェーズは以下の5段階に区分されている.{ INITIALIZE, KUEXPERIMENT, NUTSCRACKER, WUPINNOCENT, FASTREACTOR } 確かにこの辺りの用語には聞き覚えがある.どんな意味だったのかはよく覚えていないが… いずれにせよ,それなりに動作していると評価してよいのではないだろうか?このアプリのオプション6つのうち,3つはグラフに関するものだ.グラフは隣接行列として過不足なく表現できるから,グラフ同型問題を行列同型問題として解くというのは当然のアイディアだろう.我々は群論の問題に行列同型を適用しようと思っているのだが,群の乗積表は(多少特殊な)正則行列にほかならないのだから,解けて当然と言えるはずだ.

このアルゴリズムは十分な有用性を持っていると考えられるのでなんとか復活させたいものだ.どうすればよいか?自前のhugnumを使っている限り,限界に直面することは間違いないので,これをBigIntegerと置き換える必要がある.BigIntegerが使えるのは今のところVBとPythonだけだ.Pythonはどちらかというとあまり使いたくないので,そうなると,VBに移植するか,C++にBigIntを導入するかの2択ということになる.どちらが使い勝手がよいか?拡張性はどうか?BigIntはネット上に公開されているソースもあり,GitHubには複数のプロジェクトがあるので,導入はいつでも可能と言えるのだが…

現時点ではソースコードは111KBある.行数で3500行くらいだ.これをそっくりVBで書き直すというのは現実的に可能だろうか?不可能ではないとしても,相当なコストは覚悟しなくてはならない.それより,C++にBigIntを導入する方がましであるような気がするのだが… 現時点でのhugenumの廃止は不可避であり,不可欠であると思われる.

C#に移行するという選択肢はあるだろうか?C#はBigIntegerを持っていたはずだ.C#はVB.NETとも互換性があったのではないだろうか?C#でC++のネイティブコードが走るかどうか?が問題だ.それができるのであればC#に移行するというのはベストチョイスになる可能性はある.

もう一つの選択肢として,多倍長整数のライブラリをC++に組み込むという路がある.この種のライブラリは各種あり,一長一短と思われるが,Boost Multi Precision Library というのを見つけた.これはドキュメントが整備されており,かなり信頼度は高そうに見える.日本発のプロジェクトで高橋晶という人物がリーダーだ.これは買いではないだろうか?最新版は1.83.0 2023/08/11 リリースなのでプロジェクトは現在も活性状態にある.ダウンロードしてみた.

zipファイルを解凍して中に入っている bootstrap.bat を実行すると b2.exe が作られる.これをダブルクリックで実行したところ,インストールは実行されたようだが,VSから認識される状態にはなっていない.改め> .\b2.exe install -j2 –prefix=C:\Program Files \boost \boost_1_82_0 を実行してみたが,途中で止まってしまった.

don’t know how to make <e>Files\boost\boost_1_82_0
…found 1 target…
…can’t find 1 target…

PowerShellを使ってみる.結果は同じだ.管理者モードで実行してみる.⇒やはり,ダメだ.開発用のDドライブにインストールしてみよう.⇒今度はうまく行った.前回はファイルコピー時に出ていたコードが処理できないというエラーも解消し,完全にクリーンなインストールができた.あとは,これを参照できるようにするだけだ.問題はこれまでのコードと相性が合うかどうか?このプログラムは多分64ビット環境で動くようにインストールされていると思われるが,我々のプログラムのプラットフォームは基本的に32ビットシステムだ.開発環境が64ビットであっても32ビットコードを生成できないということにはならないが…

サイトにあったサンプルコードで動作確認しようとしてみたが,include パスが通らない…$(VC_IncludePath);$(WindowsSDK_IncludePath); の後に追加できるはずなのだが,認識されない.

行列同型判定プログラム ELSIE を動かす

Elsieを起動して,6.Random matrices を選択→matrix size→iteration countを入力したところで,例外が発生する.

image

freopen_s(&logfile, EXPERIMENTLOG, “a+”, logfile)で失敗している.EXPERIMENTLOGには “Experiment.log”という文字列が入っている.ソースコードにはログファイルを開いている箇所は存在しない.logfileはまったく使われている形跡がない.とりあえず,止めておくことにしよう.EXPERIMENTLOGで止めるようにした.

一応動作するようになったが,何をやっているのか?さっぱりわからない.こんな出力が出ている.

p0:EchoingMethod: ._NORMAL_ (12,12,12)
orbits=FIXED POINTS

p1:EchoingMethod: ._NORMAL_ (12,12,12)
orbits=FIXED POINTS

O0: 3 2 8 12 9 7 6 10 11 1 5 4
O1: 12 2 9 11 10 1 7 4 6 5 8 3

Matrices are isomorphic: Required time=722466:55:08, N=12, M=50, axes=0, crack=0
Psi0=(2.6136868720357000E+13:26136868720357)
Psi1=(2.6136868720357000E+13:26136868720357)
#001 The experiment complete! expo=2, X=4, Y=4, type=NORMAL
——————————————————————————

FIXED POINTSというのは,TRANSITIVEの対語のようだ.PrintOrbitsの中で使われている.ISOMORPHというクラスにはarrayが3つ,matrixが3つ,Vectが7つ入っていて,OrbitsというのはそのうちのOというVectを指しているようだ.グローバル変数としてorbits0[256], orbits1[256]というのもある.これは解析もかなり難しそうだ…

PsiNumberというのが出てくるのだが,これは何だろう?PsiNumberというのはどうもグラフに関係しているようなのだが… GraphPsiNumberと並立してMatrixOmegaNumberというのも出てくる.Psi numberにはHorizontalとVerticalがある.マトリックスはpsiHとpsiVという2つの一次配列を持っている.これが一致する必要があるらしい.CompMatrixという関数では単純に2つのマトリックスのセルを比較している.マトリックスのタイプには以下がある.

  • NORMAL:
  • IRREDUCIBLE:
  • SUBSYMMETRIC: 
  • CRYSTAL:
  • SYMMETRIC:
  • PARASYMMETRIC:
  • COMPLETE:
  • TRIFLE:  

同型判定の方式として,①Mirroringと②Echoingの二種がある.MATRIXINVARIANTがオンのときは,マトリックスの不変量を求める方法が採用される.GetMatrixInvariantではデルタマトリックスというのを生成して,プサイ数とオメガ数を計算しているようだ.これらが一致すれば同型と判定されるのだろう.見通しが悪いので,使われていない関数はすべて廃棄してしまおう.

  1. ReverseCycle
  2. PartitionDeltaMatrix
  3. CanonicalLabeling
  4. StandardDeltaMatrix
  5. RemoveVertex
  6. RetrieveOne
  7. RetrieveVector
  8. Decending
  9. CheckComponentSize
  10. printCleavage
  11. Stocktaking
  12. loadWeightArray
  13. MakeWeightArray
  14. SubMatrixInventory
  15. subMatrixInventory
  16. ChainConnection
  17. CheckBrokenBlock
  18. CheckOmegaMatrix
  19. CheckBC
  20. MakeInventory
  21. TakeInventory
  22. BuildOmegaMatrix
  23. ExchangeBlocks
  24. FixPermutation
  25. GetOmegaValue
  26. InventoryPartition
  27. Homomorphism
  28. ShadowEchoing
  29. BreakInnocent
  30. CheckLeftRightDelta
  31. CheckPolymetrie
  32. DestructiveExperiment
  33. BlockInspection
  34. HomomorphismExperiment
  35. IsTriviallyHomomorphic
  36. IsTriviallyIsomorphic
  37. MatrixHomomorphism
  38. TestMatching
  39. TransposeMatrix
  40. printPolygram
  41. PrintPolygram
  42. DecompPolygram
  43. round
  44. checkpartition
  45. testpolygram
  46. checkblock
  47. CheckNullBlock
  48. checkzeroline
  49. checkvect
  50. checklinear
  51. CheckMatrixSize
  52. checkNullmatrix
  53. CompPItree
  54. checkoverrun
  55. dumpvector
  56. dumplarge
  57. complarge
  58. PsiNumberMethod
  59. InitializeExponent
  60. CompressPSIs
  61. CompressPsi
  62. swapstr
  63. PrintPartition
  64. Euclids
  65. MakeS4sample
  66. printVector
  67. printArray
  68. PrintArray
  69. InitializeMap
  70. compmat
  71. VeryfyMapping
  72. IsValidPermutation
  73. printhugenum
  74. printarray
  75. PrintResult

75本の関数ないし関数名を除去した.使われていないもので一部残したものもある.Euclidsはユークリッド互除法の実装だが,どこで使うつもりだったのだろう?homomorphism(準同型)に関する関数がいくつかあったが,結局実装しないことになったようだ.行列同型では演算を前提としていないので,準同型の出る幕はなかったのだろう.MakeS4sampleというのがある.S4と言えば4次の対称群ということになるのだが,その辺りも少しからんでいたのだろうか?KUEXPERIMENTというフェーズ名がある.KUexperimentというのが入っていた.KellyUlamという関数まであった.興味あるところだが,とりあえず消してしまった.⇒いや,残っている.

サンプルファイルが見つかった.こんな感じのデータだ.Graph Isomorphism : Counter Example  Fri Sep 01 21:43:34 2023という表題が付いているので,「反例」ということになるが,多分,これは正規のデータだと思う.

2    1    2    0    2    2    0    0    1    0    2    2   
0    1    2    1    0    1    0    2    2    1    2    2   
2    0    0    2    1    0    1    1    0    0    2    1   
1    1    1    1    1    2    0    1    1    1    2    1   
2    2    0    0    2    2    1    1    1    0    1    0   
0    1    0    2    1    1    0    0    2    2    0    0   
2    1    0    0    1    1    2    1    2    2    1    1   
0    0    2    0    0    2    2    1    1    2    2    0   
0    1    1    2    0    1    2    2    2    2    1    0   
2    2    1    0    2    1    1    0    1    1    1    2   
0    1    1    0    0    1    1    0    0    0    2    1   
0    0    0    0    0    1    2    0    1    1    2    0   

これで見ると,行ヘッダや列ヘッダを持たない行列の中身だけが格納されたファイルになっている.行列の中身は数字だが,これはコードとして読んでもよいと思う.従って,現時点で考えている「同型な行列」のイメージとかけ離れたものではない.もう一つのサンプルは:

1    0    1    1    1    2    1    1    2    1    1    1   
0    2    0    1    2    1    2    1    1    2    1    1   
2    1    0    1    0    2    2    1    0    0    0    1   
0    2    2    1    2    2    0    0    2    1    0    0   
0    1    1    0    1    1    2    2    1    1    2    2   
0    1    1    0    0    2    0    1    1    0    1    0   
0    0    2    0    0    2    2    2    2    1    1    2   
0    2    0    0    1    2    0    0    1    1    0    0   
2    0    0    0    2    0    0    0    1    2    1    1   
2    2    1    2    2    1    0    0    1    2    1    0   
1    0    2    2    1    2    0    2    1    2    1    0   
0    1    0    1    0    1    2    0    2    1    2    2   

この2つを比較すると同型だという答えが返ってくる.多分,以下がその全単射になっているはずだ.

O0: 6 8 1 9 3 12 5 2 4 10 11 7
O1: 11 12 4 6 3 5 10 7 8 9 2 1

ただし,これが同型写像であるとすると,行と列には同じラベルが振られているということになる.実際にこの順序で並び替えて,同一であることが確認できるとよいのだが… これを一瞬で計算できるとすれば,かなりのものだ.拾い上げる価値はあるような気がする.たとえ,完全なものではなかったとしても実用的な有用性は十分あると思う.ただし,限界があるのではないか?この行列の中身である数字は2つの行列で共通でないと動作しないのではないだろうか?一つの群から派生した部分群の比較などならそれでも十分間に合うとは思うが,完全に文字コードに依存しない同型判定にはなっていないのではないだろうか?それができれば完璧なのだが,そもそもそんなことは可能なのだろうか?

いずれにしてもn!個の全単射をしらみつぶしに調べる方法に比べれば格段に有利な方法であることは間違いないと思う.

ELSIEという行列の位相同型判定プログラム

2004年頃に書いたELSIEという行列の位相同型判定プログラムのソースが見つかった.EXEは一応動いているが,ソースは現在の環境ではコンパイルできない.(2000個くらいのエラーが出る).VS2005を再インストールしてみようと思ったのだが読み込めなかった.CDが読み取り不良になっているのか?ドライブ(外付け)が壊れているのか原因は不明だが,あきらめることにした.マイクロソフトはとうの昔にサポート終了していて,ダウンロードすることはできない.(確か,Expressという無料版があったはずなのだが…)

このソフトの仕様も動作も不明で,何ができるのかもよくわからないが,なんとか動かしてみたい.エラーを一つづつ片付けてゆけば最後は動くのではないかとは思うのだが,片付くだろうか?一括修正できる場合もあるとは思うのだが,個別に修正するしかないようなパターンもある.ともかく,どんなことになるのか?やってみることにする.プロジェクトを開いたら,アップグレードを勧められたので実行した.

プロジェクト ‘ElsieComeBack’ をアップグレードしています…
     構成 ‘Debug|Win32’: プラットフォーム ツールセットを ‘v142’ に変更しています (以前は ‘v141’)。
     構成 ‘Debug|x64’: プラットフォーム ツールセットを ‘v142’ に変更しています (以前は ‘v141’)。
     構成 ‘Release|Win32’: プラットフォーム ツールセットを ‘v142’ に変更しています (以前は ‘v141’)。
     構成 ‘Release|x64’: プラットフォーム ツールセットを ‘v142’ に変更しています (以前は ‘v141’)。
再ターゲットの終了: 完了 1、失敗 0、スキップ 0

▲BLONGというクラスはIsomorphism.hの中でコメントアウトされている.⇒Blong.cppをプロジェクトから外しておこう.

▲どうもかなり具合が悪い.isomorphism.hで「E0260    明示的な型がありません (‘int’ が想定されます) 」というエラーが出ているが,該当箇所を修正しても効かない.

べき乗進数表記マトリックスでエラーが発生

▲べき乗進数表記マトリックスでエラーが発生する.BuildMatrixで起きている.α=234, e=3, γ=10.マトリックスのサイズは27×27.⇒作業用配列は指定サイズ27×27で生成されているのに,行インデックス=i=28でアクセスしている.iは1~lengthで,lengthには29が入っているので,レンジオーバーが生じる.このlengthにはγ進数表記したべき乗値が入っている.⇒暫定的にループから離脱しないようにした.

マトリックスのカラー表示のリストが空になっている.中身は入っている.Panel_LoadでSelectedIndexの設定が止めてあった.ColoringMatrixも止めてある.⇒復活させた.

2つのマトリックスが表示されるようになっているが,現在どちらを表示しているのかを管理していない.⇒いや,Matrixクラスのオブジェクトを2つ管理している.PowerMatrixとDigiMatrixだ.つまり,問題ないと考えられる.⇒どちらか一つだけ表示というのも考えられるが,とりあえず,現状のままとしておこう.

▲べき乗進数表記マトリックスの左下三角をグレー表示したい.

▲べき剰余マトリックスの縦数列カラー表示が機能していない.⇒ColoringStripeでは topn > maxrows でループを離脱するようになっている.topn=221,maxrows=27なので成立してしまう.この論理は修正していないはずなのだが… ⇒ColoringStripeをどこかの時点で修正して放置していたのだろうか?どうもかなりおかしい.

ColorOffを選択するとColorOnを表示,ColorCycle→ColorOff,ColorOn→ColorCycle,ColorStripe→無動作という感じになっている.⇒コンボボックスのリストの順序が狂っていた.一応動作するようになった.ColoringStripeがどこでどうなってしまったのかは分からない.⇒久留島喜内 2023-07-22では動作している.2023-07-29では無動作になっている. 2023-07-27ではまだ動作している.どうも,進数表記マトリックスを導入した時点でどこか壊してしまったようだ.2023-07-28では動作していない.進数表記マトリックスはこの版で導入されている.2023-07-27-1では動作しているようだ.

どうも,αの値によって変わるようだ.αが小さい値,たとえばα=7ならばカラー表示になる.また,ColoringStripeのロジックには変更は入っていないように思われるので,カバーできていないポケットがあるのではないか?つまり,ColoringStripeにはバグが残っていると見てよいように思われる.マトリックスの表示領域が27×27のとき,α=28にすると表示できない部分が出てくる.(α=28より小さい領域は着色されない)境界線の位置も間違っている.

この辺り後回しにしようかとも思ったが,片付けてしまうことにする.


べき乗進数表記マトリックスが表示できる

べき乗進数表記マトリックスが表示できるようになった.これを整備してべき剰余数列マトリックスと同等のところまで仕上げるというのが今日の仕事だ.

▲縦数列のラベル列が周期Yのインデックスになっているが,縦数列=進数表記数列なのだから,縦方向の周期性はないと考えられるので,通し番号とする.

異種文字数を出している末尾列,末尾行はしばらく空欄としておこう.なにを表示するのが最適か?はもう少し調べてみないとわからない.もっとも関心のあるところは,横数列の周期がどうなっているのか?という点だ.

べき乗進数表記マトリックスをサポートする

レンジ外のα値入力に対し,何のアウトプットもないのはまずい.⇒数値ボックスで自動的に弾いているのではないか?⇒いや,少し動作が違う.12345678901234567890を入力→9223372036854775807に書き換えられはしたが,処理は実行されている.⇒テキストをまるごと書き換えたときは,9223372036854775807として受け付けているようだ.既存テキストが入力されている場合には,後から追加したテキストはキャンセルされて元のテキストに戻っている.⇒これはアプリ側では検知できないような気がする.

εをeに一括置換しておく.⇒イベントハンドラの引数でeが使われている.⇒名前のダブりを避けるよう調整した.

加納のべき剰余等差数列定理に関係する修正を行う.まず.ValueChangedでα^ε値をγ進数表記した数列をダンプ出力することにしよう.いや,その前にα^εの生値を10進出力すべきではないのか?⇒UpdateStatusを書き換えておこう.

数値をb進表記に変換しているのはConvertNum2Stringで,その中でToBCDを呼び出してバイト配列に変換している.しかし,γは大きな整数なのでバイト配列では収まらない.同一趣旨でint配列が使えるようにする必要がある.⇒動作するようになった.NumToBCDという関数で処理するようにした.NumToBCDとToBCDの大きな違いは,出力配列の順序が逆順になっているという点だ.ToBCDでは一の位が末尾に来るようになっているが,NumToBCDでは先頭に配置される.

マトリックスを開くのに前より時間が掛かるようになった気がする.⇒扱っている数字のレンジによる.小さい数が対象なら瞬速で表示される.数字が大きいときに時間が掛かるのは避けられない.

やっとapp.configが動くようになった

▲7^2023 mod 10000 でcycleが0#0で無表示⇒再現しない.0#100で周期は100だ.X=500なので,多少は短縮されている.描画が遅れていたのだろうか?verboseが立っていた可能性はある.

7,49,343,2401,6807,7649,3543,4801,3607,5249,6743,7201,
407,2849,9943,9601,7207,449,3143,2001,4007,8049,6343,
4401,807,5649,9543,6801,7607,3249,2743,9201,4407,849,
5943,1601,1207,8449,9143,4001,8007,6049,2343,6401,4807,
3649,5543,8801,1607,1249,8743,1201,8407,8849,1943,3601,
5207,6449,5143,6001,2007,4049,8343,8401,8807,1649,1543,
801,5607,9249,4743,3201,2407,6849,7943,5601,9207,4449,
1143,8001,6007,2049,4343,401,2807,9649,7543,2801,9607,
7249,743,5201,6407,4849,3943,7601,3207,2449,7143,1,

一応動作しているようなのでこのまま運用して様子を見ることにする.

中止ボタンが効かない.⇒特にVerboseオンで効きが悪い.Stopflagが立ったときには,verboseを落とした方がよい.⇒OutputStreamの中でDoEventsを取るようにした.ここでstopflagがオンになったときはverboseを落とすようにしたのでほどなく停止できるようになった.

DispRecurringDecimalという関数は廃止した.それと連動してIverboseとういフラグも廃止することにした.

▲Matrix Testボタンを押してもかなり長時間何も出力されない.