File indexing completed on 2025-01-05 04:12:53

0001 /******************************************************************************
0002  *  filter.h : Digital Filter. Specified by its "s" transfer function.        *
0003  *             Synthesis of "z" transfert function is done by bilinear        *
0004  *             transformation :             2   z-1                           *
0005  *                                    p -> --- -----                          *
0006  *                                          T   z+1                           *
0007  *  Copyright 2005, Jean-Paul Petillon                                        *
0008  *   This program is free software; you can redistribute it and/or modify     *
0009  *   it under the terms of the GNU General Public License as published by     *
0010  *   the Free Software Foundation; either version 2 of the License, or        *
0011  *   (at your option) any later version.                                      *
0012  ******************************************************************************/
0013 #ifndef FILTER_H
0014 #define FILTER_H
0015 
0016 #include "polynom.h"
0017 
0018 template<class S> class filter {
0019 public:
0020   S out;                                // output
0021   filter(                              // constructor
0022     // "s" transfert function
0023     polynom<S>& Ns,  // numerator
0024     polynom<S>& Ds,  // denominator
0025     double dT        // sampling period (s)
0026   );
0027   void Reset();                         // reset
0028   void ConnectTo(                       // connector
0029     S& in            // input address
0030   );
0031   void NextTimeStep();                  // update
0032  ~filter();                            // destructor
0033 private:
0034   // pointer on input
0035   S* in;
0036   // order
0037   int n;
0038   // "z" transfert function
0039   polynom<S> Nz;   // numerator
0040   polynom<S> Dz;   // denominator
0041   // state vector
0042   S* x;
0043 };
0044 
0045 template<class S> filter<S>::filter(polynom<S>& Ns, polynom<S>& Ds, double dT)
0046 :Nz(0), Dz(0)
0047 {
0048   // the greatest degree between N & D
0049   n=Ns.GetDegree()>Ds.GetDegree() ? Ns.GetDegree() : Ds.GetDegree();
0050   // allocate memory for state vector
0051   x = new S[n];
0052   // reset it
0053   Reset();
0054   // as well as the output
0055   out=0.0;
0056   // computes "z" transfer function
0057   polynom<S> potzm1odt(0); potzm1odt[0]=1.0;                    // [2(z-1)/dT]^i
0058   polynom<S> dzm1odt(1); dzm1odt[1]=2.0/dT; dzm1odt[0]=-2.0/dT; // 2(z-1)/dT
0059   for (int i=0; i<=n; i++) {
0060     // (z+1)^(n-i) = 1
0061     polynom<S> pozp1(0); pozp1[0]=1.0;
0062     // z+1
0063     polynom<S> zp1(1); zp1[1]=1.0; zp1[0]=1.0;
0064     // (z+1)^(n-i)
0065     for (int j=i+1; j<=n; j++) pozp1 = (pozp1 * zp1);
0066     polynom<S> dNz(0); dNz[0]=Ns[i];
0067     dNz = dNz * pozp1 * potzm1odt;
0068     Nz = Nz + dNz;
0069     polynom<S> dDz(0); dDz[0]=Ds[i];
0070     dDz = dDz * pozp1 * potzm1odt;
0071     Dz = Dz + dDz;
0072     potzm1odt = potzm1odt * dzm1odt;
0073   }
0074 }
0075 //------------------------------------------------------------------------------
0076 template<class S> void filter<S>::Reset()
0077 // reset state vector
0078 {
0079   for (int i=0; i<n; i++) x[i]=0.0;
0080 }
0081 //------------------------------------------------------------------------------
0082 template<class S> void filter<S>::ConnectTo(S& in)
0083 {
0084   // memorizes input address
0085   this->in = &in;
0086 }
0087 //------------------------------------------------------------------------------
0088 template<class S> void filter<S>::NextTimeStep()
0089 {
0090   // Compute output
0091   out = (x[n-1] + *in * Nz[n])/ Dz[n];
0092   // update state vector x[0] .. x[n-1] (goes from output to input)
0093   for (int i=n-1; i>0; i--) {
0094     x[i] = x[i-1] + Nz[i]*(*in) - Dz[i]*out;
0095   }
0096   x[0] = Nz[0]*(*in) - Dz[0]*out;
0097 }
0098 //------------------------------------------------------------------------------
0099 template<class S> filter<S>::~filter()
0100 {
0101   // deallocate memory used by state vector
0102   delete[] x;
0103 }
0104 //------------------------------------------------------------------------------
0105 
0106 
0107 #endif // #ifndef FILTER_H