M4RIE
0.20120415
|
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