DispResidueCycleで固定桁数不一致

DispResidueCycleで固定桁数不一致が発生している.α=3, ε=4,γ=1のときに起きている.offset=0でdrop=1となっている.このoffset値はLambdaFunctionが返したものだ.LambdaFunctionまちがっていると考えるしかないだろう.いや,違う.べき乗剰余列は{0*}で固定桁1が正しいはずだ.drop=1は正しいのだから,間違っているのはLambdaFunctionの方だ.LambdaFunctionは冒頭でαないしγが1のときは復帰しているが,offsetの既定値が0になっているため,その値が返されている.既定値を1に変更しておこう.

▲マニュアルの記述と実際の動作が合わない.マニュアルでは,「列インデックスとは長さγ-1のべき剰余横数列内の相対位置を示す0~γ-2の整数」としているが,γ=15のとき,列インデックスは0~7までの値になっている.これはタイルの横幅が8であることを意味すると考えられる.αとγのGCM=3となっているので,おそらく元リックスを既約とするための操作によってそうなっている可能性があるが,この辺り精査する必要がある.φ(γ)=8なので,おそらくこの数字が適用されているのだろう.cycleカラー表示してみるとそのことがはっきり分かる.

この辺りの動作をマニュアルに反映する必要がある.この辺りの操作はまだきっちり定式化されていないのではないだろうか?アルゴリズム自体見直す必要があるかもしれない.

▲ラムダ関数にどういう表現を与えることができるか?を考える必要がある.⇒内部的にはすでに決着しているつもりなのだが… また,原始根の定義についても再確認しておいた方がよい.

▲カラー表示をstripeからcycleに戻すと,0の行の色が残ってしまう.なぜか?color offに切り替えれば元の表示に戻る.

RowTopがとり得る値には上限はない

喜内道具箱のマニュアルを書いているところだが,マトリックス操作でおかしな点が出てきた.α=775807,ε=17,γ=6117でBuild Matrixボタンを押したとき,Rα=5065,Rε=17となっているが,表示されたマトリックス(34×34)には行インデックスとして,2148~2181の区間しか表示されていない.RowTopは32733になっている.これは,おそらく配列サイズの上限に引っかかったためだろう.しかし,γ=6117なのだから,配列サイズは6116×6117であり,十分保持できるサイズであるように思われるのだが…

RowTopの値はBuildPowerGridではなく,BuildMatrixで決めている.⇒BuildMatrixで行っている調整はまったく不要だ.RowTopがとり得る値には上限はない.⇒修正した.

▲更新ボタンが押されたときの出力には基本パラメータ情報がすべて含まれるべきだ.

「喜内の道具箱」公開の機は熟しつつある

いよいよ,「久留島喜内の道具箱」公開の機は熟しつつあるが,マニュアルの方はさっぱり捗っていない.そろそろ散歩も始めなくてはならないのだが… あまり暑くならないうちに始めないとワゴンに乗り損なってしまう… 原始根の個数というのが出てきた.φ(γ-1)という数になっているようだ.原始根の列挙と並んで取り上げてもよいかもしれない.ともかく,レンジオーバーでBブロックが処理できない場合のエラーメッセージを出せるようにしておこう.エラーコードはInvertFuncで出している ERROR_POWERRESIDUEFUNC_OVERFLOWだ.

いや,メッセージはInvertFuncですでに出しているはずだ.いや,違う.このエラーを出しているのはPowerResidueFuncだ.出力パネルに残しているテキストの長さが短か過ぎる.⇒MaxOutput は現在 30000 に設定されている.十分な長さのように思われるのだが… 8万文字に増加させてようやく冒頭のエラーメッセージが見えるようになった.この小さいパネルにそんなに多くの文字が詰まっているようには見えないのだが,wordwrapオンにしても大したボリュームには感じられない.エラーで戻ったときの動作を一通りチェックしておこう.

  1. ERROR_STOPBUTTON_PRESSED 中止ボタンが押された PowerResidueFunc→
  2. ERROR_TOBCD_OVERFLOW ToBCDで配列サイズがMAXARRAYSIZEを超えた ToBCD→
  3. ERROR_MAKERECURSIONUNIT_ABORT 桁数オーバーでアボート MakeRecursionUnit→
  4. ERROR_MAKERESIDUCYCLE_OVERFLOW 桁数がMAXARRAYSIZEを超えた MakeResidueCycle→
  5. ERROR_POWERRESIDUEFUNC_OVERFLOW  除数Θ上限オーバー PowerResidueFunc→

完全とは言えないが一応整備されたことにしておこう.

α=9223372036854775807という設定でSeed Testを実行しようとして,エラーが発生した.どこでオーバーフローしているのかがはっきりしない.ループ変数 i が整数型のためと思われる.⇒BigIntegerに変更した.問題なく動作するようになった.⇒ResidueTestにも同様の問題があるので,修正しておいた.

上記設定でResidueTestを実行して例外が発生した.α値の上限_MAX_INT64を越えようとしたためだろう.⇒動作範囲を_MAX_INT64に限定するようにした.

BuildMatrixでオーバーフローが発生した.⇒RowTopに行先頭番号を入れようとしてオーバーフローしている.⇒MAXSQUARESIZEを超えないように調整した.

中止ボタンが押されたときにはメッセージを出すことにしてみよう.PowerResidueFuncのERROR_STOPBUTTON_PRESSEDに仕掛けてみたが効かない.⇒中止ボタンが押されたタイミングで出すことにする.

Matrix Test で何も出力されていない.⇒verboseで止めてあった.silentに切り替えたが,ダンプ量が多いので一部verboseに戻す.出力テキストは一定の文字数で折り返すようになっているので,WordWrapオフでも行数が増えてしまう.また格納文字数を増やすと出力が極端に遅くなるので,32767という現状のままとする.MaxOutText定数でこの設定の数字を超えても効果がない.BuildMatrix中の情報をダンプした方がよい.また,砂時計がテストの途中で落ちてしまう.

Bブロックが動作していない

Bブロックが動作していない.α=9223372036854775807のとき,β=10の10進数表記の数が,23になっている.かなりおかしい.ちなみにε=1.γ=23という設定だ.→数が大き過ぎて表示できないのではないだろうか?だとしたら,少なくとも「*****」のような表示にならないくてはならない.この値が入っているのはnotationだが,DispNotationでは直接この領域に書き込みを行っている.DispInvertFunc→ DispNotationが呼び出されていない.⇒InvertFuncが負値 ERROR_POWERRESIDUEFUNC_OVERFLOW を返している.

起動時にはウィンドウは一つだけ開くようになっていたはずだが… ボックスとパネルが開いている.⇒勘違いだったかもしれない.⇒タスクバーのアイコンから開くと2つ出る.⇒一旦ピン留めを外して再設定したら動作するようになった.原因は不明.

αが巨大数でもgcm(α, β)は計算できるはずだが,更新されていない.この値はgcm3だ.⇒DispInvertFuncで表示しているためだ.βの因数リストfactor_BもDispNotationで出しているので同じだ.⇒計算できるところはできるだけ表示するという対応の仕方も考えられるが,Bブロック全体が無効ということでよいのでは…

▲αに9223372036854775807を入力したあと,デクリメントして少し小さい数にしたらどこかでハングしてしまった.⇒一応計算完了して出てきた.Bブロックは更新できない.αを8桁まで落として数字が出るようになった.ただし,U, aU,Ξは不明のままだ.⇒出力パネルにはオーバーフローが発生していることを表示するべきだ.

喜内道具箱のマニュアルを書いている

喜内道具箱のマニュアルを書いているところだが,おかしな数字が出てきた.φ(γ)と#の最大公約数(φ(γ), #)の値がおかしい.φ(γ)=16で#=4なのに0になっている.かなりまずい.この値はgcm2に入っている.⇒更新ボタンで画面を更新したら4という値が入った.この値はResidueFuncProで計算し,その場で格納されている.この計算はPhi_γを参照しているので,Phi_γがまだ確定していなかったのではないか?⇒比較的最近,ValueChangedProでResidueFuncProとValueChangedの順序を入れ替えたのが敗因だ.⇒ResidueFuncProの前にValueChangedを実行するようにした.

大体仕上がったので,出荷の準備に入ろう

大体仕上がったので,出荷の準備に入ろう.以前一度VAIOにリリース版をインストールして試したことがあるが,今回は,サブノートに載せて動作確認することにしよう.EXEだけでは動かなかったような気がするので,実行するのに最低必要なファイルを確定しておく必がある.

BlackHawkにコピーして実行させようとしたが,EXEだけではまったく反応しない.binの下のnet5.0-windowsに入っているEXEを起動して以下のパネルが出た.

image

ともかく,.NET 5.0をインストールしておこう.これで一応実行できる環境にはなった.EXE+DLLで実行できるかどうか試してみたが,やはり無理なようだ.net5.0-windowsフォルダの中身がそっくり必要なようだ.配布版はパッケージにしてZIPで配布するしかない.配布パッケージ名はPowerGridということにしておこう.これは通常は「電力網」という意味で使われる用語だが,このツールの目玉はなんと言っても「べき剰余マトリックス」なので,適切な名前ではないかと思う.

どうもやはり,BlackHawkは足絡みになってしまうので,落としておくことにしよう.落としては見たものの日本語入力の具合がよくない.画面の左端に変換候補がちらちら現れて使い勝手がよくないだけでなく,反応が遅くていらついてしまう.平常通り,機内モードオン・VPNオンに戻して状態は戻ったが,変換候補が左に出るというのは変わらない.ただし,普通の速度でキーが打てるのでこの程度ならそれほど支障はない.どうも機内モードではファイル共有できないようなので,ファイルの受け渡しはUSBでやることにしよう.

起動時の初期画面でウィンドウが2つ開くというのはやはりノーマルではないので,パネルの方はアイコン化した状態で開くことにした.タスクバー上でホバリングすると「久留島喜内の置き土産」というアイコンが出てくるので,これをクリックするとパネルを開くことができる.タスクバーにピン留めしていなくても,タスクバー上に歯車アイコンが出ているときには,右クリックでアプリを開くことができる.

公開するとすれば,簡単な取説は必要だ.以前のCollatz Tree Generator のマニュアルにならって同系統のものを作ることにする.まず.最終版のCollatz Tree Generator の保管場所を確保しなくてはならない.コラッツではマニュアルは別フォルダで管理している.フォルダがここにあるということは,開発も開発機を使っていたものと思われるので,それも踏襲することにしよう.

マニュアルには図版が大量に入るので,やはり別建てで管理した方がよさそうだ.コラッツマニュアルにはPDF版とHTML版がある.PDF版の方が詳細なので多分こちらの方が新しいバージョンなのではないかと思う.多分最初はOpenOfficeのテキスト文書(*.ODT)として編集し,それをPDFとHTMLにエクスポートしたのではないかと思う.OpenOfficeにはHTML文書ドキュメントの編集機能はあるが,テキスト文書からHTMLにエクスポートする機能は見当たらない(PDFにはエクスポートできる).マスタードキュメントというファイル形式もあるようだが… 名前を付けて保存のところでHTMLが選択できる.従って,通常のODTファイルとして編集するというのでよいと思う.

今回のマニュアルは久留島喜内の仕事の継承という意味合いから日本語ドキュメントとして編集することにする.です/ます調(敬体)にするか,だ/である調(常体)にするかが問題だ.論文調ということであれば,だ/である調ということになるのだが… 導入部などではです/ます調,本文ではだ/である調ということでよいのではないか?いや,最初からである調でいくことにしよう.

開発機にはOpenOfficeはインストールされていない.ドキュメントのバックアップは外付けHDなので,多分VAIOで開発したのだろう.こうなると,やはり無線HDDが欲しくなる.と言っても,いまの環境ではいろいろ手間の掛かる部分もある.機内モードをオフにしなくてはならないとか… VPNもオフにする必要がある.⇒ファイル共有はできた.しばらくはこの態勢でやることにしよう.

これ以上付け加えるものはもうほとんどない

縦数列の周期は捉え難く,それをカラー表示することはかなり難しいので,その代用としてマトリックスのRの値を色コードに変換して直接表示してみることにしよう.⇒できた!

image

ごちゃごちゃし過ぎているが,こんなものだろう.R=0とR=1は特別扱いで黒と白で塗り分けている.これを小ブロックの境界を示す線で区切ることができれば,メッセージ性も多少は出てくるのだが…,ここから何かを読み取るのは難しい.色がどぎついので,透過色を使いたかったのだが,DataGridViewでは背景色を透過にすることはできないようだ.色のアルファ値を指定することまではできたが,描画されない.やむを得ず,色の明度を上げることでそれを代替することにした.

image

まぁ,こんなものではないだろうか?これならば,上よりはだいぶましと言えると思う.しかし,これでは何が何を意味するのかがまったくわからない.何か方法はあるだろうか?

ColoringStripeで算術演算オーバーフローが発生した.⇒コーディングにミスがあった.

こんなのはどうだろう?満開の桜というイメージで悪くないと思うのだが… ただし,意味不明という意味では同じだ…

image

この辺りが無難なところではないだろうか?

image

これだと,ある程度までパターンの形状が見えてくるので,周期性を考えるときの手掛かりにはなる.一応これで完成したということにしておこう.あと,やっておくとすれば,異種文字数と桁数が一致しない場合,識別できるようにしておくことぐらいだ.異種文字数=固定桁=桁数なので,固定桁がゼロでないことと異種文字数と桁数が一致しないことは同値だ.固定桁数が分かれば設定は難しくない.BuildPowerGridでは異種文字数はGetCharNumV,GetCharNumHで直接拾っている.BuildMatrixでは桁数の計算は一切行っていない.いや,ColoringCycleの中ではLambdaFunctionを呼び出している.色分けするのには周期が必要になるからだ.⇒横周期を出す時点で色で表示するようにした.

image

これで十分だと思う.異種文字数の縦と横の総和は表示されている範囲では一致しないので,表示していない.これを一致させるにはマトリックス全体の文字数をカウントしなくてはならない.さて,付け加えるものはもうほとんどなくなってきた.あと,何かあるだろうか?

さて,次は縦数列周期のカラー表示だ

さて,次は縦数列周期のカラー表示だ.方針としては,マトリックスを小ブロックに分割し,それぞれの矩形を塗り分けることで代用するというつもりだが,そのためには,ブロックの分割数,つまりサイズを決定しなくてはならない.⇒横数列周期カラー表示にブロック表示を上書きしてみた.イメージとしては,これに近いものになる.

縦数列周期カラー

このマトリックスはγ=200でα=100.横周期Λは不定だが,α=108のとき最大値20を取る.φ(γ)の値は80だが,小ブロックの周期はもっと小さい.明らかにブロックと認識される矩形サイズは10x10だ.この10という数字がどこから来るものかを知りたい.明らかに言えることは,この区切りは横に0が並んだ行であることだけは間違いない.従って,ゼロ行の発生機序が分かればおそらく小ブロックのサイズを確定できると思われる.これは多分それほど難しくないとは思われるが,試行錯誤なしで式から直接導出できるかどうかが問題だ.しかし,よく見ると,どうもこのパターンはかならずしも理論通りになっていないようにも見える.縦数列のブロックが個々に異なるのはよいのだが,横周期は少なくとも1つ置きには一致してほしい.⇒横周期のカラー表示がまだ収束していない可能性がある.もう一度確認する必要がある.

γ=200のマトリックスでα=94,ε=79 のとき,周期#は10で周期列は{94*,36*, 184, 96, 24, 56, 64, 16, 104, 176, 144, 136}のようになっている.つまり,先頭項は184だ.後半部はおおむね正しく表示されているように見えるが,横インデックスが64より前の部分ではカラー表示が崩れているように見える.どうも,まだ仕上がっていない気配だ.⇒まだいろいろあると思われるので,まず,ともかくマトリックスに異種文字数を出しておくことにしよう.これは,マトリックスに表示される値なので,BuildPowerGridで計算するというのでもよいのではないか?⇒この計算は確かTestMtrixでやっていたはずだ.

TestMatrixでやっているのは,基本的に異種文字数カウントだけだ.BuildPowerGridは独立に呼び出される可能性があるので,別物としておいた方がよい.TestMatrixではs1(), s2()という2つの配列に異種文字数カウントを入れて返している.とりあえず,BuildPowerGridの中からこの関数を呼び出してみよう.

TestMatrixを実行して,System.IndexOutOfRangeExceptionが発生した.work(MT(i, j)) = work(MT(i, j)) + 1でエラーが起きている.workのサイズはγだ.maxにはγ=200が入っている.⇒BuildMatrixにはモードがある.通常はノーマルモードで表示される範囲のマトリックスのためのテーブルを生成し,フルサイズモードの場合のみγ全体をカバーするテーブルを生成している.しかし,異種文字数をカウントするだけならフルサイズのテーブルがなくても間に合うはずなのだが…

つまり,一サイクル分を計算すれば十分なはずだ.ということは,TestMatrixの論理は大幅な書き換えが必要ということではないだろうか?横数列に関してはLambda関数で代用することはできる.縦数列の場合はそれに相当するものがない.GetResidueStripeという関数はある.この関数は文字列を返すようになっているが,改造して配列を返すようにすればよい.グリッドに表示されている範囲だけを計算し,その関数の中で異種文字数をカウントすればよいと思う.つまり,縦数列異種文字数カウント専用ルーチンということでよいのではないだろうか?横数列用も作ることにしよう.一応できたようだ.

image

ただし,BuildPowerGridでは,表示されている範囲の異種文字数しかカウントしていないので,横数列と縦数列で異種文字数の分布が一致するか否かの検定を行うことはできない.とりあえずは,これで十分だ.さて,もう一度マトリックスの不備の問題に立ち返ることにしよう.

どうも,行ヘッダに出す数宇を間違えてしまったようだ.ここにはやはりインデックスが出ていた方がよい.表面には出ていないが,通し番号は行ヘッダ部に表示されている.

横数列の異種文字数カウントには固定部文字数が入っている.このため,桁数ないしΛと一致しない.調整した方がよいのだろうか?調整した値を表示するとすれば,これは剰余数列の周期そのものになり,Λとも一致する.だとすれば,単純にΛ数ないし桁数を直接表示してしまった方が早い.⇒ここでは保留としておく.

α=94で周期の乱れが発生するのは,数列中に1が現れないためと見られる.このため.数列の末項が見つからず,おかしな形に繋がってしまっているものと思われる.⇒初項が検出された場合には必ずモードを切り替える用に修正した.⇒これで正しい表示になったものと思われる.プリントして小ブロックに区切ってみよう.

マトリックスγ200-α94

大体正しい図になったように思われるのだが,厄介な問題が一つある.周期は完全一致していると言ってよいように思われるが,位相に微妙なずれが発生する.これは,行によって固定桁が異なるためだ.従って,位相のずれは避けられないと思われるのだが,それが縦数列にどう影響するのかがまだよく分かっていない.⇒いや,均等にずれるのだから,その影響は無視できるのではないか?仕上がりは,下の図版から横数列のカラー表示を抜いたようなものになると考えられるのだが…

マトリックスγ200-α94-2

イメージとしては,概要,下図のようなものを想定しているのだが…

マトリックスγ200-α94W

この図版はγ=200を64x64で出力したものだが,縦数列の周期が10なので,200÷10=20のパターンが出現することになると考えられる.いまのところ縦数列に関して分かっていることは回文になる数列が存在するということくらいしかない.上のような色付けならある程度機械的に処理できると考えられるので,このくらいで手を打ちたいというのが本音のところだ.⇒同じ番号を同色で塗りつぶすという手も考えられる.この場合,横一列に0行と1行が並ぶので縦数列の特異性が多少なりとも見えてくるのではないだろうか?

これは試してみる価値のある実験であるとは思われる.固定部を切り捨てて,強制的に位相をそろえたらどういうことになるのだろう?それもまたおもしろい実験になりそうな気はするのだが…小ブロックのタイルを敷き詰めるというのは意味のある操作であるとは思われるが,背後になんらかのパターンがないと,ほとんど意味が通じない.意味もなくただ,ダンダラに塗り分けたようにしか見えない.

Lambda関数で周期桁数と固定桁数を返す

Lambda関数で直接周期桁数と固定桁数を返せるようにしたいのだが,頓挫している.どうすればよいか?やはり,1点づつ検査するしかないのではないだろうか?桁数は判明しているのだから,それを使ってやりくりすればなんとかなるような気がする.修正を試みているところだが,反例が出た.offset=0 <> drop=2 α=6 γ=18 Λ=0.この事例では数列は{6*, 0*}で2#0だ.⇒これは通ったが,別の反例が出てきた.offset=2 <> drop=0 α=7 γ=18 Λ=3.この事例では数列は{7, 13, 1}で0#3,また,反例が出た.offset=0 <> drop=2 α=12 γ=18 Λ=0.このサンプルは{12*, 0*}で2#0だ.まだダメだ.offset=0 <> drop=1 α=15 γ=18 Λ=1.このサンプルは{15*, 9}で1#1だ.⇒どうやらできたようだ!これができると,今度はΛとオフセットを使って剰余周期列を生成できる.⇒既存のGetResidueCycleは廃止し,別途MakeResidueCycleとして作り直すことにする.

いや,オフセットと周期が分かれば,具体的に数列を与えなくても色分けはできるはずだ.次のような手順になる.

  1. mat.RowTopからmat.maxrows分以下を行う
  2. 先頭列が固定部(オフセット)の範囲内ならば,テーブルの行を走査して初項を見つける.初項が見つかった位置から塗りつぶしを開始する.
  3. 先頭列が固定部(オフセット)の範囲外のときは,すでに区間に入っているものとして,塗りつぶしを開始する.
  4. 塗りつぶし中にゼロ項を検出したときは,そこで打ち切り
  5. 塗りつぶし中に1項を見つけときにはそこで塗りつぶしを中断し,ステップ5に戻る.

一応動き始めたが,まばらなところがある.

image

1の入っている周期列は大体表示されているようだが,それ以外は全滅だ.初項が見つかっていないのではないだろうか?⇒Lambda関数が悪い.α=1,γ=1で0を返している.⇒ようやくできたようだ!予想外のかなり興味深い図柄になった.

image

図で見ると垂直方向にも周期性がある(かの)ようにも見える.もう少し拡大した図を出してみよう.

image

縦数列の周期性がはっきり見える.γ=18を3分割して3種のパターンが繰り返されている.このパターンを反転させるとどう見えるか?というのも興味深いところだ.上の図にはまだ誤りがある.6, 12, 24, 30などで頭の固定部が塗りつぶされている.それを修正すると,上記パターンの反転は完全に同型になるはずだ.試みに反転パターンも出してみた.

image

パターンは完全に同型だが,左右反転したものになっている.個別の行は固有の反復周期を持っているが,全体としてみると,それらの公倍数となる反復周期が観察される.いまの場合の全体周期は12だ.この12という数はおそらくφ(γ)の約数列から出てくるものであろう.

さて,どこまでできているのか見てみよう.⇒ダメだ.かなり崩れている.γ=100で試してみたところ,大体は合っているが,間違っているところが出てくる.設定はα=15,ε=115となっているので,Rα=15とRε=35が画面中央付近に配置されるようなマトリックスになっているが,どうも,取っ掛かりのところで失敗しているようだ.後ろの方を見ると正しい周期に乗っている.

たとえば,α=6の剰余数列は,{6*,36,16,96,76,56,}で1#5となっているので,頭項が36,末項が56でなくてはならないが,6で始まって76で終わっている.その次からは頭項36で周期に復帰している.そもそも6は固定部に含まれるので除外されなくてはならないのだが… 結局,offsetを持つ剰余数列をうまく処理できていないと見ることができる.⇒できたようだ.⇒と思ったのも束の間,α=100,ε=115, γ=200で真っ白になってしまった.どうも,αが64を超えると誤動作が始まるようだ.65ではまだある程度まではカラー表示されているが,70ではまったく表示されなくなる.⇒大体動作するようになった.

εを操作して,枠外にはみ出すように調整しても,マトリックスがその位置を含むように開かれない.1~64の部分が表示されたままだ.α-100, γ=200, ε=79で,Rαは100,Rεは79だが,Rε=79は圏外だ.つまり,マトリックスを生成する論理ではマトリックスの水平シフトがまったく実施されていない.⇒ある程度安定した動作になってきているので,一度バックアップを取っておこう.

mat.ColumnTopはBuildMatrixで決めている.多分この論理が間違っているのだろう.Rε > maxcolumsの場合,ColumnTop = Rε – maxcolums \ 2という値が入っているが,ColumnTop + maxcolums >= maxの場合にはColumnTop = maxcolums + 1に修正されている.⇒この補正を止めたら動作するようになった.この補正は何のために入っているのか?max=γであり,このテーブルのサイズを意味している.γがMAXSQUARESIZEを超えている場合には物理的にテーブルを構成できないので縮小する必要があるためのパラメータだ.

maxcolumsはマトリックスの横幅であり,ColumnTop + maxcolumsというのは,マトリックスの右端を意味する.これはおそらく,マトリックスの右端がMAXSQUARESIZEを超えないための措置と思われるが,誤った論理になっている.書き直しておこう.これで横数列の周期カラー表示は大体まとまったのではないかと思う.

image

あと,これに縦数列の周期カラー表示を追加すればほぼ完成になるのだが,こちらの方は横数列ほど単純ではない.横数列の周期カラー表示を見ても分かるように,縦数列にも周期性が認められることは確かだが,縦数列の難しいところは,①回文というパターンがある,②一つの周期の中で同じ文字が複数回出現する,などなど.この周期性を確定するのはかなり難しい.しかし,縦数列の長周期はγに固定されているので,周期性があるとすれば,γの約数でなくてはならないから,ある程度までは絞り込むことができる.もちろん,γが素数なら周期は存在しない.

横数列で0の並びになる場合がある.このような行が存在する場合には,その行を区切りにした周期が発生する可能性がある.たとえば,γ=18の場合,6^2≡6^3≡0 mod 18dだから,周期6の数列ができる{1, 8, 9. 10, 17, 0}や{1, 10, 9, 10, 1, 0}など.

マトリックスの0行の表示がおかしい.γ=18のとき,{1, 2, 3, 4, 5, 0}の繰り返しになっている.γ-1=17の剰余になっていなくてはおかしい… 除数がΘ=φ(γ)になっている.いや,この表示は正しい.⇒やはり,異種文字数の表示は必要なのではないか?

このマトリックスにはまだ不備がある.列ヘッダに入っている番号が1からの通番になったまま変化しない.これでは問題がある.マトリックスの左端には固定部が固まっていて,これらは循環に関与しないため,Rεの値だけでは位置決めができない.たとえば,α=3, ε=121の場合,Rα=3,Rε=1の位置,つまりM(3, 121)には3という値が入っているが,Rは9である.同様のことは行についても言える.(ただし,行では実害はない)たとえば,α=123としても,行ヘッダの番号は変化しない.⇒αとεが生値でヘッダに現れるようにする必要がある.

大きい数を扱おうとするとセル幅が大きくなってしまうが仕方ないだろう.つまり,Rα,Rεをマトリックス中央に配置するのではなく,αとεの生値が中央に来るようにすべきだ.⇒いや,元々そのように作り込まれている.何か(操作的に)勘違いしていたのではないか?いや,確かに上記のような動作になる場合がある.何か調整が入っているのだろう.ColumnTopとRowTopはBuildMatrixで決めているので,そちらを見る必要がある.⇒修正した.ようやく,思ったような図になった.

縦数列で一番肝心なポイントは,γの区間がいくつに分割されるか?という点だ.横数列の場合には,この値はφ(γ)に一致する.γが素数ならγ-1だが,一般にはΛの倍数である.場合によっては,この値をΛと呼んでもよいのかもしれない.あるいは,もっと相応しい名前があるかもしれないが,いずれ,何か名前を付ける必要性が出てくるような気がする.

縦数列の場合はもっとはっきりしている.γの範囲を等分するゼロが並んだ行が発生するからだ.この分割数はγの約数であるから,γが素数の場合には1となる.いや,もしかして,これもφ(γ)なのではないだろうか?そう考えてよいような気がする.つまり,縦数列は(γ-1)/φ(γ)個の縞に分割されると考えてよい.ただし,この縞は横数列のように同じパターンの繰り返しではなく,個別に異なるものとなっている.つまり,マトリックス全体はたかだか,(γ-1)/φ(γ)個の小ブロック=タイルで埋め尽くされていると考えてよい.この小ブロックのサイズはφ(γ)xφ(γ)である.縦数列の周期をカラー表示するとしたら,この小ブロックを塗り分けることになるのではないだろうか?

剰余数列の周期をカラー表示する

まず,横数列の周期をカラー表示するところから始めよう.

パネルのタイトルが空欄になっている.「久留島喜内の置き土産」となっているはずなのだが… どこかで消してしまったようだ.

ボタンを押されたときに計算するとしてみたが,チェックがオンになっている状態でBuild Matrixが押された場合,カラー表示されないというのは不都合だ.やはり,初期描画するタイミングで色別表示するしかない.というか,マトリックスを描画しているのはForm2の関数であり,BuildMatrixではテーブルを構成しているだけなのだから,BuildPowerGridで対処すればよいのではないか?⇒チェックボックスをチェックしただけでは表示は変わらず,描画を更新するためには,BuildMatrixを押す必要があるというのでもよい.

どうもラジオボタンの使い方が難しい.すべてをオフにするためにはもう一つボタンを追加しなくてはならない.ラジオボタンの場合にはすでにオンのボタンがあると,そのボタンの(オフ)イベントが先に発生してしまう.⇒やや変則的だが,下記のようにしてみた.

image

★LambdaFunctionでγをgcm(α, γ)で割り込むという処理が組み込まれているが,この除算回数と固定部の桁数は完全に一致する.⇒これは必ずしも言えない.LambdaFunctionではΛ値を確定できるが,いまのところ固定部桁数を決定できる論理にはなっていない.

LambdaFunctionではGetResidueCycleでべき剰余数列の周期を取り出しているが,戻り値のcycは固定桁+周期のはずなのに数値が合わない場合がある.reduced+Λがcycと一致しない.たとえば,α=4, γ=16のとき,reduced=2,Λ=0, でcyc=1となっている.α=6 Γ=16 では,γ=1 reduced=4 Λ=0 cyc=1 となる.ただし,画面では 4 # 0 のように正しく表示されている.⇒GetResidueCycleの仕様をチェックする必要がある.この関数はLambdaFunction専用となっている.周期を出力しているところでは何を使っているのだろう?

周期を出力しているResidueFuncProではPowerResidueFuncで数列とその長さを取り出している.この関数では固定部と周期を分けた数値を返している.剰余数列はPRCycleという配列形式で返されて,それをDispResidueCycleで表示している.GetResidueCycleでも配列で剰余数列を返している.Λはこの配列内で1を検出することで決定している.GetResidueCycleの返す値には固定部は入っていない模様だ.cycは1を返しているが,cycle配列の内容は{0}だ.⇒GetResidueCycleはループカウンタのjを返しているが,jは0発進なので最小でも1になる.最初の値はα mod γ なので割り切れる場合は0になる.サイクルの長さに換算すれば,これは0とみなくてはならない.いずれにしても,cycには固定部は含まれないので数字の一致を求めることはできない.

逆に言うと,Λとcycはつねに一致しているのではないか?⇒そう言える.従って,Λは計算しなくても求められる.計算値は検算としては有効だが… むしろ,固定桁数とreducedが一致しない方が問題だ.α=22 Γ=12 γ=3 reduced=2 Λ=1 cyc=1の場合,2回GCMによって割り込んでいるが,FIXEDは1桁しかない.つまり,reduced値は決定的ではない.しかし,gcm(22, 12)=2でreduced=2というのはおかしい.⇒いや,数字は間違っていない.gcmで割り込んでいるのはγ値で,αには手を付けていないからだ.γ=12は2^2×3なので2で2回割られている.

おそらく,αの約数となるγの因数の個数が固定桁になるのだろう.⇒GCMが変化したときだけreducedをカウントアップするようにした.これでα=12 Γ=36 γ=1 reduced=2 Λ=0 cyc=1のときの固定桁2 # 0 と完全一致した.この計算は多分間違っていないと思われるが,GetResidueCycleの戻り値とΛが完全一致するように調整しておきたい.Λが値を持つ条件は数列に1を含むことだったと思うので,それだけをチェックしてやればよいのではないか?

GetResidueCycleはLambdaFunction+剰余数列の生成になっているので,各行ごとにGetResidueCycleを実行して周期列を取り出し,その先頭文字を見つけてそこから周期分着色するという方法で色分けしてみた.一応動いた.こんな感じになる.

image

もう一つ,これをダンダラに塗り分けてみた.

image

多少やり過ぎの感はあるが,わかり易くてよいのではないだろうか?一応動いてはいるのだが,まだどこか不備があるようだ.γ=12では失敗している.α2, 3, 4, 6, 8, 9 , 10 など,軒並み落としている.

image

GetResidueCycleでR=1が検出されない場合は0を返しているためだ.これは間違いだ.どういう場合,Λが0と判定すればよいのか?⇒Rが0になっているかどうかを見ればよい.

image

大体できたようだ.γが素数の場合にはこんな感じになる.

image

この図ではγ=17でマトリックスサイズはその倍近い32なので,中央付近で折返しになる.長さ16の周期列が最長で,これが原始根と呼ばれるものだ.つまり,γ=17の原始根は{3, 5, 6, 7, 10, 11, 12, 14}だ.素数499のマトリックスはこんな感じになった.

image

頭の1が塗りつぶされていないのは,1が周期の末項になっているためだ.設定ではεが115なのでその辺りが中央に来るように配置されている.ε=460で描画してみよう.どうもあんまり芳しい図にはならない.

image

γ=499では,ほとんどの周期は83, 166, 249, 498 などの長いものになる.これはφ(γ)が {1, 2, 3, 6, 83, 166, 249, 498} のような約数を持っているためだ.周期がマトリックスの横幅より大きいときにはすでに周期に入っていると見て,終わりを探るという動作の方が実情に合っているのではないか?この場合は末項を見つけて折り返すようになる.周期とオフセットの両方が分かれば,計算だけで出せるようになるのだが… そのためには,LambDaFunctionのオフセット仮説の証明が必要だ.これが確立すれば,LambDaFunctionだけで計算が完結する.⇒Matrix Test で検査してみよう.

▲マトリックスをビルド/テストしたときには,Λのリストを出力する.同様に原始根のリストも出力すべきだろう.これらはγだけで決定されるデータなので,ビルドマトリックスで出力するのが適当だ.

GetResidueCycleで配列サイズオーバーが発生した.γ=1でα=6.⇒修正ミスがあった.⇒対処した.

GetResidueCycleを少し改造して固定桁を計算できるようにした.この値は呼び出し元に参照渡しで返せるようにした.LambdaFunctionでも固定桁をoffsetとして参照渡しで返せるようにした.比較してみると,GetResidueCycleは使い物にならない.修正の余地はあるかもしれないが,一旦ここは廃棄するしかないような気がする.LambdaFunctionは確実に動作しているように思われるので,試してみよう.

▲α=2,γ=18でLambDaFunctionの返すoffsetとdropが一致しない.offset=1, drop=0.drio=0が正しい.GCMで割り込むという手法は正しいと思われるが,そのカウントが直ちに固定桁数に転化する訳ではない.その辺りをもう少し整理する必要がある.