2

我想计算写为 0 和 1 的 n 维数组的分形的维数。它包括装箱数、hausdorff 和包装尺寸。

我只知道如何编码装箱计数维度(只计算 n 维矩阵中的 1,然后使用以下公式:

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

哪里n-number of 1'sn-space dimension (R^n) 这种方法模拟计算最小分辨率框1 x 1 x ... x 1,所以它就像数字一样limit eps->0。您如何看待这个解决方案?

您对计算 hausdorff 或包装尺寸有任何想法(或者可能是代码)吗?

4

1 回答 1

3

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

在此处输入图像描述

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

于 2016-01-30T02:01:53.623 回答