# -*- coding: utf-8 -*-
"""
Created on Thu Mar  6 17:45:56 2025

@author: AKourgli
"""

import numpy as np
import matplotlib.pyplot as plt

# Paramètres
T = 1.0
alphas = [0, 0.25, 0.5, 0.75, 1.0]
t = np.arange(-5, 5, 0.01)  # Base de temps

def srrc_impulse(t, alpha, T):
    """Génère la réponse impulsionnelle SRRC"""
    if alpha == 0:
        return np.sinc(t/T) / np.sqrt(T)
    
    numerator = np.sin(np.pi*(1-alpha)*t/T) + (4*alpha*t/T)*np.cos(np.pi*(1+alpha)*t/T)
    denominator = np.pi*t/T * (1 - (4*alpha*t/T)**2)
    
    h = np.zeros_like(t)
    valid_mask = np.abs(denominator) >= 1e-8
    h[valid_mask] = numerator[valid_mask] / denominator[valid_mask] / np.sqrt(T)
    
    # Gestion des cas spéciaux
    # t = 0
    h[np.isclose(t, 0, atol=1e-6)] = (1 - alpha + 4*alpha/np.pi)/np.sqrt(T)
    
    # t = ±T/(4α)
    if alpha != 0:
        critical_t = T/(4*alpha)
        mask = np.isclose(np.abs(t), critical_t, atol=1e-6)
        term1 = (1 + 2/np.pi)*np.sin((np.pi/(4*alpha))*(1 - alpha))
        term2 = (1 - 2/np.pi)*np.sin((np.pi/(4*alpha))*(1 + alpha))
        limit_val = alpha/np.sqrt(2*T)*(term1 + term2)
        h[mask] = limit_val
    
    return h

# Calcul des réponses impulsionnelles
impulse_responses = []
for alpha in alphas:
    h = srrc_impulse(t, alpha, T)
    impulse_responses.append(h)

# Vérification des zéros aux instants entiers (nT, n≠0)
for i, alpha in enumerate(alphas):
    h = impulse_responses[i]
    # Masque pour les multiples entiers de T (sauf t=0)
    mask = np.isclose(t, np.round(t), atol=1e-3) & (t != 0)
    h_at_integers = h[mask]
    max_deviation = np.max(np.abs(h_at_integers))
    print(f"Alpha={alpha:.2f} : Déviation max aux entiers = {max_deviation:.2e}")

# Calcul des DSP
psds = []
for h in impulse_responses:
    N = len(h)
    dt = 0.01
    H = np.fft.fftshift(np.fft.fft(h,4*N)) * dt
    freq = np.fft.fftshift(np.fft.fftfreq(N*4, dt))
    psd = np.abs(H)**2
    psds.append(psd)

# Tracés
plt.figure()

# Réponses impulsionnelles
plt.subplot(211)
for i, alpha in enumerate(alphas):
    plt.plot(t, impulse_responses[i], label=f'α={alpha}')
plt.title('Réponses impulsionnelles SRRC')
plt.xlabel('Temps (t/T)')
plt.ylabel('Amplitude')
plt.grid(True)
plt.legend()
plt.xlim(-4, 4)
plt.ylim(-0.5, 1.5)

# DSP
plt.subplot(212)
for i, alpha in enumerate(alphas):
    plt.plot(freq, psds[i], label=f'α={alpha}')
plt.title('Densités Spectrales de Puissance')
plt.xlabel('Fréquence (Hz)')
plt.ylabel('PSD')
plt.grid(True)
plt.legend()
plt.xlim(-2, 2)
plt.ylim(-0.2, 1.3)

plt.tight_layout()
plt.show()