Advertisement
Guest User

Draft of ModPoly

a guest
Aug 9th, 2012
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.12 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.     PyObject *r_modulus;
  14.     PyObject *n_modulus;
  15.     PyObject *degree;
  16. } ModPoly;
  17.  
  18.  
  19. static PyTypeObject ModPolyType;
  20. static PyObject *ModPoly_Equal(PyObject *, PyObject *);
  21.  
  22.  
  23. static void
  24. ModPoly_dealloc(ModPoly *self)
  25. {
  26.     Py_XDECREF(self->r_modulus);
  27.     Py_XDECREF(self->n_modulus);
  28.     Py_XDECREF(self->degree);
  29.     self->ob_type->tp_free((PyObject *)self);
  30. }
  31.  
  32.  
  33. static PyObject *
  34. ModPoly_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
  35. {
  36.     ModPoly *self;
  37.    
  38.     self = (ModPoly *)type->tp_alloc(type, 0);
  39.     if (self != NULL) {
  40.         self->r_modulus = PyInt_FromLong(BAD_MODULUS);
  41.         if (self->r_modulus == NULL) {
  42.             Py_DECREF(self);
  43.             return NULL;
  44.         }
  45.        
  46.         self->n_modulus = PyInt_FromLong(BAD_MODULUS);
  47.         if (self->n_modulus == NULL) {
  48.             Py_DECREF(self);
  49.             return NULL;
  50.         }
  51.        
  52.         self->degree = PyInt_FromLong(BAD_DEGREE);
  53.         if (self->degree == NULL) {
  54.             Py_DECREF(self);
  55.             return NULL;
  56.         }
  57.     }
  58.    
  59.     return (PyObject *)self;
  60. }
  61.  
  62.  
  63. static int
  64. ModPoly_init(ModPoly *self, PyObject *args, PyObject *kwds)
  65. {
  66.     PyObject *r_modulus=NULL, *n_modulus=NULL, *coefs=NULL, *tmp;
  67.    
  68.     static char *kwlist[] = {"r_modulus", "n_modulus", "coefficients", NULL};
  69.    
  70.     if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O", kwlist,
  71.                                      &r_modulus, &n_modulus, &coefs))
  72.         return -1;
  73.    
  74.     if (r_modulus) {
  75.         if (!PyInt_Check(r_modulus) && PyLong_Check(r_modulus)) {
  76.             PyErr_SetString(PyExc_TypeError, "The r modulus must be an integer.");
  77.             return -1;
  78.         }
  79.         tmp = self->r_modulus;
  80.         Py_INCREF(r_modulus);
  81.         self->r_modulus = r_modulus;
  82.         Py_XDECREF(tmp);
  83.     }
  84.    
  85.     if (n_modulus) {
  86.         if (!PyInt_Check(n_modulus) && PyLong_Check(n_modulus)) {
  87.             PyErr_SetString(PyExc_TypeError, "The n modulus must be an integer.");
  88.             Py_DECREF(self->r_modulus);
  89.             return -1;
  90.         }
  91.         tmp = self->n_modulus;
  92.         Py_INCREF(n_modulus);
  93.         self->n_modulus = n_modulus;
  94.         Py_XDECREF(tmp);
  95.     }
  96.    
  97.     self->degree = PyInt_FromLong(1);
  98.     if (self->degree == NULL) {
  99.         Py_DECREF(self->r_modulus);
  100.         Py_DECREF(self->n_modulus);
  101.         return -1;
  102.     }
  103.    
  104.     return 0;
  105. }
  106.  
  107.  
  108. static PyObject *
  109. ModPoly_compare(PyObject *a, PyObject *b, int op)
  110. {
  111.     switch (op) {
  112.         case Py_EQ:
  113.             return ModPoly_Equal(a, b);
  114.             break;
  115.         case Py_NE: {
  116.             PyObject *res = ModPoly_Equal(a, b);
  117.             int r;
  118.             if (res == NULL)
  119.                 return NULL;
  120.             r = PyObject_Not(res);
  121.             Py_DECREF(res);
  122.             if (r) {
  123.                 Py_RETURN_TRUE;
  124.             } else {
  125.                 Py_RETURN_FALSE;
  126.             }
  127.             break; }
  128.         default:
  129.             Py_INCREF(Py_NotImplemented);
  130.             return Py_NotImplemented;
  131.             break;
  132.     }
  133. }
  134.  
  135.  
  136. static PyObject *
  137. ModPoly_Equal(PyObject *a, PyObject *b)
  138. {
  139.     if (!ModPoly_Check(b)) {
  140.         Py_RETURN_FALSE;
  141.     }
  142.     ModPoly *A=(ModPoly *)a, *B=(ModPoly *)b;
  143.    
  144.     if (!PyObject_RichCompareBool(A->r_modulus, B->r_modulus,Py_EQ)) {
  145.         Py_RETURN_FALSE;
  146.     } else if (!PyObject_RichCompareBool(A->n_modulus, B->n_modulus,Py_EQ)) {
  147.         Py_RETURN_FALSE;
  148.     }
  149.    
  150.     Py_RETURN_TRUE;
  151. }
  152.  
  153.  
  154.  
  155. static PyMemberDef ModPoly_members[] = {
  156.     {"r_modulus", T_OBJECT_EX, offsetof(ModPoly, r_modulus), READONLY,
  157.      "The exponent of the polynomial modulus (x^r-1)."},
  158.     {"n_modulus", T_OBJECT_EX, offsetof(ModPoly, n_modulus), READONLY,
  159.      "The coefficient modulus."},
  160.     {"degree", T_OBJECT_EX, offsetof(ModPoly, degree), READONLY,
  161.      "The polynomial degree."},
  162.     {NULL}
  163. };
  164.  
  165.  
  166.  
  167. static PyTypeObject ModPolyType = {
  168.     PyObject_HEAD_INIT(NULL)
  169.         0,                                                                      /* ob_size        */
  170.         "algebra.polynomials.ModPolynomial",                    /* tp_name        */
  171.         sizeof(ModPoly),                                                /* tp_basicsize   */
  172.         0,                                                                      /* tp_itemsize    */
  173.         (destructor)ModPoly_dealloc,                            /* tp_dealloc     */
  174.         0,                                                                      /* tp_print       */
  175.         0,                                                                      /* tp_getattr     */
  176.         0,                                                                      /* tp_setattr     */
  177.         0,                                                                      /* tp_compare     */
  178.         0,                                                                      /* tp_repr        */
  179.         0,                                                                      /* tp_as_number   */
  180.         0,                                                                      /* tp_as_sequence */
  181.         0,                                                                      /* tp_as_mapping  */
  182.         0,                                                                      /* tp_hash        */
  183.         0,                                                                      /* tp_call        */
  184.         0,                                                                      /* tp_str         */
  185.         0,                                                                      /* tp_getattro    */
  186.         0,                                                                      /* tp_setattro    */
  187.         0,                                                                      /* tp_as_buffer   */
  188.         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,               /* tp_flags       */
  189.         "Represent a polynomial on (Z/nZ)[x]/x^r-1",            /* tp_doc         */
  190.     0,                                                          /* tp_traverse */
  191.     0,                                                          /* tp_clear */
  192.     (richcmpfunc)ModPoly_compare,                           /* tp_richcompare */
  193.     0,                                                          /* tp_weaklistoffset */
  194.     0,                                                          /* tp_iter */
  195.     0,                                                          /* tp_iternext */
  196.     0,                                                      /* tp_methods */
  197.     ModPoly_members,                                        /* tp_members */
  198.     0,                                                      /* tp_getset */
  199.     0,                                                      /* tp_base */
  200.     0,                                                      /* tp_dict */
  201.     0,                                                      /* tp_descr_get */
  202.     0,                                                      /* tp_descr_set */
  203.     0,                                                      /* tp_dictoffset */
  204.     (initproc)ModPoly_init,                                 /* tp_init */
  205.     0,                                                      /* tp_alloc */
  206.     ModPoly_new,                                            /* tp_new */
  207. };
  208.  
  209. static PyMethodDef module_methods[] = {
  210.     {NULL, NULL, 0, NULL}  /* Sentinel */
  211. };
  212.  
  213.  
  214. #ifndef PyMODINIT_FUNC
  215. #define PyMODINIT_FUNC void
  216. #endif
  217.  
  218. PyMODINIT_FUNC
  219. init_modpoly(void)
  220. {
  221.         PyObject *m;
  222.     ModPolyType.tp_new = PyType_GenericNew;
  223.         if (PyType_Ready(&ModPolyType) < 0)
  224.                 return;
  225.  
  226.         m = Py_InitModule3("_modpoly", module_methods,
  227.                            "Representation of polynomials on (Z/nZ)[x]/x^r-1.");
  228.         if (m == NULL)
  229.                 return;
  230.  
  231.         Py_INCREF(&ModPolyType);
  232.         PyModule_AddObject(m, "ModPolynomial", (PyObject *)&ModPolyType);
  233. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement