bessel_proto.cpp
上传用户:jtjnyq9001
上传日期:2014-11-21
资源大小:3974k
文件大小:10k
源码类别:

3G开发

开发平台:

Visual C++

  1. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. //
  3. //  File = bessel_proto.cpp
  4. //
  5. //  Prototype Bessel Filter
  6. //
  7. #include <math.h>
  8. #include "parmfile.h"
  9. #include <stdlib.h>
  10. #include "bessel_proto.h"
  11. #include "ipow.h"
  12. #include "filter_types.h"
  13. //#include "elipfunc.h"
  14. #include "laguerre.h"
  15. //#include "complex.h"
  16. //#include "cmpxpoly.h"
  17. extern ParmFile ParmInput;
  18. #ifdef _DEBUG
  19.   extern ofstream *DebugFile;
  20. #endif
  21. //======================================================
  22. //  constructor
  23. BesselPrototype::BesselPrototype( int filt_order, 
  24.                                   bool norm_for_delay)
  25.                 :AnalogFilterPrototype(filt_order)
  26. {
  27.   int indx, indx_m1, indx_m2;
  28.   int i, n, ii, work_order;
  29.   double epsilon, epsilon2;
  30.   int max_iter, laguerre_status;
  31.   long q_poly[3][MAX_BESSEL_ORDER];
  32.   std::complex<double> *denom_poly, *work_coeff;
  33.   std::complex<double> root, work1, work2;
  34.   double renorm_val, smallest;
  35.   CmplxPolynomial *work_poly;
  36.   //-------------------------------------------------------
  37.   //  these values are reciprocals of values in Table 5.10
  38.   double renorm_factor[9] = { 0.0,     0.0,     0.72675, 
  39.                               0.57145, 0.46946, 0.41322, 
  40.                               0.37038, 0.33898, 0.31546};
  41.  Pole_Locs = new std::complex<double>[Filt_Order+1];
  42.  Pole_Locs[0] = Filt_Order;
  43.  Num_Poles = Filt_Order;
  44.  Zero_Locs = new std::complex<double>[1];
  45.  Zero_Locs[0] = 0;
  46.  Num_Zeros = 0;
  47.  
  48.  H_Zero = 1.0;
  49.   denom_poly = new std::complex<double>[MAX_BESSEL_ORDER];
  50.   //Denom_Poly = new double[Filt_Order+1];
  51.   work_coeff = new std::complex<double>[MAX_BESSEL_ORDER];
  52.   indx = 1;
  53.   indx_m1 = 0;
  54.   indx_m2 = 2;
  55.   renorm_val = renorm_factor[Filt_Order];
  56.   //-----------------------------------------
  57.   // initialize polynomials for n=0 and n=1
  58.   for( i=0; i<(3*MAX_BESSEL_ORDER) ; i++) 
  59.       q_poly[0][i] = 0;
  60.   q_poly[0][0] = 1;
  61.   q_poly[1][0] = 1;
  62.   q_poly[1][1] = 1;
  63.   RealPolynomial qq_poly[3];
  64.   qq_poly[0] = RealPolynomial(1.0);
  65.   *DebugFile << "qq_poly[0]" << endl;
  66.   qq_poly[0].DumpToStream(DebugFile);
  67.   qq_poly[1] = RealPolynomial(1.0, 1.0);
  68.   *DebugFile << "qq_poly[1]" << endl;
  69.   qq_poly[1].DumpToStream(DebugFile);
  70.   //----------------------------------------------
  71.   //  compute polynomial using recursion from n=2
  72.   //  up through n=order
  73.   RealPolynomial s_sqrd(1.0, 0.0, 0.0);
  74.   for( n=2; n<=filt_order; n++)
  75.     {
  76.     indx = (indx+1)%3;
  77.     indx_m1 = (indx_m1+1)%3;
  78.     indx_m2 = (indx_m2+1)%3;
  79.     qq_poly[indx] =  double(2*n-1) * qq_poly[indx_m1];
  80.     for( i=0; i<n; i++)
  81.       {
  82.       q_poly[indx][i] = (2*n-1) * 
  83.                              q_poly[indx_m1][i];
  84.       }
  85.     qq_poly[indx] += qq_poly[indx_m2] * s_sqrd;
  86.     for( i=2; i<=n; i++)
  87.       {
  88.       q_poly[indx][i] = q_poly[indx][i] + 
  89.                              q_poly[indx_m2][i-2];
  90.       }
  91.     }
  92.   #ifdef _DEBUG
  93.     for( i=0; i<=Filt_Order; i++)
  94.       {
  95.       *DebugFile << "q_poly[" << i << "] = "
  96.                 << q_poly[indx][i] << endl;
  97.       }
  98.     qq_poly[indx].DumpToStream(DebugFile);
  99.   #endif
  100.   double* denom_coef = new double[filt_order+1];
  101.   if(norm_for_delay)
  102.     {
  103.     for( i=0; i<=filt_order; i++)
  104.       {
  105.       denom_coef[i] = qq_poly[indx].GetCoefficient(i);
  106.       denom_poly[i] = std::complex<double>(denom_coef[i], 0.0);
  107.       //denom_poly[i] = std::complex<double>(double(q_poly[indx][i]), 0.0);
  108.       #ifdef _DEBUG
  109.       *DebugFile << "q_poly[" << i << "] = "
  110.                 << q_poly[indx][i] << endl;
  111.       #endif
  112.       }
  113.     }
  114.   else
  115.     {
  116.     for( i=0; i<=filt_order; i++)
  117.       {
  118.       denom_coef[i] = qq_poly[indx].GetCoefficient(i) 
  119.                       * ipow(renorm_val, (filt_order-i));
  120.       denom_poly[i] = std::complex<double>(denom_coef[i], 0.0);
  121.       }
  122.     }
  123.   Denom_Poly = RealPolynomial(filt_order, denom_coef);
  124.   Degree_Of_Denom = filt_order;
  125.   //delete [] denom_coef;
  126.   #ifdef _DEBUG
  127.     for( i=0; i<=filt_order; i++)
  128.       *DebugFile << "denom_coef[" << i << "] = "
  129.                 << denom_coef[i] << endl;
  130.     for( i=0; i<=filt_order; i++)
  131.       *DebugFile << "denom_poly[" << i << "] = "
  132.                 << (denom_poly[i].real()) << endl;
  133.   #endif
  134.   H_Zero = denom_poly[0].real();
  135.   //---------------------------------------------------
  136.   // use Laguerre method to find roots of the
  137.   // denominator polynomial -- these roots are the
  138.   // poles of the filter
  139.   epsilon = 1.0e-6;
  140.   epsilon2 = 1.0e-6;
  141.   max_iter = 10;
  142.   for(i=0; i<=filt_order; i++) work_coeff[i] = denom_poly[i];
  143.   int i_stop;
  144.   int biquad_cnt=0;
  145.   if(Filt_Order%2)
  146.     { //odd
  147.     Num_Biquad_Sects = (Filt_Order-1)/2;
  148.     i_stop = 1;
  149.     }
  150.   else
  151.     { // even
  152.     Num_Biquad_Sects = Filt_Order/2;
  153.     i_stop = 2;
  154.     }
  155.   B0_Coef = new double[Num_Biquad_Sects];
  156.   B1_Coef = new double[Num_Biquad_Sects];
  157.   //Biquad_Coef_C = new double[(Filt_Order + (Filt_Order%2))/2];
  158.   ///for(i=Filt_Order; i>1; i--)
  159.   for(i=Filt_Order; i>i_stop; i-=2)
  160.     {
  161.     root = std::complex<double>(0.0,0.0);
  162.     work_order = i;
  163.     work_poly = new CmplxPolynomial( work_order, work_coeff );
  164.     laguerre_status = LaguerreMethod( work_poly,
  165.                                       &root,
  166.                                       epsilon,
  167.                                       epsilon2,
  168.                                       max_iter);
  169.     delete work_poly;
  170.     #ifdef _DEBUG
  171.     *DebugFile << "laguerre_status = "
  172.               << laguerre_status << endl;
  173.     #endif
  174.     if(laguerre_status <0)
  175.       {
  176.       #ifdef _DEBUG
  177.       *DebugFile << "FATAL ERROR - n"
  178.                 << "Laguerre method failed to converge.n"
  179.                 << "Unable to find poles for desired Bessel filter." 
  180.                 << endl;
  181.       #endif
  182.       exit(-1);
  183.       }
  184.     #ifdef _DEBUG
  185.     *DebugFile << "root = ( " << root.real() << ", " << root.imag() << ")" << endl;
  186.     #endif
  187.     //--------------------------------------------
  188.     // if imaginary part of root is very small
  189.     // relative to real part, set it to zero
  190.     if(fabs( root.imag() ) < epsilon*fabs( root.real() ))
  191.       {
  192.       root = std::complex<double>( root.real(), 0.0);
  193.       }
  194. //    Pole_Locs[filt_order+1-i] = root;
  195.     Pole_Locs[filt_order-i] = root;
  196.     Pole_Locs[filt_order+1-i] = std::conj(root);
  197.     //Biquad_Coef_A[biquad_cnt] = 1.0;
  198.     B1_Coef[biquad_cnt] = -2.0*root.real();
  199.     B0_Coef[biquad_cnt] = std::norm(root);
  200.     biquad_cnt++;
  201.     //---------------------------------------------
  202.     // deflate working polynomial by removing 
  203.     // (s - r) factor where r is newly found root
  204.     work1 = work_coeff[i];
  205.     for(ii=i-1; ii>=0; ii--)
  206.       {
  207.       work2 = work_coeff[ii];
  208.       work_coeff[ii] = work1;
  209.       work1 = work2 + root * work1;
  210.       }
  211.     work1 = work_coeff[i-1];
  212.     for(ii=i-2; ii>=0; ii--)
  213.       {
  214.       work2 = work_coeff[ii];
  215.       work_coeff[ii] = work1;
  216.       work1 = work2 + std::conj(root) * work1;
  217.       }
  218.     } // end of loop over i
  219.   #ifdef _DEBUG
  220.   *DebugFile << "work_coeff[1] = ( " << work_coeff[1].real() 
  221.             << ", " << work_coeff[1].imag() << ")" << endl;
  222.   *DebugFile << "work_coeff[0] = ( " << work_coeff[0].real() 
  223.             << ", " << work_coeff[0].imag() << ")" << endl;
  224.   #endif
  225.   
  226.   if(filt_order%2)
  227.     { // order is odd
  228.     Pole_Locs[filt_order-1] = -work_coeff[0];
  229.     Real_Pole = -(work_coeff[0].real());
  230.     }
  231.   else
  232.     { // order is even
  233.     // the remaining unfactored polynomial should
  234.     // be a quadratic with real-valued coefficients
  235.     // use these coefficients as-is for biquad and solve
  236.     // for complex conjugate roots to get last twp poles
  237.     double b_work = work_coeff[1].real();
  238.     double c_work = work_coeff[0].real();
  239.     root = std::complex<double>(-b_work/2.0, sqrt(4.0*c_work - b_work*b_work)/2.0);
  240.     Pole_Locs[filt_order-2] = root;
  241.     Pole_Locs[filt_order-1] = std::conj(root);
  242.     //Biquad_Coef_A[biquad_cnt] = 1.0;
  243.     B1_Coef[biquad_cnt] = -2.0*root.real();
  244.     B0_Coef[biquad_cnt] = std::norm(root);
  245.     biquad_cnt++;
  246.     #ifdef _DEBUG
  247.     *DebugFile << "work_coeff[2] = ( " << work_coeff[2].real() 
  248.               << ", " << work_coeff[2].imag() << ")" << endl;
  249.     *DebugFile << "work_coeff[1] = ( " << work_coeff[1].real() 
  250.               << ", " << work_coeff[1].imag() << ")" << endl;
  251.     *DebugFile << "work_coeff[0] = ( " << work_coeff[0].real() 
  252.               << ", " << work_coeff[0].imag() << ")" << endl;
  253.     #endif
  254.     }
  255.   #ifdef _DEBUG
  256.   *DebugFile << "pole[" << filt_order-1 << "] = ( "
  257.             << Pole_Locs[filt_order-1].real() << ", " 
  258.             << Pole_Locs[filt_order-1].imag() << ")" 
  259.             << endl;
  260.   #endif
  261.   //----------------------------------------------
  262.   // sort poles so that imaginary parts are in
  263.   // ascending order.  This order is critical for
  264.   // sucessful operation of ImpulseResponse().
  265.   #ifdef _DEBUG
  266.   for(i=0; i<filt_order; i++)
  267.     {
  268.     *DebugFile << "pole[" << i << "] = (" 
  269.               << Pole_Locs[i].real() << ", "
  270.               << Pole_Locs[i].imag() << ")" << endl;
  271.     }
  272.   *DebugFile << endl;
  273.   #endif
  274.   for(i=0; i<filt_order-1; i++)
  275.     {
  276.     smallest = Pole_Locs[i].imag();
  277.     for( ii=i+1; ii<filt_order; ii++)
  278.       {
  279.       if(smallest <= Pole_Locs[ii].imag()) continue;
  280.         work1 = Pole_Locs[ii];
  281.         Pole_Locs[ii] = Pole_Locs[i];
  282.         Pole_Locs[i] = work1;
  283.         smallest = work1.imag();
  284.       }
  285.     }
  286.   #ifdef _DEBUG
  287.   for(i=0; i<filt_order; i++)
  288.     {
  289.     *DebugFile << "pole[" << i << "] = (" 
  290.               << Pole_Locs[i].real() << ", "
  291.               << Pole_Locs[i].imag() << ")" << endl;
  292.     }
  293.   #endif
  294.   return;
  295. };
  296. //==============================================
  297. BesselPrototype::~BesselPrototype(void)
  298. {
  299. }