RealPolynomial AnalogFilterPrototype::GetNumerPoly(bool binomial_use_enab)
{
 //---------------------------------------------------
 //  if numerator polynomial is not built yet,
 //  build it by multiplying together (s-z[i]) binomial
 //  factors where the z[i] are the zeros of the filter.
 
 if(Degree_Of_Numer <0)
   {
      if(binomial_use_enab)
      {
         CmplxPolynomial cmplx_poly =
                        CmplxPolynomial( d_complex_t( 1.0, 0.0), -Zero_Locs[0] );

         //for(int ii=2; ii<= Num_Zeros; ii++)
         for(int ii=1; ii< Num_Zeros; ii++)
         {
            cmplx_poly *= CmplxPolynomial( d_complex_t(1.0, 0.0), -Zero_Locs[ii] );
         }                                                          
         cmplx_poly.DumpToStream(&*DebugFile);

         Numer_Poly = RealPolynomial(cmplx_poly);

         Degree_Of_Numer = Numer_Poly.GetDegree();

         *DebugFile << "\nreal-valued version:" << endl;
         Numer_Poly.DumpToStream(&*DebugFile);
      }
      else
      {
      } 
   }                                  
 return(Numer_Poly);
}
Esempio n. 2
0
void CmplxPolynomial::FindRoots( void )
{
  complex* root;
  int status, i;
  CmplxPolynomial root_factor;
  root = new complex[Degree];
  CmplxPolynomial work_poly;
  double epsilon=0.0000001;
  double epsilon2=1.0e-10;
  int max_iter=12;
  
  if(Root == NULL) Root = new complex[Degree];
  //------------------------------------------------
  // find coarse locations for roots

  work_poly = CmplxPolynomial(Coeff, Degree);

  for(i=0; i<Degree-1; i++)
    {
    Root[i] = complex(0.0,0.0);
    status = LaguerreMethod( &work_poly, &(Root[i]), 
                             epsilon, epsilon2, max_iter);
    if(status <0) 
      {
      std::cout << "Laguerre method did not converge" << std::endl;
      exit(55);
      }
    std::cout << "Root[" << i << "] = " << Root[i] 
         << " (" << status << ")" << std::endl;
    root_factor = CmplxPolynomial( complex(1.0,0.0),-Root[i]);
    work_poly /= root_factor;
    work_poly.DumpToStream(&std::cout);
    pausewait();
    }
  Root[Degree-1] = -(work_poly.GetCoeff(0));
  std::cout << "Root[" << Degree-1 << "] = " << Root[Degree-1] << std::endl;

  //------------------------------------------------
  //  polish the roots
  work_poly = CmplxPolynomial(Coeff, Degree);
  for(i=0; i<Degree; i++)
    {
    status = LaguerreMethod( &work_poly, &(Root[i]), 
                             epsilon, epsilon2, max_iter);
    if(status <0) 
      {
      std::cout << "Laguerre method did not converge" << std::endl;
      exit(55);
      }
    std::cout << "Polished Root[" << i << "] = " << Root[i] 
         << " (" << status << ")" << std::endl;
    pause();
    }
  return;
}
//===================================================
RealPolynomial AnalogFilterPrototype::GetDenomPoly(bool binomial_use_enab)
{
 //-----------------------------------------------------
 //  if denominator polynomial is not built yet, build
 //  it by multiplying together binomial factors (s-p[i]) 
 //  where the p[i] are the poles of the filter
 
 if(Degree_Of_Denom <0)
   {
   if(binomial_use_enab)
    { // use binomials
    *DebugFile << "using binomials\0" << endl;
    CmplxPolynomial cmplx_denom_poly =
                           CmplxPolynomial( std::complex<double>(1.0, 0.0),
                                            -Pole_Locs[0] );
    //                                        -Pole_Locs[1] );
    //for(int ii=2; ii<= Num_Poles; ii++)
    for(int ii=1; ii< Num_Poles; ii++)
      {
       cmplx_denom_poly *= CmplxPolynomial( std::complex<double>(1.0, 0.0),
                                            -Pole_Locs[ii] );
      }                                                                
    *DebugFile << "about to dump cmplx_denom_poly" << endl;
    cmplx_denom_poly.DumpToStream(&*DebugFile);
    
    Denom_Poly = RealPolynomial( cmplx_denom_poly);
    //Denom_Poly = poly_cast( cmplx_denom_poly);
    
    Degree_Of_Denom = Denom_Poly.GetDegree();
    
    *DebugFile << "\nin AnalogFilterPrototype::GetDenomPoly" << endl;
    *DebugFile << "(using binomials) real-valued version:" << endl;
    Denom_Poly.DumpToStream(&*DebugFile);
    }
  else
    { // use biquads

    *DebugFile << "using biquads\0" << endl;
    Denom_Poly = RealPolynomial( 1.0 );
   
    for(int ii=0; ii< Num_Biquad_Sects; ii++)
      {
       Denom_Poly *= RealPolynomial( 1.0, B1_Coef[ii], B0_Coef[ii] );
      }                                                                  
    Degree_Of_Denom = Denom_Poly.GetDegree();

    if(Filt_Order%2)
      { //odd order
      Denom_Poly *= RealPolynomial( 1.0, Real_Pole );
      }
    } // end of use biquds
   }                                    
  #ifdef _DEBUG
    
    *DebugFile << "\nin AnalogFilterPrototype::GetDenomPoly" << endl;
    *DebugFile << "denominator coefficients:" << endl;
    Denom_Poly.DumpToStream(&*DebugFile);
  #endif
   
 return(Denom_Poly);
}