def continuous_discrete_time_signals():
    t = np.arange(-10, 10.01, 0.01)
    n = np.arange(-10, 11, 1.0)
    x_t = np.exp(-0.1 * (t ** 2))  # continuous signal
    x_n = np.exp(-0.1 * (n ** 2))  # discrete signal

    fig = figure(figsize=(17,5))
    plot(t, x_t, label="$e^{-0.1*t^{2}}$")
    stem(n, x_n, label="$e^{-0.1*n^{2}}$", basefmt='.')
    ylim(-0.1, 1.1)
    xticks(fontsize=25)
    yticks(fontsize=25)
    xlabel('Time', fontsize=25)
    legend(prop={'size':30});
    savefig("img/cont_disc.svg", format="svg")

continuous_discrete_time_signals()

"""
Explanation: <h1>Introduction to Signal Processing</h1>
<h3>Lecture 1</h3>
<h2 class="title_stuff">Sivakumar Balasubramanian</h2>
<h4 class="title_stuff">Lecturer in Bioengineering</h4>
<h4 class="title_stuff">Christian Medical College, Vellore</h4>

<h6 class="header">Introduction to Signal Processing (Lecture 1)</h6>
<h1>What is the course about?</h1>
<hr>
<ul class="content">
    <li>Course on the theory and practice of signal processing techniques.</li>
    <li>First part of the course will focus on continuous-time signal processing.</li>
    <li>Second part of the course will focus on <b>digital signal processing</b>.</li>
    <li>Final part of the course will introduce ideas on time-frequency analysis.</li>
</ul>

<h1>What to expect from the course?</h1>
<hr>
<ul class="content">
    <li>A good understanding of the theory of continuous and discrete-time signal processing.</li>
    <li>Ability to analyze and synthesize analog and digital filters.</li>
    <li>An intuitive understanding of time-frequency analysis.</li>
</ul>

<h6 class="header">Introduction to Signal Processing (Lecture 1)</h6>
<h1>Pre-requisites</h1>
<hr>
<ul class="content">
    <li>Basic understanding of calculus (limits, derivative, integration).</li>
    <li>Basic understanding of probability theory.</li>
    <li>Experience in programming (C and Python would be ideal).</li>
</ul>

<h6 class="header">Introduction to Signal Processing (Lecture 1)</h6>
<h1>Course Layout</h1>
<hr>
<ul class="content">
<li><b>Total score: 100</b>[25 + 15 + 15 + 45]
        <ul class="content">
        <li> Assignments [6]: 5 x 5 = 25</li>
        <li> Suprise quizes [4]: 3 x 5 = 15</li>
        <li> Mid-term exam: 15</li>
        <li> Final exam: 45</li>
        </ul>
    </li>
</ul>

<h6 class="header">Introduction to Signal Processing (Lecture 1)</h6>
<h1>Course Content</h1>
<hr>
<ul class="content-packed">
    <li><b>Signals and systems</b></li>
    <li><b>Continuous-time Signals</b></li>
    <li><b>Continuous-time Systems</b></li>
    <li><b>Impulse response and convolution integral</b></li>
    <li><b>Fourier and Laplace transforms</b></li>
    <li><b>Introduction to filtering</b></li>
    <li><b>Analog filters</b></li>
    <li><b>Sampling theorem</b></li>
    <li><b>Discrete-time signals and systems</b></li>
    <li><b>Discrete Fourier transform and its computation</b></li>
    <li><b>Z-transform</b></li>
    <li><b>Digital filter design and implementation</b></li>
    <li><b>Stochastic processes and spectral estimation</b></li>
    <li><b>Time-frequency analysis</b></li>
</ul>

<h6 class="header">Introduction to Signal Processing (Lecture 1)</h6>
<h1>Reference material:</h1>
<hr>
<ul class="content-packed">
    <li>Oppenhein, Alan V., and Ronald W. Schafer. <i>"Discrete-time signal processing."</i> Prentice Hall, New York, 1999.</li>
    <li>Proakis, John G. <i>Digital signal processing: principles algorithms and applications.</i> Pearson Education India, 2001.</li>
    <li>Devasahayam, Suresh R. <i>Signals and systems in biomedical engineering: signal processing and physiological systems modeling</i>. Springer, 2012.</li>
    <li>Haykin, Simon, and Barry Van Veen. <i>Signals and systems</i>. John Wiley & Sons, 2007.</li>
    <li>[<i>In progress</i>] https://github.com/siva82kb/intro_to_signal_processing/</li>    
</ul>

<h6 class="header">Introduction to Signal Processing (Lecture 1)</h6>
<h1>What is signal processing?</h1>
<hr>
<ul class="content">
    <li class="small">"Signal processing is an enabling technology that encompasses the fundamental theory, applications, algorithms, and implementations of <b>processing or transferring information</b> contained in many different physical, symbolic, or abstract formats broadly designated as signals and uses <b>mathematical, statistical, computational, heuristic, and/or linguistic representations</b>, formalisms, and techniques for <b>representation, modeling, analysis, synthesis, discovery, recovery, sensing, acquisition, extraction, learning, security, or forensics.</b>"[1]</li>
    <li>An umbrella term to describe a wide variety of things.</li>
</ul>

<br>
<p class="reference">[1] Moura, J.M.F. (2009). "What is signal processing?, President’s Message". <i>IEEE Signal Processing Magazine</i> <b>26</b> (6). doi:10.1109/MSP.2009.934636</p>

<h6 class="header">Introduction to Signal Processing (Lecture 1)</h6>
<h1>What is a signal?</h1>
<p class="normal">Any physical quantity carrying information that varies with one or more independent variables.</p>
<div class="formula"> $$ s\left(t\right) = 1.23t^2 - 5.11t +41.5 $$ </div>
<div class="formula"> $$ s\left(x,y\right) = e^{-(x^2 + y^2 + 0.5xy)} $$ </div>
<p class="normal">Mathematical representation will not be possible <i>(e.g. physiological signals,  either because the exact function is not known or is too complicated.)</i></p>

<p class="normal"><i>Can you think of example of 3D and 4D signals?</i></p>

<h6 class="header">Introduction to Signal Processing (Lecture 1)</h6>
<h1>Classification of signals</h1>

<p class="normal"> &raquo; Based on the dimensions. <i>e.g. 1D, 2D signals</i><br>

<p class="normal"> &raquo; <b>Scalar</b> vs. <b>Vector</b>: <i>e.g: gray-scale versus RGB image</i></p>
<div class="formula"> $$ I_g(x,y) \in \mathbb{R} \,\,\, \text{and} \,\,\, I_{color} \in \mathbb{R}^3 $$ </div>

<p class="normal"> &raquo; <b>Continuous-time</b> vs. <b>Discrete-time</b>: <i>based on values assumed by the independent variable.</i></p>
<div class="formula">
$$\begin{cases}
x(t) = e^{-0.1t^{2}}, \,\, t \in \mathbb{R} & \text{Continuous-time} \\
x[n] = e^{-0.1n^{2}}, \,\, n \in \mathbb{Z} & \text{Discrete-time}
\end{cases}
$$
</div>
End of explanation
"""


def continuous_discrete_valued_signals():
    t = np.arange(-10, 10.01, 0.01)
    n_steps = 10.
    x_c = np.exp(-0.1 * (t ** 2))
    x_d = (1/n_steps) * np.round(n_steps * x_c)

    fig = figure(figsize=(17,5))
    plot(t, x_c, label="Continuous-valued")
    plot(t, x_d, label="Discrete-valued")
    ylim(-0.1, 1.1)
    xticks(fontsize=25)
    yticks(fontsize=25)
    xlabel('Time', fontsize=25)
    legend(prop={'size':25});
    savefig("img/cont_disc_val.svg", format="svg")

continuous_discrete_valued_signals()

"""
Explanation: <p class="normal"> &raquo; <b>Continuous-valued</b> vs. <b>Discrete-valued</b>: <i>based on values assumed by the dependent variable.</i></p>
<div class="formula">
$$ \begin{cases}
x(t) \in [a, b] & \text{Continuous-valued} \\
x(t) \in \{a_1, a_2, \cdots\} & \text{Discrete-valued} \\
\end{cases}
$$
</div>
End of explanation
"""


def continuous_discrete_combos():
    t = np.arange(-10, 10.01, 0.01)
    n = np.arange(-10, 11, 0.5)
    n_steps = 5.

    # continuous-time continuous-valued signal
    x_t_c = np.exp(-0.1 * (t ** 2))
    # continuous-time discrete-valued signal
    x_t_d = (1/n_steps) * np.round(n_steps * x_t_c)
    # discrete-time continuous-valued signal
    x_n_c = np.exp(-0.1 * (n ** 2))
    # discrete-time discrete-valued signal
    x_n_d = (1/n_steps) * np.round(n_steps * x_n_c)

    figure(figsize=(17,8))
    subplot2grid((2,2), (0,0), rowspan=1, colspan=1)
    plot(t, x_t_c,)
    ylim(-0.1, 1.1)
    xticks(fontsize=25)
    yticks(fontsize=25)
    title("Continuous-time Continuous-valued", fontsize=25)

    subplot2grid((2,2), (0,1), rowspan=1, colspan=1)
    plot(t, x_t_d,)
    ylim(-0.1, 1.1)
    xticks(fontsize=25)
    yticks(fontsize=25)
    title("Continuous-time Discrete-valued", fontsize=25)

    subplot2grid((2,2), (1,0), rowspan=1, colspan=1)
    stem(n, x_n_c, basefmt='.')
    ylim(-0.1, 1.1)
    xlim(-10, 10)
    xticks(fontsize=25)
    yticks(fontsize=25)
    title("Discrete-time Continuous-valued", fontsize=25)

    subplot2grid((2,2), (1,1), rowspan=1, colspan=1)
    stem(n, x_n_d, basefmt='.')
    ylim(-0.1, 1.1)
    xlim(-10, 10)
    xticks(fontsize=25)
    yticks(fontsize=25)
    title("Discrete-time Discrete-valued", fontsize=25);
    
    tight_layout();
    
    savefig("img/signal_types.svg", format="svg");


continuous_discrete_combos()

"""
Explanation: <p class="normal">Last two classifications can be combined to have four possible combinations of signals:</p>
<ul class="content">
<li><i>Continuous-time continuous-valued signals</i></li>
<li><i>Continuous-time discrete-valued signals</i></li>
<li><i>Discrete-time continuous-valued signals</i></li>
<li><i>Discrete-time discrete-valued signals</i></li>
</ul>
End of explanation
"""


def deterministic_stochastic():
    t = np.arange(0., 10., 0.005)
    x = np.exp(-0.5 * t) * np.sin(2 * np.pi * 2 * t)
    y1 = np.random.normal(0, 1., size=len(t))
    y2 = np.random.uniform(0, 1., size=len(t))

    figure(figsize=(17, 10))

    # deterministic signal
    subplot2grid((3,3), (0,0), rowspan=1, colspan=3)
    plot(t, x, label="$e^{-0.5t}\sin 4\pi t$")
    title('Deterministic signal', fontsize=25)
    xticks(fontsize=25)
    yticks(fontsize=25)
    legend(prop={'size':25});

    # stochastic signal - normal distribution
    subplot2grid((3,3), (1,0), rowspan=1, colspan=2)
    plot(t, y1, label="Normal distribution")
    ylim(-4, 6)
    title('Stochastic signal (Normal)', fontsize=25)
    xticks(fontsize=25)
    yticks(fontsize=25)
    legend(prop={'size':25});

    # histogram
    subplot2grid((3,3), (1,2), rowspan=1, colspan=1)
    hist(y1)
    xlim(-6, 6)
    title("Histogram", fontsize=25)
    xticks(fontsize=25)
    yticks([0, 200, 400, 600], fontsize=25)
    legend(prop={'size':25});

    # stochastic signal - normal distribution
    subplot2grid((3,3), (2,0), rowspan=1, colspan=2)
    plot(t, y2, label="Normal distribution")
    ylim(-0.3, 1.5)
    title('Stochastic signal (Uniform)', fontsize=25)
    xticks(fontsize=25)
    yticks(fontsize=25)
    legend(prop={'size':25});

    # histogram
    subplot2grid((3,3), (2,2), rowspan=1, colspan=1)
    hist(y2)
    xlim(-0.2, 1.2)
    title("Histogram", fontsize=25)
    xticks(fontsize=25)
    yticks([0, 100, 200], fontsize=25)
    legend(prop={'size':25})
    
    tight_layout()
    
    savefig("img/det_stoch.svg", format="svg");

deterministic_stochastic()

"""
Explanation: <p class="normal">EMG recorded from a linear electrode array.</p>

<p class="normal"> &raquo; <b>Deterministic</b> vs. <b>Stochastic</b>: <i>e.g. EMG is an example of a stochastic signal.</i></p>
End of explanation
"""


def even_odd_decomposition():
    t = np.arange(-5, 5, 0.01)
    x = (0.5 * np.exp(-(t-2.1)**2) * np.cos(2*np.pi*t) + 
         np.exp(-t**2) * np.sin(2*np.pi*3*t))

    figure(figsize=(17,4))
    # Original function
    plot(t, x, label="$x(t)$") 
    # Even component
    plot(t, 0.5 * (x + x[::-1]) - 2, label="$x_{even}(t)$")
    # Odd component
    plot(t, 0.5 * (x - x[::-1]) + 2, label="$x_{odd}(t)$")
    xlim(-5, 8)
    title('Decomposition of a signal into even and odd components', fontsize=25)
    xlabel('Time', fontsize=25)
    xticks(fontsize=25)
    yticks([])
    legend(prop={'size':25})
    savefig("img/even_odd.svg", format="svg");


even_odd_decomposition()

"""
Explanation: <p class="normal"> &raquo; <b>Even</b> vs. <b>Odd</b>: <i>based on symmetry about the $t=0$ axis.</i></p>
<div class="formula">
$$
\begin{cases}
x(t) = x(-t), & \text{Even signal} \\
x(t) = -x(-t), & \text{Odd signal} \\
\end{cases}
$$
</div>

<p class="normal"><i>Can there be signals that are neither even nor odd?</i></p>

<div class="theorem"><b>Theorem</b>: Any arbitrary function can be represented as a sum of an odd and even function.
<div class="formula">$$ x(t) = x_{even}(t) + x_{odd}(t) $$</div>
where,<div class="formula-inline">$ x_{even}(t) = \frac{x(t) + x(-t)}{2} $</div> and <div class="formula-inline">$ x_{odd}(t) = \frac{x(t) - x(-t)}{2} $</div>.
</div>
End of explanation
"""


def memory():
    dt = 0.01
    N = np.round(0.5/dt)
    t = np.arange(-1.0, 5.0, dt)
    x = 1.0 * np.array([t >= 1.0, t < 3.0]).all(0)

    # memoryless system
    y1 = 0.5 * x
    # system with memory.
    y2 = np.zeros(len(x))
    for i in xrange(len(y2)):
        y2[i] = np.sum(x[max(0, i-N):i]) * dt

    figure(figsize=(17,4))
    plot(t, x, lw=2, label="$x(t)$")
    plot(t, y1, lw=2, label="$0.5x(t)$")
    plot(t, y2, lw=2, label="$\int_{t-0.5}^{t}x(p)dp$")
    xlim(-1, 5)
    ylim(-0.1, 1.1)
    xticks(fontsize=25)
    yticks(fontsize=25)
    xlabel('Time', fontsize=25)
    legend(prop={'size':25})
    
    savefig("img/memory.svg", format="svg");

memory()

"""
Explanation: <p class="normal"> &raquo; <b>Periodic</b> vs. <b>Non-periodic</b>:  <i>a signal is periodic, if and only if</i></p>
<div class="formula">
$$ x(t) = x(t + T), \,\, \forall t, \,\,\, T \text{ is the fundamental period.}$$
</div>

<p class="normal"> &raquo; <b>Energy</b> vs. <b>Power</b>:  <i>indicates if a signal is short-lived.</i></p>
<div class="formula">
$$
E = \int_{-\infty}^{\infty}\left|x(t)\right|^{2}dt \,\,\,\,\,\,\,\,\,\, P = \lim_{T\to\infty}\frac{1}{T}\int_{-T/2}^{T/2}\left|x(t)\right|^{2}dt
$$
</div>
<p class="normal"><i> A signal is an energy signal, if</i></p>
<div class="formula"> $$ 0 < E < \infty $$ </div>
<p class="normal"><i> and a signal is a power signal, if</i></p>
<div class="formula"> $$ 0 < P < \infty $$ </div>

<h6 class="header">Introduction to Signal Processing (Lecture 1)</h6>
<h1>What is a system?</h1>
<p class="normal">A system is any physical device or algorithm that performs some operation on a signal to transform it into another signal.</p>

<h6 class="header">Introduction to Signal Processing (Lecture 1)</h6>
<h1>Classification of systems</h1>
<p class="normal"><i>Based on the properties of a system:</i></p>
<p class="normal"> &raquo; <b>Linearity:</b> $\implies$ <i><b>scaling</b> and <b>superposition</b> </i></p>
<p class="normal"> Lets assume, </p>
<div class="formula"> $$ f: x_i(t) \mapsto y_i(t) $$ </div>
<p class="normal"> The system is linear, if and only if,</p>
<div class="formula"> $$ f: \sum_{i}a_ix_i(t) \mapsto \sum_{i}a_iy_i(t) $$ </div>

<p class="normal"><i>Which of the following systems are linear?</i></p>
<div class="formula">(a) $y(t) = k_1x(t) + k_2x(t-2)$</div>
<div class="formula">(b) $y(t) = \int_{t-T}^{t}x(\tau)d\tau$</div>
<div class="formula">(c) $y(t) = 0.5x(t) + 1.5$</div>

<p class="normal"> &raquo; <b>Memory:</b> <i>a system whose output depends on past, present or future values of input is a <b>system with memory</b>, else the system is <b>memoryless</b></i></p>
<p class="normal">Memoryless system: </p>
<div class="formula"> $$ y(t) = 0.5x(t) $$ </div>
<p class="normal">System with memory: </p>
<div class="formula"> $$ y(t) = \int_{t-0.5}^{t}x(\tau)d\tau$$ </div>
End of explanation
"""


%pylab inline
import seaborn as sb

# Functions to generate plots for the different sections.
def signal_examples():
    t = np.arange(-5, 5, 0.01)
    s1 = 1.23 * (t ** 2) - 5.11 * t + 41.5
    x, y = np.arange(-2.0, 2.0, 0.01), np.arange(-2.0, 2.0, 0.01)

    fig = figure(figsize=(17, 7))
    subplot(121)
    plot(t, s1)
    xlabel('Time', fontsize=20)
    xlim(-5, 5)
    xticks(fontsize=25)
    yticks(fontsize=25)
    title("$1.23t^2 - 5.11t + 41.5$", fontsize=30)

    subplot(122)
    s = np.array([[np.exp(-(_x**2 + _y**2 + 0.5*_x*_y)) for _y in y] for _x in x])
    X, Y = meshgrid(x, y)
    contourf(X, Y, s)
    xticks(fontsize=25)
    yticks(fontsize=25)
    title("$s(x, y) = e^{-(x^2 + y^2 + 0.5xy)}$", fontsize=30);
    savefig("img/signals.svg", format="svg")

def memory():
    dt = 0.01
    N = np.round(0.5/dt)
    t = np.arange(-1.0, 5.0, dt)
    x = 1.0 * np.array([t >= 1.0, t < 3.0]).all(0)

    # memoryless system
    y1 = 0.5 * x
    # system with memory.
    y2 = np.zeros(len(x))
    for i in xrange(len(y2)):
        y2[i] = np.sum(x[max(0, i-N):i]) * dt

    figure(figsize=(17,4))
    plot(t, x, lw=2, label="$x(t)$")
    plot(t, y1, lw=2, label="$0.5x(t)$")
    plot(t, y2, lw=2, label="$\int_{t-0.5}^{t}x(p)dp$")
    xlim(-1, 5)
    ylim(-0.1, 1.1)
    xlabel('Time', fontsize=15)
    legend(prop={'size':20});


from IPython.core.display import HTML
def css_styling():
    styles = open("../../styles/custom_aero.css", "r").read()
    return HTML(styles)

css_styling()

"""
Explanation: <p class="normal"> &raquo; <b>Causality:</b> <i>a system whose output depends on past and present values of input.</i></p>

<p class="normal"> &raquo; <b>Time invariance:</b> <i>system remains the same with time.</i></p>
<p class="normal">If a system is time invariant, then if </p>
<div class="formula">$$ x(t) \mapsto y(t) \implies x(t-\tau) \mapsto y(t-\tau)$$</div>

<p class="normal"> &raquo; <b>Stability:</b> <i>bounded input produces bounded output</i></p>
<div class="formula">$$ \left|x(t)\right| < M_x < \infty \mapsto \left|y(t)\right| < M_y < \infty $$</div>

<p class="normal"> &raquo; <b>Invertibility:</b> <i>input can be recovered from the output</i></p>
End of explanation
"""


