Print 1
Print 1
Q1) Determine the Z-Transform X(z) of x(n)=0.5^(n-2) * u(n-2) and draw the pole
zero plot of X(z).
Step 3) Then find out the numerator b and denominator coefficients a from X(Z).
Step 4) Then verify the input sequence using python function "filter" from X(Z).
Step 5) Draw the pole zero plot from X(Z).
Solution:
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import lfilter, tf2zpk
# Define the range of n
n = np.arange(0, 10)
# Original sequence x(n) = 0.5^(n-2) * u(n-2)
x_n = 0.5**(n-2) * (n >= 2)
# Coefficients of X(z) derived from the transfer function
b = [1]
a = [1, -0.5, 0]
# Input to the filter: unit impulse (delta function)
delta = np.zeros(len(n))
delta[2] = 1 # Shifting the impulse to n=2 to match the original sequence
# Apply filter
x_n_verification = lfilter(b, a, delta)
# Plot the original sequence in the first subplot
plt.figure(figsize=(10, 6))
plt.subplot(2, 1, 1)
plt.stem(n, x_n, linefmt='b-', markerfmt='bo', basefmt='r-')
plt.title('Original Sequence x(n)')
plt.xlabel('n')
plt.ylabel('x(n)')
plt.grid(True)
# Plot the filtered sequence in the second subplot
plt.subplot(2, 1, 2)
122EC0579
plt.stem(n, x_n_verification, linefmt='b-', markerfmt='bo', basefmt='r-')
plt.title('Filtered Sequence from X(z)')
plt.xlabel('n')
plt.ylabel('x(n)')
plt.grid(True)
# Show the plots
plt.tight_layout()
plt.show()
# Calculate poles and zeros
zeros, poles, _ = tf2zpk(b, a)
# Plot pole-zero plot with ROC
plt.figure()
# Plot poles and zeros
plt.scatter(np.real(zeros), np.imag(zeros), marker='o', color='blue',
label='Zeros')
plt.scatter(np.real(poles), np.imag(poles), marker='x', color='red',
label='Poles')
# Plot ROC circle
outermost_pole = max(abs(poles))
roc_circle = plt.Circle((0, 0), outermost_pole, color='green', fill=False,
linestyle='--', label='ROC Boundary')
plt.gca().add_artist(roc_circle)
# Fill the ROC area outside the outermost pole
theta = np.linspace(0, 2*np.pi, 100)
roc_boundary = outermost_pole * np.exp(1j*theta)
plt.fill(np.real(roc_boundary), np.imag(roc_boundary), color='green', alpha=0.2)
# Plot unit circle
unit_circle = plt.Circle((0, 0), 1, color='orange', fill=False, linestyle=':',
label='Unit Circle')
plt.gca().add_artist(unit_circle)
# Ensure the circle fits in the plot area
plt.gca().set_aspect('equal', adjustable='box')
# Calculate the limits dynamically and add extra margin
max_radius = max(outermost_pole, 1)
plt.xlim(-max_radius-1, max_radius+1)
plt.ylim(-max_radius-1, max_radius+1)
plt.axhline(0, color='black')
plt.axvline(0, color='black')
plt.title('Pole-Zero Plot with ROC and Unit Circle')
plt.xlabel('Real')
plt.ylabel('Imaginary')
plt.grid(True)
plt.legend()
plt.show()
122EC0579
PLOTS:
122EC0579
SUMMARY: This Python script analyzes a discrete-time sequence and its
corresponding transfer function X(z). The script:
1. Generates the Sequence: Computes the original sequence x(n) for n=0 to
999.
3. Plots the Sequences: Compares the original and filtered sequences using
stem plots.
4. Visualizes Poles and Zeros: Creates a pole-zero plot, showing the poles,
zeros, the unit circle, and the Region of Convergence (ROC).
This script provides a clear visualization of the sequence and its system
characteristics.
122EC0579
Q2) Determine the inverse z transform X(Z)=1/((1-0.9z^-1) ^2(1+0.9z^-1))
,|z|>0.9 and draw the pole zero plot.
STEP 1) find out the numerator and denominator of the given transfer function
Step 2) find the residue and poles using the python function residues
Step 3) then verify the input sequnece x(n) using the lfilter function frim X(Z)
CODE:
import numpy as np
import matplotlib.pyplot as plt
import scipy.signal as signal
def transfer_function_coefficients():
# Define roots and their multiplicities
roots = [(0.9, 2), (-0.9, 1)]
# Generate polynomial from roots
denominator_poly = np.poly([root for root, multiplicity in roots for _ in
range(multiplicity)])
# Numerator coefficients
numerator_coeff = [1, 0, 0]
return numerator_coeff, denominator_poly
def compute_residues(b_coeff, a_coeff):
residues, poles, direct_term = signal.residuez(b_coeff, a_coeff)
return residues, poles, direct_term
def generate_impulse_response(b_coeff, a_coeff, N):
impulse = np.zeros(N)
impulse[0] = 1
return signal.lfilter(b_coeff, a_coeff, impulse)
def calculate_xn_analytically(A, B, C, alpha, N):
n = np.arange(0, N)
return np.real(3 * A * alpha ** n + B * n * alpha ** n + C * (-alpha) ** n)
def plot_impulse_response(n, x_n_analytical, recovered_signal):
plt.figure(figsize=(10, 5))
plt.subplot(2, 1, 1)
plt.stem(n, x_n_analytical, linefmt='b-', markerfmt='bo', basefmt='r-')
plt.title('Impulse Response x[n] Using Analytical Calculation')
122EC0579
plt.xlabel('n')
plt.ylabel('x[n]')
plt.grid()
plt.subplot(2, 1, 2)
plt.stem(n, recovered_signal, linefmt='g-', markerfmt='go', basefmt='r-')
plt.title('Impulse Response x[n] Using Filter')
plt.xlabel('n')
plt.ylabel('x[n]')
plt.grid()
plt.tight_layout()
plt.show()
def plot_pole_zero(b_coeff, a_coeff):
plt.figure()
plt.title('Pole-Zero Plot of X(z)')
plt.xlabel('Real')
plt.ylabel('Imaginary')
zeros = np.roots(b_coeff)
poles = np.roots(a_coeff)
plt.scatter(np.real(zeros), np.imag(zeros), marker='o', color='r',
label='Zeros')
plt.scatter(np.real(poles), np.imag(poles), marker='x', color='b',
label='Poles')
circle = plt.Circle((0, 0), 1, color='g', fill=False)
plt.gca().add_patch(circle)
plt.axhline(0, color='black', linewidth=0.5)
plt.axvline(0, color='black', linewidth=0.5)
plt.grid()
plt.legend()
plt.show()
if __name__ == "__main__":
b_coeff, a_coeff = transfer_function_coefficients()
residues, poles, direct_term = compute_residues(b_coeff, a_coeff)
print("Residues:", residues)
print("Poles:", poles)
N = 8 # Number of samples
recovered_signal = generate_impulse_response(b_coeff, a_coeff, N)
print("Recovered signal using filter:", recovered_signal)
A, B, C = 0.25, 0.5, 0.25
alpha = 0.9
x_n_analytical = calculate_xn_analytically(A, B, C, alpha, N)
print("Calculated x(n) analytically:", x_n_analytical)
n = np.arange(0, N)
plot_impulse_response(n, x_n_analytical, recovered_signal)
plot_pole_zero(b_coeff, a_coeff)
122EC0579
OUTPUT:
PLOTS:
122EC0579
SUMMARY:
This Python script analyzes the impulse response of a discrete-time linear system
represented by a transfer function. It calculates the system's response to an
impulse input using two methods:
1. Analytical Method: The script calculates the response using residues, poles,
and direct terms derived from the transfer function's coefficients.
122EC0579
2. Filter Method: The script uses the scipy.signal.lfilter function to compute
the impulse response directly from the transfer function.
The script then plots both the analytically computed impulse response and the
response obtained from the filter for comparison. Additionally, it generates a
pole-zero plot to visualize the system's poles and zeros in the complex plane. The
code is organized into functions for clarity and reusability, with a main section to
execute the defined tasks.
122EC0579