## Signals

A signal is a discrete function that maps an integer (the time step or point in time) to a real value or a vector of real values. $\begin{array}{}\text{(1)}& \begin{array}{rlr}x& :\mathbb{Z}\to \mathbb{R}:& n↦x\left[n\right]\\ \stackrel{\to }{x}& :\mathbb{Z}\to {\mathbb{R}}^{m}:& n↦\stackrel{\to }{x}\left[n\right]\end{array}\end{array}$ In the simplest case, $x$ will just map to a scalar $\left(\mathbb{R}\right)$, but in general, it can also map to an $m$-dimensional vector $\left({\mathbb{R}}^{m}\right)$. This will be useful later, when we'll introduce systems with multiple inputs and outputs, or systems with multiple internal states.

A signal that is zero for all $n<0$ is called a unilateral or one-sided signal.

## Discrete-Time Linear Time-Invariant Systems

Discrete-Time Linear Time-Invariant Systems, or DTLTI systems for short, are systems that perform a linear transformation on signals. Time-invariance means that the transformation doesn't change over time, it is independent of the time step $n$, so it doesn't matter if you apply it to a certain signal now or in ten minutes, the resulting output signals will be the same.

A DTLTI system maps one signal to another: $T:\left(\mathbb{Z}\to {\mathbb{R}}^{m}\right)\to \left(\mathbb{Z}\to {\mathbb{R}}^{m}\right):\stackrel{\to }{x}\left[n\right]↦\stackrel{\to }{y}\left[n\right]\triangleq T\left(\stackrel{\to }{x}\left[n\right]\right)$

We'll define the properties of DTLTI systems mathematically:

$T$ is the transformation performed by a Discrete-Time Linear Time-Invariant (DTLTI) system if and only if
1. The transformation is linear:
$T\left(a\cdot h\left[n\right]+b\cdot g\left[n\right]\right)=a\cdot T\left(h\left[n\right]\right)+b\cdot T\left(g\left[n\right]\right)$
2. The transformation is time-invariant:
If $y\left[n\right]\triangleq T\left(h\left[n\right]\right)$, then $\mathrm{\forall }k\in \mathbb{N}:T\left(h\left[n-k\right]\right)=y\left[n-k\right]$

### Nonlinear systems

As an example of a system that is not linear, consider the system $T:x\left[n\right]↦\sqrt{x\left[n\right]}$. It is not linear, because $T\left(2\cdot 2\right)=\sqrt{4}=2\ne 2\cdot T\left(2\right)=2\sqrt{2}$.
Nonlinear systems are many times more complicated than linear systems, so they will not be covered in this series of articles.

### Time-varying systems

The system $T:x\left[n\right]↦n\cdot x\left[n\right]$ is not time-invariant, because the mapping explicitly depends on the time step $n$.
All systems in the following discussions will be time-invariant.

## Example

### Mathematical description

We'll define and plot a simple example signal, and then we'll apply a simple transformation to it. The input signal $x\left[n\right]$ is just a signal that oscillates between 3 and 1: $x:\mathbb{Z}\to \mathbb{R}:n↦\mathrm{cos}\left(\pi n\right)+2$ The transformation maps each point of the signal to the average of the current value and the previous value: $T:\left(\mathbb{Z}\to \mathbb{R}\right)\to \left(\mathbb{Z}\to \mathbb{R}\right):x\left[n\right]↦\frac{x\left[n\right]+x\left[n-1\right]}{2}$ The output signal $y\left[n\right]$ is defined as: $y\left[n\right]\triangleq T\left(x\left[n\right]\right)$

The input signal $x\left[n\right]$ and the output signal of the system $y\left[n\right]$ are plotted in the figure below.

### Block diagram

The system could be implemented as follows.

The arrows indicate the direction of the data flow. The rectangular $D$ block is called a delay or memory element, and it just delays the incoming signal by one time step. Sometimes, the Greek capital delta ($\mathrm{\Delta }$) is used instead, or in some contexts, it is indicated using ${z}^{-1}$, for reasons that will become apparent in the page on the Z-transform. The circle with the $+$ is a summator, it just adds all incoming signals together. Finally, the triangle containing a number is a scalar, and it just multiplies the signal with a constant factor.

### Python implementation

A possible implementation of this system in Python is given in the code snippet below.
We just have to save the input to the delay element on each time step, because we need it to calculate the next output.

from numpy import array, arange, cos, pi

class ExampleDTLTISystem:
    def __init__(self, initial_state: float = 0.0):
        self.state = initial_state

    def __call__(self, x_n: float) -> float:
        # y[n] = (x[n] + x[n-1]) / 2
        y_n = (x_n + self.state) / 2.0
        # x[n] will be x[n-1] on the next time step, 
        # so save it in the system's state
        self.state = x_n
        return y_n

n = arange(9)                # Create the time variable [0,1,2,…,7,8]
x = cos(pi * n) + 2          # Generate the input signal x[n]

T = ExampleDTLTISystem(1.0)  # Instantiate the system with x[-1] = 1
y = map(T, x)                # Apply the transformation y[n] = T(x[n])

It is a good exercise to try to understand how these three representations of the same system are related (the mathematical definition of $T$, the block diagram, and the Python implementation).