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

レンジ外のα値入力に対し,何のアウトプットもないのはまずい.⇒数値ボックスで自動的に弾いているのではないか?⇒いや,少し動作が違う.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ボタンを押してもかなり長時間何も出力されない.

app.configを使うのは止めよう

VB.NETにはアプリケーションの設定を保存するための機構として,app.configという仕組みが備わっている.以前はINIファイルを使うかレジストリに保存というのが標準的な手法だったが,いつの間にか世の中変わってしまった.どうも慣れないせいかうまく動作してくれないので,2023-07-18-1版まで戻ることにした.ここではエラーは発生していないように思われるので,ここから出直すことにする.⇒いや,ダメだ.プロジェクトの設定を開こうとするとやはりエラーが出る.

image

起動時にはこのファイルを読み込んでいるはずなのだが,そこではエラーは発生していない.⇒App.configを一旦削除したら,エラーは発生しなくなった.しかし,今度は起動時にエラーが出るようになってしまった.app.configの難点は機構が複雑過ぎて開発環境がうまく管理できていないように思われる点だ.実行時には,app.config以外に別の*.configファイルが作られているだけでなく,どこかに隠しファイルを持っていて同一内容をキープしているような感触があり,それらの間で不整合が発生しているという感じだ.とりあえず,INIファイルかレジストリを使う方向に転換することにした.

設定の保存のところで足止め

まず,設定の保存の問題を片付けておこう.アプリ終了時の設定が次回起動時にはそのまま反映されているという仕掛けだ.保存されるべきパラメータは以下の通り.

  1. α numN 123
  2. β numB 10
  3. γ numK 7
  4. ε numE 1
  5. Wordwrap wordrap False
  6. Verbose verbose False
  7. Save saveon False
  8. filename filename output.txt
  9. folder path workdir C:\desktop
  10. α+ ncount 20
  11. β+ bcount 20
  12. γ+ kcount 20
  13. matrixW matrixw 26
  14. matrixH matrixh 26
  15. Color coloring 0
  16. panel Window State panelwstate 

プロジェクトのプロパティ→設定を開こうとすると下記エラーになる.

image

▲初期起動時,以下のエラーになる.

image

リリース版を起こした 1.0 R2023-07-18

リリース版を起こした.V1.0 R2023-07-18.bin\ReleaseにPowerGridというフォルダがある.いつ作ったのかよく覚えていない.中に更新日付が2023/06/26というEXEが入っている.紛らわしいので削除しておこう.多分配布用というつもりだったのではないかと思う.どこまでリリースすればよいのか?それが問題だ.ソースコードまで公開してしまうのが早いような気がするのだが… 今回はフルパッケージでリリースするということにしてみる.

縦長になったため,横幅が少し足りない感じがする.行間隔を詰めてもう少しコンパクトにしてみよう.⇒調整した.一応これで完成したということにしておこう.しばらくは,これで運用してみることにする.前回設定を覚えておくという機構があったはずだが…

どうなっているのだろう?アプリ終了時に設定を保存するためには,My.Application.SaveMySettingsOnExit がオンになっている必要があるようだ.Kinai_FormClosingでは設定をMy.Settingsに書き込んでいるが,ロード時にはやっていないように見える(一部読み出しているものもある)た,これを作動させるためにはapp.configにあらかじめ設定する必要があったのではないだろうか?

ColoringStripeでレンジオーバーエラー

α=8, ε=2023, γ=54でマトリックスを表示しようとしてColoringStripeでエラーになった.

image

.Rows(topn).Cells(leftn).Style.BackColor = colでセルの背景色を設定しているところだ.topn=6, leftn=2006が入っている.maxrowsは34,maxcolumns=34だから,明らかにレンジを逸脱している.mat.ColumnTopの2006という数がそのまま適用されている.どこかで修正ミスを冒しているのではないか?おかしい.この論理は元々は .Rows(i).Cells(j).Style.BackColor = colのようになっていたはずだ.⇒確かにこれでエラーは発生しなくなったが,カラーリングがおかしい.

image

かなりややこしい.難しい論理になっている.一応動作するようになった.多分これで間違いないと思う.

ここまでで一旦閉じることにする

さて,いよいよ最後の課題に掛かることにしよう.縦数列のセグメントを半分に折ってそれぞれを着色するという課題だ.これを行えば,異なる数列で和が一致してしまう場合を分離することができる.また,副次効果として回文の見える化にも寄与するはずだ.かなり面倒な仕掛けだが,やってできないというほどのものではない.また,やるだけの価値はあるものと思われる.現行のstripeカラーはそのまま温存したいので,このカラーリングは追加ということになるが,問題は管理パネル上の余白が乏しくなっていることだ.

このカラーリングをとりあえずsegmentカラーリングと呼んでおく.ボタンを止めて,リスト化するという方法も考えられる.というか,それしかないのではないか?ボタンの方が素早く切り替えらえられるという利点はあるが,この機能は必要に応じて使われるような種類のものなので,許されるのではないだろうか?リストは以下のような構成になる.

  1. Color off
  2. Color on
  3. Color cycle
  4. Color stripe
  5. Color segment

最後のColor segmentというのが,これから実装しようとしているセグメントカラーリングだ.γの周期性に関わるパラメータX, Y, Zはこれまでchi, upsilon, zetaとしてきたが,間違い易い/書きづらいので,X, Y, Z に統一することにする.Xの値はLambdaFunctionが返す周期#の最大値である.⇒カラリングの切り替えをラジオボタンからコンボボックスに変更した.それほど違和感は感じない.

セグメントを細分割する際の手掛かりとして,異種文字数1の行というのを考えてみたが,どうもうまく割り切れるようには見えないので,当初予定通り単純に2分割するという方向で進めることにする.手順は下記のようなものになる.

  1. Yが奇数の場合は,最下行の0行を除外すると偶数になるので,2頭分して個別に色分けする
  2. Yが偶数の場合は,最下行を含めてそのまま2分割して色分けするか,ないし最下行と中央の行を除外して残りを色分け表示する

γ=18の場合,Y=6で偶数だが,ほとんど同色で塗りつぶされている.なぜか?{1,4,9,16,7}=37,{1,8,9,10,17}=45,{1,16,9,4,13}=43,{1,14,9,16,11}=51でそれぞれ値は異なるのにほぼ同じ色に見えてしまう.⇒色々調整してみたがなかなかうまくゆかない.異種文字数がまったく異なるのに同じ色になってしまうというのは納得ゆかない.むしろ,異種文字数を基準にした方がよいのではないか?

異種文字数は列に属する値でセグメントと1対1対応していないが,異種文字数の4倍を加算することで分離できるようになった.母数を大きくしないでオーバーフローしたときは360の剰余を取るようにしてかなり解像度は高くなったのではないかと思われる.

いろいろ検討してみたが,セグメントカラーリングは取りやめることにする.ある程度色で識別できるようになったので,しばらくはこのまま運用してみることにする.あとはマニュアルを書くだけだ.

異種文字数に関しては整合するようになった

α=15, ε=4,γ=12のときの異種文字数がおかしい.上から見てくると,α=7で{7, 1, 7, 1,}が1となり,その次の{8, 4, 8, 4, }が3,{9, 9, 9, 9, }が2,{10, 4, 4, 4, }が1と軒並みおかしい.12行目では{0, 0, 0, 0, }で2となっている.異種文字数のカウントはBuildMatrix,それを読んでBuildPowerGridでマトリックスに表示しているはずだが,どちらが間違っているのだろう?

配列の内容はcharNVが{0, 12, 4, 9, 4, 0},charNHが{0, 1, 3, 2, 1, 2, 2, 0}となっているので,配列の中身がそのまま表示されている.つまり,配列の内容が間違っている.ただし,charNV(1)=12はマトリックスでは9と表示されているので,食い違いがある.charNHとcharNVの値はGetCharNumHとGetCharNumVで取り出している.⇒原因はわかった.縦数列では横数列のように周期で区切ることができないという点が見落とされている.つまり,セグメントというのは単なる区切りであり,周期ではないということがよく理解されていない.言い換えると縦数列の検定では検定区間をγより短くはできない.別の言葉で言えば,縦周期Yが区間と誤認されている.

いまの場合はγ=12でY=6だが,縦周期Yで繰り返されるという仮定で動作している.これは誤りだ.

BuildMatrixとBuildPowerGridで区間γに対応するよう修正した.これで概ね異種文字数の表示は正しくなったように思われるが,まだ二三不審な点がある.γ=12のマトリックスで最下行の異種文字数のうち最左の9というのはおかしい.0~11までの数字が現れるのだから,12でなくてはならない.また,12行目と24行目の最初の数字は0になっているにも関わらず,異種文字数は2となっている.

charNV(1)=12となっているのに,表示が9となっているのはなぜか?かなり微妙な問題だ.charNV配列の長さはX+Zで事例ではX=2, Z=1となっている.BuildPowerGridではこの標準配列を使ってテーブル上の任意の矩形領域を表示しようとしているため,列番号から標準配列のインデックスへの変換を行っているが,この論理の中に列番号がゼロになった場合はXに読み替えるという処理が入っている.この辺りで誤動作しているものと思われる.

マトリックス先頭列+jの値がXより小さい場合は変換しないで直接適用するように書き換えておこう.⇒解決したようだ.事例ではγ=12となっているので,αが12の倍数であれば剰余は0でなくてはならないから,12行目,24行目の最左ノードが0であるというのは正しい.従って,異種文字数が2となっている方が間違っているように思われる.⇒上記と同様な仕組みになっている.行がγの倍数のときはYで置き換えるようになっている.Yでなくて,γでなくてはならない.

修正して動作するようになった.これで異種文字数に関しては整合するようになったのではないかと思う.upsilonつまりYを参照しているところはすべて点検しておく必要がある.⇒一応OKのようだ.

まだいろいろあるが,かなり整って来た

57428571880/142857143を計算しようとして,どこかでハングしてしまった.GetDivisorsで手間取っている.yakusu=288でO(288^2)だが…ラムダ関数が反復呼び出されているためだ.⇒DispModPowではi=1 to γ でラムダ関数を実行しているが,γ={142857143}なので,途方もない時間が掛かっている.ここでやっているのは,X, Y, Z値の計算だ.現在i={1683067}なのでまだまだ停止しそうもない.γが大きいときにはここはパスした方がよい.

MAXPOWERINDEX=65535 べき乗指数の上限を限界としておこう.⇒上限まではループを回すようにした.上限で打ち切られた場合には値は不正確なものになる可能性はあるが,出ないよりはましなのではないだろうか?⇒MAXPOWERINDEXでは大き過ぎる.MAXSQUARESIZE=32767まで落としてみた.上の事例ではXとZには値が入り,Yは空欄となった.⇒Yには0を出すようにした.⇒いや,Y=0というのはおかしい.不定という方がましだ.

MatrixにsumR, charNV, charNHという配列を設置して事前に異種文字数とセグメント和を格納しておくようにした.sumRは横周期X・セグメント数,charNVは横周期X,charNHは縦周期Yという大きさになっている.Xは横周期,Yは縦周期なのでこれ以上小さくはできないが,横周期の場合には固定部というのがあるので,もう少し広げておく必要がある.この値はzetaに入っている.

マトリックスに異種文字数が表示されない.⇒「異種文字数をカウント」をBuildMatrixに移しただけで,表示の方は手当てしていない.これから整備する必要がある.⇒従来論理を復活させたら,「色相の値が不正」というエラーになった.maxcol=153で, sumR=408, col={255, 255, 255, 255}になっている. maxcolは=γ * (γ +1) / 2で計算しているが,sumR<maxcolでなくてはならないはずだ. γ ^ 2 としておこう.いや,それでもまだ足りない.max=289に対しval=408だ.γ=17だから,24個以上加算されたことになる.

わかった.同じ位置にダブって書き込まれているのだろう.セグメント和を計算しているのはGetCharNumVだが,ここでは1~maxcolumsまでのすべての行が対象となっている.

α=8,γ1=1のとき,BuildMatrixでゼロ除算エラーが起きた.Y(upsilon)が不定になっている.⇒DispModPowでΩがゼロのときは,upsilon=γとした.γ値はゼロにはならないので安全だ.

ゼロ行の異種文字列がゼロとなっているが,これでよいのか?0は1桁の周期列とみなすということにしたはずなのだから,異種文字数1でなくてはならないのではないか?仮にゼロ行に関しては異種文字数0でよいとしても,γ=2のとき,縦数列で0と1が混在しているのにゼロになっているのは明らかに誤りだ.もし,0もカウントするとすれば,ここでは2になっていなくてはならない.

γ=3のとき,1列目は{1, 2, 0}で3となっている.2列目は{1, 1, 0}で0,以下同じで異種文字列の行は{3, 0, 3, 0, }のようになっている.γ=4のとき,3行目は{3, 1, 3, 1}で1,{1, 1, 1,,}でも1だ.γ=5では,{1, 1, 1, 1,}の列が0になっている.

まだいろいろあるが,かなり整って来たことは確かだ.ゼロ行の異種文字数がゼロという問題を片付けておこう.「異種文字数のカウントからあらかじめ固定部を除く」という提案があるのだが,これはどうか?横数列と縦数列で異種文字数の合計が一致するという予測がある.特に,番外の固定部の異種文字数合計は一致しなくてはならない.⇒ゼロ行の異種文字数は0でもよいような気はする.これはある種のセパレータになっているので,0が表示されていた方が区切りが見つけ易いのではないか?0は固定部にはカウントされないという規則はすでに確立している.異種文字からも除外するというのはそれほど変則ではないのではないか?むしろ,縦数列で{1, 1, 1, }が0となっている方が問題だ.ただし,縦数列ではどうも0をカウントに入れているようにも思われる.γ=17で異種文字数17という列があるのだから間違いない.

縦数列の異種文字数カウントでループが回っていない.yoko = X+Z = 16+0になっている.つまり,周期の境界線が外されている.⇒というか,Xの剰余がゼロになってしまう.Xの剰余ゼロのときはXを使うように調整した.これで縦数列で{1, 0, 1, 0,}の場合は異種文字数2ということになった.0をカウントしないとすれば,1になるが,話がややこしくなるので,シンプルに0もカウントするということに決定しよう.⇒横数列で0がカウントに入らないのも上と同じ理由だ.つまり,Yの剰余がゼロになっている.⇒調整を入れた.これで完全に整った.

「異種文字数のカウントからあらかじめ固定部を除く」という件に関しては取り敢えず保留とする.まだ,縦・横の異種文字数の関係が完全に解明されていないので,もう少し詳しいことがわかってからでも遅くはないだろう.これで縦数列のカラーリングはひとまず落着したことになるのだが,もう一つだけ懸案がある.数列の内容は異なるのに合計が一致してしまうという問題だ.たとえば,γ=7の場合,縦数列は{1, 1, 1, 1,}を除いて2色で塗り分けられているが,実際には4パターンあり,合計が一致しているために2種に縮退している.

{1+2+3+4+5+6}={1+1+6+1+6+6}=21,{1+4+2+2+4+1}={1+2+4+4+2+1}=14.これを弁別するためにセグメントを半分に分割して着色するというアイディアがある.こうすると,①パターンの異なることが明白になる,②回文になっていることも色で推定できるようになる,という利点がある.もし,これを実装するとしたら,全セグメントカラーと半セグメントカラーのオプションを選択できるようにする必要があるだろう.ここまでできれば,とりあえず当初予定したレベルには達したと言えるのではないだろうか?かなり込み入った話にはなってくるが,やってみるだけの価値はあると思う.

この検定で興味深いところは,Yが偶数のとき,中央の境界線では異種文字数1になるのではないかと予測されているからである.異種文字数1という行の典型は0行と1行だが,それ以外の数字でも起きる場合があり,これは特異なパターンとして注目されてよい現象と思われるので,それを際立たせるという意味からも意義があるように思われる.ただし,Yが小さい場合には細分化されて細切れ様になってしまうため図柄的に分かり辛いもになってしまうというところもあるのだが…

▲どうもまだ異種文字数カウントにバグが残っているようだ.α=15, ε=4,γ=12のとき,α=7の横数列{7, 1, 7, 1,}が1,{8, 4, 8, 4,}が3,{9, 9, ..}が2など数字がまったく合っていない.固定部を持たない0行が2になっているところもある.

異種文字数のカウントにやや問題がある

▲異種文字数のカウントにやや問題がある.異種文字数はBuildPowerGridの中でカウントしているが,この方法だと計算を誤る可能性がある.生成されるマトリックスは必ずしもγ全体に及ぶとは限らないのでカウントされない部分が出てくる可能性がある.異種文字数の計算は少なくともBuildMatrixの中で実施して,BuildPowerGridではその結果だけを使うというようにしないとまずいと思う.また,固定部桁数は別途計算できるので,異種文字数のカウントからあらかじめ固定部を除くようにした方がよい.ただし,マトリックスのカラー表示は現物のマトリックスを対象としているので,その点注意する必要がある.

GetCharNumVとGetCharNumHはテーブルを使わずに直接計算している.ただし,内部で使っている作業用配列は最大MaxOutput=32767だ.これをMAXARRAYSIZEまで拡張しておけばよいのではないか?TestMatrixの中にも異種文字数をカウントしているところはある.ここでは配列上限はMAXSQUARESIZE=32767だ.BuildPowerGridではGetCharNumVとGetCharNumHを呼び出しているので,現状で問題ないのではないか?一応この問題はこれで落着ということにしておこう.

▲R値はテーブルから取り出しているが,セグメントがテーブルの境界をまたいでいる場合には計算できない.⇒セグメント値の計算もGetCharNumVのように直接実行するということは考えられる.GetCharNumVではすべてのR値を現物計算しているので,そこでセグメント単位に加算すればよいはずだ.GetCharNumVでは1~γまでのR値を計算しているので,その中でR=0となる位置を区切りとして集計すればよいのではないか?計算結果を配列に格納しておいて呼び出し側に渡してやれば,なんとかなるのではないか?それほど面倒な話ではないはずだ.セグメントを2つに分割するという話も出てきているが,それはこの工作が終わってから考えることにしよう.

セグメント数をどこで計算していたか見ておこう.この値は現在Y(upsilon)として表示されているものだ.Yはλの固有値でDispModPowで計算している.また,この値はBuildMatrixで転記されてマトリックスのupsionに格納されているから,いつでも使うことができる.とりあえず,matrixにSumR()という配列を置くことにしよう.⇒一応動き始めてはいるが,方式的な欠陥がある.

BuildPowerGridでは最初にGetCharNumVを実行した後,ColoringMatrixを実行しているが,これではsumRを取り出すことはできない.sumRは列毎に異なる値を取るので,格納するとすれば二次元配列が必要になる.一次元で間に合わせようとするのなら,GetCharNumVと並行してカラリングしなくてはならない.GetCharNumVは共通処理,ColoringMatrixは個別処理なので分離しておきたい.とすれば,二次元配列を使うしかない.

横数列は完全周期を持っているので,それほど大きな配列にはならないだろう.幅はXで高さがγ¥Yだ.⇒逆にGetCharNumVの過剰動作が起きている.GetCharNumVはBuildPowerGridから呼び出されているため構築されたマトリックスの範囲のデータを揃えようとしているが,Xがそれよりも小さい場合は過剰動作となる.むしろ,この処理はBuildMatrixに移して標準動作とした方が効率はよいのだが… 現行のまま進めるとすれば,すでに書き込まれた部分はパスするように作らなくてはならない.かなり厄介な話だ.

処理をBuildMatrixに移し,必要な最小サイズの配列を生成するようにする.配列はMatrixに格納しておけばよい.BuildPowerGridではこれをスープストックとして伸ばして使えばよい.⇒しかし,これでもまだ厄介な点は残る.横数列は巡回するとは言え,冒頭の固定部は無視できない.最低でも固定部+周期列の長さは必要だ.剰余を格納しているMTは実際に生成されるマトリックスに合わせている.