`numpy` - Генерация однострочной матрицы из векторизованной функции? - PullRequest
0 голосов
/ 27 апреля 2019

Я работал над программой на python, которая генерирует масштаб для набора Мандельброта, генерируя все кадры и комбинируя их, используя ffmpeg.

Для генерации указанных кадров я используютри матрицы, каждая из которых хранит значения r, g, b соответственно, затем объединяет их с np.dstack((r,g,b)) и сохраняет результат как изображение, используя PIL.Image.

Вот как я создаю матрицы RGB:

def fract(self,xmin,xmax,ymin,ymax,iters):
    width = self.data['width']
    height = self.data['height']
    xpix = (xmax-xmin)/width
    ypix = (ymax-ymin)/height
    r,g,b = [np.zeros((height,width),dtype=np.int8) for i in range(3)]
    for x in range(width):
        for y in range(height):
            r[y,x] = self.color(self.mandelbrot(xmin+(x*xpix),ymin+(y*ypix),iters),iters,0)
            g[y,x] = self.color(self.mandelbrot(xmin+(x*xpix),ymin+(y*ypix),iters),iters,1)
            b[y,x] = self.color(self.mandelbrot(xmin+(x*xpix),ymin+(y*ypix),iters),iters,2)
    self.im = np.dstack((r,g,b))

Итак, сначала я определяю некоторые полезные переменные (ширина / высота изображения, размер пикселя в координатах, количество итераций) и модифицирую каждое значение матрицы по значению.Теперь эта система очень неоптимизирована и довольно медленная, поэтому я хотел посмотреть, возможно ли сгенерировать три матрицы, уже содержащие то, что я хочу сэкономить, в фрактальных вычислениях.

Поэтому я попытался выяснить,может генерировать r с np.fromfunction следующим образом:

r = np.fromfunction(np.vectorize(lambda i,j: self.color(self.mandelbrot(xmin+(j*xpix),ymin+(i*ypix),iters),iters,0)),(height,width),dtype=np.int8)

Но когда я это делаю, оказывается, что матрицы не равны.Большинство рассчитанных значений не соответствуют тому, что в противном случае я должен был получить.Что-то не так с тем, как я использую векторизацию, или fromfunction в целом?

Здесь также есть функции color и mandelbrot

#Calculates color depending on Mandelbrot iterations
#n = iteration
#iters = max iter
#col = color (0 = red, 1 = green, 2 = blue)
def color(self,n,iters,col):
    if n in [0,iters]: return (0,0,0)[col]
    return self.palette[n%len(self.palette)][col]
#Calculates Mandelbrot iterations
#real = Real part of c
#imag = Imaginary part of c
#iters = Max iteration
def mandelbrot(self,real,imag,iters):
    c = complex(real,imag)
    z = 0.0j
    for i in range(iters):
        z = (z**2)+c
        if (((z.real)**2) + ((z.imag)**2)) >= 4: return i
    return iters
...