From 673d0bf7217a593214dd6b1f21b0eeb02ef77dda Mon Sep 17 00:00:00 2001 From: dance858 Date: Wed, 7 Oct 2026 19:27:54 +0200 Subject: [PATCH 1/2] Add make_atan2 binding for the engine's leaf-only atan2 atom atan2(y, x), C argument order, both arguments must be distinct variables of the same shape; a NULL from new_atan2 becomes a RuntimeError. Requires SparseDifferentiation/SparseDiffEngine#133; the submodule pointer is bumped once that lands on engine main. Co-Authored-By: Claude Fable 5.1 --- sparsediffpy/_bindings/atoms/atan2.h | 35 ++++++++++++++++++++++++++++ sparsediffpy/_bindings/bindings.c | 3 +++ 2 files changed, 38 insertions(+) create mode 100644 sparsediffpy/_bindings/atoms/atan2.h 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"}, From 3eba08a077abd7958a3e4982b56a2eb6129f8826 Mon Sep 17 00:00:00 2001 From: dance858 Date: Thu, 8 Oct 2026 08:36:00 +0200 Subject: [PATCH 2/2] Bump SparseDiffEngine to 6612747 (atan2 atom, #133) Co-Authored-By: Claude Fable 5.1 --- SparseDiffEngine | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SparseDiffEngine b/SparseDiffEngine index 1334e80..6612747 160000 --- a/SparseDiffEngine +++ b/SparseDiffEngine @@ -1 +1 @@ -Subproject commit 1334e802a899f9e795aedc01cbf188810382b50c +Subproject commit 6612747632675f556dc627bbc3a57a3904418a39