Created
June 8, 2015 05:34
-
-
Save douglas-larocca/099bf7460d853abb7c17 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%%file _chi2.c | |
#include <Python.h> | |
#include <numpy/arrayobject.h> | |
#include "chi2.h" | |
static char module_docstring[] = | |
"This module provides an interface for calculating chi-squared using C."; | |
static char chi2_docstring[] = | |
"Calculate the chi-squared of some data given a model."; | |
static PyObject *chi2_chi2(PyObject *self, PyObject *args); | |
static PyMethodDef module_methods[] = { | |
{"chi2", chi2_chi2, METH_VARARGS, chi2_docstring}, | |
{NULL, NULL, 0, NULL} | |
}; | |
PyMODINIT_FUNC PyInit__chi2(void) | |
{ | |
PyObject *module; | |
static struct PyModuleDef moduledef = { | |
PyModuleDef_HEAD_INIT, | |
"_chi2", | |
module_docstring, | |
-1, | |
module_methods, | |
NULL, | |
NULL, | |
NULL, | |
NULL | |
}; | |
module = PyModule_Create(&moduledef); | |
if (!module) return NULL; | |
/* Load `numpy` functionality. */ | |
import_array(); | |
return module; | |
} | |
static PyObject *chi2_chi2(PyObject *self, PyObject *args) | |
{ | |
double m, b; | |
PyObject *x_obj, *y_obj, *yerr_obj; | |
/* Parse the input tuple */ | |
if (!PyArg_ParseTuple(args, "ddOOO", &m, &b, &x_obj, &y_obj, | |
&yerr_obj)) | |
return NULL; | |
/* Interpret the input objects as numpy arrays. */ | |
PyObject *x_array = PyArray_FROM_OTF(x_obj, NPY_DOUBLE, NPY_IN_ARRAY); | |
PyObject *y_array = PyArray_FROM_OTF(y_obj, NPY_DOUBLE, NPY_IN_ARRAY); | |
PyObject *yerr_array = PyArray_FROM_OTF(yerr_obj, NPY_DOUBLE, | |
NPY_IN_ARRAY); | |
/* If that didn't work, throw an exception. */ | |
if (x_array == NULL || y_array == NULL || yerr_array == NULL) { | |
Py_XDECREF(x_array); | |
Py_XDECREF(y_array); | |
Py_XDECREF(yerr_array); | |
return NULL; | |
} | |
/* How many data points are there? */ | |
int N = (int)PyArray_DIM(x_array, 0); | |
/* Get pointers to the data as C-types. */ | |
double *x = (double*)PyArray_DATA(x_array); | |
double *y = (double*)PyArray_DATA(y_array); | |
double *yerr = (double*)PyArray_DATA(yerr_array); | |
/* Call the external C function to compute the chi-squared. */ | |
double value = chi2(m, b, x, y, yerr, N); | |
/* Clean up. */ | |
Py_DECREF(x_array); | |
Py_DECREF(y_array); | |
Py_DECREF(yerr_array); | |
if (value < 0.0) { | |
PyErr_SetString(PyExc_RuntimeError, | |
"Chi-squared returned an impossible value."); | |
return NULL; | |
} | |
/* Build the output tuple */ | |
PyObject *ret = Py_BuildValue("d", value); | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment