I currently have this code to generate a discrete signal with random amplitudes, but a fixed frequency:
import matplotlib.pyplot as plt
import numpy as np
# constants
t_len = 0.5
freq = 10.0
dt = 0.001
# set the see for reproducible results
rng = np.random.RandomState(0)
# create the random values to interpolate between
assert dt < freq
white_size = int(t_len * freq)
white_vals = rng.uniform(low=-1, high=1, size=white_size)
# setup the interpolation
white_noise = np.zeros(int(t_len / dt))
assert white_size < white_noise.shape[0]
# how can I avoid using this for-loop?
for w_i in xrange(white_size):
white_noise[int(w_i/freq/dt):int((w_i+1)/freq/dt)] = white_vals[w_i]
# plot the result for visual verificaition
plt.plot(white_noise)
plt.show()
It generates something like this:
Like it says in the code comments, how do I get rid of this for-loop and vectorize the operation? I feel like I should be using reshape
to accomplish this, but I'm not sure how.
1 Answer 1
I figured out that this assignment could be rephrased as a vectorized multiplication which eliminates the need for a for-loop and costly indexing of individual groups of elements.
import matplotlib.pyplot as plt
import numpy as np
import ipdb
# constants
t_len = 0.5
freq = 10.0
dt = 0.001
# set the see for reproducible results
rng = np.random.RandomState(0)
# create the random values to interpolate between
assert dt < freq
white_size = int(t_len * freq)
white_vals = np.random.uniform(low=-1, high=1, size=white_size)
# do the interpolation
tot_size = int(t_len / dt)
step_size = int(1 / freq / dt)
n_shape = (white_size, step_size)
white_noise = (white_vals[:, None] * np.ones(n_shape)).reshape(tot_size)
assert white_vals.shape[0] < white_noise.shape[0]
# plot the result for visual verificaition
plt.plot(white_noise)
plt.show()
Explore related questions
See similar questions with these tags.