2
\$\begingroup\$

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:

sig_plots

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.

\$\endgroup\$
3
\$\begingroup\$

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()
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.