Utils_2.h
上传用户:speoil
上传日期:2021-10-06
资源大小:100k
文件大小:12k
源码类别:

3G开发

开发平台:

C/C++

  1. #ifndef UTILS_2
  2. #define UTILS_2
  3. #include <math.h>
  4. #include "Utils_1.h"
  5. /************************************************************************
  6.  *
  7.  * GF(q)
  8.  *
  9.  ************************************************************************/
  10. class GFq
  11. {
  12. public:
  13.   // General field definition parameter
  14.   static int q;
  15.   static int log_2_q;         // If q is not prime
  16.   static int  mask;           // if q is not prime - 1's at first positions
  17.   static GFq alpha[MAX_Q];
  18.   static int reverse_alpha[MAX_Q];
  19.   static GFq inverse[MAX_Q];
  20.   static BOOLEAN IsPrimeQ;
  21.   static BOOLEAN IsModuloOperations;
  22.   // Value of field
  23.   int val;
  24. public:
  25.   GFq(GFq &g) : val(g.val) {}
  26.   BOOLEAN IsZero()
  27.   {
  28.      return val == 0;
  29.   }
  30.   BYTE GetVal()     { return val; }
  31.   static void Initialize(int p_q);
  32.   static void GenerateAlphas(int m);
  33.   static GFq &One()   
  34.   { 
  35.      if (IsModuloOperations)
  36.      {     
  37.         static GFq ConstOne(1);
  38.         return ConstOne;
  39.      }
  40.      else
  41.         return alpha[0]; 
  42.   }
  43.   BOOLEAN operator==(GFq g)
  44.   { 
  45.      return val == g.val;  
  46.   }
  47.   GFq(int i) : val((BYTE)i) {}
  48.   GFq(BYTE b = 0) : val(b) {}
  49.   GFq &operator+=(GFq g)
  50.   {
  51.      if(IsModuloOperations)
  52.         val = (val + g.val) % q;
  53.      else
  54.         val ^= g.val;
  55.      return *this;
  56.   }
  57.   GFq &operator=(GFq &g)
  58.   {
  59.     val = g.val;
  60.     return *this;
  61.   }
  62.   GFq &operator=(BYTE b)
  63.     { 
  64.       val = b;
  65.       return *this;
  66.     }
  67.   GFq &operator=(int i)
  68.     { 
  69.       val = (BYTE)i;
  70.       return *this;
  71.     }
  72.   GFq &operator-=(GFq g) 
  73.   {
  74.      if(IsModuloOperations)
  75.         val = (q + val - g.val) % q;
  76.      else
  77.         val ^= g.val;
  78.      return *this;
  79.   }
  80.   GFq &operator*=(GFq g)
  81.   {
  82.      if ((val == 0) || (g.val == 0))
  83.         val = 0;
  84.      else
  85.      {
  86.         if (IsModuloOperations)
  87.         {
  88.             if (!IsPrimeQ)
  89.             {
  90.                cout << "GFq::operator*=: Invalid multiplication (q is not prime)n";
  91.                exit(1);
  92.             }
  93.         
  94.             val = (val * g.val) % q;
  95.         }
  96.         else
  97.            val = alpha[(reverse_alpha[this->val] + reverse_alpha[g.val]) % (q-1)].val;
  98.      }
  99.      return *this;
  100.   }
  101.   GFq &Inverse()
  102.   {
  103.      return inverse[val];
  104.   }
  105.   GFq &Minus()
  106.   {
  107.      static GFq g;
  108.      if (IsModuloOperations)
  109.         g.val = (q - val) % q;
  110.      else      // GF(2^m)
  111.         g.val = val;
  112.      return g;
  113.   }
  114.   void RandomSelect()      // Random select among nonzero elements
  115.   { val = uniform_random(q-1) + 1; }
  116.   GFq &operator/=(GFq g)
  117.   {
  118.      if (val == 0) 
  119.         val = 0;
  120.      else if (g.val == 0)
  121.      {
  122.         cout << "GFq::operator /= division by zeron";
  123.         exit(1);
  124.      }
  125.      else
  126.      {
  127.         if (IsModuloOperations)
  128.         {
  129.             if (!IsPrimeQ)
  130.             {
  131.                cout << "GFq::operator*=: Invalid multiplication (q is not prime)n";
  132.                exit(1);
  133.             }
  134.         
  135.             *this *= inverse[g.val];
  136.         }
  137.         else
  138.            val = alpha[(q-1 + (reverse_alpha[this->val] - reverse_alpha[g.val])) % (q-1)].val;
  139.      }
  140.      return *this;
  141.   }
  142.   GFq &operator*(GFq g)
  143.     {
  144.       static GFq result;
  145.       result = *this;
  146.       result *= g;
  147.       return result;
  148.     }
  149.   GFq &operator/(GFq g)
  150.     {
  151.       static GFq result;
  152.       result = *this;
  153.       result /= g;
  154.       return result;
  155.     }
  156.   GFq &operator+(GFq g)
  157.     {
  158.       static GFq result;
  159.       result = *this;
  160.       result += g;
  161.       return result; 
  162.     }
  163.   GFq &operator-(GFq g)
  164.     {
  165.       static GFq result;
  166.       result = *this;
  167.       result -= g;
  168.       return result; 
  169.     }
  170. };
  171. inline ostream &operator<<( ostream &s, GFq g )
  172. {
  173.   s << (int)g.val;
  174.   
  175.   return s;
  176. }
  177. inline istream &operator>>( istream &s, GFq &g )
  178. {
  179.    int i;
  180.    s >> i;
  181.    
  182.    g.val = i;
  183.   
  184.    return s;
  185. }
  186. /************************************************************************
  187.  *
  188.  * GF(q) matrix
  189.  *
  190.  ************************************************************************/
  191. class check_node;
  192. class matrix
  193. {
  194. public:
  195.    GFq *Elements;
  196.    int M, N;
  197.    int TotalSize;
  198. public:
  199.    matrix() : Elements(NULL), M(0), N(0), TotalSize(0)
  200.    {  }
  201.    matrix(matrix &M) : Elements(NULL), M(0), N(0), TotalSize(0)
  202.    {
  203.       *this = M;
  204.    }
  205.    matrix &operator=(matrix &A)
  206.    {
  207.       Init(A.M, A.N);
  208.       for (int i = 0; i < TotalSize; i++)
  209.          Elements[i] = A.Elements[i];
  210.       return *this;
  211.    }
  212.    matrix &Extract(int ColFirst, int CountCols)
  213.    {
  214.       static matrix A;
  215.       A.Init(M, CountCols);
  216.       for (int j = 0; j < CountCols; j++)
  217.          for (int i = 0; i < M; i++)
  218.             A.Element(i, j) = Element(i, ColFirst + j);
  219.       return A;
  220.    }
  221.    void Init(int p_M, int p_N)
  222.    {
  223.       if ((M != p_M) || (N != p_N))
  224.       {
  225.          deAllocate();
  226.          M = p_M;
  227.          N = p_N;
  228.          TotalSize = p_M * p_N;
  229.          if (TotalSize > 0)
  230.          {
  231.             Elements = new GFq[TotalSize];
  232.             for (int i = 0; i < TotalSize; i++)
  233.                Elements[i].val = 0;
  234.          }
  235.          else
  236.             Elements = NULL;
  237.       }
  238.    }
  239.    matrix(int p_M, int p_N = 1) : Elements(NULL), M(0), N(0), TotalSize(0)
  240.    {
  241.       Init(p_M, p_N);
  242.    }
  243.    GFq &Element(int i, int j)
  244.       // i in range 0,...,M-1 and j in range 0,...,N-1
  245.    {
  246.       return Elements[N * i + j];
  247.    }
  248.    GFq &operator[] (int i)
  249.    {
  250.       return Elements[i];
  251.    }
  252.    ~matrix()
  253.    {
  254.       deAllocate();
  255.    }
  256.    
  257.    void deAllocate()
  258.    {
  259.       if (TotalSize > 0)
  260.       {
  261.          delete Elements;
  262.          TotalSize = M = N = 0;
  263.          Elements = NULL;
  264.       }
  265.    }
  266.    void Add(int row, check_node &Check, GFq Mult);
  267.    void Set(int row, check_node &Check);
  268.    void SwitchColumns(int j1, int j2)
  269.    {
  270.       GFq Aux;
  271.       for (int i = 0; i < M; i++)
  272.       {
  273.          Aux = Element(i, j1);
  274.          Element(i, j1) = Element(i, j2);
  275.          Element(i, j2) = Aux;
  276.       }
  277.    }
  278.    matrix &operator*(matrix &B)
  279.    {
  280.       static matrix Result;
  281.       matrix &A = *this;
  282.       if (A.N != B.M)
  283.       {
  284.          cout << "Attempt to multiply incompatible matricesn";
  285.          exit(1);
  286.       }
  287.       Result.Init(A.M, B.N);
  288.       for (int i = 0; i < Result.M; i++)
  289.          for (int j = 0; j < Result.N; j++)
  290.          {
  291.             Result.Element(i,j) = 0;
  292.             for (int k = 0; k < A.N; k++)
  293.                Result.Element(i,j) += A.Element(i,k) * B.Element(k,j);
  294.          }
  295.       return Result;
  296.    }
  297.    void SwitchRows(int i1, int i2)
  298.    {
  299.       GFq Aux;
  300.       for (int j = 0; j < N; j++)
  301.       {
  302.          Aux = Element(i1, j);
  303.          Element(i1, j) = Element(i2, j);
  304.          Element(i2, j) = Aux;
  305.       }
  306.    }
  307.    void MultiplyByMinusOne()
  308.    {
  309.       for (int i = 0; i < TotalSize; i++)
  310.          Elements[i] = Elements[i].Minus();
  311.    }
  312.    void AddRow(int i1, int i2, GFq mult)
  313.    {
  314.       for (int j = 0; j < N; j++)
  315.          Element(i1, j) += Element(i2, j) * mult;
  316.    }
  317.    void MultRow(int i, GFq mult)
  318.    {
  319.       for (int j = 0; j < N; j++)
  320.          Element(i, j) *= mult;
  321.    }
  322.    matrix &Inverse();
  323.    void SetNull()
  324.    {
  325.       deAllocate();
  326.    }
  327.    BOOLEAN IsNull()
  328.    { return (TotalSize == 0); }
  329. } ;
  330. class column_vector : public matrix
  331. {
  332. public:
  333.    column_vector() : matrix()  {}
  334.    column_vector( int p_M ) : matrix( p_M, 1 )  {}
  335.    void Init(int p_M)
  336.    {
  337.       matrix::Init(p_M, 1);
  338.    }
  339. //   ~column_vector()
  340. //   {
  341. //      deAllocate();
  342. //   }
  343.    GFq &operator[](int i)
  344.    {
  345.       return this->Elements[i];
  346.    }
  347.    column_vector &operator=(long p_Val)
  348.    {
  349.       // LSB is first
  350.       for (int i = 0; i < M; i++)
  351.       {
  352.          (*this)[i].val = p_Val & GFq::mask;
  353.          p_Val >>= GFq::log_2_q;
  354.       }
  355.       return *this;
  356.    }
  357.    column_vector &operator=(matrix &Matrix)
  358.    {
  359.       if (Matrix.N != 1)
  360.       {
  361.          cout << "column_vector::operator= : Incompatible rows/columns in assignmentn";
  362.          exit(1);
  363.       }
  364.       Init(Matrix.M);
  365.       for (int i = 0; i < M; i++)
  366.          (*this)[i] = Matrix.Element(i, 0);
  367.       return *this;
  368.    }
  369.    void Extract(column_vector &p_Source, int RowFirst)
  370.    {
  371.       int SourceIndex = RowFirst;
  372.       // If attempting to extract more elements than exist in source
  373.       if (M > (p_Source.M - RowFirst))
  374.       {
  375.          cout << "column_vector::Extract : Incompatible rowsn";
  376.          exit(1);
  377.       }
  378.       for (int i = 0; i < M; i++, SourceIndex++)
  379.          (*this)[i] = p_Source[SourceIndex];
  380.    }
  381.    void Combine(column_vector &p_Vector1, column_vector &p_Vector2)
  382.    {
  383.       if (M != (p_Vector1.M + p_Vector2.M))
  384.       {
  385.          cout << "column_vector::Combine: Incompatible rowsn";
  386.          exit(1);
  387.       }
  388.       int index = 0;
  389.       for (int i = 0; i < p_Vector1.M; index++, i++)
  390.          (*this)[index] = p_Vector1[i];
  391.       for (int i = 0; i < p_Vector2.M; index++, i++)
  392.          (*this)[index] = p_Vector2[i];
  393.    }
  394. } ;
  395. ostream &operator<<( ostream &s, matrix &m );
  396. #define MAX_BUF 10000
  397. istream &operator>>( istream &s, matrix &m );
  398. /************************************************************************
  399.  *
  400.  * IntArray
  401.  *
  402.  ************************************************************************/
  403. class IntArray
  404. {
  405. public:
  406.    int *Elements;
  407.    int M, N;
  408. public:
  409.    IntArray(): Elements(NULL), M(0), N(0)  {}
  410.    IntArray(int p_M, int p_N) : Elements(NULL), M(0), N(0)  
  411.    {  Allocate(p_M, p_N);  }
  412.    ~IntArray()
  413.    {
  414.       deAllocate();
  415.    }
  416.    void Allocate(int p_M, int p_N)
  417.    {
  418.       if ((M != p_M) || (N != p_N))
  419.       {
  420.          deAllocate();
  421.          M = p_M;
  422.          N = p_N;
  423.          Elements = new int[M * N];
  424.       }
  425.    }
  426.    void deAllocate()
  427.    {
  428.       M = 0;
  429.       N = 0;
  430.       if (Elements != NULL) delete Elements;
  431.       Elements = NULL;
  432.    }
  433.    int &Element(int i, int j)
  434.    {
  435.       return Elements[i * N + j];
  436.    }
  437. } ;
  438. /************************************************************************
  439.  *
  440.  * Vector
  441.  *
  442.  ************************************************************************/
  443. class vector
  444. {
  445. public:
  446.    double *Elements;
  447.    int CountElements;
  448. public:
  449.    vector(int p_Elements = 0) : Elements(NULL), CountElements(0)
  450.    { Allocate(p_Elements); }
  451.    ~vector()
  452.    { deAllocate(); }
  453.    int GetSize()
  454.    { return CountElements; }
  455.    double &operator[] (int i)
  456.    {
  457.       return Elements[i];
  458.    }
  459.    void Allocate( int p_Elements )
  460.    {
  461.       if (CountElements != p_Elements)
  462.       {
  463.          deAllocate();
  464.          if (p_Elements != 0)
  465.          {
  466.             Elements = new double[p_Elements];
  467.             CountElements = p_Elements;
  468.          }
  469.       }
  470.    }
  471.    void deAllocate()
  472.    {
  473.       if (Elements != NULL)
  474.          delete Elements;
  475.       Elements = NULL;
  476.       CountElements = 0;
  477.    }
  478.    vector &operator=( vector &p_Vector )
  479.    {
  480.       Allocate(p_Vector.CountElements);
  481.       for (int i = 0; i < CountElements; i++)
  482.          Elements[i] = p_Vector.Elements[i];
  483.       return *this;
  484.    }
  485.    vector &operator=( column_vector &p_Vector )
  486.    {
  487.       Allocate(p_Vector.M);
  488.       for (int i = 0; i < CountElements; i++)
  489.          Elements[i] = p_Vector.Elements[i].val;
  490.       return *this;
  491.    }
  492. } ;
  493. inline ostream &operator<<( ostream &s, vector &v )
  494. {
  495.    s << "[";
  496.    for (int i = 0; i < v.GetSize(); i++)
  497.    {
  498.       if (i != 0)
  499.          s << " ";
  500.       s << v[i];
  501.    }
  502.    s << "]";
  503.    return s;
  504. }
  505. #endif