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
20#include <cstdlib>
21#include <vector>
22
24#include "PyOpal/Globals.h"
25#include "PyOpal/PyPolynomialCoefficient.h"
26
28/*
29 PolynomialCoefficient(std::vector<int> inVariablesByVector,
30 int outVariable,
31 double coefficient)
32*/
33int _init(PyObject* self, PyObject *args, PyObject *kwds) {
34 PyCoefficient* py_coeff = reinterpret_cast<PyCoefficient*>(self);
35 // failed to cast or self was not initialised - something horrible happened
36 if (py_coeff == nullptr) {
37 PyErr_SetString(PyExc_TypeError,
38 "Failed to resolve self as PolynomialCoefficient in __init__");
39 return -1;
40 }
41 // legal python to call initialised_object.__init__() to reinitialise, so
42 // handle this case
43 if (py_coeff->coeff != nullptr) {
44 delete py_coeff->coeff;
45 py_coeff->coeff = nullptr;
46 }
47 // read in arguments
48
49 PyObject* py_index;
50 int value_axis;
51 double coefficient;
52 static char *kwlist[] = {const_cast<char*>("index_by_vector"),
53 const_cast<char*>("output_axis"),
54 const_cast<char*>("coefficient_value"),
55 nullptr};
56 if (!PyArg_ParseTupleAndKeywords(args, kwds, "Oid", kwlist,
57 &py_index, &value_axis, &coefficient)) {
58 return -1;
59 }
60
61 // convert from list to std::vector<int>
62 // first check validity of coefficients
63 if (!PyList_Check(py_index)) {
64 PyErr_SetString(PyExc_TypeError,
65 "Failed to resolve index as a list");
66 return -1;
67 }
68 size_t list_size = PyList_Size(py_index); // nb: size 0 is legal
69 std::vector<int> index(list_size);
70 // now loop over the rows
71 for (size_t i = 0; i < list_size; ++i) {
72 PyObject* py_value = PyList_GetItem(py_index, i);
73 index[i] = int(PyLong_AsLong(py_value));
74 if (PyErr_Occurred() != nullptr) { // not an int
75 return -1;
76 }
77 }
78 // now initialise the internal coeff
79 try {
80 py_coeff->coeff = new interpolation::PolynomialCoefficient(index, value_axis, coefficient);
81 } catch (std::exception& exc) {
82 PyErr_SetString(PyExc_RuntimeError, (&exc)->what());
83 return -1;
84 }
85 return 0;
86}
87
88PyObject *_alloc(PyTypeObject *type, Py_ssize_t nitems) {
89 void* void_coeff = std::malloc(sizeof(PyCoefficient));
90 PyCoefficient* coeff = reinterpret_cast<PyCoefficient*>(void_coeff);
91 coeff->coeff = nullptr;
92 Py_REFCNT(coeff) = 1;
93 Py_TYPE(coeff) = type;
94 return reinterpret_cast<PyObject*>(coeff);
95}
96
97PyObject *_new(PyTypeObject *type, Py_ssize_t nitems) {
98 return _alloc(type, nitems);
99}
100
101void _free(PyCoefficient * self) {
102 if (self != nullptr) {
103 if (self->coeff != nullptr)
104 delete self->coeff;
105 free(self);
106 }
107}
108
110 _free(self);
111}
112
113static PyMemberDef _members[] = {
114{nullptr}
115};
116
117static PyMethodDef _methods[] = {
118{nullptr}
119};
120
121std::string class_docstring =
122std::string("PolynomialCoefficient docstring\n");
123
124static PyTypeObject PyCoefficientType = {
125 PyObject_HEAD_INIT(nullptr)
126 "polynomial_coefficient.PolynomialCoefficient", /*tp_name*/
127 sizeof(PyCoefficient), /*tp_basicsize*/
128 0, /*tp_itemsize*/
129 (destructor)_dealloc, /*tp_dealloc*/
130 0, /*tp_print*/
131 0, /*tp_getattr*/
132 0, /*tp_setattr*/
133 0, /*tp_compare*/
134 0, /*tp_repr*/
135 0, /*tp_as_number*/
136 0, /*tp_as_sequence*/
137 0, /*tp_as_mapping*/
138 0, /*tp_hash */
139 0, /*tp_call*/
140 0, /*tp_str*/
141 0, /*tp_getattro*/
142 0, /*tp_setattro*/
143 0, /*tp_as_buffer*/
144 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
145 class_docstring.c_str(), /* tp_doc */
146 0, /* tp_traverse */
147 0, /* tp_clear */
148 0, /* tp_richcompare */
149 0, /* tp_weaklistoffset */
150 0, /* tp_iter */
151 0, /* tp_iternext */
152 _methods, /* tp_methods */
153 _members, /* tp_members */
154 0, /* tp_getset */
155 0, /* tp_base */
156 0, /* tp_dict */
157 0, /* tp_descr_get */
158 0, /* tp_descr_set */
159 0, /* tp_dictoffset */
160 (initproc)_init, /* tp_init */
161 (allocfunc)_alloc, /* tp_alloc, called by new */
162 0, // (newfunc)_new, /* tp_new */
163 (freefunc)_free, /* tp_free, called by dealloc */
164};
165
166} // namespace PyPolynomialCoefficient
167
168const char* module_docstring =
169 "polynomial_coefficient module contains the PolynomialCoefficient class";
170
171static struct PyModuleDef polynomial_coefficient_def = {
172 PyModuleDef_HEAD_INIT,
173 "polynomial_coefficient", /* m_name */
174 module_docstring, /* m_doc */
175 -1, /* m_size */
176 nullptr, /* m_methods */
177 nullptr, /* m_reload */
178 nullptr, /* m_traverse */
179 nullptr, /* m_clear */
180 nullptr, /* m_free */
181};
182
183PyMODINIT_FUNC PyInit_polynomial_coefficient(void) {
185 PyPolynomialCoefficient::PyCoefficientType.tp_new = PyType_GenericNew;
186 if (PyType_Ready(&PyPolynomialCoefficient::PyCoefficientType) < 0)
187 return nullptr;
188
189 PyObject* module = PyModule_Create(&polynomial_coefficient_def);
190 if (module == nullptr)
191 return nullptr;
192
193 PyTypeObject* polynomial_coeff_type =
194 &PyPolynomialCoefficient::PyCoefficientType;
195 Py_INCREF(polynomial_coeff_type);
196 PyModule_AddObject(module, "PolynomialCoefficient",
197 reinterpret_cast<PyObject*>(polynomial_coeff_type));
198 return module;
199}
PyMODINIT_FUNC PyInit_polynomial_coefficient(void)
const char * module_docstring
void Initialise()
Definition Globals.cpp:50
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.
interpolation::PolynomialCoefficient * coeff