$$$$
$\quad$初投稿
$\quad$MZVの具体値とか求めるアプリいる?$\quad$ってきいたら作って欲しいといわれたので作りました。$\quad$…$\quad$それだけなのですが、そこまでにいろいろとあるのでそれを話します。$\quad$プログラムの数学
$\quad$
mathlogのコミュニティガイドライン
$\quad$を読んできたのですが、実は結構震えています。$\quad$数学として、プログラムの話をしてもよいのでしょうか。$\quad$どう考えてもさすがにそれはまずいので、計算量の話をしますが、$\quad$それでもここで話す内容ではないのではと考えてしまいます。$\quad$Mathlog で投稿可能な内容として次のようなものがあります。物理学やコンピュータサイエンス、経済学などの数学の応用先となる分野の内容*
*$\\$運営としては、物理やコンピューターサイエンスなどの数学を応用した内容によって、数学に対する見方が変わる人や数学を学ぶきっかけになる人も多くいると考えております。そのため、数学を応用した分野の内容も投稿可能としています。
$\quad$とあるので、少しだけ安心しました。$\quad$いろいろと調べるうちに、コードのサポートもあるようなので、$\quad$それも使ってみたいと思います。$\quad$本題
$\quad$まず$MZV$は初見なので定義を聞きました。←MZVの文字かっこいい!\begin{eqnarray*}
\zeta(s_1,s_2,\dots,s_r)
:= \sum_{0<n_1<n_2< \dots <n_r} n_1^{-s_1}n_2^{-s_2} \dots n_r^{-s_r}
\end{eqnarray*}
$\quad$頑張って打ちました。$\quad$これ初めて見たときぎょっとしましたね。なんでΣの上に数字が無いんやと。$\quad$よく下をみたらありますね。謎の範囲が。$\quad$これを満たすような$n_1,n_2,\dots,n_r$のすべてのパターンで足し算するらしいです。$\quad$これをプログラムにぶち込んで計算しましょう。$\quad$というわけなのですが、ここはmathlogなので、プログラムではなく計算量の話をします。$\quad$MZVの計算量がおおい。
$\quad$MZVは見ての通りすごい形で総和を計算するのですが、プログラムにするのは簡単で、$\quad$ループを何回かかませば簡単に実装できます。$\quad$では本題の計算量がどれくらいになるのかなのですが、$\quad$このままだと上限を決めていないので無限大になってしまいます。$\color{#0af}\infty!!$$\quad$これではいけないので、次のような関数を定義してみましょう\begin{eqnarray}
\zeta_{a}^{p}(s_1,s_2,\dots,s_r)
:= \sum_{{\color{red} {\large a}} <n_1<n_2< \dots <n_r< {\color{red} {\large p+r}}} n_1^{-s_1}n_2^{-s_2} \dots n_r^{-s_r} \qquad(a<p)
\end{eqnarray}
$\quad$このようにして範囲を制限してあげることで、計算量が無限大にならないようにします。$ $具体的な計算法
$\quad$具体的には、このように変形してあげます。\begin{eqnarray}
\zeta_{a}^{p}(s_1,s_2,\dots,s_r)
&=& \sum_{n_1=a+1}^{p} \; \sum_{n_2=n_1+1}^{p+1} \; \dots \sum_{n_r=n_{r-1}+1}^{p+r-1} \; n_1^{-s_1}n_2^{-s_2} \dots n_r^{-s_r}
\end{eqnarray}
$\quad$こうすることでプログラムの形が見えてきます。$\quad$$r=3$と限定してコードを書いてみましょう。$\quad$サイトに実装して動かすのでjavascript
で書きます。
$\quad$$\;\;$[VScode:Dark (Visual Studio -C/C++)]
$\quad$ 0$\quad$function MZV3(inputs) {
$\quad$ 1$\quad$ var results = []; //結果を入れる箱
$\quad$ 2$\quad$ let n = Number(inputs[3].value);
$\quad$ 3$\quad$
$\quad$ 4$\quad$ let i1=0;
$\quad$ 5$\quad$ let i2=0;
$\quad$ 6$\quad$ let i3=0;
$\quad$ 7$\quad$ let y1;
$\quad$ 8$\quad$ let y2;
$\quad$ 9$\quad$ let y3;
$\quad$10$\quad$ let d1 = new BigNumber(0);
$\quad$11$\quad$ let d2 = new BigNumber(0);
$\quad$12$\quad$
$\quad$13$\quad$ let s1 = inputs[0].value; //ユーザーからの入力
$\quad$14$\quad$ let s2 = inputs[1].value;
$\quad$15$\quad$ let s3 = inputs[2].value;
$\quad$16$\quad$ let sum = new BigNumber(0);
$\quad$17$\quad$ for(i1 = 1; i1 <= n-2; i1++){
$\quad$18$\quad$ for(i2 = i1 + 1; i2 <= n-1; i2++){
$\quad$19$\quad$ for(i3 = i2 + 1; i3 <= n ; i3++){
$\quad$20$\quad$ y1 = BigNumber(i1).pow(s1); //i3 ^ s1
$\quad$21$\quad$ y2 = BigNumber(i2).pow(s2); //i3 ^ s2
$\quad$22$\quad$ y3 = BigNumber(i3).pow(s3); //i3 ^ s3
$\quad$23$\quad$ d1 = y1.times(y2);
$\quad$24$\quad$ d2 = d1.times(y3);
$\quad$25$\quad$ d1 = BigNumber(1).dividedBy(d2);
$\quad$26$\quad$ sum = sum.plus(d1); //sumに計算した値を足していく。
$\quad$27$\quad$ }
$\quad$28$\quad$ }
$\quad$29$\quad$ }
$\quad$30$\quad$ results.push(sum.toString()); //結果を詰め込む
$\quad$31$\quad$ let results;
$\quad$32$\quad$}
$\quad$という感じです。(ぐへぇ)$\quad$プログラムが分からない人もいると思うので、説明すると、プログラム中にあるfor
というものが、$\quad$ここでいう$\sum$の範囲にあたります。$\quad$これを重ねているのは、$\sum$が連なっているということと同じです。
$\quad$で、計算量はどのくらいになるのかというのを見積もると、超大雑把にみて$\mathcal{O}(p^r)$$\quad$くらいかなぁと考えました。$\quad$(javascript
の四則演算の計算量のオーダーがはっきりとしないので、$\quad$ここでいう計算量はループの数ということにして、計算量を比較していきます。)$\quad$ここで、$p$と$r$は$\zeta_{a}^{p}(s_1,s_2,\dots,s_r)$から来ています。$\quad$実用的にはpのほうがrよりもずっと大きく設定するので、これでいいでしょう。$\quad$これ、指数レベルのオーダーなので、多変数&精度を求められると、計算時間が爆発してしまいます。$\quad$さて、$\mathcal{O}(p^r)$というのは、ループの数のオーダーなのですが、$\quad$これをいかにして減らすのでしょうか???????$\quad$名言より
$\quad$ルロイ修道士の名言に、次のようなものがあります。$\quad$これはルネ・デカルトの言葉なのですが、ルロイ修道士の方がなじみ深いですね。$\quad$この言葉をもとに、まずは簡単な問題へとレベルを落としてみます。$\quad$手始めに、こういうものをしてみましょう\begin{eqnarray}
\zeta_{0}^{5}(1,1)
&=& \sum_{0<n_1<n_2< 7} n_1^{-1}n_2^{-1} \\
\end{eqnarray}
\begin{eqnarray}
\qquad \quad \; \,= \frac{1}{1\cdot2}+\frac{1}{1\cdot3}+\frac{1}{1\cdot4}+\frac{1}{1\cdot5}&+&\frac{1}{1\cdot6} \\
+\,\frac{1}{2\cdot3}+\frac{1}{2\cdot4}+\frac{1}{2\cdot5}&+&\frac{1}{2\cdot6} \\
+\,\frac{1}{3\cdot4}+\frac{1}{3\cdot5}&+&\frac{1}{3\cdot6} \\
+\,\frac{1}{4\cdot5}&+&\frac{1}{4\cdot6} \\
&+&\frac{1}{5\cdot6} \\
\end{eqnarray}
$\quad$実際に書いてみると、きれいですね。$\quad$きれいに並んでいるので、どうにかうまい計算方法を見つけたいものですが...$\quad$例えばこういう風にするとどう見えるでしょうか。\begin{eqnarray}
\frac{1}{1}\left( \frac{1}{2}+\frac{1}{3}+\frac{1}{4}+\frac{1}{5}+\frac{1}{6} \right) \\
+\frac{1}{2}\qquad\,\left( \frac{1}{3}+\frac{1}{4}+\frac{1}{5}+\frac{1}{6} \right) \\
+\frac{1}{3}\qquad\qquad\,\,\left( \frac{1}{4}+\frac{1}{5}+\frac{1}{6} \right) \\
+\frac{1}{4}\qquad\qquad\qquad\,\,\,\left( \frac{1}{5}+\frac{1}{6} \right) \\
+\frac{1}{5}\qquad\qquad\qquad\qquad\,\,\,\,\left( \frac{1}{6} \right) \\
\end{eqnarray}
$\quad$おお、綺麗にまとまりましたね。こうすると、下から計算していくと、計算量が減らせそうです。$\quad$例えば$\quad$$\frac{1}{2}+\frac{1}{3}+\frac{1}{4}+\frac{1}{5}+\frac{1}{6}$を計算するときに$\quad$$\frac{1}{3}+\frac{1}{4}+\frac{1}{5}+\frac{1}{6}$の計算結果を使いまわせます!$\quad$こうすることで、計算量を減らすことができます。(すごい発見)$ $でも、一般の場合は?
$\quad$ここで問題になってくるのが、一般の場合です。$\quad$一般の場合、、、急に想像しずらくなりました。$\quad$でも、私たちには上に書いた具体例という強力な武器があります。$\quad$これをもとに考えてみましょう。
$\quad$もし、$p$が大きくなったとしても、$r=2$ならば上記の方法をのばすことで対応できます。$\quad$では、$r$を変えたとき、どう対処すればよいでしょうか。$\quad$私はどうしたかというと、ルロイ修道士の名言に従いました。\begin{eqnarray}
\zeta_{0}^{4}(1,1,1)
&=& \sum_{0<n_1<n_2<n_3<7} n_1^{-1}n_2^{-1}n_3^{-1} \\
\end{eqnarray}
$\quad$これを展開してみましょう。(頑張って)...と言いたいところですが、賢い皆さんならこれが3次元的に広がりそうなのは分かると思います。なので、さらに問題を分割してみたいと思います具体的には、$n_1=1$の時を考えます。\begin{eqnarray}
\frac{1}{1\cdot2\cdot3}+\frac{1}{1\cdot2\cdot4}+\frac{1}{1\cdot2\cdot5}&+&\frac{1}{1\cdot2\cdot6} \\
+\,\frac{1}{1\cdot3\cdot4}+\frac{1}{1\cdot3\cdot5}&+&\frac{1}{1\cdot3\cdot6} \\
+\,\frac{1}{1\cdot4\cdot5}&+&\frac{1}{1\cdot4\cdot6} \\
&+&\frac{1}{1\cdot5\cdot6} \\
\end{eqnarray}これを見ると分かる通り、綺麗にくくれそうです。\begin{eqnarray}
\frac{1}{1} \biggl( \frac{1}{2\cdot3}+\frac{1}{2\cdot4}+\frac{1}{2\cdot5}&+&\frac{1}{2\cdot6} \\
+\frac{1}{3\cdot4}+\frac{1}{3\cdot5}&+&\frac{1}{3\cdot6} \\
+\frac{1}{4\cdot5}&+&\frac{1}{4\cdot6} \\
&+&\frac{1}{5\cdot6} \bigg)
\end{eqnarray}むむむ、、、よく見てみるとさっきの2変数の形に似ています。というよりこれこう書けるじゃないですか!\begin{eqnarray}
\frac{1}{1}\bigg( \quad \large\zeta_{1}^{5}(1,1) \quad \bigg)
\end{eqnarray}ということは$n_1 = 2$のときもなりそう、、、\begin{eqnarray}
\frac{1}{2} \zeta_{2}^{5}(1,1)
\end{eqnarray}実際になりましたね!(実際になるか展開して確かめるのは読者に任せる。)ということで、結局こうなります。\begin{eqnarray}
\zeta_{0}^{4}(1,1,1) = \sum_{0<n_1<5} \frac{1}{n_1} \zeta_{n_1}^{5}(1,1)
\end{eqnarray}
よし、やっと一般の場合を予想できます。多分こんな感じでしょう。\begin{eqnarray}
\zeta_{a}^{p}(s_1,s_2,\dots,s_r) = \sum_{a<n_1<p+1} \frac{1}{n_1^{s_1}} \zeta_{n_1}^{p+1}(s_2,s_3,\dots,s_r)
\end{eqnarray}
これ、証明できるかな? 証明
証明の強力な手助けとして、上に頑張って書いた具体例があります。
それをもとに証明方法を考えてみましょう。
と言っても、多分$n_1$が$a+1,a+2,\dots,p$の時を考えて全部足せばいけるやろ!
という気持ちでやってみます。
\begin{eqnarray}
\zeta_{a}^{p}(s_1,s_2,\dots,s_r)
&=& \sum_{a <n_1<n_2< \dots <n_r< p+r} n_1^{-s_1}n_2^{-s_2} \dots n_r^{-s_r} \\
\end{eqnarray}
ここで、右辺の
\begin{eqnarray}
\sum_{a <n_1<n_2< \dots <n_r< p+r} n_1^{-s_1}n_2^{-s_2} \dots n_r^{-s_r} \\
\end{eqnarray}
において$n_1=t \;\; (a<t<p+1)$の時、この式は、
\begin{eqnarray}
\sum_{{\color{gray}(a<)}t<n_2< \dots <n_r< p+r} t^{-s_1}n_2^{-s_2} \dots n_r^{-s_r} &=&
\quad t^{-s_1} \sum_{t<n_2< \dots <n_r< p+r} n_2^{-s_2} \dots n_r^{-s_r} \\
&=& \quad \frac{1}{t^{s_1}} \zeta_{t}^{p+1}(s_2,s_3,\dots,s_r)
\end{eqnarray}
となりますね!
あとはこれを$t=a+1,a+2,\dots,p$の時をすべて足すだけです!
\begin{eqnarray}
\zeta_{a}^{p}(s_1,s_2,\dots,s_r) = \sum_{a<t<p+1} \frac{1}{t^{s_1}} \zeta_{t}^{p+1}(s_1,s_2,\dots,s_r)
\end{eqnarray}
証明できました!$\small\blacksquare$
\begin{eqnarray}
\zeta_{a}^{p}(s_1,s_2,\dots,s_r) = \sum_{a<n_1<p+1} \frac{1}{n_1^{s_1}} \zeta_{n_1}^{p+1}(s_1,s_2,\dots,s_r)
\end{eqnarray}
...証明できましたが、これがどう計算量の削減につながるのでしょうか。じつは、ここにはさっき見出した素晴らしい発見が見えない形になってしまっています。そう、それが計算結果の使いまわしです。おお、綺麗にまとまりましたね。こうすると、例えば$\frac{1}{2}+\frac{1}{3}+\frac{1}{4}+\frac{1}{5}+\frac{1}{6}$を計算するときに$\frac{1}{3}+\frac{1}{4}+\frac{1}{5}+\frac{1}{6}$の計算結果を使いまわせます!こうすることで、計算量を減らすことができます。(すごい発見)はいはい、さっきやりましたね。でもいったいどこに消えたのでしょうか。上の方の、計算結果を使いまわせます!のところで書いていた分数たちに注目しましょう。\begin{eqnarray}
\frac{1}{1}\left( \frac{1}{2}+\frac{1}{3}+\frac{1}{4}+\frac{1}{5}+\frac{1}{6} \right) \\
+\frac{1}{2}\qquad\,\left( \frac{1}{3}+\frac{1}{4}+\frac{1}{5}+\frac{1}{6} \right) \\
+\frac{1}{3}\qquad\qquad\,\,\left( \frac{1}{4}+\frac{1}{5}+\frac{1}{6} \right) \\
+\frac{1}{4}\qquad\qquad\qquad\,\,\,\left( \frac{1}{5}+\frac{1}{6} \right) \\
+\frac{1}{5}\qquad\qquad\qquad\qquad\,\,\,\,\left( \frac{1}{6} \right) \\
\end{eqnarray}これですね。これをよくよく考えると次のように表せられます。\begin{eqnarray}
\frac{1}{1} \left( \zeta_{1}^{6}(1) \right)
+\frac{1}{2} \left( \zeta_{2}^{6}(1) \right)
+\frac{1}{3} \left( \zeta_{3}^{6}(1) \right)
+\frac{1}{4} \left( \zeta_{4}^{6}(1) \right)
+\frac{1}{5} \left( \zeta_{5}^{6}(1) \right)
\end{eqnarray}これ、さっきの公式1に似てませんか?ね、似てるよね。ここで、使いまわしはどれをどう使いまわしていたのか思い出すと、$\frac{1}{2}+\frac{1}{3}+\frac{1}{4}+\frac{1}{5}+\frac{1}{6}$を計算するときに$\frac{1}{3}+\frac{1}{4}+\frac{1}{5}+\frac{1}{6}$の計算結果を使いまわせます!なので、$\zeta_1^6(1)$を計算するとき、$\zeta_2^6(1)$を使いまわせる!と言っているのです。うん...は?
ということでこれ、どうやって一般の場合に前回の結果を使うのでしょうか。上の具体例をよく見ると、こういうことになっています。\begin{eqnarray}
\zeta_{1}^{6}(1) = \zeta_{2}^{6}(1) + \frac{1}{6}
\end{eqnarray}つまり?\begin{eqnarray}
\zeta_{1}^{6}(1) - \zeta_{2}^{6}(1) = \frac{1}{6}
\end{eqnarray}とみれば、下の数をずらした物の差は、簡単に表せるような気がします。では、これに従い公式1を使って計算してみましょう。いい結果が出ろ!たのむ!\begin{eqnarray}
\zeta_{a}^{p}(s_1,s_2,\dots,s_r)-\zeta_{a+1}^{p}(s_1,s_2,\dots,s_r)&=&\sum_{a<n_1<p+1} \frac{1}{n_1^{s_1}} \zeta_{n_1}^{p+1}(s_1,s_2,\dots,s_r)-\sum_{a+1<n_1<p+1} \frac{1}{n_1^{s_1}} \zeta_{n_1}^{p+1}(s_1,s_2,\dots,s_r)\\
&=&\frac{1}{(a+1)^{s_1}}\zeta_{a+1}^{p+1}(s_2,s_3,\dots,s_r)
\end{eqnarray}うわぁぁぁぁでたぁぁぁぁ!!!!$n_1=a+1$のときだけ引き算されなくてこんな式ができました\begin{eqnarray}
\zeta_{a}^{p}(s_1,s_2,\dots,s_r)-\zeta_{a+1}^{p}(s_1,s_2,\dots,s_r)={(a+1)^{-s_1}}\zeta_{a+1}^{p+1}(s_2,s_3,\dots,s_r)
\end{eqnarray}
ここまで来て気づいたこと
はい、急に何かと思われるでしょうがここまで来て一つかなり重い問題が浮かび上がってきましたそれは、、、記事を書くのがめんどくさすぎる!!!!ここまで書いてきましたが皆さん分かってますよね、おかしいと。背景がまずおかしいし、一番上では文字がうごくし、なんか急にめっちゃカラフルなプログラムが出てきたりとこれね、ほとんどHTMLで書いているのでいろいろできるんですねできるんです、できるんですけど問題が山ほどありますCSSが使えない、プレビューが異次元に飛ぶ、$\TeX$がバグりにバグるHTMLもバグりにバグる。しんどかったですそろそろ頭もMathlogもパンクしそうなので、これは$part1$としてここまでにしたいと思います。(ごめんね)次回!!!
あの公式2が主人公に⁉⁉⁉計算量が指数時間から○○○時間まで落ちた!!!!お楽しみに!参考にさせていただいた記事、サイト
MathlogでのHTMLテクニック 任意色の枠など |sinh76821661
MathlogにおけるMarkdown記法に関するメモ (2020年12月時点) |ぱるま
エディタの使い方 |Mathlog ヘルプ
chatGPT