The echo loop of What is a system? (4.1), fed a single 1. Watch each stem come from the one before.
Describe this picture
A row of stems for , fed a single 1, with a delay box labelled “one step back” and a table under the stems with one row per sample, each written (box). In each new row the last result goes into the box, is halved, and is added to the input. At the end a curve passes through the stem tops, and the caption says “This whole row of stems is the answer.” The clip plays by itself; its only controls are the transport under it: Play or Replay, Step back and Step forward, which move one sample at a time, and a time slider.
Each answer comes from the last one
Remember the feedback loop in What is a system? (4.1). Set its gain to one half. A sound goes out and comes back half as loud, and that echo goes round again and comes back half as loud again. Each echo is made from the one before it.
I can write that rule as an equation. Let be the sample number, the input at sample , and the output. The symbol is the output one step earlier, the shift from Shifting, reversing and scaling time (2.1). It is the number held in the delay block from 4.1, which I call the delay box; the picture at the top of the page labels it “one step back”. The echo loop says
In words: take the number sitting in the delay box, halve it, and add the new input. An equation that gives each output sample from the input and from earlier output samples is a difference equation. The input here is a single 1 at and 0 for ever after, the unit sample from Impulse, step and ramp (3.1), and the box starts at 0.
Make a guess: what is ? Then go back to the loop at the top of the page, with Step back and Step forward if you like, and watch the stem for appear: it is , half of the the box held.
The input arrived once, and the output goes on. That is the loop remembering. Each stem is half the one before, so the stems are , which is .
The answer to a difference equation is not one number. It is the whole row of stems, one output for every . Running the rule forward, one sample at a time, is how I solve it.
This row is also something you already know. The input was the unit sample and the box started empty, so the row is the impulse response from The impulse response (5.1). The next sections explain why a box that starts empty matters.
With a loop and without one
Smoothing is a good job for a difference equation. Suppose a thermometer gives a noisy reading each second, and I want a steadier number. There are two ways to do it.
The first way is to average the last three readings. This is the 3-point moving average:
The second way is to keep a running estimate and nudge it halfway toward each new reading. The nudge gives , which simplifies to
I call this the leaky integrator. An integrator adds up its input as it goes, as the running sum in Operations on amplitude (2.2) does, and keeps all of its old total. This one keeps only half of the old total at each step, so the total leaks.
The two equations differ in a way you can see in a diagram. The moving average uses only inputs, so its diagram has no wire from the output back to the input side. We call it non-recursive. The leaky integrator uses its own past output, so its diagram has a loop. We call it recursive.
Feed both smoothers the same single 1 at , and look at .
Describe this picture
Two panels of stems, “Moving average · no loop” and “Leaky integrator · a loop”, both fed a single 1 at ; one stem appears in each every second. At the moving-average panel stamps “exactly 0 from here on” and the leaky-integrator panel stamps “still not 0”. A transport plays and pauses the clip.
The moving average has three stems of , then a stem of 0 at , and stays at 0. The leaky integrator is at , still not 0. By its stem is , tiny but not zero.
This is the reason behind the FIR and IIR of Properties of LTI systems (5.4). Without a loop, the output has no way to remember the input beyond the three samples it uses, so once the input has passed, the output stops. With this loop, the output feeds itself, so it never quite stops.
What is stored, and what is pushed in
Think of a bath. The water in it at any moment comes from two places: the water that was already there, and the water the tap has added since. The output of a difference equation has the same two sources.
Take . Each step keeps of the old output and adds the new input. Before the first sample, the box already holds some number. I write it , the output one step before the start, and I call it the stored value.
Here is a question to answer before the next instrument. There is a 2 in the box, so , and then a 1 arrives. What is ?
I want to pull that answer apart into the part from the 2 and the part from the 1. The way to do it is two experiments. First, switch the input off and let the stored 2 run on its own. Second, empty the box and switch the input on.
The first experiment gives the zero-input response, the output caused by the stored value alone. The second gives the zero-state response, the output caused by the input alone when the box starts empty. A system that starts with every stored value equal to 0 is said to be at initial rest, which for this equation means .
Watch the two experiments run, then stack.
Describe this picture
Stems for , with 2 in the box at the start. The legend names the marks: an open circle for the zero-input stem, a bare stem for the zero-state part, and a diamond for the total. First the label says “input off”, and the stored 2 shrinks; this run has its own vertical scale, from 0 to 2.2, so the small stems are easy to read, and the scale widens before the next run starts. Next the box is emptied, the label says “input on: 1”, and the stems climb. Last, both are put back, with 2 in the box and the input on, and the two sets of stems slide together and stack. A transport plays and pauses the clip.
With the input off, the stored 2 shrinks: . With the box emptied, the input is the unit step from Impulse, step and ramp (3.1), switched on and left on, and the stems climb: . Last, the two sets of stems stack.
Look at in the stacked picture. The open-circle stem is tall. The stem stacked on top of it is the zero-state part, long. The diamond at its top is their sum, . That is , the answer to the question above. The same holds at every : the total is the two stems added.
Why can the two be added? Each output sample is made by multiplying by fixed numbers and adding. This is superposition, from System properties (4.2): the response to a sum of causes is the sum of the responses to each. Here the two causes are the stored value and the input.
There is one more reason to care about initial rest. Scale the input by 0 and a linear system must give 0, which is the homogeneity half of the linearity test. With a 2 in the box, the output is not 0, because the stored 2 keeps going. So a system that starts with something stored fails the linearity test, and we usually start from rest. From rest the equation describes a linear, time-invariant system, and everything in The impulse response (5.1) applies.
Both parts have exact formulas. The stored part is multiplied by at every step, so after steps from ,
For the input part, run the rule step by step from rest with . Then , , , and so on, so . Here I use the finite geometric sum, which I take from algebra rather than derive:
With this gives . The total is , and the worked example checks the first four values against direct iteration.
The maths behind it · matrix powers
With the input off, each step multiplies by the same number: . For a system with several stored values, collect them in a vector , and each step multiplies by a matrix , so after steps you have . The number , or in the matrix case a number found from called an eigenvalue, sets how fast the stored part shrinks. The output depends on the pair (stored values, input) in a linear way, so it splits into what the stored values give alone plus what the input gives alone.
Every term is a wire
So far I have written equations and drawn diagrams as if they were two things. They are one thing, and this section shows how. Take the equation
It adds the input, twice the previous input, and half the previous output. There are three terms on the right.
Each term becomes one wire into the adder. A term with needs a delay box on its wire, one box for each step back, and a gain triangle for its number. A gain of 1 is not drawn. A term with sends a wire back from the output.
Watch each term light up and draw its wire into the diagram.
Describe this picture
The equation above a block diagram. The terms light up in turn, two seconds each, and as a term lights its wire draws itself into the diagram in the accent colour; at the end only the loop wire, the one for , stays in the accent colour. Then a single 1 goes in at , the label “x[0] = 1” appears over the input wire while the first stem grows, and five stems appear: . The caption at the end says “The wire back from the output is the loop. That is what “recursive” means.” A transport plays and pauses the clip.
The wire back from the output is the loop. A wire starts at the output and runs back through a delay box. A term always sends such a wire, which is exactly what recursive means. If no term has a , there is no loop and the equation is non-recursive.
Read the other way, a diagram gives its equation: write one term for each wire into the adder. A wire that starts at the input is an term, and one that starts at the output is a term. The number of delay boxes on a wire is how many steps back it reaches, and its gain triangle is the coefficient. A wire with no gain triangle has a gain of 1. The worked example below does this for a diagram.
The general form
Now I can write every such equation at once. On this page are the numbers that multiply past outputs and are the numbers that multiply inputs. (The page Fourier series coefficients (7.2) uses the same letters for a different job.) The general difference equation is
with the first coefficient fixed at
Here and are the largest steps back in the outputs and the inputs. The output terms are on the left, so has : moving to the left changes its sign. This is the convention of the SciPy function lfilter(b, a, x).
Solve for and you get the rule to run forward:
It needs the stored values , which are zero at initial rest. The equation is recursive when some with is not zero.
Worked example
-
Iteration. Take with and initial rest. Running forward gives 1, 0.5, 0.25, 0.125, 0.0625, 0.03125, 0.015625, 0.0078125 for to . This is , so .
-
Moving average and leaky integrator. Let at , and 0 after. The 3-point moving average gives for to . For example . Its last nonzero output is at , two samples after the last input, and it is 0 from on: no loop. The leaky integrator with gives and at , never exactly 0.
-
Zero-input plus zero-state. Take with . The zero-input part is , which gives 1.6, 1.28, 1.024, 0.8192 for to . The zero-state part is , which gives 1, 1.8, 2.44, 2.952. The totals are 2.6, 3.08, 3.464, 3.7712. Direct iteration agrees:
-
Equation to impulse response. Take with . Then . For the three terms are , and , so . After that only the loop acts, so each value is half the one before: is 1, 2.5, 1.25, 0.625, 0.3125. In the card’s convention, , , and . In SciPy this is
lfilter([1, 2], [1, -0.5], x). -
Diagram to equation. Fig. 1 shows a diagram. It has three wires into the adder, so the equation has three terms. The straight wire from the input gives . The wire from the input through one delay box and a gain of gives . The wire from the output through one delay box and a gain of gives . Together,
Fig. 1. A diagram with three wires into the adder. The wire back from the output, through one delay box and a gain of 0.9, is drawn in the accent colour. and it is recursive, because it has a loop. In the card’s convention , and . From rest, a unit sample gives and . After that each value is times the one before: is 1, −0.1, −0.09, −0.081.
Where you’ll meet this
Most digital filters in audio effects, sensors and radios run a difference equation, one sample at a time, in a loop like the ones on this page. The leaky integrator is one of the cheapest smoothers: one stored number and two multiplications per sample. The code that runs these filters carries the stored values from one block of samples to the next and calls them the filter’s state. The stored values produce the zero-input part of this page, and SciPy’s lfiltic turns them into the zi argument that lfilter takes.
The next page, Differential equations and analog systems (6.2), does the same job for a circuit, where time is not counted in samples. There the stored part and the pushed-in part appear again, along with a second way to cut the answer in two. Then First- and second-order systems (6.3) names the number that sets how fast the loop here shrinks.
The maths behind it · weighted moving averages
The moving average is the sample mean of the last few readings. The leaky integrator is the same idea with more weight on recent readings, known as an exponentially weighted moving average, and it is a standard way to track a mean that drifts. Feed it readings that are random, independent, average 0 and have an average squared size of 1. Then, once it settles, its output has average squared size when the equation is . For that is , about . A larger smooths more, but it reacts more slowly: that is the trade.
Reference card
| Quantity | Formula | Notes |
|---|---|---|
| Difference equation | , | output terms on the left, so has ; same convention as scipy.signal.lfilter(b, a, x) |
| Run forward | needs the stored | |
| Recursive or non-recursive | some with : a loop. All with : no loop | non-recursive is always FIR |
| Diagram and equation | one wire into the adder per term; delay boxes = steps back; gain triangle = coefficient | a wire from the output is a loop |
| Initial rest | gives a causal LTI system | |
| Total | : input off, stored values only. : input on, starting from rest | |
| Zero-input response, first order | for | here |
| Finite geometric sum | ||
| Leaky integrator | , | step response , which settles at 1 |
| Moving average, points | is samples of |