Hausdorff 和包装维度是基于测度论的纯数学工具。它们在这种情况下具有出色的特性,但不太适合实验。简而言之,没有理由期望您可以根据某个集合的单个矩阵近似来估计它们的值。
相比之下,盒子计数维度非常适合数值研究。具体来说,让表示覆盖分形集所需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)

这个矩阵是一个很好的测试,因为它可以证明存在一个实际的限制对象,其分形维数log(1+sqrt(5))/log(2)
约为 1.694,但它足够复杂,使得盒子计数估计有点棘手。
现在,这个矩阵是 512 行 x 1024 列;它自然地分解成 2 个 512 x 512 的矩阵。每个矩阵自然地分解成 4 个 256 x 256 的矩阵,依此类推。对于每个这样的分解,我们需要计算至少有一个非零的子矩阵的数量元素。我们可以按如下方式执行此分析:
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')

这确实看起来接近线性,表明我们可能期望我们的盒子计数技术能够很好地工作。不过,首先,排除似乎是异常值的一点可能是合理的。事实上,这是这种方法的理想特性之一。这样做的方法如下:
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

嗯,结果看起来还不错。特别是,这是一个明确的例子,表明这种方法比仅使用一个数据点的简单想法更有效。不过,公平地说,不难找到简单方法效果更好的例子。此外,这组足够有规律,我们得到了一些不错的结果。一般来说,人们不能真的期望盒子计数计算太可靠。