Commit 6acabfbf authored by Purves, Murray's avatar Purves, Murray
Browse files

WIP Python bindings for interpolate module

parent 4ae1cbc4
Pipeline #27472 failed with stages
in 2 minutes and 15 seconds
......@@ -5,7 +5,8 @@
#ifndef RADIX_RADIXMATH_INTEPOLATE_HH_
#define RADIX_RADIXMATH_INTEPOLATE_HH_
#include "radixcore/visibility.hh"
#include "../../build/radix/radixcore/visibility.hh"
//#include "radixcore/visibility.hh"
#include <vector>
......
#include <Python.h>
#include <stdexcept>
#include <vector>
#include "../interpolate.hh"
//#include "radixmath/interpolate.hh"
/**
* Conversion from PyObject to double vector.
* Adapted from https://gist.github.com/rjzak/5681680
*/
std::vector<double> pyObjectToDoubleVector(PyObject* object)
{
std::vector<double> vector;
// Different conversion methods for list and tuple objects
if (PyTuple_Check(object))
{
for(Py_ssize_t i = 0; i < PyTuple_Size(object); ++i)
{
PyObject* value = PyTuple_GetItem(object, i);
vector.push_back(PyFloat_AsDouble(value));
}
}
else if (PyList_Check(object))
{
for(Py_ssize_t i = 0; i < PyList_Size(object); ++i)
{
PyObject* value = PyList_GetItem(object, i);
vector.push_back(PyFloat_AsDouble(value));
}
}
else
{
throw std::logic_error(
"Input PyObject was not a list or tuple - cannot convert");
}
return vector;
}
/**
* Conversion from double vector to PyObject list.
* Adapted from https://gist.github.com/rjzak/5681680
*/
PyObject* doubleVectorToListPyObject(const std::vector<double> &vector)
{
PyObject* list = PyList_New(vector.size());
if (!list)
{
throw std::logic_error("Unable to initialise Python list - cannot convert");
}
for(size_t i = 0; i < vector.size(); ++i)
{
PyObject* value = PyFloat_FromDouble(vector[i]);
if(!value)
{
Py_DECREF(list);
throw std::logic_error("Unable to convert list member - cannot convert");
}
PyList_SetItem(list, i, value);
}
return list;
}
static PyObject* interpolateValues(PyObject* self, PyObject* args)
{
PyObject* baseValuesObj;
PyObject* valuesToInterpObj;
bool circular;
double missingValue;
// Get the arguments from the call
if (!PyArg_ParseTuple(args, "OOpd", &baseValuesObj, &valuesToInterpObj,
&circular, &missingValue))
{
return NULL;
}
// Parse the vector arguments
std::vector<double> baseValuesVec = pyObjectToDoubleVector(baseValuesObj);
std::vector<double> valuesToInterpVec =
pyObjectToDoubleVector(valuesToInterpObj);
// Carry out the interpolation
std::vector<double> interpolatedValuesVec = radix::interpolateValues(
baseValuesVec, valuesToInterpVec, circular, missingValue
);
// Convert the result back into a Python object
PyObject* interpolatedValuesObj =
doubleVectorToListPyObject(interpolatedValuesVec);
return interpolatedValuesObj;
}
static PyMethodDef interpolate_methods[] = {
{"interpolateValues", interpolateValues, METH_VARARGS, "Interpolate/extrapolate missing values from a data vector"},
{NULL, NULL, 0, NULL},
};
static struct PyModuleDef interpolate_definition = {
PyModuleDef_HEAD_INIT,
"interpolate",
"Python bindings for radixmath/interpolate methods",
-1,
interpolate_methods,
};
PyMODINIT_FUNC PyInit_interpolate(void)
{
Py_Initialize();
PyObject* m = PyModule_Create(&interpolate_definition);
return m;
}
from distutils.core import setup, Extension
interpolate_module = Extension(
'interpolate',
sources=['interpolatemodule.cc'],
language='C++',
)
setup(
name='interpolate',
version='0.1.0',
description='Python module for radixmath/interpolate',
ext_modules=[interpolate_module],
)
import interpolate
missing_value = -9999.0
tolerance = 0.0001
circular = False
base_values = [10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0]
interp_values = [1.0, missing_value, 3.0, missing_value, 6.0, missing_value,
1.0]
expect_values = [1.0, 2.0, 3.0, 4.5, 6.0, 3.5, 1.0]
print("Base values: ", str(base_values))
print("Before interpolation: ", str(interp_values))
test_values = interpolate.interpolateValues(base_values, interp_values,
circular, missing_value)
print("After interpolation: ", str(interp_values))
print("Expected values: ", str(expect_values))
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment