{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Homework \\#6 - Python exercise" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%pylab inline\n", "import matplotlib\n", "import matplotlib.pyplot as plt\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Filtering a Sequence of Independent Random Variables\n", " \n", "Let $x[n]$ be a real-valued white Gaussian random process, with zero mean and variance $\\sigma_x^2=3$. We filter the process with the FIR filter $h[n]$ where\n", "$$\n", "h[1]=1/2, \\quad h[2]=1/4, \\quad h[3]=1/4, \\quad\n", "h[n]=0~\\forall~n\\neq 1,2,3\n", "$$\n", "Moreover, at the output of the filter, we add white Gaussian noise $z[n]$ with unit variance. \n", "\n", "* Write a routine in Python to generate $N$ samples of the input process, $N$ samples of the additive Gaussian noise and compute the output of the system.\n", "* write a routine to estimate the power spectral density of the output\n", "* compare the numerical estimation of the PSD with its theoretical value" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Solution\n", "\n", "For a comparison with the theoretical value we need the exact PSD of the output process, which is ...\n", "\n", "The following function computes a single $N$-point realization of the output process\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def compute_y(N):\n", " h = np.array([0, 0.5, 0.25, 0.25])\n", " # generate x[n]\n", " x = ...\n", " # filter it with h[n]; you may want to consult the Jupyter notebook FIRImplementation for\n", " # details about border effects when filtering a finite-length data set\n", " y1 = ...\n", " # generate z[n]\n", " z = ...\n", " # generate y[n]\n", " y = y1 + z\n", " return y " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The following function estimates the PSD using $M$ independent realizations of the process:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def estimate_psd(N, M):\n", " # estimate the PSD using M realizations\n", " ..." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This function computes the values of the theoretical PSD for the same frequency bins as the estimated PSD" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def theoretical_PSD(N):\n", " # define range for omega\n", " omega = np.arange(0, N) * 2 * np.pi / N \n", " p = ...\n", " return p" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# compare the experimental PSD to the theoretical PSD for different values of M\n", "N = 50\n", "for M in [50, 500, 5000]:\n", " plt.plot(estimate_psd(N, M), 'r--', label='estimate')\n", " plt.plot(theoretical_PSD(N), 'b-', label='theoretical')\n", " plt.legend()\n", " plt.show() " ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.7" } }, "nbformat": 4, "nbformat_minor": 4 }