2

0 と 1 の n 次元配列として書かれたフラクタルの次元を計算したいと思います。これには、箱詰め数、ハウスドルフ、梱包寸法が含まれます。

ボクシング カウント次元をコーディングする方法しか考えていません (n 次元マトリックスで 1 を数えてから、次の式を使用するだけです。

boxing_count=-log(v)/log(n);

wheren-number of 1'sn-space dimension (R^n) このアプローチは、最小解像度ボックスのカウントをシミュレートする1 x 1 x ... x 1ため、数値は のようになりlimit eps->0ます。このソリューションについてどう思いますか?

ハウスドルフまたはパッキング寸法を計算するためのアイデア (またはコード) はありますか?

4

1 に答える 1

3

ハウスドルフ次元と充填次元は、測定理論に基づく純粋な数学的ツールです。それらはその文脈で素晴らしい特性を持っていますが、実験にはあまり適していません. 要するに、ある集合に対する単一の行列近似に基づいてそれらの値を推定できると期待する理由はありません。

対照的に、ボックス カウント次元は、数値調査に適しています。具体的には、フラクタル セットをカバーするために必要なN(e)辺の長さの正方形の数を示します。eご存知のように、セットのボックス数の寸法は現在の制限e->0です

log(N(e))/log(1/e)

ただし、利用可能な最小値を選択するだけでeは、一般的に良い考えではないと思います。私が理解しているように、物理学の文献における標準的な解釈は、 と の間の関係が幅広い値にわたって維持されるべきであるN(e)と推測することです。eボックス カウント次元を計算する標準的な方法は、幾何学的にゼロになる傾向があるシーケンスから選択されたN(e)のいくつかの選択肢を計算することです。e次に、対数対数プロットの点に線を当てはめますN(e)1/eボックス カウントの次元は、その線の傾きにほぼ等しい必要があります。

具体的な例として、次の Python コードは、フラクタル構造を記述するバイナリ マトリックスを生成します。

import numpy as np

size = 1024
first_row = np.zeros(size, dtype=int)
first_row[int(size/2)-1] = 1
rows = np.zeros((int(size/2),size),dtype=int)
rows[0] = first_row
for i in range(1,int(size/2)):
    rows[i] = (np.roll(rows[i-1],-1) + rows[i-1] + np.roll(rows[i-1],1)) % 2
m = int(np.log(size)/np.log(2))
rows = rows[0:2**(m-1),0:2**m]

各 1 を黒のピクセルとして、各 0 を白のピクセルとして解釈するだけで、フラクタル構造を表示できます。

import matplotlib.pyplot as plt
plt.matshow(rows, cmap = plt.cm.binary)

ここに画像の説明を入力

このマトリックスは、フラクタル次元が約 1.694 である実際の制限オブジェクトが存在することを示すことができるため、優れたテストになりますがlog(1+sqrt(5))/log(2)、ボックス カウントの推定を少し難しくするほど複雑です。

現在、この行列は 512 行 x 1024 列です。512 x 512 の 2 つの行列に自然に分解されます。これらのそれぞれは、256 x 256 などの 4 つの行列に自然に分解されます。このような分解ごとに、少なくとも 1 つの非ゼロの部分行列の数をカウントする必要があります。エレメント。この分析は次のように実行できます。

cnts = []
for lev in range(m):
    block_size = 2**lev
    cnt = 0
    for j in range(int(size/(2*block_size))):
        for i in range(int(size/block_size)):
            cnt = cnt + rows[j*block_size:(j+1)*block_size, i*block_size:(i+1)*block_size].any()
    cnts.append(cnt)
data = np.array([(2**(m-(k+1)),cnts[k]) for k in range(m)])
data

# Out:
# array([[  512, 45568],
#       [  256, 22784],
#       [  128,  7040],
#       [   64,  2176],
#       [   32,   672],
#       [   16,   208],
#       [    8,    64],
#       [    4,    20],
#       [    2,     6],
#       [    1,     2]])

ここで、あなたの考えは単純にlog(45568)/log(512)約 1.7195 を計算することですが、これはそれほど悪くはありません。このデータの両対数プロットを調べることをお勧めします。

xs = np.log(data[:,0])
ys = np.log(data[:,1])
plt.plot(xs,ys, 'o')

ここに画像の説明を入力

これは確かに線形に近いように見えます。これは、ボックス カウント手法が適切に機能することを期待できることを示しています。ただし、最初に、外れ値と思われる 1 つのポイントを除外するのが合理的かもしれません。実際、これはこのアプローチの望ましい特徴の 1 つです。その方法は次のとおりです。

plt.plot(xs,ys, 'o')
xs = xs[1:]
ys = ys[1:]
A = np.vstack([xs, np.ones(len(xs))]).T
m,b = np.linalg.lstsq(A, ys)[0]
def line(x): return m*x+b
ys = line(xs)
plt.plot(xs,ys)
m

# Out: 1.6902585379630133

ここに画像の説明を入力

さて、結果はかなり良さそうです。特に、これは、このアプローチが 1 つのデータ ポイントのみを使用するという単純なアイデアよりもうまく機能する決定的な例です。ただし、公平を期すために、単純なアプローチがうまく機能する例を見つけるのは難しくありません。また、このセットは十分に規則的であるため、いくつかの良い結果が得られます。一般に、ボックス カウント計算の信頼性が高すぎるとは期待できません。

于 2016-01-30T02:01:53.623 に答える