geometry > 連番から分岐経路番号を取得する実装 (上部:4分岐, 最下部のみ:3分岐)> v0.4: d値のテスト実装

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
```

v0.1: [geometry > 連番から分岐経路番号を取得する実装 (上部:4分岐, 最下部のみ:3分岐)> v0.1, v0.2](https://qiita.com/7of9/items/29b746b6bd71fe121010)

### やろうとしていること

[geometry > sub-triangles > Triangular van der Corput列 > v0.1 > for文のネスト](https://qiita.com/7of9/items/ed5d8146aa03a5be2221)
の方法を使う場合、連番から分岐経路番号(d値)を取得する必要がある。

```math
T(d1, d2) = (T(d1))(d2)
```

```math
T(d1, d2, d3) = ((T(d1))(d2))(d3)
```

のような感じ。

ただし、d1,..d{n_1}は{0..3}の値を取り、最後のdn(例: d3)だけ{1..3}の値を持つとする。
(d値が0となる点は若い連番ですでに取得しているという理由から)


## v0.4

### 変更点

d値を計算する関数を作ったが、それが正しいか気になっていた。
@shiracamus さんに[教えていただいた](https://qiita.com/7of9/items/dc01bfdafceff470dae5/#comment-ec41b284a31fe5b94ccb)方法でテスト関数に入替えてみた。

### code v0.4

```idxToDary_171014.py
import numpy as np
import math
import sys

# on Python 3.5.2

# v0.4 Oct. 17, 2017
#  - replace test_darrays() with a different algorithm
#     + add convert_to_dvalue()
# v0.3 Oct. 14, 2017
#  - add test_darrays()
#  - add calc_darrays()
# v0.2 Oct. 14, 2017
#  - refactor
# v0.1 Oct. 14, 2017
#  - add show_darrays()
#  - add get_depth()


def get_depth(idx):
    if idx == 0:
        return 1
    depth = int(math.log(idx, 4))+1
    return depth


def calc_darrays(idx):
    depth = get_depth(idx)
    # print(idx, depth, end=': ')

    # MSB
    if depth == 1:
        d1 = idx % 4
        # print(d1)
        return [d1]
    remnant = (idx - 4**(depth-1))
    d1 = remnant // 4**(depth-2) // (4-1)
    # print(d1, end=' ')

    res = [d1]
    # inbetween
    for mi in range(depth-1, 1, -1):
        dm = remnant // (4**(mi-2)) // (4-1) % 4
        # print(dm, end=' ')
        res += [dm]

    # LSB
    last = remnant % (4-1) + 1
    # print("", last)
    res += [last]
    return res


def show_darrays(idx):
    res = calc_darrays(idx)
    print(idx, res)


def convert_to_dvalue(decimal, base):
    if decimal < base:
        return [decimal]
    res = [(decimal - 1) % (base-1) + 1]
    while decimal >= base:
        res += [(((decimal - base) * base // (base-1)) // base) % base]
        decimal //= base
    res.reverse()
    return res


def test_darrays():
    base = DVAL_BASE
    depth = MAX_DEPTH
    for idx in range(base ** depth):
        res1 = convert_to_dvalue(idx, base)
        res2 = calc_darrays(idx)
        if res1 == res2:
            print('.', end='')
        else:
            print('!', end='')
    print()


MAX_DEPTH = 5
DVAL_BASE = 4


test_darrays()
sys.exit()

# test
for idx in range(18):
    show_darrays(idx)

show_darrays(63)
show_darrays(64)

show_darrays(255)
show_darrays(256)

show_darrays(1023)
show_darrays(1024)

```

`
$ python3 idxToDary_171014.py
................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................

`

ビックリマークが出ていないので、calc_darrays()は正しいのだろう。