Проблема векторизации многомерных нормальных функций (также гувекторизация) - PullRequest
0 голосов
/ 13 сентября 2018
import numpy as np
from numba import vectorize, guvectorize
from scipy import random

@vectorize('float64(int32)', nopython = True)
def box_muller(n):
    """Generate n random normal deviates."""

    u1 = np.random.random((n+1)//2)
    u2 = np.random.random((n+1)//2)
    r_squared = -2*np.log(u1)
    r = np.sqrt(r_squared)
    theta = 2*np.pi*u2
    x = r*np.cos(theta)
    y = r*np.sin(theta)
    z = np.empty(n)
    z[:((n+1)//2)] = x
    z[((n+1)//2):] = y
    return z[:n]

@vectorize(["float64[:,:](float64[:], float64[:,:], int32)"], nopython = True)#"(s)(m,n)() -> (m,n)",nopython=True)
def mvn(mu, sigma, n=1):
    """Generate n samples from multivarate normal with mean mu and covariance sigma."""

    A = np.linalg.cholesky(sigma)
    p = len(mu)

    zs = np.zeros((n, p))
    for i in range(n):
        z = box_muller(p)
        zs[i] = mu + A@z
    return zs

n = 100
mu = 4.0*np.ones(n)
matrixSize = n
A = random.rand(matrixSize,matrixSize)
sigma = np.dot(A,A.transpose())
R = mvn(mu, sigma, n).T

Итак, выше я попытаюсь адаптировать эти функции с помощью векторизованного или guvectorize декоратора. Они оба прекрасно работают с jiit, но хотели посмотреть, будет ли он еще лучше. Я получаю следующую ошибку с приведенным выше кодом о проблеме преобразования типов:

TypingError: No conversion from array(float64, 1d, C) to float64 for '$0.77', defined at None

File "<ipython-input-23-cda0f9d41cab>", line 19:
def box_muller(n):
    <source elided>
    z[((n+1)//2):] = y
    return z[:n]

Я не понимаю, почему это также не выдает ошибку, используя jiit. Очевидно, что что-то мне не хватает в dtypes и vectorize / guvectorize. Какие-либо предложения? Также возникают проблемы с пониманием «символической формы», необходимой для этих двух функций, чтобы использовать guvectorize. Спасибо за чтение.

...