Advertisement
Guest User

Draft of ModPoly with coefs

a guest
Aug 9th, 2012
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.32 KB | None | 0 0
  1. #include <Python.h>
  2. #include <structmember.h>
  3.  
  4.  
  5. #define BAD_MODULUS -1
  6. #define BAD_DEGREE -1
  7. #define ModPoly_Check(v) (PyObject_TypeCheck(v, &ModPolyType))
  8.  
  9.  
  10. typedef struct {
  11.     PyObject_HEAD
  12.     /* Type specific fields */
  13.    
  14.     Py_ssize_t ob_size;
  15.     PyObject **ob_item;
  16.     Py_ssize_t allocated;
  17.    
  18.     PyObject *r_modulus;
  19.     PyObject *n_modulus;
  20.     PyObject *degree;
  21. } ModPoly;
  22.  
  23.  
  24. static PyTypeObject ModPolyType;
  25. static PyObject *ModPoly_Equal(PyObject *, PyObject *);
  26.  
  27.  
  28. static void
  29. ModPoly_dealloc(ModPoly *self)
  30. {
  31.     Py_XDECREF(self->r_modulus);
  32.     Py_XDECREF(self->n_modulus);
  33.     Py_XDECREF(self->degree);
  34.     if (self->ob_item != NULL) {
  35.         Py_ssize_t i;
  36.         for (i=0; i < self->ob_size; i++) {
  37.             Py_XDECREF(self->ob_item[i]);
  38.         }
  39.         free(self->ob_item);
  40.     }
  41.    
  42.     self->ob_type->tp_free((PyObject *)self);
  43. }
  44.  
  45.  
  46. static PyObject *
  47. ModPoly_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
  48. {
  49.     ModPoly *self;
  50.    
  51.     self = (ModPoly *)type->tp_alloc(type, 0);
  52.     if (self != NULL) {
  53.         self->r_modulus = PyInt_FromLong(BAD_MODULUS);
  54.         if (self->r_modulus == NULL) {
  55.             Py_DECREF(self);
  56.             return NULL;
  57.         }
  58.        
  59.         self->n_modulus = PyInt_FromLong(BAD_MODULUS);
  60.         if (self->n_modulus == NULL) {
  61.             Py_DECREF(self);
  62.             return NULL;
  63.         }
  64.        
  65.         self->degree = PyInt_FromLong(BAD_DEGREE);
  66.         if (self->degree == NULL) {
  67.             Py_DECREF(self);
  68.             return NULL;
  69.         }
  70.        
  71.         self->ob_size = 0;
  72.         self->ob_item = NULL;
  73.         self->allocated = 0;
  74.     }
  75.    
  76.     return (PyObject *)self;
  77. }
  78.  
  79.  
  80. static int
  81. ModPoly_init(ModPoly *self, PyObject *args, PyObject *kwds)
  82. {
  83.     PyObject *r_modulus=NULL, *n_modulus=NULL, *coefs=NULL, *tmp;
  84.     PyObject **tmp_ar;
  85.    
  86.     static char *kwlist[] = {"r_modulus", "n_modulus", "coefficients", NULL};
  87.    
  88.     if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O", kwlist,
  89.                                      &r_modulus, &n_modulus, &coefs))
  90.         return -1;
  91.    
  92.     if (r_modulus) {
  93.         if (!PyInt_Check(r_modulus) && PyLong_Check(r_modulus)) {
  94.             PyErr_SetString(PyExc_TypeError, "The r modulus must be an integer.");
  95.             return -1;
  96.         }
  97.         tmp = self->r_modulus;
  98.         Py_INCREF(r_modulus);
  99.         self->r_modulus = r_modulus;
  100.         Py_XDECREF(tmp);
  101.     }
  102.    
  103.     if (n_modulus) {
  104.         if (!PyInt_Check(n_modulus) && PyLong_Check(n_modulus)) {
  105.             PyErr_SetString(PyExc_TypeError, "The n modulus must be an integer.");
  106.             Py_DECREF(self->r_modulus);
  107.             return -1;
  108.         }
  109.         tmp = self->n_modulus;
  110.         Py_INCREF(n_modulus);
  111.         self->n_modulus = n_modulus;
  112.         Py_XDECREF(tmp);
  113.     }
  114.    
  115.     self->degree = PyInt_FromLong(1);
  116.     if (self->degree == NULL) {
  117.         Py_DECREF(self->r_modulus);
  118.         Py_DECREF(self->n_modulus);
  119.         return -1;
  120.     }
  121.    
  122.     tmp_ar = (PyObject **)malloc(2 * sizeof(PyObject*));
  123.     if (tmp_ar == NULL) {
  124.         Py_DECREF(self->r_modulus);
  125.         Py_DECREF(self->n_modulus);
  126.         Py_DECREF(self->degree);
  127.         return -1;
  128.     }
  129.    
  130.     tmp_ar[0] = PyInt_FromLong(0);
  131.     if (tmp_ar[0] != NULL) {
  132.         tmp_ar[1] = PyInt_FromLong(1);
  133.     }
  134.    
  135.     if (tmp_ar[0] == NULL || tmp_ar[0] == NULL) {
  136.         Py_DECREF(self->r_modulus);
  137.         Py_DECREF(self->n_modulus);
  138.         Py_DECREF(self->degree);
  139.         Py_XDECREF(tmp_ar[0]);
  140.         Py_XDECREF(tmp_ar[1]);
  141.         free(tmp_ar);
  142.         return -1;
  143.     }
  144.    
  145.     self->ob_size = 2;
  146.     self->allocated = 2;
  147.    
  148.     return 0;
  149. }
  150.  
  151.  
  152. static PyObject *
  153. ModPoly_compare(PyObject *a, PyObject *b, int op)
  154. {
  155.     switch (op) {
  156.         case Py_EQ:
  157.             return ModPoly_Equal(a, b);
  158.             break;
  159.         case Py_NE: {
  160.             PyObject *res = ModPoly_Equal(a, b);
  161.             int r;
  162.             if (res == NULL)
  163.                 return NULL;
  164.             r = PyObject_Not(res);
  165.             Py_DECREF(res);
  166.             if (r) {
  167.                 Py_RETURN_TRUE;
  168.             } else {
  169.                 Py_RETURN_FALSE;
  170.             }
  171.             break; }
  172.         default:
  173.             Py_INCREF(Py_NotImplemented);
  174.             return Py_NotImplemented;
  175.             break;
  176.     }
  177. }
  178.  
  179.  
  180. static PyObject *
  181. ModPoly_Equal(PyObject *a, PyObject *b)
  182. {
  183.     if (!ModPoly_Check(b)) {
  184.         Py_RETURN_FALSE;
  185.     }
  186.     ModPoly *A=(ModPoly *)a, *B=(ModPoly *)b;
  187.    
  188.     if (!PyObject_RichCompareBool(A->r_modulus, B->r_modulus,Py_EQ)) {
  189.         Py_RETURN_FALSE;
  190.     } else if (!PyObject_RichCompareBool(A->n_modulus, B->n_modulus,Py_EQ)) {
  191.         Py_RETURN_FALSE;
  192.     }
  193.    
  194.     Py_RETURN_TRUE;
  195. }
  196.  
  197.  
  198.  
  199. static PyObject *
  200. ModPoly_getcoefs(ModPoly *self, void *closure)
  201. {
  202.     PyTupleObject *res=(PyTupleObject*)PyTuple_New(self->ob_size);
  203.     Py_ssize_t i;
  204.     PyObject *tmp;
  205.    
  206.     if (res == NULL)
  207.         return NULL;
  208.    
  209.     for (i=0; i < self->ob_size; i++) {
  210.         tmp = self->ob_item[i];
  211.         Py_INCREF(tmp);
  212.         PyTuple_SET_ITEM(res, i, tmp);
  213.     }
  214.     return (PyObject *)res;
  215. }
  216.  
  217. static PyObject *
  218. ModPoly_setcoefs(ModPoly *self, PyObject *value, void* closure)
  219. {
  220.     PyErr_SetString(PyExc_AttributeError,
  221.                     "Cannot set the coefficients of a polynomial.");
  222.     return NULL;
  223. }
  224.  
  225.  
  226.  
  227. static PyMemberDef ModPoly_members[] = {
  228.     {"r_modulus", T_OBJECT_EX, offsetof(ModPoly, r_modulus), READONLY,
  229.      "The exponent of the polynomial modulus (x^r-1)."},
  230.     {"n_modulus", T_OBJECT_EX, offsetof(ModPoly, n_modulus), READONLY,
  231.      "The coefficient modulus."},
  232.     {"degree", T_OBJECT_EX, offsetof(ModPoly, degree), READONLY,
  233.      "The polynomial degree."},
  234.     {NULL}
  235. };
  236.  
  237.  
  238. static PyGetSetDef ModPoly_getsetters[] = {
  239.   {"coefficients",
  240.       (getter)ModPoly_getcoefs, (setter)ModPoly_setcoefs,
  241.     "The polynomial coefficients.", NULL},
  242.   {NULL, 0, 0, NULL, NULL}  
  243. };
  244.  
  245.  
  246. static PyTypeObject ModPolyType = {
  247.     PyObject_HEAD_INIT(NULL)
  248.     0,                                                      /* ob_size        */
  249.     "algebra.polynomials.ModPolynomial",                    /* tp_name        */
  250.     sizeof(ModPoly),                                        /* tp_basicsize   */
  251.     0,                                                      /* tp_itemsize    */
  252.     (destructor)ModPoly_dealloc,                            /* tp_dealloc     */
  253.     0,                                                      /* tp_print       */
  254.     0,                                                      /* tp_getattr     */
  255.     0,                                                      /* tp_setattr     */
  256.     0,                                                      /* tp_compare     */
  257.     0,                                                      /* tp_repr        */
  258.     0,                                                      /* tp_as_number   */
  259.     0,                                                      /* tp_as_sequence */
  260.     0,                                                      /* tp_as_mapping  */
  261.     0,                                                      /* tp_hash        */
  262.     0,                                                      /* tp_call        */
  263.     0,                                                      /* tp_str         */
  264.     0,                                                      /* tp_getattro    */
  265.     0,                                                      /* tp_setattro    */
  266.     0,                                                      /* tp_as_buffer   */
  267.     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,               /* tp_flags       */
  268.     "Represent a polynomial on (Z/nZ)[x]/x^r-1",            /* tp_doc         */
  269.     0,                                                      /* tp_traverse */
  270.     0,                                                      /* tp_clear */
  271.     (richcmpfunc)ModPoly_compare,                           /* tp_richcompare */
  272.     0,                                                      /* tp_weaklistoffset */
  273.     0,                                                      /* tp_iter */
  274.     0,                                                      /* tp_iternext */
  275.     0,                                                      /* tp_methods */
  276.     ModPoly_members,                                        /* tp_members */
  277.     ModPoly_getsetters,                                     /* tp_getset */
  278.     0,                                                      /* tp_base */
  279.     0,                                                      /* tp_dict */
  280.     0,                                                      /* tp_descr_get */
  281.     0,                                                      /* tp_descr_set */
  282.     0,                                                      /* tp_dictoffset */
  283.     (initproc)ModPoly_init,                                 /* tp_init */
  284.     0,                                                      /* tp_alloc */
  285.     ModPoly_new,                                            /* tp_new */
  286. };
  287.  
  288. static PyMethodDef module_methods[] = {
  289.     {NULL, NULL, 0, NULL}  /* Sentinel */
  290. };
  291.  
  292.  
  293. #ifndef PyMODINIT_FUNC
  294. #define PyMODINIT_FUNC void
  295. #endif
  296.  
  297. PyMODINIT_FUNC
  298. init_modpoly(void)
  299. {
  300.     PyObject *m;
  301.     ModPolyType.tp_new = PyType_GenericNew;
  302.     if (PyType_Ready(&ModPolyType) < 0)
  303.         return;
  304.  
  305.     m = Py_InitModule3("_modpoly", module_methods,
  306.                "Representation of polynomials on (Z/nZ)[x]/x^r-1.");
  307.     if (m == NULL)
  308.         return;
  309.  
  310.     Py_INCREF(&ModPolyType);
  311.     PyModule_AddObject(m, "ModPolynomial", (PyObject *)&ModPolyType);
  312. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement