创建空间相关噪声的更快方法?
Faster method for creating spatially correlated noise?
在我当前的项目中,我对计算大型模型网格的空间相关噪声很感兴趣。噪声应该在短距离内强相关,而在远距离上不相关。我当前的方法使用具有指定所有单元格之间相关性的协方差矩阵的多元高斯。
不幸的是,这种方法对于大型网格来说非常慢。您对如何更有效地生成空间相关噪声有什么建议吗? (不一定是高斯)
import scipy.stats
import numpy as np
import scipy.spatial.distance
import matplotlib.pyplot as plt
# Create a 50-by-50 grid; My actual grid will be a LOT larger
X,Y = np.meshgrid(np.arange(50),np.arange(50))
# Create a vector of cells
XY = np.column_stack((np.ndarray.flatten(X),np.ndarray.flatten(Y)))
# Calculate a matrix of distances between the cells
dist = scipy.spatial.distance.pdist(XY)
dist = scipy.spatial.distance.squareform(dist)
# Convert the distance matrix into a covariance matrix
correlation_scale = 50
cov = np.exp(-dist**2/(2*correlation_scale)) # This will do as a covariance matrix
# Sample some noise !slow!
noise = scipy.stats.multivariate_normal.rvs(
mean = np.zeros(50**2),
cov = cov)
# Plot the result
plt.contourf(X,Y,noise.reshape((50,50)))
更快的方法:
- 生成空间不相关的噪声。
- 使用高斯滤波器内核进行模糊,使噪声在空间上相关。
由于滤波器内核相当大,使用基于快速傅里叶变换的卷积方法是个好主意。
import numpy as np
import scipy.signal
import matplotlib.pyplot as plt
# Compute filter kernel with radius correlation_scale (can probably be a bit smaller)
correlation_scale = 50
x = np.arange(-correlation_scale, correlation_scale)
y = np.arange(-correlation_scale, correlation_scale)
X, Y = np.meshgrid(x, y)
dist = np.sqrt(X*X + Y*Y)
filter_kernel = np.exp(-dist**2/(2*correlation_scale))
# Generate n-by-n grid of spatially correlated noise
n = 50
noise = np.random.randn(n, n)
noise = scipy.signal.fftconvolve(noise, filter_kernel, mode='same')
plt.contourf(np.arange(n), np.arange(n), noise)
plt.savefig("fast.png")
此方法的示例输出:
问题中慢速方法的示例输出:
图像大小与 运行 时间:
在我当前的项目中,我对计算大型模型网格的空间相关噪声很感兴趣。噪声应该在短距离内强相关,而在远距离上不相关。我当前的方法使用具有指定所有单元格之间相关性的协方差矩阵的多元高斯。
不幸的是,这种方法对于大型网格来说非常慢。您对如何更有效地生成空间相关噪声有什么建议吗? (不一定是高斯)
import scipy.stats
import numpy as np
import scipy.spatial.distance
import matplotlib.pyplot as plt
# Create a 50-by-50 grid; My actual grid will be a LOT larger
X,Y = np.meshgrid(np.arange(50),np.arange(50))
# Create a vector of cells
XY = np.column_stack((np.ndarray.flatten(X),np.ndarray.flatten(Y)))
# Calculate a matrix of distances between the cells
dist = scipy.spatial.distance.pdist(XY)
dist = scipy.spatial.distance.squareform(dist)
# Convert the distance matrix into a covariance matrix
correlation_scale = 50
cov = np.exp(-dist**2/(2*correlation_scale)) # This will do as a covariance matrix
# Sample some noise !slow!
noise = scipy.stats.multivariate_normal.rvs(
mean = np.zeros(50**2),
cov = cov)
# Plot the result
plt.contourf(X,Y,noise.reshape((50,50)))
更快的方法:
- 生成空间不相关的噪声。
- 使用高斯滤波器内核进行模糊,使噪声在空间上相关。
由于滤波器内核相当大,使用基于快速傅里叶变换的卷积方法是个好主意。
import numpy as np
import scipy.signal
import matplotlib.pyplot as plt
# Compute filter kernel with radius correlation_scale (can probably be a bit smaller)
correlation_scale = 50
x = np.arange(-correlation_scale, correlation_scale)
y = np.arange(-correlation_scale, correlation_scale)
X, Y = np.meshgrid(x, y)
dist = np.sqrt(X*X + Y*Y)
filter_kernel = np.exp(-dist**2/(2*correlation_scale))
# Generate n-by-n grid of spatially correlated noise
n = 50
noise = np.random.randn(n, n)
noise = scipy.signal.fftconvolve(noise, filter_kernel, mode='same')
plt.contourf(np.arange(n), np.arange(n), noise)
plt.savefig("fast.png")
此方法的示例输出:
问题中慢速方法的示例输出:
图像大小与 运行 时间: