![]() |
(23) |
The leaky integration transformation
(19)
is a special case of
the backsolving transformation
when
and a2=0.
To see this, you need to notice that the matrices in
(23)
and
(19)
are mutually inverse.
The transformation
(23) can be derived
by multiplying two polynomials,
Y(Z) = y0 + y1 Z+ y2 Z2 + y3 Z3 + y4 Z4 + y5 Z5 times
A(Z) = 1 + a1 Z + a2 Z2.
Identifying the k-th power of Z in the product
X(Z)=A(Z)Y(Z) gives the k-th row of the transformation
(23).
Thus the operator in (23) is Y(Z)=X(Z)/A(Z).
The polynomials in Z are called Z transforms.
They may be recognized as Fourier transforms
where
.
Convolution corresponds to multiplying polynomials (convolving the coefficients) and deconvolution (or backsolving) corresponds to polynomial division.
A causal operator is one that uses its present and past inputs to make its current output. Anticausal operators use the future but not the past. Causal operators are generally associated with lower triangular matrices and positive powers of Z, whereas adjoint operators are associated with upper triangular matrices and negative powers of Z.
Ordinary differential equations lead us to the backsolving operator. For example, the damped pendulum leads to equation (23) with the three nonzero filter coefficients. There is a huge literature on finite-difference solutions of ordinary differential equations, especially in connection with electrical circuits. You might notice the nonphysical meaning of the adjoint. It is like the forward operator except that we must begin at the final time and revert towards the first. The adjoint pendulum damps as we compute it backward in time, but that, of course, means that the adjoint pendulum diverges as it is viewed moving forward in time.
A module to backsolve polydiv is polydiv.
module polydiv { # Polynomial division
real, dimension (:), pointer :: a
integer, dimension (:), pointer :: lag
#% _init ( a, lag)
#% _lop ( x, y)
integer ia, ix, iy
real t
if( adj)
do ix= size(x), 1, -1 {
t = y( ix)
do ia = 1, size(a) {
iy = ix + lag( ia); if (iy > size(x)) exit
t = t - a( ia) * x( iy)
}
x( ix) = x( ix) + t
}
else
do iy= 1, size(x) {
t = x( iy)
do ia = 1, size(a) {
ix = iy - lag( ia); if (ix < 1) exit
t = t - a( ia) * y( ix)
}
y( iy) = y( iy) + t
}
}
Inputs required for module polydiv to backsolve polydiv are nb=2 and the filter coefficients and lags in two tables as follows:
i lag(i) b(i)
--- ------ ----
1 1 a1
2 2 a2
We could simplify use of module polydiv by internalizing
lag(i)=i however,
later in this book,
we will encounter examples
with many zero valued coefficients
where great efficiency is gained by
omitting the zero-valued coefficients from the tables.