M4RIE  0.20120415
 All Data Structures Files Functions Variables Defines
mzd_poly.h
00001 #ifndef M4RIE_MZD_POLY_H
00002 #define M4RIE_MZD_POLY_H
00003 
00004 /******************************************************************************
00005 *
00006 *            M4RIE: Linear Algebra over GF(2^e)
00007 *
00008 *    Copyright (C) 2011 Martin Albrecht <martinralbrecht@googlemail.com>
00009 *
00010 *  Distributed under the terms of the GNU General Public License (GEL)
00011 *  version 2 or higher.
00012 *
00013 *    This code is distributed in the hope that it will be useful,
00014 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 *    General Public License for more details.
00017 *
00018 *  The full text of the GPL is available at:
00019 *
00020 *                  http://www.gnu.org/licenses/
00021 ******************************************************************************/
00022 
00023 #include <m4ri/m4ri.h>
00024 #include <stdarg.h>
00025 
00026 /********************************************************************
00027  * Internal representation
00028  *******************************************************************/
00029 
00030 static inline void _poly_add(mzd_t **c, const mzd_t **a, const mzd_t **b,const unsigned int length) {
00031   switch(length) {
00032   case 16: mzd_add(c[15], a[15], b[15]);
00033   case 15: mzd_add(c[14], a[14], b[14]);
00034   case 14: mzd_add(c[13], a[13], b[13]);
00035   case 13: mzd_add(c[12], a[12], b[12]);
00036   case 12: mzd_add(c[11], a[11], b[11]);
00037   case 11: mzd_add(c[10], a[10], b[10]);
00038   case 10: mzd_add(c[ 9], a[ 9], b[ 9]);
00039   case  9: mzd_add(c[ 8], a[ 8], b[ 8]);
00040   case  8: mzd_add(c[ 7], a[ 7], b[ 7]);
00041   case  7: mzd_add(c[ 6], a[ 6], b[ 6]);
00042   case  6: mzd_add(c[ 5], a[ 5], b[ 5]);
00043   case  5: mzd_add(c[ 4], a[ 4], b[ 4]);
00044   case  4: mzd_add(c[ 3], a[ 3], b[ 3]);
00045   case  3: mzd_add(c[ 2], a[ 2], b[ 2]);
00046   case  2: mzd_add(c[ 1], a[ 1], b[ 1]);
00047   case  1: mzd_add(c[ 0], a[ 0], b[ 0]);
00048   case  0:
00049     break;
00050   default:
00051     for(unsigned int i=0; i<length; i++)
00052       mzd_add(c[ i], a[ i], b[ i]);
00053   }
00054 }
00055 
00056 void _poly_addmul2(mzd_t **X, const mzd_t **a, const mzd_t **b);
00057 void _poly_addmul4(mzd_t **X, const mzd_t **a, const mzd_t **b);
00058 
00059 /*********************************************************************
00060  * mzd_poly_t will be the data type for matrices over GF(2)[x] in the
00061  * future
00062  *
00063  * DO NOT USE YET.
00064  *
00065  *********************************************************************/
00066 
00067 typedef int deg_t;
00068 
00069 typedef struct {
00070   mzd_t **x;
00071   rci_t nrows; 
00072   rci_t ncols; 
00073   deg_t depth;   
00074 } mzd_poly_t;
00075 
00076 static inline mzd_poly_t *_mzd_poly_add(mzd_poly_t *C, const mzd_poly_t *A, const mzd_poly_t *B, unsigned int offset) {
00077   _poly_add(C->x+offset, (const mzd_t**)A->x, (const mzd_t**)B->x, A->depth);
00078   return C;
00079 }
00080 
00081 static inline mzd_poly_t *mzd_poly_add(mzd_poly_t *C, const mzd_poly_t *A, const mzd_poly_t *B) {
00082   assert(C->depth >= A->depth && A->depth == B->depth);
00083   return _mzd_poly_add(C, A, B, 0);
00084 }
00085 
00086 static inline mzd_poly_t *mzd_poly_init(const deg_t d, const rci_t m, const rci_t n) {
00087   mzd_poly_t *A = (mzd_poly_t*)m4ri_mm_malloc(sizeof(mzd_poly_t));
00088   A->x = (mzd_t**)m4ri_mm_malloc(sizeof(mzd_t*)*d);
00089 
00090   A->nrows = m;
00091   A->ncols = n;
00092   A->depth = d+1;
00093 
00094   for(int i=0; i<A->depth; i++)
00095     A->x[i] = mzd_init(m,n);
00096   return A;
00097 }
00098 
00099 static inline void mzd_poly_free(mzd_poly_t *A) {
00100   for(int i=0; i<A->depth; i++)
00101    mzd_free(A->x[i]);
00102 #if __M4RI_USE_MM_MALLOC
00103   _mm_free(A);
00104 #else
00105   free(A);
00106 #endif
00107 }
00108 
00109 
00110 static inline mzd_poly_t *_mzd_poly_adapt_depth(mzd_poly_t *A, const deg_t new_depth) {
00111   if (new_depth < A->depth) {
00112     for(int i=new_depth; i<A->depth; i++) {
00113       mzd_free(A->x[i]);
00114       A->x[i] = NULL;
00115     }
00116   } else {
00117     for(int i=A->depth; i<new_depth; i++) {
00118       A->x[i] = mzd_init(A->nrows,A->ncols);
00119     }
00120   }
00121   A->depth = new_depth;
00122   return A;
00123 }
00124 
00125 #endif //M4RIE_MZD_POLY_H