Generating random square wave that last for certain time
Question:
I am trying to generate a random square wave signal in Python that lasts for a certain amount of time. Specifically,each square wave should have a fixed duration of 5 minutes and a random amplitude that is bounded between 0 and 1. The square wave should remain at each amplitude level for the full 5 minutes and then transition to a new amplitude level.
I’ve tried adapting existing code, but so far, I haven’t been able to generate the square waves as described. I’m using NumPy and Matplotlib for the simulation and visualization.
import numpy as np
import matplotlib.pyplot as plt
# Define the bounds of the random vectors
min_value = 0.0
max_value = 1.0
# Define the duration of each square value in seconds
square_duration = 5 * 60 # 5 minutes
# Define the total number of samples in the simulation
max_sim = 1 * 60 * 60 # 24 hours * 60 minutes/hour * 60 seconds/minute
# Initialize the load and renewable profiles vectors
pl = np.zeros(max_sim)
# Generate the random bounded vectors
for i in range(max_sim):
if i % (square_duration + 1) == 0: # Start a new square value
square_value = np.random.uniform(min_value, max_value)
square_counter = 0
square_change = np.random.randint(1, square_duration + 1)
if square_counter < square_change: # Use the same square value
pl[i] = square_value
square_counter += 1
else: # Start a new square value
square_value = np.random.uniform(min_value, max_value)
pl[i] = square_value
square_counter = 0
square_change = np.random.randint(1, square_duration + 1)
# Add sinusoidal variation to the load profile
pl[i] += np.sin(i / max_sim * 2 * np.pi) * 0.15 * 1
# Clip the values to the defined bounds
pl[i] = np.clip(pl[i], min_value, max_value)
plt.show()
Can anyone suggest how to modify the existing code or provide an alternative solution to generate the random square wave profiles I need?
This is the output I am having:
It is almost ready but I need that the duration of each square to be constant.
Answers:
Would something like below work for you? Although you should tweak it according to your needs. Right now I am setting the square count manually. Maybe you can calculate it from simulation duration.
import numpy as np
import matplotlib.pyplot as plt
min_value = 0.0
max_value = 1.0
square_count = 20
square_duration = 60*5
a = np.random.uniform(min_value, max_value, size=(square_count, 1))
a = np.tile(a, (1, square_duration)).flatten()
plt.plot(a)
output image:
Several suggestions
Clearer variable names
I suggest making clear what is the amplitude and what is the y value at a particular time.
You can also specify units, such as seconds which will help you.
Separate the creation of the amplitude from creation of the y value
You also will need a variable for the period of the square wave.
If you really mean the amplitude, the wave should go from +amplitude to -amplitude (not to 0)
Source: https://no.wikipedia.org/wiki/Amplitude
Possible solution
import numpy as np
import matplotlib.pyplot as plt
# Define the bounds of the random vectors
min_value = -1.0
max_value = 1.0
square_wave_half_period_seconds = 30
block_duration_seconds = 5 * 60 # 5 minutes
simulation_duration_seconds = 1 * 60 * 60 # 1 hour * 60 minutes/hour * 60 seconds/minute
# Initialize the load and renewable profiles vectors
ys = np.zeros(simulation_duration_seconds)
# Generate the random bounded vectors
for t_seconds in range(simulation_duration_seconds):
if t_seconds % (block_duration_seconds) == 0: # Start a new square value
amplitude = np.random.uniform(min_value, max_value)
am_in_first_half_of_square_wave = (t_seconds // square_wave_half_period_seconds) % 2 == 0
ys[t_seconds] = amplitude * (1 if am_in_first_half_of_square_wave else -1)
ys[t_seconds] += np.sin(t_seconds * 2 * np.pi) * 0.15 * 1
# Clip the values to the defined bounds
ys[t_seconds] = np.clip(ys[t_seconds], min_value, max_value)
plt.plot(ys)
plt.show()
I am trying to generate a random square wave signal in Python that lasts for a certain amount of time. Specifically,each square wave should have a fixed duration of 5 minutes and a random amplitude that is bounded between 0 and 1. The square wave should remain at each amplitude level for the full 5 minutes and then transition to a new amplitude level.
I’ve tried adapting existing code, but so far, I haven’t been able to generate the square waves as described. I’m using NumPy and Matplotlib for the simulation and visualization.
import numpy as np
import matplotlib.pyplot as plt
# Define the bounds of the random vectors
min_value = 0.0
max_value = 1.0
# Define the duration of each square value in seconds
square_duration = 5 * 60 # 5 minutes
# Define the total number of samples in the simulation
max_sim = 1 * 60 * 60 # 24 hours * 60 minutes/hour * 60 seconds/minute
# Initialize the load and renewable profiles vectors
pl = np.zeros(max_sim)
# Generate the random bounded vectors
for i in range(max_sim):
if i % (square_duration + 1) == 0: # Start a new square value
square_value = np.random.uniform(min_value, max_value)
square_counter = 0
square_change = np.random.randint(1, square_duration + 1)
if square_counter < square_change: # Use the same square value
pl[i] = square_value
square_counter += 1
else: # Start a new square value
square_value = np.random.uniform(min_value, max_value)
pl[i] = square_value
square_counter = 0
square_change = np.random.randint(1, square_duration + 1)
# Add sinusoidal variation to the load profile
pl[i] += np.sin(i / max_sim * 2 * np.pi) * 0.15 * 1
# Clip the values to the defined bounds
pl[i] = np.clip(pl[i], min_value, max_value)
plt.show()
Can anyone suggest how to modify the existing code or provide an alternative solution to generate the random square wave profiles I need?
This is the output I am having:
It is almost ready but I need that the duration of each square to be constant.
Would something like below work for you? Although you should tweak it according to your needs. Right now I am setting the square count manually. Maybe you can calculate it from simulation duration.
import numpy as np
import matplotlib.pyplot as plt
min_value = 0.0
max_value = 1.0
square_count = 20
square_duration = 60*5
a = np.random.uniform(min_value, max_value, size=(square_count, 1))
a = np.tile(a, (1, square_duration)).flatten()
plt.plot(a)
output image:
Several suggestions
Clearer variable names
I suggest making clear what is the amplitude and what is the y value at a particular time.
You can also specify units, such as seconds which will help you.
Separate the creation of the amplitude from creation of the y value
You also will need a variable for the period of the square wave.
If you really mean the amplitude, the wave should go from +amplitude to -amplitude (not to 0)
Source: https://no.wikipedia.org/wiki/Amplitude
Possible solution
import numpy as np
import matplotlib.pyplot as plt
# Define the bounds of the random vectors
min_value = -1.0
max_value = 1.0
square_wave_half_period_seconds = 30
block_duration_seconds = 5 * 60 # 5 minutes
simulation_duration_seconds = 1 * 60 * 60 # 1 hour * 60 minutes/hour * 60 seconds/minute
# Initialize the load and renewable profiles vectors
ys = np.zeros(simulation_duration_seconds)
# Generate the random bounded vectors
for t_seconds in range(simulation_duration_seconds):
if t_seconds % (block_duration_seconds) == 0: # Start a new square value
amplitude = np.random.uniform(min_value, max_value)
am_in_first_half_of_square_wave = (t_seconds // square_wave_half_period_seconds) % 2 == 0
ys[t_seconds] = amplitude * (1 if am_in_first_half_of_square_wave else -1)
ys[t_seconds] += np.sin(t_seconds * 2 * np.pi) * 0.15 * 1
# Clip the values to the defined bounds
ys[t_seconds] = np.clip(ys[t_seconds], min_value, max_value)
plt.plot(ys)
plt.show()