I am trying to generate time series noise. My noise array are ~350,000 in size so they must be heap allocated. How can I return my heap allocated array back to the python code that called the function when the function is called? I have tried converting it to a nd.array but python complains during compilation.
I am new to cython and would love a real explanation on how this works. Everything I find online is super convoluted and not beginner friendly.
Also, if anyone know how to replace the np.random.normal call for a cython version that would be great. I can't find anything on the internet that is not super complex for a simple gaussian random number generator.
Here is my pyx file:
import numpy as np
cimport numpy as np
from libc.stdlib cimport malloc, free
# TODO turn this into a cython script. Generate function is slow for 350,000 samples
cdef class NoiseGenerator():
cdef double mean, std, tau, start_value, previous_value
cdef double* noise
def __cinit__(self, double mean=0.0, double std=1.0, float tau=0.2, float start_y=0):
self.mean = mean
self.std = std
self.tau = tau
self.start_value = start_y
cdef double sample_next(NoiseGenerator self, double dx):
cdef double red_noise, wnoise
if self.previous_value is None:
red_noise = self.start_value
else:
wnoise = np.random.normal(loc=self.mean, scale=self.std, size=1)
red_noise = ((self.tau/(self.tau + dx)) * (dx*wnoise + self.previous_value))
self.previous_value = red_noise
return red_noise
cdef np.array generate(NoiseGenerator self, double dx, int samples):
self.noise = <double *>malloc(samples * sizeof(double))
for idx in range(samples):
noise[idx] = self.sample_next(dx)
return nd.array(self.noise)
def __dealloc__(NoiseGenerator self):
free(self.noise)
from a python script this is how I want to use it:
import numpy as np
import pyximport; pyximport.install(setup_args={'include_dirs': np.get_include()})
from CNoiseGenerator import NoiseGenerator
mean = -2.5914938426209425e-06
std=0.00024610271604726564
dx=0.0018104225094430712
samples=352036
noise = NoiseGenerator(mean, std).generate(dx, samples)
Any advice on how to refactor my class would be greatly appreciated. Again still learning here!