![]() |
(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 a2We 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.