OPAL (Object Oriented Parallel Accelerator Library) 2024.2
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
25/*
26 PolynomialCoefficient(std::vector<int> inVariablesByVector,
27 int outVariable,
28 double coefficient)
29*/
30int _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
85PyObject *_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
94PyObject *_new(PyTypeObject *type, Py_ssize_t nitems) {
95 return _alloc(type, nitems);
96}
97
98void _free(PyCoefficient * self) {
99 if (self != nullptr) {
100 if (self->coeff != nullptr)
101 delete self->coeff;
102 free(self);
103 }
104}
105
107 _free(self);
108}
109
110static PyMemberDef _members[] = {
111{nullptr}
112};
113
114static PyMethodDef _methods[] = {
115{nullptr}
116};
117
118std::string class_docstring =
119std::string("PolynomialCoefficient docstring\n");
120
121static 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
165const char* module_docstring =
166 "polynomial_coefficient module contains the PolynomialCoefficient class";
167
168static 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
180PyMODINIT_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
PyMODINIT_FUNC PyInit_polynomial_coefficient(void)
const char * module_docstring
void Initialise()
Definition Globals.cpp:50
struct PyPolynomialCoefficient::@055207143244216163206126060230133307334117036130 PyCoefficient
int _init(PyObject *self, PyObject *args, PyObject *kwds)
PyObject * _alloc(PyTypeObject *type, Py_ssize_t nitems)
void _free(PyCoefficient *self)
void _dealloc(PyCoefficient *self)
PyObject * _new(PyTypeObject *type, Py_ssize_t nitems)
PolynomialCoefficient represents a coefficient in a multi-dimensional polynomial.