OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
PyPolynomialCoefficient.cpp
Go to the documentation of this file.
1 //
2 // Python API for PolynomialCoefficient (part of the multidimensional polynomial fitting routines)
3 //
4 // Copyright (c) 2008-2023, Chris Rogers, STFC Rutherford Appleton Laboratory, Didcot, UK
5 //
6 // This file is part of OPAL.
7 //
8 // OPAL is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
15 //
16 
17 #include <Python.h>
18 #include <structmember.h>
19 
21 #include "PyOpal/Globals.h"
22 #include "PyOpal/PyPolynomialCoefficient.h"
23 
24 namespace PyPolynomialCoefficient {
25 /*
26  PolynomialCoefficient(std::vector<int> inVariablesByVector,
27  int outVariable,
28  double coefficient)
29 */
30 int _init(PyObject* self, PyObject *args, PyObject *kwds) {
31  PyCoefficient* py_coeff = reinterpret_cast<PyCoefficient*>(self);
32  // failed to cast or self was not initialised - something horrible happened
33  if (py_coeff == nullptr) {
34  PyErr_SetString(PyExc_TypeError,
35  "Failed to resolve self as PolynomialCoefficient in __init__");
36  return -1;
37  }
38  // legal python to call initialised_object.__init__() to reinitialise, so
39  // handle this case
40  if (py_coeff->coeff != nullptr) {
41  delete py_coeff->coeff;
42  py_coeff->coeff = nullptr;
43  }
44  // read in arguments
45 
46  PyObject* py_index;
47  int value_axis;
48  double coefficient;
49  static char *kwlist[] = {const_cast<char*>("index_by_vector"),
50  const_cast<char*>("output_axis"),
51  const_cast<char*>("coefficient_value"),
52  nullptr};
53  if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oid", kwlist,
54  &py_index, &value_axis, &coefficient)) {
55  return -1;
56  }
57 
58  // convert from list to std::vector<int>
59  // first check validity of coefficients
60  if (!PyList_Check(py_index)) {
61  PyErr_SetString(PyExc_TypeError,
62  "Failed to resolve index as a list");
63  return -1;
64  }
65  size_t list_size = PyList_Size(py_index); // nb: size 0 is legal
66  std::vector<int> index(list_size);
67  // now loop over the rows
68  for (size_t i = 0; i < list_size; ++i) {
69  PyObject* py_value = PyList_GetItem(py_index, i);
70  index[i] = int(PyLong_AsLong(py_value));
71  if (PyErr_Occurred() != nullptr) { // not an int
72  return -1;
73  }
74  }
75  // now initialise the internal coeff
76  try {
77  py_coeff->coeff = new interpolation::PolynomialCoefficient(index, value_axis, coefficient);
78  } catch (std::exception& exc) {
79  PyErr_SetString(PyExc_RuntimeError, (&exc)->what());
80  return -1;
81  }
82  return 0;
83 }
84 
85 PyObject *_alloc(PyTypeObject *type, Py_ssize_t nitems) {
86  void* void_coeff = malloc(sizeof(PyCoefficient));
87  PyCoefficient* coeff = reinterpret_cast<PyCoefficient*>(void_coeff);
88  coeff->coeff = nullptr;
89  Py_REFCNT(coeff) = 1;
90  Py_TYPE(coeff) = type;
91  return reinterpret_cast<PyObject*>(coeff);
92 }
93 
94 PyObject *_new(PyTypeObject *type, Py_ssize_t nitems) {
95  return _alloc(type, nitems);
96 }
97 
98 void _free(PyCoefficient * self) {
99  if (self != nullptr) {
100  if (self->coeff != nullptr)
101  delete self->coeff;
102  free(self);
103  }
104 }
105 
106 void _dealloc(PyCoefficient * self) {
107  _free(self);
108 }
109 
110 static PyMemberDef _members[] = {
111 {nullptr}
112 };
113 
114 static PyMethodDef _methods[] = {
115 {nullptr}
116 };
117 
118 std::string class_docstring =
119 std::string("PolynomialCoefficient docstring\n");
120 
121 static PyTypeObject PyCoefficientType = {
122  PyObject_HEAD_INIT(nullptr)
123  "polynomial_coefficient.PolynomialCoefficient", /*tp_name*/
124  sizeof(PyCoefficient), /*tp_basicsize*/
125  0, /*tp_itemsize*/
126  (destructor)_dealloc, /*tp_dealloc*/
127  0, /*tp_print*/
128  0, /*tp_getattr*/
129  0, /*tp_setattr*/
130  0, /*tp_compare*/
131  0, /*tp_repr*/
132  0, /*tp_as_number*/
133  0, /*tp_as_sequence*/
134  0, /*tp_as_mapping*/
135  0, /*tp_hash */
136  0, /*tp_call*/
137  0, /*tp_str*/
138  0, /*tp_getattro*/
139  0, /*tp_setattro*/
140  0, /*tp_as_buffer*/
141  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
142  class_docstring.c_str(), /* tp_doc */
143  0, /* tp_traverse */
144  0, /* tp_clear */
145  0, /* tp_richcompare */
146  0, /* tp_weaklistoffset */
147  0, /* tp_iter */
148  0, /* tp_iternext */
149  _methods, /* tp_methods */
150  _members, /* tp_members */
151  0, /* tp_getset */
152  0, /* tp_base */
153  0, /* tp_dict */
154  0, /* tp_descr_get */
155  0, /* tp_descr_set */
156  0, /* tp_dictoffset */
157  (initproc)_init, /* tp_init */
158  (allocfunc)_alloc, /* tp_alloc, called by new */
159  0, // (newfunc)_new, /* tp_new */
160  (freefunc)_free, /* tp_free, called by dealloc */
161 };
162 
163 } // namespace PyPolynomialCoefficient
164 
165 const char* module_docstring =
166  "polynomial_coefficient module contains the PolynomialCoefficient class";
167 
168 static struct PyModuleDef polynomial_coefficient_def = {
169  PyModuleDef_HEAD_INIT,
170  "polynomial_coefficient", /* m_name */
171  module_docstring, /* m_doc */
172  -1, /* m_size */
173  nullptr, /* m_methods */
174  nullptr, /* m_reload */
175  nullptr, /* m_traverse */
176  nullptr, /* m_clear */
177  nullptr, /* m_free */
178 };
179 
180 PyMODINIT_FUNC PyInit_polynomial_coefficient(void) {
182  PyPolynomialCoefficient::PyCoefficientType.tp_new = PyType_GenericNew;
183  if (PyType_Ready(&PyPolynomialCoefficient::PyCoefficientType) < 0)
184  return nullptr;
185 
186  PyObject* module = PyModule_Create(&polynomial_coefficient_def);
187  if (module == nullptr)
188  return nullptr;
189 
190  PyTypeObject* polynomial_coeff_type =
191  &PyPolynomialCoefficient::PyCoefficientType;
192  Py_INCREF(polynomial_coeff_type);
193  PyModule_AddObject(module, "PolynomialCoefficient",
194  reinterpret_cast<PyObject*>(polynomial_coeff_type));
195  return module;
196 }
197 
198 
PolynomialCoefficient represents a coefficient in a multi-dimensional polynomial. ...
void Initialise()
Definition: Globals.cpp:50
void _free(PyCoefficient *self)
interpolation::PolynomialCoefficient * coeff
void _dealloc(PyCoefficient *self)
int _init(PyObject *self, PyObject *args, PyObject *kwds)
c Accompany it with the information you received as to the offer to distribute corresponding source complete source code means all the source code for all modules it plus any associated interface definition plus the scripts used to control compilation and installation of the executable as a special exception
Definition: LICENSE:157
PyMODINIT_FUNC PyInit_polynomial_coefficient(void)
PyObject * _alloc(PyTypeObject *type, Py_ssize_t nitems)
PyObject * _new(PyTypeObject *type, Py_ssize_t nitems)
SDDS1 &description type
Definition: test.stat:4