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

3G开发

开发平台:

Visual C++

  1. // poly_pf.cpp
  2. //
  3. #include <iostream>
  4. #include <fstream>
  5. #include "poly_pf.h"
  6. #include "pfelem.h"
  7. #include "stdlib.h"
  8. extern ofstream DebugFile;
  9. PolyOvrPrimeField::PolyOvrPrimeField( void )
  10. {
  11.   
  12.   Prime_Base = 9999;
  13.   Degree=0;
  14.   Coeff = new PrimeFieldElem[Degree+1];
  15.   Coeff[0] = PrimeFieldElem(Prime_Base,0); 
  16. }
  17. PolyOvrPrimeField::PolyOvrPrimeField(int prime_base)
  18. {
  19.   
  20.   Prime_Base = prime_base;
  21.   Degree=0;
  22.   Coeff = new PrimeFieldElem[Degree+1];
  23.   Coeff[0] = PrimeFieldElem(Prime_Base,0); 
  24. }
  25. //======================================
  26. PolyOvrPrimeField::PolyOvrPrimeField( int prime_base,
  27.                                       int degree)
  28. {
  29.   int i;
  30.   Prime_Base = prime_base;
  31.   Degree = degree;
  32.   Coeff = new PrimeFieldElem[Degree+1];
  33.   for(i=0; i<=Degree; i++)
  34.       Coeff[i] = PrimeFieldElem(Prime_Base,0);
  35. }
  36. //======================================
  37. PolyOvrPrimeField::PolyOvrPrimeField( int prime_base,
  38.                                       int degree, 
  39.                                       PrimeFieldElem coeff)
  40. {
  41.   int i;
  42.   Prime_Base = prime_base;
  43.   Degree = degree;
  44.   Coeff = new PrimeFieldElem[Degree+1];
  45.   for(i=0; i<=Degree; i++)
  46.       Coeff[i] = PrimeFieldElem(Prime_Base,0);
  47.   Coeff[degree] = coeff;
  48.   Coeff[0] = PrimeFieldElem(Prime_Base,1);
  49. }
  50. //======================================
  51. PolyOvrPrimeField::PolyOvrPrimeField( int prime_base,
  52.                                       int degree, 
  53.                                       PrimeFieldElem* coeff[])
  54. {
  55.   int i;
  56.   Prime_Base = prime_base;
  57.   Degree = degree;
  58.   Coeff = new PrimeFieldElem[Degree+1];
  59.   for(i=0; i<=Degree; i++)
  60.       Coeff[i] = *(coeff[i]);
  61. }
  62. //============================================================
  63. PolyOvrPrimeField::PolyOvrPrimeField( int prime_base,
  64.                                       PolyOvrIntegers *poly)
  65. {
  66.   int i, raw_val;
  67.   Prime_Base = prime_base;
  68.   Degree = poly->MaxDegree();
  69.   Coeff = new PrimeFieldElem[Degree+1];
  70.   for(i=0; i<=Degree; i++)
  71.     {
  72.     raw_val = (Prime_Base+(poly->Coefficient(i)))%Prime_Base;
  73.     Coeff[i] = PrimeFieldElem(Prime_Base,raw_val);
  74.     }
  75. }
  76. //============================================================
  77. int PolyOvrPrimeField::PrimeBase(void)
  78. {
  79.   return Prime_Base;
  80. }
  81. //============================================================
  82. int PolyOvrPrimeField::MaxDegree(void)
  83. {
  84.   return Degree;
  85. }
  86. //========================================================
  87. int PolyOvrPrimeField::NumberOfTerms(void)
  88. {
  89.   int num_terms=0;
  90.   for(int i=0; i<=Degree; i++)
  91.     {
  92.     if( Coeff[i].Value != 0 ) num_terms++;
  93.     }
  94.   return(num_terms);
  95. }
  96. //========================================================
  97. int PolyOvrPrimeField::PenultimateDegree(void)
  98. {
  99.   int pen_deg=0;
  100.   for(int i=Degree-1; i>=0; i--)
  101.     {
  102.     if( Coeff[i].Value == 0 ) continue;
  103.       pen_deg = i;
  104.       break;
  105.     }
  106.   return(pen_deg);
  107. }
  108. //========================================================
  109. PrimeFieldElem PolyOvrPrimeField::Coefficient(int degree)
  110. {
  111.   return Coeff[degree];
  112. }
  113. //========================================================
  114. void PolyOvrPrimeField::GetCoeffs( PrimeFieldElem *coeff_vec)
  115. {
  116.   for(int i=0; i<=Degree; i++)
  117.     {
  118.     coeff_vec[i] = PrimeFieldElem(Prime_Base, Coeff[i].Value); 
  119.     }
  120. }
  121. //===========================================================
  122. PolyOvrPrimeField& PolyOvrPrimeField::operator* 
  123.                               (const PolyOvrPrimeField &right)
  124. {
  125.   PolyOvrPrimeField *result;
  126.   result = new PolyOvrPrimeField( Prime_Base, 
  127.                                   Degree + right.Degree );
  128.   //--------------------------------
  129.   // perform multiplication
  130.   for(int rgt_idx=0; rgt_idx<= right.Degree; rgt_idx++)
  131.     {
  132.     for( int this_idx=0; this_idx <=Degree; this_idx++)
  133.       {
  134.       result->Coeff[this_idx+rgt_idx] +=
  135.                 (Coeff[this_idx] * right.Coeff[rgt_idx]);
  136.       }
  137.     }
  138.   return *result;
  139. }
  140. //===========================================================
  141. void PolyOvrPrimeField::operator= 
  142.                             (const PolyOvrPrimeField &right)
  143. {
  144.   delete[] Coeff;
  145.   Degree = right.Degree;
  146.   Prime_Base = right.Prime_Base;
  147.   Coeff = new PrimeFieldElem[Degree+1];
  148.   for(int i=0; i<=Degree; i++)
  149.       Coeff[i] = right.Coeff[i];
  150. }
  151. //===========================================================
  152. PolyOvrPrimeField& PolyOvrPrimeField::operator*= 
  153.                             (const PolyOvrPrimeField &right)
  154. {
  155.   //---------------------------------------------------
  156.   // save pointer to original coefficient array so that
  157.   // this array can be deleted once no longer needed
  158.   PrimeFieldElem *orig_coeff = Coeff;
  159.   int orig_degree = Degree;
  160.   int i;
  161.   //------------------------------------------------------
  162.   // create new longer array to hold the new coefficients
  163.   Degree += right.Degree;
  164.   Coeff = new PrimeFieldElem[Degree+1];
  165.   for( i=0; i<=Degree; i++)
  166.       Coeff[i] = PrimeFieldElem(Prime_Base,0);
  167.   //--------------------------------
  168.   // perform multiplication
  169.   for(int rgt_idx=0; rgt_idx<= right.Degree; rgt_idx++)
  170.     {
  171.     for( int orig_idx=0; orig_idx <=orig_degree; orig_idx++)
  172.       {
  173.       Coeff[orig_idx+rgt_idx] +=
  174.                 (orig_coeff[orig_idx] * right.Coeff[rgt_idx]);
  175.       }
  176.     }
  177.   //delete []orig_coeff;
  178.   return *this;
  179. }
  180. //===========================================================
  181. PolyOvrPrimeField& PolyOvrPrimeField::operator-= 
  182.                             (const PrimeFieldElem &const_term)
  183. {
  184.   Coeff[0] -= const_term;
  185.   return *this;
  186. }
  187. //===========================================================
  188. PolyOvrPrimeField& PolyOvrPrimeField::operator/ 
  189.                             (const PolyOvrPrimeField &divisor)
  190. {
  191.   int dividend_deg, divisor_deg, j, k;
  192.   PolyOvrPrimeField *result;
  193.   dividend_deg = Degree;
  194.   divisor_deg = divisor.Degree;
  195.   if(dividend_deg < divisor_deg)
  196.     {
  197.     // if degree of divisor is larger than degree
  198.     // of the dividend, the quotient is zero
  199.     PolyOvrPrimeField *result = new PolyOvrPrimeField(Prime_Base,0);
  200.     }
  201.   else
  202.     {    
  203.     // perform "synthetic" division to generate quotient
  204.     PrimeFieldElem *work = new PrimeFieldElem[dividend_deg+1];
  205.     result = new PolyOvrPrimeField( Prime_Base,
  206.                                     dividend_deg-divisor_deg);
  207.     for(j=0; j<= dividend_deg; j++)
  208.       {
  209.       work[j] = Coeff[j];
  210.       }
  211.     for(k=dividend_deg-divisor_deg; k>=0; k--)
  212.       {
  213.       result->Coeff[k] = work[divisor_deg+k]/divisor.Coeff[divisor_deg];
  214.       work[divisor_deg+k]=PrimeFieldElem(Prime_Base,0);
  215.       for(j=divisor_deg+k-1; j>=k; j--)
  216.         work[j] = work[j] - (result->Coeff[k]) * divisor.Coeff[j-k];
  217.       }
  218.     result->Degree = dividend_deg-divisor_deg;
  219.     delete[] work;
  220.     }
  221.   return *result;
  222. }
  223. //===========================================================
  224. PolyOvrPrimeField& PolyOvrPrimeField::operator% 
  225.                             (const PolyOvrPrimeField &divisor)
  226. {
  227.   int dividend_deg, divisor_deg, j, k;
  228.   PolyOvrPrimeField *result;
  229.   dividend_deg = Degree;
  230.   divisor_deg = divisor.Degree;
  231.   if(dividend_deg < divisor_deg)
  232.     {
  233.     // if degree of divisor is larger than degree of the
  234.     // dividend, the remainder is equal to the dividend
  235.     PolyOvrPrimeField *result = new PolyOvrPrimeField(Prime_Base,0);
  236.     *result = *this;
  237.     DebugFile << "Error - dividend smaller than divisor" << endl;
  238.     exit(0);
  239.     }
  240.   else
  241.     {    
  242.     // perform "synthetic" division to genrate remainder
  243.     PrimeFieldElem *work = new PrimeFieldElem[dividend_deg+1];
  244.     PrimeFieldElem *quotient = new PrimeFieldElem[dividend_deg-divisor_deg+1];
  245.     for(j=0; j<= dividend_deg; j++)
  246.       {
  247.       work[j] = Coeff[j];
  248.       }
  249.     for(k=dividend_deg-divisor_deg; k>=0; k--)
  250.       {
  251.       quotient[k] = work[divisor_deg+k]/divisor.Coeff[divisor_deg];
  252.       work[divisor_deg+k]=PrimeFieldElem(Prime_Base,0);
  253.       for(j=divisor_deg+k-1; j>=k; j--)
  254.         work[j] = work[j] - quotient[k] * divisor.Coeff[j-k];
  255.       }
  256.     //result->Degree = dividend_deg-divisor_deg;
  257.     int rem_deg = 0;
  258.     for(j=0; j<=dividend_deg ; j++)
  259.       {
  260.       if(work[j] != 0) rem_deg = j;
  261.       }
  262.     result = new PolyOvrPrimeField( Prime_Base, rem_deg);
  263.     for(j=0; j<=rem_deg; j++)
  264.       {
  265.       result->Coeff[j]=work[j];
  266.       }
  267.     delete[] work;
  268.     delete[] quotient;
  269.     }
  270.   return *result;
  271. }
  272. //============================================================
  273. PolyOvrPrimeField& PolyOvrPrimeField::operator/= 
  274.                             (const PolyOvrPrimeField &divisor)
  275. {
  276.   int dividend_deg, divisor_deg, j, k;
  277.   //------------------------------------------
  278.   //
  279.   dividend_deg = Degree;
  280.   divisor_deg = divisor.Degree;
  281.   if(dividend_deg < divisor_deg)
  282.     {
  283.     // if degree of divisor is larger than degree
  284.     // of the dividend, the quotient is zero,
  285.     // and the remainder is equal to the dividend
  286.     Degree = 0;
  287.     Coeff[0] = PrimeFieldElem(Prime_Base, 0);
  288.     }
  289.   else
  290.     {    
  291.     // perform "synthetic" division to generate
  292.     // quotient and remainder
  293.     PrimeFieldElem *work = new PrimeFieldElem[dividend_deg+1];
  294.     for(j=0; j<= dividend_deg; j++)
  295.       {
  296.       work[j] = Coeff[j];
  297.       Coeff[j] = PrimeFieldElem(Prime_Base,0);
  298.       }
  299.     for(k=dividend_deg-divisor_deg; k>=0; k--)
  300.       {
  301.       Coeff[k] = work[divisor_deg+k]/divisor.Coeff[divisor_deg];
  302.       work[divisor_deg+k]=PrimeFieldElem(Prime_Base,0);
  303.       for(j=divisor_deg+k-1; j>=k; j--)
  304.         work[j] = work[j] - Coeff[k] * divisor.Coeff[j-k];
  305.       }
  306.     Degree = dividend_deg-divisor_deg;
  307.     delete[] work;
  308.     }
  309.   return *this;
  310. }
  311. //============================================================
  312. PolyOvrPrimeField& PolyOvrPrimeField::operator%= 
  313.                             (const PolyOvrPrimeField &divisor)
  314. {
  315.   int dividend_deg, divisor_deg, j, k;
  316.   //------------------------------------------
  317.   //
  318.   dividend_deg = Degree;
  319.   divisor_deg = divisor.Degree;
  320.   if(dividend_deg < divisor_deg)
  321.     {
  322.     // if degree of divisor is larger than degree of the
  323.     // dividend, the remainder is equal to the dividend
  324.     }
  325.   else
  326.     {    
  327.     // perform "synthetic" division to generate
  328.     // quotient and remainder
  329.     PrimeFieldElem *work = new PrimeFieldElem[dividend_deg+1];
  330.     PrimeFieldElem *quotient = new PrimeFieldElem[dividend_deg-divisor_deg+1];
  331.     for(j=0; j<= dividend_deg; j++)
  332.       {
  333.       work[j] = Coeff[j];
  334.       //Coeff[j] = PrimeFieldElem(Prime_Base,0);
  335.       }
  336.     for(k=dividend_deg-divisor_deg; k>=0; k--)
  337.       {
  338.       quotient[k] = work[divisor_deg+k]/divisor.Coeff[divisor_deg];
  339.       work[divisor_deg+k]=PrimeFieldElem(Prime_Base,0);
  340.       for(j=divisor_deg+k-1; j>=k; j--)
  341.         work[j] = work[j] - quotient[k] * divisor.Coeff[j-k];
  342.       }
  343.     //Degree = dividend_deg-divisor_deg;
  344.     int rem_deg = 0;
  345.     for(j=0; j<=dividend_deg ; j++)
  346.       {
  347.       if(work[j] != 0) rem_deg = j;
  348.       }
  349.     Degree = rem_deg;
  350.     delete[] Coeff;
  351.     Coeff = new PrimeFieldElem[Degree+1];
  352.     for(j=0; j<=rem_deg; j++)
  353.       Coeff[j] = work[j];
  354.     delete[] work;
  355.     delete[] quotient;
  356.     }
  357.   return *this;
  358. }
  359. //=========================================================
  360. //  dump polynomial to an output stream
  361. void PolyOvrPrimeField::DumpToStream( ostream* output_stream)
  362. {
  363.  (*output_stream) << "Degree = " << Degree << endl;
  364.  
  365.  for(int i=Degree; i>=0; i--)
  366.    {
  367.     (*output_stream) << "Coeff[" << i << "] = " 
  368.                      << Coeff[i] << endl;
  369.    }
  370.  return;
  371. }
  372. //===========================================================
  373. PolyOvrPrimeField* Derivative(const PolyOvrPrimeField *right)
  374. {
  375.   PolyOvrPrimeField *result;
  376.   result = new PolyOvrPrimeField( right->Prime_Base, 
  377.                                   right->Degree-1 );
  378.   for(int i=0; i<=right->Degree-1; i++)
  379.     {
  380.     (result->Coeff)[i] = (i+1)*((right->Coeff)[i+1]);
  381.     }
  382.   return result;
  383. }
  384. //===========================================================
  385. PolyOvrPrimeField& EuclideanAlgorithm( const PolyOvrPrimeField *poly1,
  386.                                        const PolyOvrPrimeField *poly2)
  387. {
  388.   PolyOvrPrimeField r_poly, u_poly, v_poly, *gcf_poly;
  389.   if( (poly1->Degree) > (poly2->Degree) )
  390.     {
  391.     u_poly = *poly1;
  392.     v_poly = *poly2;
  393.     }
  394.   else
  395.     {
  396.     u_poly = *poly2;
  397.     v_poly = *poly1;
  398.     }
  399.   int modulus = u_poly.Prime_Base;
  400.   bool done = false;
  401.   while( !done )
  402.     {
  403.     // calculate remainder of u/v
  404.     r_poly = u_poly % v_poly;
  405.     //DebugFile << "u_poly: " << endl;
  406.     //u_poly.DumpToStream(&DebugFile);
  407.     //DebugFile << "v_poly: " << endl;
  408.     //v_poly.DumpToStream(&DebugFile);
  409.     //DebugFile << "r_poly: " << endl;
  410.     //r_poly.DumpToStream(&DebugFile);
  411.     // examine remainder
  412.     if( r_poly.Degree == 0 )
  413.       {
  414.       done = true;
  415.       if( r_poly.Coeff[0].Value != 0 )
  416.         {
  417.         // set gcf to 1
  418.         v_poly.Degree = 0;
  419.         v_poly.Coeff[0].Value = 1;
  420. //        (v_poly->Coeff[0]).Modulus = modulus;
  421. // this should be okay as is, and it will be OBE when deep-copy
  422. // assignments are implemented
  423.         }
  424.       }
  425.     else
  426.       {
  427.       u_poly = v_poly;
  428.       v_poly = r_poly;
  429.       }
  430.     } // end of while( !done )
  431.   int gcf_deg = v_poly.Degree;
  432.   gcf_poly = new PolyOvrPrimeField(modulus,gcf_deg);
  433.   for(int i=0; i<=gcf_deg; i++)
  434.     {
  435.     gcf_poly->Coeff[i] = v_poly.Coeff[i];
  436.     }
  437.   return( *gcf_poly );
  438. }