View Raw SPL
/*****************************************************************************
* *
* DECONV.SPL Copyright (C) 2002-2006 DSP Development Corporation *
* All Rights Reserved *
* *
* Author: Randy Race *
* *
* Synopsis: Deconvolves two series *
* *
* Revisions: 28 Aug 2002 RRR Creation, adaptation of PD source *
* 1 Dec 2006 RRR ITERATE for simple column iteration *
* *
*****************************************************************************/
#include
#if @HELP_DECONV
DECONV
Purpose: Deconvolves two series.
Syntax: (q, r) = DECONV(b, a)
b - A series.
a - A series.
Returns: A series such that b = conv(a, q) + r
Example:
a = {1, 2, 3};
x = {1, 0, -1, 2};
b = conv(a, x);
(q, r) = deconv(b, a);
b == {1, 2, 3, 0, 1, 6}
q == {1, 0, -1, 2}
r == {0, 0, 0, 0, 0, 0}
(q, r) = deconv({1, 5, 1, 2}, a)
q == {1, 3}
r == {0, 0, -8, -7}
conv(q, a) + r == {1, 5, 1, 2}
Remarks:
If a and b represent polynomial coefficients, q will contain
the quotient of the polynomial and r the lowest order remainder
polynomial.
See FDECONV for an implementation using the FFT.
See Also:
Conv
Fdeconv
#endif
/* deconvolve a into b */
ITERATE deconv(b, a)
{
local na, nb, q, r, dummy;
if (argc < 2) error("deconv - numerator and denominator series required");
if (not(isarray(b))) b = castseries(b);
if (not(isarray(a))) a = castseries(a);
if (a[1] == 0) error("deconv - first denominator coefficient cannot be zero");
nb = length(b);
na = length(a);
if (na > nb)
{
q = {0};
r = b;
}
else
{
/* polynomial division is the impulse response of the system */
q = filteq(b, a / a[1], extract({1}, 1, (nb - na + 1))) / a[1];
/* handle output units */
dummy = extract(b, 1, 1) / extract(a, 1, 1);
sethunits(q, gethunits(dummy));
setvunits(q, getvunits(dummy));
if (outargc > 1)
{
/* only compute if requested */
r = b - conv(q, a);
}
else
{
r = {0};
}
}
/* proper deltax */
setdeltax(q, deltax(b));
/* proper lengths */
q = extract(q, 1, nb - na + 1);
return(q, r);
}