Skip to content

Instantly share code, notes, and snippets.

@scls19fr
Last active February 29, 2024 12:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save scls19fr/8a7e0a6bd153be697851e2391390276b to your computer and use it in GitHub Desktop.
Save scls19fr/8a7e0a6bd153be697851e2391390276b to your computer and use it in GitHub Desktop.
Python Numpy - quantization of signal - example of a 2 bits quantization
# https://stackoverflow.com/questions/38152081/how-do-you-quantize-a-simple-input-using-python
def clamp(x: float, x_min=0.0, x_max=1.0):
"""
clamp a value to be within two bounds
returns lo if x < lo, hi if x > hi else x
"""
return min(x_max, max(x, x_min))
def normalize(x, x_min, x_max):
"""
normalizes the parameter x inside the value range specified by the x_min and x_max parameters.
"""
return (x - x_min) / (x_max - x_min)
def scale(val, x_min, x_max):
"""
scales the normalized real parameter val where ( 0.0 <= val <= 1.0 ) in value range specified by the y_min and y_max parameters
"""
return val * (x_max - x_min) + x_min
def quantization_lin(x, x_min, x_max, q, N):
"""
linear quantization of x given x_min, x_max and quantum q
"""
return np.round(x / q)
def quantization(x, x_min, x_max, nb_possible_values):
"""
quantization of x given x_min, x_max and quantum q
"""
q = 1.0 / (nb_possible_values - 1)
v_clamp = np.vectorize(lambda x: clamp(x, 0, nb_possible_values - 1))
v_quantization_lin = np.vectorize(lambda x0: quantization_lin(x0, x_min, x_max, q, N))
x_norm = normalize(x, x_min, x_max)
x = v_quantization_lin(x_norm)
x = v_clamp(x)
x = scale(x * q, x_min, x_max)
return x
x_min, x_max = 0.0, 5.0
x_min, x_max = -1.0, 1.0
x_min, x_max = 10.0, 15.0
N = 1_000_000
x = np.linspace(x_min - 1.5, x_max + 1.5, N)
bits = 2
nb_possible_values = 2 ** bits
#q = (x_max - x_min) / (nb_possible_values - 1)
x_q = quantization(x, x_min, x_max, nb_possible_values)
fig, ax = plt.subplots()
ax.set_title(f"Quantization with {nb_possible_values} possible values")
ax.add_patch(Rectangle((x_min, x_min), x_max - x_min, x_max - x_min, fill=False, edgecolor="grey", linestyle="--"))
ax.plot(x, x, label="x")
ax.plot(x, x_q, label="x quantized")
ax.set_xlabel("input")
ax.set_ylabel("output")
ax.legend()
Ts = 0.01 # sampling period (s)
t = np.arange(0.0, 5.0, Ts)
f = 1.0 # signal frequency
ys = np.sin(2 * np.pi * f * t) # sin signal
bits = 2
nb_possible_values = 2 ** bits
ysq = quantization(ys, -0.95, 0.95, nb_possible_values)
plt.plot(t, ys, label="input signal")
plt.plot(t, ysq, label="quantized signal", linestyle="-") # '-', '--', '-.', ':', 'None', ' ', '', 'solid', 'dashed', 'dashdot', 'dotted'
plt.xlabel("Time (s)")
plt.ylabel("Signal")
plt.legend(loc="upper right")
@scls19fr
Copy link
Author

image

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment