在python中:缺少随机性(分数布朗运动)

时间:2015-09-23 10:28:23

标签: python random matplotlib fractals seed

我是Python新手。我有两个用于生成和绘制2D点阵的脚本,这些脚本以分形图像的形式表示空间分布的属性。第一个脚本包含函数生成分形(正统名称:使用逆傅里叶变换的光谱合成),而第二个脚本只调用函数,绘制它,广告将其写入一个.csv文件。 函数依赖于多个random.gauss(0.0, sigma)调用来获取正态分布的随机数。它还会调用random.random(),因为它需要其他随机数。 以下是代码感谢任何有帮助的人!

问题:情节总是显示相同的模式,因此让我觉得代码中有一些不随机的东西。我的目的是每次运行代码时获得不同的分形图像。什么使它不随机?在第二个脚本中是seed=122吗? PS :请注意,由于该过程引入了给定程度的周期性,并且由于我不希望显示该周期性,因此绘制的晶格小于生成的晶格。特别是,我使用 size(绘制)= 101x101 ,而 size(生成)= 256x256

第一个脚本:函数本身

from __future__ import division #Avoids the floor of the mathematical result of division if the args are ints or longs
import numpy
import random
import math
import pylab

def SpectralSynthesisFM2D(max_level, sigma, H, seed=0, normalise=True, bounds=[0,1]):
  """
  ________________________________________________________________________
  Args:
      max_level : Maximum number of recursions (N = 2^max_level)
      sigma     : Initial standard deviation
      H         : Roughness constant (Hurst exponent), varies form 0.0 to 1.0
      H=0.8 is a good representation of many natural phenomena (Voss, 1985)
      seed      : seed value for random number generator
      normalise : normalizes the data using bound
      bounds    : used for normalization of the grid data
  Result:     
      Output is given in the form of an array (grid) which holds surface
      values for a square region.  
  _________________________________________________________________________
  """   

  N = int(2**max_level)
  A = numpy.zeros((N,N), dtype = complex)
  random.seed() #Seeds the random number generator
  PI = 3.141592
  for i in range(0,int((N-1)/2)):
    for j in range(0,int((N-1)/2)):
      phase = 2*PI*random.random() #/random.randrange(1,Arand)
      if i != 0 or j != 0:
        rad = pow((i*i + j*j),(-(H+1)/2) )*random.gauss(0.0, sigma)
      else:
        rad = 0.0

      A[i][j] = rad*math.cos(phase) + rad*math.sin(phase)*j 

      if i ==0: 
        i0 = 0
      else:
        i0 = N - i

      if j==0:
        j0 = 0
      else:
        j0 = N - j

      A[i0][j0] = rad * math.cos(phase) - rad*math.sin(phase)*j

  for i in range(1,int((N-1)/2)):
    for j in range(1,int((N-1)/2)):
      phase = 2*PI*random.random() #/random.randrange(1,Arand)
      rad = pow((i*i + j*j),(-(H+1)/2) )*random.gauss(0.0, sigma)
      A[i][N-j] = rad * math.cos(phase) + rad* math.sin(phase)*j
      A[N-i][j] = rad * math.cos(phase) - rad* math.sin(phase)*j

  Grid = numpy.real(pylab.ifft2(( A ))) #Implements the Discrete Inverse Fast Fourier Transform on a 2D lattice (grid)
  if(normalise):
        Grid += numpy.amin(Grid)*-1 + bounds[0]
        Grid = (Grid/numpy.amax(Grid)) * bounds[1]
  return Grid

第二个脚本:绘制函数并获得分形图像:

from __future__ import division #Avoids the floor of the mathematical result of division if the args are ints or longs
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mc
import SSFM2D 


#Parameter assignments
max_level=8               #This is the exponent controlling the grid size. In this case N=2^8=256. Use only integers.
N=2**max_level
sigma=1                   #Variation for random Gauss generation (standardised normal distribution)
H=0.8                     #Hurst exponent (0.8 is a recommended value for natural phenomena)
seed=122                    #Setting the seed for random Gauss generation
print ('The lattice size is '+str(N)+'x'+str(N))


#Lattice initialization
Lattice=np.zeros((256,256))


#Calling Spectral fBm function
Lattice=SSFM2D.SpectralSynthesisFM2D(max_level, sigma, H, seed, normalise=True, bounds=[0,1])


#Plotting the lattice
M=np.zeros((101,101))     #Lattice to be plotted. Size(M) != size(Lattice) to minimize visual fBm periodic features. 
for i in range(0,101):
    for j in range(0,101):
        M[i][j]=Lattice[i][j]


#Lattice statistics              
print M[-101:,-101:].sum()
print M[-101:,-101:].max()
print M[-101:,-101:].min()
print M[-101:,-101:].mean()        


#Writing X, Y and values to a .csv file from scratch
import numpy
import csv
with open('C:\\Users\\Francesco\\Desktop\\Python_files\\csv\\fBm_256x256.csv', 'w') as f: # Change directory if necessary
    writer = csv.writer(f)
    writer.writerow(['X', 'Y', 'Value'])
    for (x, y), val in numpy.ndenumerate(M):
        writer.writerow([x, y, val])

# Plotting - Showing interpolation of randomization
plt.imshow(M[-101:,-101:].T, origin='lower',interpolation='nearest',cmap='Blues', norm=mc.Normalize(vmin=0,vmax=M.max()))
title_string=('fBm: Inverse FFT on Spectral Synthesis')
subtitle_string=('Lattice size: 101x101')
plt.suptitle(title_string, y=0.99, fontsize=17)
plt.title(subtitle_string, fontsize=9)
plt.show()

# Makes a custom list of tick mark intervals for colour bar (assumes minimum is always zero)
numberOfTicks = 5
ticksListIncrement = M.max()/(numberOfTicks)
ticksList = []
for i in range((numberOfTicks+1)):
    ticksList.append(ticksListIncrement * i) 

cb=plt.colorbar(orientation='horizontal', format='%0.2f', ticks=ticksList) 
cb.set_label('Values') 
plt.show()
plt.xlim(0, 100)
plt.xlabel('Easting (Cells)') 
plt.ylim(100, 0)
plt.ylabel('Northing (Cells)')

1 个答案:

答案 0 :(得分:1)

通常使用seed初始化随机数生成器。同一seed - >相同的随机数序列(非常适合测试)。

import random

random.seed(22)

for i in range(10):
    print(random.randint(0, 100))

所以不管你运行那个程序多少次(甚至在什么机器上运行),输出总是一样的。

但是当你想要“真正的”随机性(或至少更好的随机性)时,你最好打电话

random.seed()  # or: random.seed(None)

没有参数。然后python使用当前系统时间调用seed - 这提供了一些随机性的来源。

因为我不知道你的图书馆,我无法确定,但我敢打赌它以一种简单的方式工作。您可以尝试设置seed=Noneseed=random.randint(something)

无论如何:请务必阅读您图书馆的api文档并查看seed的内容。