diff --git a/SparseDiffEngine b/SparseDiffEngine index 1334e80..6612747 160000 --- a/SparseDiffEngine +++ b/SparseDiffEngine @@ -1 +1 @@ -Subproject commit 1334e802a899f9e795aedc01cbf188810382b50c +Subproject commit 6612747632675f556dc627bbc3a57a3904418a39 diff --git a/sparsediffpy/_bindings/atoms/atan2.h b/sparsediffpy/_bindings/atoms/atan2.h new file mode 100644 index 0000000..77ed409 --- /dev/null +++ b/sparsediffpy/_bindings/atoms/atan2.h @@ -0,0 +1,35 @@ +#ifndef ATOM_ATAN2_H +#define ATOM_ATAN2_H + +#include "bivariate_restricted_dom.h" +#include "common.h" + +/* atan2(y, x), C argument order. Both arguments must be distinct variables of + the same shape; the engine returns NULL otherwise. */ +static PyObject *py_make_atan2(PyObject *self, PyObject *args) +{ + PyObject *y_capsule; + PyObject *x_capsule; + if (!PyArg_ParseTuple(args, "OO", &y_capsule, &x_capsule)) + { + return NULL; + } + expr *y = (expr *) PyCapsule_GetPointer(y_capsule, EXPR_CAPSULE_NAME); + expr *x = (expr *) PyCapsule_GetPointer(x_capsule, EXPR_CAPSULE_NAME); + if (!y || !x) + { + PyErr_SetString(PyExc_ValueError, "invalid child capsule"); + return NULL; + } + + expr *node = new_atan2(y, x); + if (!node) + { + PyErr_SetString(PyExc_RuntimeError, "failed to create atan2 node"); + return NULL; + } + expr_retain(node); /* Capsule owns a reference */ + return PyCapsule_New(node, EXPR_CAPSULE_NAME, expr_capsule_destructor); +} + +#endif /* ATOM_ATAN2_H */ diff --git a/sparsediffpy/_bindings/bindings.c b/sparsediffpy/_bindings/bindings.c index 3244d33..a3ee501 100644 --- a/sparsediffpy/_bindings/bindings.c +++ b/sparsediffpy/_bindings/bindings.c @@ -6,6 +6,7 @@ #include "atoms/add.h" #include "atoms/asinh.h" #include "atoms/atan.h" +#include "atoms/atan2.h" #include "atoms/atanh.h" #include "atoms/broadcast.h" #include "atoms/convolve.h" @@ -121,6 +122,8 @@ static PyMethodDef DNLPMethods[] = { {"make_tanh", py_make_tanh, METH_VARARGS, "Create tanh node"}, {"make_asinh", py_make_asinh, METH_VARARGS, "Create asinh node"}, {"make_atan", py_make_atan, METH_VARARGS, "Create atan node"}, + {"make_atan2", py_make_atan2, METH_VARARGS, + "Create atan2 node: atan2(y, x), both arguments must be variables"}, {"make_atanh", py_make_atanh, METH_VARARGS, "Create atanh node"}, {"make_upper_tri", py_make_upper_tri, METH_VARARGS, "Create upper_tri node"}, {"make_broadcast", py_make_broadcast, METH_VARARGS, "Create broadcast node"},