ほとんど整数（ピゾ数）

### ほとんど整数（almost integer）

[ほとんど整数（Wikipedia）](https://ja.wikipedia.org/wiki/%E3%81%BB%E3%81%A8%E3%82%93%E3%81%A9%E6%95%B4%E6%95%B0) とは。

> ある数がほとんど整数であるとは、整数ではないが、整数に非常に近いことを意味する。

ちょっと何のことだが分からないので代表的なピゾ数について紹介します。

## ピゾ数（Pisot–Vijayaraghavan number）

[Pisot–Vijayaraghavan number(Wikipedia 英語のみ)](https://en.wikipedia.org/wiki/Pisot%E2%80%93Vijayaraghavan_number)残念ながら日本語の説明が少ないですが、ぶっちゃけて言うと、$(a+\sqrt{b}) ^n $の$n$を大きくすると整数に近づく数の事です。

```math 
n \rightarrow \infty \hspace{10mm}(a+\sqrt{b}) ^n \rightarrow \mathbb{Z}
```

代表的なものとして黄金比$\large \phi$が挙げられます。
```math 
\large \phi= \frac{1+\sqrt{5}}{2}
```

試しにphyhonのdecimalを使って$\large \phi^n$の高精度の計算を行ってみると$n>=100$でかなり整数に近づいているのが分かります。

```python 
import decimal
decimal.getcontext().prec = 50
phi = (1+decimal.Decimal(5).sqrt())/2  # (1+sqrt(5))/2
print(f"phi = {phi}")
for n in range(100,104):
  print(f"phi^{n} = {pow(phi,n)}")
# phi = 1.6180339887498948482045868343656381177203091798058
# phi^100 = 792070839848372253126.99999999999999999999873748848
# phi^101 = 1281597540372340914251.0000000000000000000007802791
# phi^102 = 2073668380220713167377.9999999999999999999995177677
# phi^103 = 3355265920593054081629.0000000000000000000002980469
```

## ピゾ数のn乗はなぜ整数に近づくか

これは上記のWikiにも説明がありますが、$\phi$の共役無理数は以下のようになり、

```math 
\overline{\phi} =  \frac{1-\sqrt{5}}{2}
```

簡単な計算により以下の基本対称式が両方とも整数になることが確認できます。、

```math 
\phi + \overline{\phi} = 1, \hspace{10mm}

\phi \times \overline{\phi} = -1 \hspace{20mm} \cdots (1)
```
以下の（2）は対称式なので、（1）の基本対称式の多項式で表すことができるので整数になります。([対称式の基本定理の証明（高校数学の美しい物語）](https://manabitimes.jp/math/1239#1))。
```math
\phi^n + \overline{\phi}^n は整数\hspace{20mm} \cdots (2)
```
たとえば$n=2$の時は以下のように$3$になります。

```math 
\phi^2 + \overline{\phi}^2 =  (\phi + \overline{\phi})^2-2\phi \overline{\phi} = 1^2-2 \times (-1) = 3
```

ここで$\overline{\phi}=-0.618$の絶対値は1より小さいので、$\overline{\phi}^n $は$n$が大きくなると$0$に近づきます。

従って

```math 
n \rightarrow \infty \hspace{10mm} \phi^n \rightarrow 整数　
```
となることが言えます。一般的に

```math 
\begin{align}
&(a+\sqrt{b}) ^n \rightarrow \mathbb{Z}　となるには \\
&|a-\sqrt{b}| < 1 が条件となります。
\end{align}
```

### ピゾ数の応用

```math 
(\sqrt{a}+\sqrt{b})^{2n}がn \rightarrow \infty で整数に収束する条件は何でしょうか？
```

以下のように変形するとピゾ数の形になります。

```math 
\begin{align}
(\sqrt{a}+\sqrt{b})^{2n} &= ((\sqrt{a}+\sqrt{b})^2)^n \\
&= (a+b+2\sqrt{ab})^n \\
整数に収束する条件は\\
 |(a+b-2\sqrt{ab})| < 1\\
すなわち　\\
|\sqrt{a}-\sqrt{b}| < 1
です
\end{align}
```

試しに$a=7 b=3$の時

```math 
\begin{align}
|\sqrt{7}-\sqrt{3}| = 0.9137.. < 1なので　\\
(\sqrt{7}+\sqrt{3})^{2n}は整数に収束しそうです。
\end{align}
```
一応プログラム書いてみると、小数部が１に近づいているのが分かります。（整数部はかなり大きくなるので表示していません）

```python
import decimal
decimal.getcontext().prec = 200
X = (decimal.Decimal(7).sqrt()+decimal.Decimal(3).sqrt())  # (sqrt(7)+sqrt(3))
print(f"X = {X:.010f} (sqrt(7)+sqrt(3))")
for n in range(10,100+1,10):
  Xn = pow(X,2*n)
  print(f"X^(2x{n}) = {Xn-int(Xn):.010f}")
# X = 4.3778021186 (sqrt(7)+sqrt(3))
# X^(2x10) = 0.8355335628
# X^(2x20) = 0.9729507910
# X^(2x30) = 0.9955513130
# X^(2x40) = 0.9992683403
# X^(2x50) = 0.9998796665
# X^(2x60) = 0.9999802092
# X^(2x70) = 0.9999967451
# X^(2x80) = 0.9999994647
# X^(2x90) = 0.9999999120
# X^(2x100) = 0.9999999855
```

（開発環境：Google Colab）

この考え方はPdoject Euler Problem 318: 2011 Ninesを解くのに役に立ちます。