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で割り込むという手法は正しいと思われるが,そのカウントが直ちに固定桁数に転化する訳ではない.その辺りをもう少し整理する必要がある.

更新モードとテストモードを切り替える

初期画面の表示でMakeRecursionUnit から一行出力されているが,不要なのではないか?⇒更新出力で表示されているので,明らかに不要だ.modflagを新設しValueChangedProの入口で立てるようにした.

Residue Test では「原始根を検出」という表示が出る.Seed Test でも一二行の表示が出るが,前回項目の直後に出力されるため,混同のおそれがある.画面更新の後に改行を入れるようにした方がよい.PrimeTestでは更新出力は出ない.この方がよいと思う.そのテストの結果のみを表示するようにした方がよい.InvertTest も同様の方式だが,MakeRecursionUnitの行が出るだけだ.Matrix Test では更新情報を出しているが,これも抑制した方がよい.つまり,更新モードとテストモードを明示的に切り替えるべきだ.⇒対処した.

固定部と#,gcd(φ(γ),#)の更新が遅れてバタつきが気になる.テキストボックスのクリアは不要なのではないか?⇒ValueChangedの冒頭でClearParameterを実行している.その理由は更新損ねて古いデータが残るような事態を避けるためだが,そろそろ外してもよいのではないだろうか?⇒対処した.快適な表示になった.

★原始根を持つことと離散対数が決まること,Λ値が確定することは同値だろうか?たとえば,α=39,γ=27 の場合,cycle={12*, 9*, 0*}でΛ=不定になるが,R=12や9の離散対数(べき指数)は決定できる.尽数列は現れないから,原始根は持たない.

★ある数αの循環単位Uがβ進数で生成するΞがレピュニット数になる条件はgcd(α, β)=1である.つまり,αとβが互いに素であれば,αの循環単位Uはレピュニット数Ξを生成する.この命題の真偽は?

Prime Test で Test Completeの表示の後に,MakeRecursionUnitの表示が出る.Test Complete はPrimeTestClickで出している.その後,PrimeTest_Clickに戻ったところでvalue_βを書き換えているので,ValueChangedが起動されている.順序が逆転している.PrimeTest_Clickで完了メッセージを出すようにした.

Matrix Test でテストの終わりにステータス情報が2回出る.α=2, γ=31とα=39, γ=31だ.後の方は通常のルーチンだが,最初のは余分な感じがする.どこで出しているのだろう?⇒MatrixTestではテスト終了時にγとαを書き戻している.passflagは落ちているので更新イベントが実行される.現行ではγしか書き換えていないはずだから,αの書き換えは不要なのではないか?⇒これで一度だけになった.⇒いや,αもテスト中に書き換えている.passflagをリセットする位置を一つ下げるということも考えられるが,だとしたら,むしろテスト中はpassflagをオンのままにして,完了時に明示的に更新するようにした方がよい.つまり,完了メッセージを出してからリセットという手順がよいと思う.

これはつまり,OutputStatusの冒頭でUpdateParameterを実行するということを意味する.しかし,これだけではUpdateParameterが起動されない.OutputStatusはValueChangedProから呼び出されているので,イベントを捨てているのだから,テスト完了時点で明示的にOutputStatusを実行する必要がある.⇒OutputStatusではなく,UpdateParameterの起動だ.また,OutputStatusはUpdateStatusにリネームした.大体予定通りの動作になったと思う.

タスクバーのアイコンの状態がおかしい.タスクバーにピン留めすると,古いアイコンが出てきてしまう.⇒アプリケーションとパッケージでそれぞれアイコンを指定できるようになっている.パッケージでも歯車アイコンを使うようにしたが,戻ってしまう.元のリピートアイコンのファイルをフォルダから削除しても効果がない.最終的にリブートしてまともな動作になった.原因は不明だ.

テストの内容については見直しは必要だが,大まかな枠組みだけは整理できた.マトリックスに異種文字数を出すところから着手しよう.⇒いや,異種文字数を出すのではなく,「周期」を図形的に可視化すればよいのではないか?塗りつぶしかないし枠で囲むような形式で周期単位を明示することはそれほど難しくない.行末に数字を見せるより,ずっと直感的なのではないだろうか?異種文字数を仮に出すとしたら,その数字を本体数字と誤読する可能性もある.

(色別にすればよいのかもしれないが)そうなると,マトリックス画面でもコマンドを実行できるようにする必要が出てくる.ポップアップメニューで選択できるようにするというのは一案だが…場合によっては,パネルにボタンを設置することも可能だ.Build Matrixのボックスにチェックボックスを2つ追加してみた.

image

現行では,マトリックスの生成では単純にマトリックスを構成しているだけで,周期などの計算は一切行っていない.マトリックス構築時にこの計算をやってもよいが,チェックが入った時点で初めて計算するというのでもよいのではないか?この計算は行ないし列ごとに行わなくてはならないので,できれば表示されている範囲の計算で間に合わせることにしたいのだが,可能だろうか?横数列の場合はほぼそれで問題ないのではないかと思う.横数列では同じ数がでてくればそれは周期に当たるからだ.周期が見つからなかったとしても,それは長い周期の一部なのだから,特に問題はない.縦数列の周期というのはいまのところ,まだ具体的には実装されたことがない.縦数列の場合には回文というのが出てくるが,これに関しては一応の解析は行っている.

マトリックスは64x64以上のものは作れないが,テーブル自体は原則γ^2のテーブルを生成している.ただし,MAXSQUARESIZE=32767を超えることはできない.従って,γがこれ以上大きい場合にはマトリックスを開くことはできないと考えられる.とりあえずは,これでよいことにしておこう.ベースになるテーブルが存在していれば,マトリックスが小さい場合でも対応は可能だろう.おそらく,Test Matrix ではそれに近いことをやっているはずだ.

出荷直前というモードには入っているが…

出荷直前というモードに入っているが,まだ遠い.

関数名にギリシャ文字を含むというのはあまり美しくない.配列名と読み間違えることもある.⇒Λ()という関数はLambda()に変更した.ΛFunctionはLambdaFunction に変更する.

α=2,γ=244のとき,MatrixTestで配列サイズオーバーが出た.⇒sumh()で起きている.配列サイズをmaxcolumsで指定していた.⇒maxに改めた.また,配列を使い回ししていないときは,Array.Clearは不要と思われる.

TestMatrixでDumpMatrixを実行するようにしたが,時間が掛かり過ぎる.∑だけを表示するようにしてみたが,同じだ.DumpMatrix自体を取り止めるしかない.⇒BuildMartixの中でもDumpMatrixを実行していた.しかし,それを止めると何もダンプされなくなってしまう.⇒止めてあった「縦軸と横軸の異種文字数の分布を比較」を復活させた.今回は,暫定的にここまでとしておく.

異種文字数に関連して,2023/05/15に「文字数xGCMは k-1 に一致することを確認する」という項目がある.これはγが素数の場合に限られているようだが,チェックする必要がある.異種文字数が一致するというのも素数に限られているようだ.多分,この証明は容易に得られると思う.γが素数の場合「(異種)文字数xGCMは k-1 に一致する」のは当然だろう.γ=Pであるとすれば,異種文字数=周期数列=p-1でGCMはつねに1となると考えられるからだ.異種文字数=γ-1となるための条件はγが原始根を持つことであり,非素数でもそのような場合はあり得る.

γが素数の場合は横数列と縦数列で異種文字数の分布が完全に一致する.つまり,異種文字数のリストが順序を無視して一致する.γが非素数で原始根を持つ場合はどうか?⇒Test Matrix を使って調査する.

TestMatrixでは結局異種文字数のカウントしかしていなことになるが,このテストが意義のあるものになるよう結果を整理する必要がある.

updateで出力されるパラメータを見ておこう.「αとγが互いに素でΛ数が立たない場合」という表示が出ている.γが1の場合は除外してもよいだろう.DispNotationが計4回出てくる.DispNotationの呼び出しは,①ValueChangedPro,②DispInvertFunc,③valueBetaChangedで出てくる.①は不要と思われるので止めておこう.⇒DispNotationでダブって表示していた.⇒updateでは画面上のデータをすべてダンプするという形式でよいのではないかと思う.このとき,計算値ではなく,画面上のデータを拾い出して出力するだけでよいのではないか?その方が整理されて分かり易いのではないか,データは網羅的である必要もある.

B面に数字和と数字根を出すことも考えられる.しかし,この2つだけでは一行が埋まらない.もう一つくらいあるとよいのだが… βの素因数は出してある.φ(β)が出ていないのは片手落ちの感じもするが,βはかなり小さい数字なので意味があるかどうか?Λという数は,現在Lamda(α, γ)として取り出しているが,Λβ=Lamda(α, β)というのもあるのではないか?ただし,βの場合はβが基数とも見られるので,Λβ=(β, α)となる可能性もある.⇒最初にすべての出力をverboseで止めておこう.⇒何も出なくなった.ValueChangedProからは,ResidueFuncProをsilent=Trueで呼び出すようにした.

「互いに素でないのに1の項」というメッセージが出た.α=34 γ=18 初項=16 (α, γ)=2 one=1 zero=14 overflow=False.ε=115,β=10.α=37, 39でも出ている.αを変化させただけでは発現しない.このメッセージはDispResidueCycleが出している.どうもこれは,誤動作ではないかという気もするが… ⇒計算がまったく合っていない.検定中のダンプと検定終了後の画面では内容がまったく違う.⇒おそらくValueChangedProを呼び出したあとで障害が発生しているのだろう.アウトプットは画面の内容を転写しているだけなので不一致が生じる可能性がある.テスト中に画面を書き換えていない場合は参照できない.

αの因数が出力されていない.⇒いや,出ている.順序が違うだけだ.

これはかなり由々しき問題だ.⇒再現した.αを39固定とし,γを小さい数から31まで増加させて発生した.表示ではγ=31となっているが,エラーメッセージではγ=30となっている.このエラーはεないしγの値変更イベントから実行されている.上ではγを増加させてとしているが,逆のようだ.31→30の書き換えだろう.⇒ダメだ.再現しなくなってしまった.かなり厄介なことになった.どうもこれはタイミングの問題ではないかと思う.つまり,連続したイベントが重複して処理されているため整合しなくなっているのではないだろうか?

上記の再現テストをやっていて,配列サイズオーバーが起きた.

image

RSという配列で起きている.RSのlengthは34,i=34だ.max2=47でiは範囲内だ.RSは呼び出し元で生成されているが,max2も引数で渡されているので,範囲内に入っているはずなのだが… 呼び出し元のResidueFuncProではmax1=47でPRCycle(47+1)で生成している.PRCycleはシステムに常駐する配列でこの配列をReDimしているのはResidueFuncProだけだ.ResidueFuncProでは引数のnumでαを更新している.これはかなり問題がありそうだ.⇒確かにResidueFuncProがネストして実行されている.K_TextChangedではpassflagを見ているが,立ててはいない.しかし,passflag1本でコントロールするのは難しいと思われる.むしろ,内部に静的変数としてフラグを持たせた方がよいのではないか?⇒収まったようだ.これ以外の数値ボックスの動作もチェックしておこう.⇒総点検し整備した.

MakeRecursionUnitで「γが素数で原始根にならない場合」というのが発生している.γ=43でα=39.固定桁と#,およびgcm(γ, #)に値が入っていない.この現象はβ値を連続的に変えているときに起きた.β=10から増加方向に変化させるとこのエラーが続く.マトリックスが間違っていないとすれば,この動作は正しいということになるのだが… いや,まったく正しい.「r^λ≡1 mod γとなるような最小の整数をrの位数Λと呼ぶ.Λ=γ-1のとき,rをγの原始根と呼ぶ.」当然,γが素数でも原始根にならないαはいくらでも存在する.βを変更しても,αとγの関係は変わらないので連続して,このメッセージが出てきたというだけだ.このメッセージは止めてよい.一応,Λがγ-1でないことだけはチェックしておくことにしよう.

γ=43の場合は,{3 5 12 18 19 20 26 28 29 30 33 34}の原始根がある.⇒Matrix Testでは原始根のリストを出力すべきだろう.ないし,BuildMatrixでマトリックスを生成するタイミングで情報を出力してもよい.⇒一番手っ取り早いのは,異種文字数をマトリックスに表示することではないだろうか?異種文字数がγ-1であるような行は原始根であると言える.⇒マトリックスの末尾桁/行に異種文字数を出しておこう.

▲γ=43, α=1, 2, 4, 8などでは逆数の循環桁数はゼロとなり,U, αU,Ξは空欄になっているのに,レピュニットがTRUEになっている.

通常はコントロールパネルは閉じたまま

#=0の場合を例外として,Λ値をつねに確定値として表示できるようになったので,すでに「Get Λ」というボタンは不要である.というか,これを押すとむしろ,誤動作することになる.現行のGet ΛはΛが不定の場合,γ値を小さくなる方向で操作して有効なΛ取得するということをやっているが,不要というより,有害である.

コントロールパネルは通常は閉じたままという使い方をすることが多いと思われるので,updateボタンを道具箱に移すというのが適当なのではないだろうか?再描画という意味で使われる時計回りの回転アイコンを使えばレイアウトを崩さずに場所を確保することもできるだろう.このツールのアイコンが再描画アイコンと向きが違うだけのものになっているというところが痛いところだが… 循環を示すもっと気の利いたアイコンはないものだろうか?⇒車輪アイコンというのはパターンがいろいろあっておもしろそうだ.歯車のような形状のものもある.

自転車の車輪というのもあるが,スポークと剰余数列には何か結びつきがあるだろうか?歯車アイコンはどうか?2つの歯車が噛み合っている図式などもある.歯車から2つの整数の公約数を求める運動などを連想することは可能だ.数というのが,ある種の歯車装置になっているという直感はかなり正しいような気がするので,これを採用することにしよう.歯車アイコン10というのを以下からダウンロードした.

https://icooon-mono.com/14476-%E6%AD%AF%E8%BB%8A%E3%82%A2%E3%82%A4%E3%82%B3%E3%83%B310/

ただし,これだけではアイコンとして使えない.PNGをアイコンに転換するツールが必要だ.ドラッグ&ドロップするだけでアイコンを生成してくれるToYconというのがあったので,インストールしてみた.

https://www.snapfiles.com/downloads/toycon/dltoycon.html

確かに一発でアイコンができた.

image

思ったほどのインパクトはないが,意味は通じるのでこれでよいことにする.以下がおそらく最終的なレイアウトになるだろう.

image

image

一般ユーザはおそらくマトリックスを生成するとき以外はこのパネルを操作しないものと思われる.このパネルは閉じていても問題なく操作できるので,特に不自由はないというより,その方が軽く使えてよいと思う.そうなると,マトリックス生成ボタンも主画面に移すということが考えられるのだが,その辺りはどうか?⇒マトリックスはそう頻繁に開くものではないので,現行でよいのではないだろうか?

これまでブランクになることが多かったΛの値がつねに決まっているというのは気持ちいいものだ.アウトプットにはまだ古い記号遣いが残っている.これらも完全に合わせなくてはならない.出力内容については今回は保留としておきたいが,Matrix Testのアウトプット量がやや少ない感じがする.もう少し何か出してもよいのではないか?

ψγという表示は間違っている.かつてγと呼ばれた変数が現在ψと呼ばれているものなので,ψγではまったく意味が通らない.⇒対処した.

どうも,もう一度変数名を再考する必要がありそうだ.まず,べき指数のψは止めて,εと呼ぶことにしよう.現在独立変数はα,β,γ,ψの4種であり,その意味ではα,β,γ,ε は覚えやすいし,意味もはっきりしている.Rはその意味では従属変数であり(ユーザ入力は可能だが,多少変則的な性格がある),独立変数をギリシャ小文字とし,従属変数は大文字で統一するのがよいと思う.R,Λ,Uはすべて従属変数だ.

ψαとψγはどちらもマトリックスのインデックスに関わる値なので,一種の位相のようなものとしてべき指数と共通のψという文字を割り当てたが,①いずれも従属変数であり,②位相という概念を導入するのはまだ時期尚早,③実態は剰余であり,Rα/Rεないし,αR/εRのような表記の方が適切,かつ直感的と結論した.⇒また,記号の一括変換をやらなくてはならない.こんどのは少し厄介だ.⇒いや,簡単に終わった.

アウトプットで使われている文字をチェックしておこう.⇒どうも現状ではどのテストもほとんど何も(独自)出力していないように見える.MatrixTestの出力が少ないのはDumpMatrixを止めているためだろう.

▲PrimeTestで「φ=keta」のような表示が出ているが,これはΛがφ(α)を割り切ると考えていた頃の残留物ではないか?

▲テストの開始と終了を明示的にアウトプットする.

アウトプットとストリームへの書き出しが未整備⇒OutputStreamというルーチンを新設し,①Debug.WriteLine, ②出力パネルへの書き込み,③パネルのスクロールを一括操作できるようにした.

φ(α)とφ(γ)の約数列が出なくなってしまった.φ_αTextとφ_γTextだ.⇒これらの文字列はouttextで保持していたため,verboseで止めてしまっていた.⇒解消した.

α=244, γ=2でΛ検出不能になる.αがγで割り切れてしまうためだ.これはγを(α, γ)で割り込んでいったときに1となることで判明する.このような場合には検出不能を表示しない.

α=244,Γ=2のとき,Λ=2となるが,ΛFunction=0で一致しない.検算のため,GetResidueCycleの結果と比較しているが,cycが1を返しているため,Λが2となっている.⇒cycには固定部の長さも含まれる.⇒論理ミスがあった.修正して正しく動作するようになった.

▲DumpMatrixで配列サイズオーバーが発生した.

▲保存ファイル名とホルダーの指定の動作が芳しくない.

Λ値が周期桁数と完全一致するようになった

ユーザがR値を変更して,離散対数を求めることが一応できるようになった.ここまでやったのだから,Rをテキストボックスから数値ボックスに変えるところまでやってしまおう.現在ユーザが設定可能なパラメータは4つあり,すべて数値ボックスになっている.数値ボックスの利点は,①UpDownボタンが使えること,②数値が確定するまでイベントが発生しないというところだ.特に①は使い勝手にかなり影響するので,実用性を重んじるなら必須だろう.

離散対数にはまだあまり本格的に足を突っ込んでいないので,そこまでやるか?という感もあるが,踏み出した足を引っ込める訳にもゆかない.数値ボックスの弱点は最大でもInt64の範囲の値しかとれないという点だが,今のところはそれで十分だろう.Rには現在pRtextという名前が付いている.これまではRの他にもαR,γRのという類似項目があったのだが,今回これらとは縁が切れたので別の名前で呼ぶことにしよう.とりあえず,valueRとしてみよう.

Rの設定値がγを超えても何の変化もない.⇒γ値を超えられないようにした方がよい.⇒対処した.

周期#がゼロとなるのは,ψα=φ(γ)となる場合に限られているのではないだろうか?これは横数列が(固定部を除き)0の並びになっている場合である.もちろん,(φ,#)=0である.⇒周期がゼロとなるのは,対象数αが除数(法)γで割り切れることを意味する.ただし,これはかならずしも α ≡ 0 mod γ を意味しない.α^ψ ≡ 0 mod γ となるような整数 ψ が存在すれば,周期数列桁#はかならずゼロになる.

周期数列桁#=0 の場合は,Λ値は不定であるとする.Λはφ(γ)の約数なので,除数ゼロとなってしまうからだ.また,Λは α^ψ ≡ 1 mod γとなるような最小ψ値と定義されているので,もし,Λ=0となることを許せば α^0 ≡ 1 mod γ がつねに成立してしまうので,Λ値は0しか取れないということになってしまうためである.

リターンキーを押しただけではR値は確定しない.Rは値が適合しない場合を許容しているためだ.ψの変化を見ていれば,Rが適合しているかどうかは判定可能だが,見落とした場合適合しているのか否かが分からなくなる.無効な値であることを何らかの方法で示す必要がある.一番確かなのは背景色を変えることではないだろうか?⇒実装した.とてもわかり易くなった.R値がグレー表示されている場合は,無効値である.このような場合にはコントロールパネルの「update」を押すことでノーマルな値に書き換えられる.

★Λ値は剰余数列が固定部をもつとき,そのときのみ不定になる.これは(α,γ)<>1であることと同値である.⇒この命題は間違っている.Λ不定≡(α,γ)<>1ではあるが,このような場合でも固定部0となるケースはある.α=182, γ=250では(182, 250)=2だが,固定部0:#4.従って,Λ値が不定であることと(α,γ)<>1は同値であるとしなくてはならない.⇒最終的にはΛ値不定というのは周期桁#=0の場合に限られることになった.それ以外ではつねに#=Λとなる.

psiの文字列をΛに一括変換した.113個が変換された.⇒変換しきれなかった項目が3つ残っていた.ついでにtotをφに変換した.61個あった.2005年のEFAではU-length function という用語と ψ値が並列に使われている.ようやくEFAからテイクオフできたのではないか?

ΦないしΛの約数列を参考表示する.⇒φ(γ)の約数リストを画面に表示するようにした.Λ値をその横に表示するようにしているので,Λがφ(γ)の約数であることが明瞭に示されるようになった.

ΛがΦの約数であることをべき剰余検定に応用できないだろうか?つまり,そのことを使って周期数列をより効率的に生成することはできないだろうか?しかし,Φ=γ-1になるときの#は#=Φとなるので,どっちみちγ-1の計算を実行するしかないのだが… 剰余数列をリストアップするのではなく,Λ数を取得するだけなら,Φを使うのは意味があるだろう.意味のない数ではないので,Φの約数リストを出力してみよう.φ(γ)として表示するようにした.Λが空欄になっている場合でも{φ(γ)}には#値は必ず入っている.従って,Λ=#とすることには合理性があると思われるのだが,べき剰余を直接計算して#を求めるのとは別の何らかの手段でΛを獲得することができなくてはならない.

手がかりになるのは(α, γ)値だが,これをどう適用すればよいのか?適用可能なのか?の手掛かりがつかめない.#がゼロという場合もある.このような場合には約数列{φ(γ)}の中に0は入っていないので,不定となることはやむを得ないと考えられるが,それ以外では#=Λでよいはずだ.(α, γ)がゼロでない場合には,αとγをこの値で割って既約にすることができる.このようにしても,既約のα’,γ’の対から生成される{φ(γ’)}の項は,すべて{φ(γ)}の中に含まれていると見られるので,既約対を用いれば,多少は問題を小さくすることはできそうだ.γが素数の場合は別として,γが大きな合成数である場合には,φ(γ)の約数だけをΛの候補とすることで計算を効率化できる可能性は十分あると思う.

Λ関数の引数でφを渡しているが,内部で再計算しているので不要だ.確かにループでαを変えながら複数回実行しているところはあるので,事前に計算しておいた方が有利だが,渡し方を間違える可能性があるので,冗長でも内部で計算した方がよい.⇒対処した.

現行のΛ関数はφ(γ)の約数をΛの候補として見ているが,R=1の場合しかチェックしていない.R=0になる場合,および固定部がある場合に対応する必要がある.

(α, γ)が1でないときは,互い素となるまでGCMでγを割り込んでゆくという方法が効果があるかもしれない.gcm=1ならば従来の方法で解けるので,得られたΛが共通パラメータとして通用する.⇒できた!完璧だ!おそらくこれは今回のセッションで得られた最大の収穫だ.⇒多分,証明はそれほど難しくないと思う.一度正しい命題が発見されれば,その証明は後から付いて来る.

α=77, γ=76のとき,Λ関数で停止した.α=76, γ=76,α=39, γ=76,α=31, γ=30でも.⇒逆手順になっていた.既約操作を実施した後で,互いに素のチェックをやっていた.

#=0の場合を除き完全にΛと#が一致するようになった.#=0ということは循環がないということなので,ある意味当然である.たとえば,α=17, γ=17など割り切れる場合にはそのような現象が起こる.

離散対数を求める問題

現在,3つの剰余値にR, αR,γRのようなラベルを付けているが,Rとそれ以外の剰余を区別するために,別の文字を割り当てることにする.αR,γR はいずれも数列の周期を表す数字なので,λを用いることにする.λは物理学では波長の意味で使われているので連想が効くのではないかと思う.一旦バックアップを取ってから修正に入ることにしよう.

記号文字の割当てに関してはこれで完璧ではないかと思う.これらはほとんど英文字一文字なので一括変換してすべてのテキスト出力を同期させておきたい.かなり大掛かりな修正になるが,整理してしまった方がよいと思う.⇒作業に入る前に記号の割当てについてもう少し考えてみよう.ψという文字は心理学では超能力を表し,量子力学では波動関数を表す.数学ではフィボナッチ数列の逆数和として使われている.

この意味ではψを剰余数列という波動を示す関数とみなすというのは外れていないとは思われるが,周期であるという点に注目すればむしろ,波長λの方が適切であるような気もする.この場合,αR,γRなどは位相と見るのが順当である.位相には,β,φ,ψが使われることが多い.この意味ではψ(α),ψ(γ)のような使い方が考えられる.未決の懸案事項として,#=ψとするかどうか?という問題があるが,とりあえず,n→α,e→γ,K→Θ,B→βのみ確定としてフィックスしてしまうことにする.

関数内部で同名の記号をローカル変数として使っている場合がある.→nはグローバル変数ではないのだから,差し支えないはずだ.n/Nで269個あった.コンパイルエラーは1件に留まる.b/Bは145個.k/Kは2件しかなかった.本当だろうか?⇒丸残りになっていた.205個出た.γはeとして使われる場合がある.しかし,eはイベントハンドラの引数にも現れるので注意が必要だ.ψ→Λも実行することにする.ψα,ψγも片付けてしまうことにしよう.パネル出力は別として,ほぼ仕上がったのではないかと思う.あとはこれをツールとして活用するというフェーズに入ることになるが,あえて取り上げるとすれば,「離散対数を求める」問題を実装するというのがある.

離散対数というのは,剰余Rに対して決まるγ値のことで,いまのところどうやってそれを求めればよいのか?というアイディアはまとまっていない.しかし,グループでしきりにこの話題が取り上げられているので,いま,ここでそれに対応するというのもありではないかという気がする.少し方式を考えてみることにしよう.Rとγの関係は,

α^γ÷Θ=Q…R つまり,α^γ≡R mod Θ

であるから,α^γ-R≡0 mod Θ を満たすγを求めるという問題になる.αとΘは固定であるから,マトリックスΘのΨαの行でRの位置を求めることに等しい.Rは複数位置に存在し得るので,最小のΨγを見つけることになるだろう.ただし,Matrix(Θ).rows(Ψα)上にRが存在しないという場合もあり得る.(R<Θ)ただし,Θを素数に限定すればかならずγを得ることはできる.⇒いや,できない場合もある.たとえば,α=138, Θ=241のとき,Ψα=138だが,この行はΛ=80で剰余数列の長さは80しかないから,この数列に乗らないRはいくらでもある.

一般には「n を整数として既約剰余類群 G = (Z/nZ)× が巡回群であると仮定」することになっているようだ.「そのような n は 2, 4 および素数冪 q と 2 q の形に書けるものに限られる」とされる.この条件は群Gが原始根を持つ場合と一致するということのようだ.たとえば,α=3,Θ=17は原始根3を持っている.このときの離散対数は指数(index)と呼ばれることもある.離散対数の定義は以下のようなものだ.

G を位数 n の有限巡回群とする。b を G の生成元とすれば、G の任意の元 g は、適当な整数 k を用いて g = b^k の形に書ける。さらに、g を表現する二つの整数 k1, k2 は必ず n を法として合同である。したがって、g に n を法とする k の合同類を対応させることにより log_b:G→Z/nZ なる函数を定義することができる.この函数は準同型写像であり,bを底とする離散対数と呼ばれる.

従って,この問題に入り込むには,まず群が巡回群であるか否かを判定するところから始めなくてはならない.

B進表記を10進表記に変換する機能が壊れている.(動作しない)⇒イベントハンドラは残っていたが,ハンドルが消えていた.⇒復活できたが,他にもこのようなところはあるだろうか?⇒一通りチェックした限りでは大丈夫なようだ.

『群 G が巡回群となるかどうかを見るには G の単項生成部分群で G 自身に一致するものがあるかどうかを調べるだけで十分である』

「巡回群とは,だた一つの元で生成される群(単項生成群)のことである」から,これは巡回群の定義そのものである.

「位数 n の群が巡回群となるための必要十分条件は、n の任意の約数 d に対して位数 d の部分群をちょうど一つ持つこと」

これを我々の言語に翻訳すると,位数Λの剰余数列がΛの任意の約数dに対して位数dの剰余数列を持つことのようになる.⇒どうもまったく意味不明だ.いずれにしても,我々はまだ,Λの約数のようなものをチェックしてみたことがない.しかし,いまの場合はφ(Θ)=Λなので,φ(Θ)=の約数を見ることになる.まだやってみたことはないかもしれないが,このアプローチは我々の方法とかけ離れたものではない.原理はよくわからないが,Rからγを逆算ないし探索するというのはそれほど難しくないと思われるので,とりあえず実装してみることにしよう.

‘System.ArgumentOutOfRangeException’ という例外が発生している.⇒Θに61という値を代入しただけで発生している.この数には限らない.もっと小さくても起きる.⇒DispInvertFuncの中で起きている.⇒DispNotationで起きている.⇒notation.Textに空文字列を書き込んだだけでエラーになっている.⇒Kinai.vbをデザインモードで開けなくなっている.⇒プロジェクトのフォルダ名を変更しようとしたら,別のプロセスがこのフォルダを使っているというメッセージが出た.食事後(落ちていた)にバックアップした版に戻っても同じ.もう一つ前のバックアップ久留島喜内 2023-06-17-4は開けた.⇒この版では障害は発生しない.ここから再開することにする.

WinMergeをインストールしてフォルダを比較してみた.Handles notation.TextChangedを追加しただけだ.⇒DispInvertFuncの中からClearInverseが呼び出され,それがトリガーになってnotation_TextChangedが呼び出されるというループになっていた.passflagを立てて回避するようにした.⇒念のため,ここでバックアップを取っておこう.⇒離散対数計算はざっくり動作するようになった.

パラメータの記号はほぼ固まったことになっているのだが,もう一度考えてみたい.現行では,Nをαとし,Bをβ,KをΘ,eをγとしているが,αβγという三つ組を考えるとすれば,むしろ,NBKではないだろうか?なぜかというと,B進の1/Nの循環節の長さを剰余数列としてみようとすると,β→N,N→Kのようになり,NBKが三つ巴の関係になっているように見えるからだ.このことから考えると,ΘをBとするようなローテーションもあり得るように思われる.群論ではKはnと呼ばれていて,主観的にも相互転換しやすい方がよいような気がする.

現在γと呼ばれているものはΨγと同種のインデックスの仲間と考えられるので,αやβとはカテゴリが違うと考えられる.従って,この値はむしろψと呼んだ方が適切であるかもしれない.ψの用途は位相・角度・電束などとなっており,γよりベターであるような気がする.#や@にはまだ名前は付いていないが,Λの仲間と思われる.γをまず,ψに変更し,ついでΘをγに変えることにする.

行ヘッダ・列ヘッダを整備する

厄介な問題が出てきた.パネルに出しているαR,γRとマトリックス上のデータが一致しない.原因ははっきりしている.横数列の周期がΘではなく,Θ-1になっているためだ.Θ-1というより,正確に言えばφ(Θ)だ.φ(Θ)の剰余を表示するようにすれば正しく対応できるようになるとは思われるが,そうなると,大きなマトリックスを出す意味が失われてしまう.考えられる方法としては,列ヘッダを2行にして①γの生値と②γ mod φ(Θ) を併記することではないだろうか?そうすると,実際のデータは3行目から始まることになる.

同様のことは行ヘッダに付いても言えるかもしれない.行ヘッダに数字を表示できるようにするにはどうすればよいのか?

https://dobon.net/vb/dotnet/datagridview/drawrownumber.html

①CallPaintingイベントハンドラを使う,②RowPostPaintイベントハンドラを使う,

https://atmarkit.itmedia.co.jp/fdotnet/dotnettips/506dgvlinenum/dgvlinenum.html

https://atmarkit.itmedia.co.jp/ait/articles/0610/27/news141.html

列ヘッダにはγ値が表示されているので,その下の行に γ mod φ(Θ)を出すようにしてみよう.⇒わかり易くなった.この行だけ色付けしてみよう.行ヘッダに関しては現状のままでよい.こんな感じになった.これなら間違いないだろう.この値はγRに対応しているので,γRのテキストボックスの色もグレーにしておこう.

image

いや,逆にパネルの色に合わせて行をカーキで塗りつぶしてみよう.少し派手めだが,この程度露骨な方がわかり易いと思う.この行を固定できるとさらによいのだが… ⇒やり方はある.Frozenという属性をTrueにすればよい.最左の第一列も同じ色で塗り潰しておこう.完璧だ.

image

これでマトリックスとパネルを完全に結びつけることができた.あとは行ヘッダを出すだけだ.⇒出た!

.RowHeadersVisible = True
.RowHeadersWidthSizeMode =
DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders

しかし,セル幅がムダに広くなっている.⇒どうもかなり具合が悪い.

.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToFirstHeader

という設定が取り敢えず,一番まともに近いものになるが,二桁以上の数字になると一部が掛けてしまう.AutoSizeToAllHeadersとすればこのようなことは避けられるが,今度は列ヘッダを選択しても列選択できなくなる.これは行ヘッダ幅とテーブルの左上セルの幅が一致しなくなるためだ.⇒多少見苦しいところは残るが,いまのところ,AutoSizeToFirstHeader よりましな方法がない.

行ヘッダにはマトリックスに表示された範囲の整数値を生で表示したいと思っているのだが,問題がある.マトリックスというのはΘだけで決定されるものであり,α値の如何に依らない.これはγ値についても言えることだが,γ値はすべての検定で1から始まる値なので,特に断らなくてもよいように思われる.テーブルの位置決めにはαRとγRが参照されているので,まるきり無関係という訳ではないが,αやγnは剰余であり,生値は参照されていない.⇒行ヘッダはむしろ非表示という方が分かり易いのではないだろうか?現行では下図のようになっている.

image

これはΘ=244のマトリックスで,αR=123,γR=122だ.これで見ると,マトリックスの左上点は(107,106)ということになるから生値ではないが,シフトした値が出ていることは間違いない.ただし,どうもまだ正しく動作しているようには見えない.どうもマトリックスの計算が間違っているようだ.α=119,γ=121,Θ=244のとき,R=119のはずだが,マトリックス上にこの値が見当たらない.α=119,γ=96,Θ=89のとき,αR=30,γR=33,R=52はマトリックス上にある.マトリックスの左上点が(1,1)の場合は動作しているのではないだろうか?

いずれにしても行番号をヘッダ部に表示することは諦めた方がよい.むしろ,列ヘッダと同様にヘッダ用の列を別途追加するようにした方がよい.その方が安全だ.

行選択→列選択のとき,行選択を解除しないで十文字に選択できるとよいのだが… 列ヘッダでなくコントロールキーを押しながらドラッグして拡張選択する方法で十文字に選択することはできる.またシフトキーを押しながら先頭行のセルを選択すると矩形領域が選択され,その右下セルがRの位置になる.⇒列ヘッダをクリックすると列選択モードに切り替わるが,それを廃止して,列ヘッダのクリック→列のセルを拡張選択するようにした方がよい.⇒対応修正した.

まだ,合わない.α=125,γ=124,Θ=244のとき,αR=125,γR=123でR=149だが,125の行に149という数字は見当たらない.ただし,cycle={125,9,149,81,121,241,113,217,41,1}となっているので,マトリックスの方が間違っているのではないか?マトリックスサイズを36×36から64×64に変えたら乗ってきた.確かにこのテーブルは正しい.⇒γRの値がおかしい.φ(Θ)=120でγRが123というのはあり得ない.⇒以下のような調整を行っている.

If tot < Θ – 1 Then eR = eR + tot
If eR = 0 Then eR = Θ – 1

これが間違っているのではないだろうか?とりあえず,両方止めてみた.今度は一致している.ただし,上記の数字と合っていない.上ではR=149となっているが,R=81だ.正しい答えは81だ.あるいは手順が異なっているのか?テーブルを読み損なっていたか?

image

列を1個追加してα値を表示するように改修したところだが,この値は実際には剰余を取ってからの値であり,既存マトリックスの第一列目とまったく同じなので表示する意味がない.⇒列ヘッダと同じように通し番号にしてみよう.

image

この方がよい.この番号はおそらく生値なので巨大数になる可能性もあるが,仕方ないだろう.一応これで仕上がったのではないかと思う.一度バックアップを取っておこう.TestMatrixにも対応しておく必要がある.TestMatrixではマトリックスは生成しないが,テーブルはフルサイズで構築することになっている.当然,左上セルはつねに(1, 1)だ.

TestMatrixではダンプは出さない方がよい.時間が掛かり過ぎる.また,カーソルが砂時計にならないのはなぜだろう?⇒テスト完了したら,出力コンソールに何かしらメッセージを出した方がよい.⇒対処した.

ダメだ.まだ数字が合っていない.α=125,γ=110,Θ=244,φ(Θ)=120 のとき,αR=125,γR=110 で R=1 のところ,クロスポイントには217とある.cycle={125,9,149,81,121,241,113,217,41,1}なので,R=1 も 217 も候補には入ってくるが… 正しい答えは R=1 だ.ということはγRが間違っていることになる.周期は10でφ(Θ)の約数になっているのだから,φ(Θ)で mod を取るというので間違いないと思われるのだが… γR=94が列の先頭になっている.このときの値は81であっているのだが,その次の数字が217で外れている.つまり,第一列目の選択に問題があるか,ないし,第一列目の評価に問題がある.

周期はそれぞれの行によって異なるので,同期を取るためにはφ(Θ)で分割する必要がある.つねに,φ(Θ)の倍数が第一列に来るようにすればよいのだが,それでは大きなテーブルに対応できない.どうすればよいか?最初の糸口が見つかるまで空回しするしかないのではないか?たとえば,α=125の場合,γ=94ならば,R=81, γ=95ならR=121,96で241,… このマトリックスの値はテーブルから引いているものなので,テーブルが間違っているのだろうか?⇒確かにそのようだ.各項ごとにべきを再計算しなくてはならない.コストは掛かるが仕方ないだろう.

列ヘッダをクリックしてその列を全選択するという操作は簡単に実装できたが,多少使い勝手上の問題がある.単純な拡張選択になっているため,別の列を選択すると複数列が選択状態になってしまう.これはあまり芳しくない.すでに選択されている場合には選択を落とすという動作も考えられるが,この場合の問題はその列全体を落とすと,行選択されている場合に欠落セルが出る可能性がある.現在選択されている行を取り出すことは可能だろうか?SelectedRowsというパラメータはあるようだ.⇒できた.自由に列選択ができるようになった.これで十分だ.

αやγに大きい数字を入れると,インデックスが1から始まるようになる.つまり,巻き戻しされてしまう.これでよいのだろうか?⇒マトリックスのインデックス行/列に現れる数値はインデックスであり,生値ではない.つまり,表示されているのはαRとγRであり,それらが見える範囲が表示されているというに過ぎない.従って,これらのヘッダ行ないしヘッダ列にはΘないし,φ(Θ)を超える値が現れることはない.

いや,その説明は間違っている.どちらも通番として表示されているのでΘやφ(Θ)を超えることはある.これは便宜上そうしているだけであって,αやγの生値を表示しているものではないことに注意する必要がある.⇒αやγの数字が大きいか小さいかには関係ない.インデックス行/列に表示されるのは,αRやγRであり,これらの値が小さければ1から始まるようになる.ただし,マトリックスの連続性を強調するために,インデックス行/列に表示される数字そのものの剰余は取らず,通番に見えるように表示している.

列ヘッダとインデックス行はまったく同じ内容に見える.列ヘッダは不要なのではないか?あるいは,逆にインデックス行は通番ではなくインデックス表示した方がましかもしれない.その方がわかり易くなると思う.⇒剰余の式が間違っていた.括弧が落ちていた.⇒修正して違いがはっきり見えるようになった.横数列の周期はΦ=φ(Θ)であり,この値はΘよりずっと小さくなる場合もある.γRはこの値を超えない.

どうも,まだ合っていないところがある.α=130,γ=115,Θ=244,φ(Θ)=120でαR=130,γR=115,R=172のとき,stripeと縦数列が一致しない.stripeの中に115が出てこない.⇒このリストはGetResidueStripeで生成されているが,ModPowの演算で除数がΘのままになっている.⇒Φに変えてみた.115は出ているが,まだマトリックスと一致しない.⇒stripeに表示されるのはR値であり,当然Θが除数でなくてはならないから,この修正は間違っている.R=172が記載されていないのだから,stripeの誤りと考えられる.

⇒stripeの出力は完全に正しい.マトリックスの読み方が間違っている.インデックス行に表示されている値はインデックスであり,剰余Rではない.つまり,カーキ色の行/列は剰余数列データには含まれない!⇒cycle出力もチェックしておこう.⇒完全に合っている.cycleの桁数はstripeよりずっと小さいが,周期的に繰り返されていることが確認できる.これらのテキスト出力の長さには最大MaxOutput=10000という制限があるが,実用上は特に問題にならないだろう.これでマトリックスは完成したのではないかと思う.

GetResiduCycleにはバグが残っている

BuildPowerGridでエラーが起きている.まだ,修正が完結していない.BuildPowerGridでは,範囲を限定したマトリックスを操作するようになっているが,BuildMatrixの対応修正が完了していない.まず,左上点を指定して範囲限定のマトリックスを生成できるようにする必要がある.左上点の計算はBuildPowerGridから借用してきているので,あとはそれを使ってマトリックスをシフトするだけだ.⇒一応数字は出てきた.

▲行ヘッダをクリックしたら,ヘッダ列に1という数字の並びが出現した.行ヘッダには数字は表示されないものと思い込んでいたのだが… 何か設定があるのだろうか?しかも,すべての行に1が表示されてしまうというのはどういうことだろう.

α=7, γ=2, Θ=13という設定で,GetResidueCycleで停止した.j=13,R=10で周期が検出され,j=j+1でループを抜けようとして j > maxとなった.この関数はPsiFunctionから呼び出されている.cycle(0)=7でcycle(1)=10だ.GetResidueCycleの戻り値は周期だが,cycle(12)=7となっているのを見落としているのではないか?2023-06-13に「φ(Θ)剰余数列周期の公倍数である」という発見があり,このときにGetResidueCycleと類似のGetResidueStripeという関数を新設しているが,この辺りはまだ十分バグが取れていないのではないだろうか?

この時期より前の版に戻って同じ障害が発生するかどうかを見てみよう.GetResidueStripeは元々はMakeStripePatternという関数だ.また,GetResiduCycleはBuildMatrixをお手本にして新規に作られたものと思われる.従って,まだバグが残っている可能性は十分あると見なくてはならない.GetResiduCycle→GetResidueCycleとリネームしておこう(eが落ちていた).GetResiduCycleを修正して,cycle(0)に格納されている初期値を参照するようにした.

ValueChangedでPrimeK.Checked <> primeで停止した.⇒PrimeK.Checkedを設定している場所がない.どうも一行誤って消してしまったようだ.IsPrimeという関数も内部でTotientFuncを呼んでいるが,比較的小さな素数に関するテストを事前に実行して効率化しているので,こちらを使うべきだ.(いましばらくは並列実行して検算する必要があるとしても)⇒仕掛りの箇所には何か目印(『暫定』など)を付けて置かないと忘れてしまう.

ダメだ.どこを間違えたのだろう.すべてのセルが1になってしまった.MT(i, 1) = BigInteger.ModPow(RowTop + i – 1, ColumnTop, Θ)の式が間違っている.ColumnTop – 1から始めていたので,指数がすべて0になってしまっていた.しかし,これでも間違っている.古い版の論理は正しく動作している.確かに横数列の周期はΘ-1になるので,それを加味しなくてはならないのだが… どうすればよいのだろう?

Θの上限→MAXARRAYSIZE=268435455

画面はエラーを出した状態で止まっている.BuildPowerGrid内だ.

image

α=123456, Θ=1234567890123456,γ=2,eR = 352731702317570.⇒この関数の中では全ての変数をIntegerとして扱っている.⇒ViewGridは行も列もIntegerの範囲に制限されている.kだけInt64に変更しておいた.⇒二次元配列Tの上限はMAXARRAYSIZEではなく,MAXSQUARESIZEに変更されている.⇒対処したが,まだ別のところでエラーが起きている.TestMatrix内だ.TestMatrixでは異種文字数カウント用にworkという配列を使っているが,ここでオーバーフローが起きている.workはサイズΘで生成しているので,間に合っているはずだが,テーブルTへのアクセスでレンジオーバーになっているのだろう.MAXSQUARESIZEの範囲に限定しなくてはならない.

とりあえず,エラーなしで動作するようになったが,Θ=123456789という順当なサンプルで尋常でない時間が掛かっている.TestMatrixにはいくつもループが入っていて,それぞれがどうしようもないくらい時間が掛かる.いずれにせよ,BuildMatrixには現実的な上限を設けるしかないと思う.MAXSQUARESIZE=&H7FFFでよいのではないだろうか?⇒関数レベルではなく,BuildMatrixないしTestMatrixのコマンドレベルで弾くようにした.Θ自体にも制限を掛けることにしよう.Θの上限はMAXARRAYSIZE=268435455とする.

もうひとつやることがある.マトリックスは本体では基本的に参照されず,ユーザの比較の便のためにだけ表示されているものなので,Θのすべての範囲のテーブルを作る必要はない.本来はべき剰余マトリックスの構造を確認するために,ある程度広い範囲で計算を実施する必要性があったが,横数列・縦数列ともにΘ以下の周期を持つということが確立されたので,もはや無闇に大きなテーブルを作ることは意味がなくなった.

MatrixTestでは全域テーブルが必要だが,それもΘの範囲内で十分なので,それ以上のテーブルを生成する必要はない.BuildMatrixでΘの範囲を超えたマトリックスが要求された場合にのみ大きいテーブルを作ればよい.⇒いや,現状そういう作りになっているのではないか?⇒指定された列数・行数がΘに満たない場合には,Θのフルサイズでテーブルを生成している.この部分は廃止されてよいと思う.

MatrixTestではΘxφの範囲のテストを実施しているが,廃止することにする.しかし,これを廃止してもTestMatrixは相当重い.異種文字数のカウントに相当な時間が掛かっている.BuildMatrixはツールとして常用する部分なので,ここではTestMatrixを実施しないようにする.また,TestMatrixコマンドではΘの範囲をもっと制限した方がよい.

▲BuildMatrixで行/列がΘより小さいときはΘまで拡張するという措置を廃止したところ,BuildPowerGridでエラーになった.topn=25150,leftn=26997で範囲外になっている.生成するテーブル自体オフセットを加味したものになっていなくてはならない.

パラメータの受け渡しが簡単にできるようにMatrixというクラスを新設し,BuildMatrixとTestMatrix,DumpMatrixをこのクラスに移した.⇒移植は簡単にできたが,マトリックスに何も表示されない.Matrixにまだ何も書き込んでいなかった.⇒大体できた.マトリックスも表示されるようになった.⇒まだ,エラーが出ている.

image