natumpy 4.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
natumpy-4.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Eternals
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
natumpy-4.0.1/PKG-INFO ADDED
@@ -0,0 +1,9 @@
1
+ Metadata-Version: 2.4
2
+ Name: natumpy
3
+ Version: 4.0.1
4
+ Requires-Python: >=3.8
5
+ License-File: LICENSE
6
+ Requires-Dist: numpy>=1.20.0
7
+ Dynamic: license-file
8
+ Dynamic: requires-dist
9
+ Dynamic: requires-python
@@ -0,0 +1,215 @@
1
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
2
+ [![Python: 3.8+](https://img.shields.io/badge/python-3.8%2B-blue)](https://www.python.org/downloads/)
3
+ [![Architecture: Nawa](https://img.shields.io/badge/Architecture-Complex%20Valued-purple)]()
4
+
5
+ > **"Beyond Probability. Into Dynamics."**
6
+
7
+ **natumpy** is a high-performance C++ extension implementing the **Nawa Architecture**: a deterministic, complex-valued dynamical system designed for next-generation AI reasoning.
8
+
9
+ Unlike traditional neural networks that rely on statistical inference (matrix multiplication), Nawa models intelligence as **coupled oscillators** on a high-dimensional graph. It leverages **Symplectic Integration** (Hamiltonian Mechanics) to ensure energy conservation and reversible logic, and uses **Complex Numbers** to enable signal superposition and phase-dependent gating.
10
+
11
+ ---
12
+
13
+ ## Core Concepts
14
+
15
+ ### 1. The "Superposition" Hijack
16
+ Standard AI uses scalar values ($x$). Nawa uses **Complex State Vectors** ($z = r + i\theta$).
17
+ * **Real Component ($r$):** Represents Magnitude/Activation strength.
18
+ * **Imaginary Component ($\theta$):** Represents Phase/Timing.
19
+ * **Benefit:** Allows orthogonal information processing. Two signals can travel through the same node without corruption if their phases are orthogonal.
20
+
21
+ ### 2. Symplectic Integrator
22
+ We do not use simple Euler integration. Nawa employs a **Semi-Implicit Symplectic Solver**.
23
+ * **Stability:** Guarantees that the phase-space volume is preserved.
24
+ * **Reversibility:** The system logic can be reversed in time ($t \to -t$) to trace cause-and-effect.
25
+
26
+ ### 3. Struct of Arrays (SoA)
27
+ Optimized for modern CPU Cache and SIMD (Single Instruction, Multiple Data). Data is separated into contiguous memory blocks (`q_r`, `q_i`, `p_r`, `p_i`) ensuring maximum throughput during physics stepping.
28
+ # NATUMPY
29
+
30
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
31
+ [![Python Version](https://img.shields.io/badge/python-3.8%2B-blue)](https://www.python.org/downloads/)
32
+ [![Build Status](https://img.shields.io/badge/build-passing-brightgreen)]()
33
+
34
+ **natumpy** is a highly optimized C++ extension for Python, designed to facilitate efficient numerical field simulations and particle physics modeling. It leverages a C++17 core engine exposed through the Python C-API, providing direct memory access via NumPy without the overhead of data copying.
35
+
36
+ This library is engineered for production environments requiring low-latency physics stepping, thread safety, and seamless integration with the scientific Python ecosystem.
37
+
38
+ ---
39
+
40
+ ## Resources
41
+
42
+ - **Source Code**: [github.com/arclaav/natumpy](https://github.com/arclaav/natumpy)
43
+ - **Official Documentation**: [natumpy-docs.defacer.dedyn.io](http://natumpy-docs.defacer.dedyn.io)
44
+
45
+ ---
46
+
47
+ ## Key Features
48
+
49
+ * **High-Performance Core**: The simulation logic is implemented entirely in C++17 (`natcore`), utilizing optimized memory structures and loop unrolling where applicable.
50
+ * **Zero-Copy NumPy Integration**: Implements the Python Buffer Protocol. The internal state of the C++ engine is directly accessible as a NumPy structured array (`float64`).
51
+ * **Thread Safety & Concurrency**: Critical sections are protected by `std::mutex`. Computationally intensive methods (e.g., `step`) release the Python Global Interpreter Lock (GIL), allowing for true multi-threaded execution.
52
+ * **Robust Physics Engine**: Built-in support for damping, target-seeking behavior, and coupled resonance dynamics.
53
+ >>>>>>> 2ab1e845db617a91ec8da8e83bf2d6945013c182
54
+
55
+ ---
56
+
57
+ ## Installation
58
+
59
+ ### Prerequisites
60
+ <<<<<<< HEAD
61
+ * Python 3.8+
62
+ * C++17 Compliant Compiler (GCC, Clang, MSVC)
63
+ * NumPy $\ge$ 1.20.0
64
+
65
+ ### Build from Source
66
+ =======
67
+ * Python 3.8 or higher
68
+ * A C++17 compliant compiler (GCC, Clang, or MSVC)
69
+ * NumPy $\ge$ 1.20.0
70
+
71
+ ### Building from Source
72
+
73
+ To install the latest version directly from the repository:
74
+
75
+ >>>>>>> 2ab1e845db617a91ec8da8e83bf2d6945013c182
76
+ ```
77
+ git clone https://github.com/arclaav/natumpy.git
78
+ cd natumpy
79
+ pip install .
80
+ ```
81
+ <<<<<<< HEAD
82
+
83
+ # Usage Guide
84
+ 1. Initialization & Memory View
85
+ Nawa exposes its internal C++ memory directly to Python via the Buffer Protocol. Zero-Copy.
86
+ =======
87
+ For development environments (editable install):
88
+ ```
89
+ pip install -e .
90
+ ```
91
+
92
+ ## Usage Guide
93
+ 1. Initialization and Data Views
94
+ Initialize a field engine and access its memory directly via NumPy.
95
+ >>>>>>> 2ab1e845db617a91ec8da8e83bf2d6945013c182
96
+ ```
97
+ import natumpy
98
+ import numpy as np
99
+
100
+ <<<<<<< HEAD
101
+ # Initialize the Nawa Engine with 1,000 nodes
102
+ # This allocates aligned memory for Real/Imaginary states
103
+ engine = natumpy.NawaEngine(1000)
104
+
105
+ # Access the raw memory views (Modifying these updates the C++ engine instantly)
106
+ # q_r = Position (Real), q_i = Position (Imaginary/Phase)
107
+ q_real = engine.q_r
108
+ q_imag = engine.q_i
109
+
110
+ # Initialize a specific state (e.g., Node 0)
111
+ # Set Magnitude to 1.0, Phase to 0.0
112
+ q_real[0] = 1.0
113
+ q_imag[0] = 0.0
114
+
115
+ 2. Wiring the Topology
116
+ Connect nodes to create logic gates or resonant pathways.
117
+ # connect(source, destination, weight, type)
118
+ # Type 0: Standard Coupling (Spring-like)
119
+ # Type 2: Phase Coupling (Resonance-only)
120
+
121
+ # Connect Node 0 to Node 1 with Phase Resonance
122
+ engine.connect(0, 1, weight=0.5, type=2)
123
+
124
+ 3. Running the Dynamics
125
+ Advance the Hamiltonian system.
126
+ # Run 100 physics cycles
127
+ engine.step(100)
128
+
129
+ # Observe the result
130
+ ## Did the signal propagate? Did the phase shift?
131
+ print(f"Node 1 State: {q_real[1]:.4f} + {q_imag[1]:.4f}j")
132
+ ```
133
+
134
+ # Stability & Unitary Constraints
135
+ Because Nawa operates on continuous physics, numerical drift (floating-point errors) is a reality. The engine includes a mechanism to mitigate this:
136
+ Unitary Constraint (enforce_unitary_constraints):
137
+ If enabled, the engine normalizes the magnitude of the complex vector at each step (|z| \to 1.0), ensuring that information is stored purely in the Phase. This prevents "exploding gradients" or signal decay in long-running simulations.
138
+ # API Reference
139
+ natumpy.NawaEngine(size: int)
140
+ Creates a new simulation context.
141
+ Methods
142
+ | Method | Description |
143
+ |---|---|
144
+ | step(cycles: int) | Advances the symplectic integrator. Releases GIL for threading. |
145
+ | connect(u, v, w, type) | Creates a directed edge from node u to v. |
146
+ | set_node_state(...) | Atomic setter for q_r, q_i, p_r, p_i. |
147
+ | enforce_unitary_constraints() | Manually triggers normalization to fix numerical drift. |
148
+ Properties (NumPy Arrays)
149
+ | Property | Type | Physics Meaning |
150
+ |---|---|---|
151
+ | q_r | float64[] | Generalized Coordinate (Real Part) |
152
+ | q_i | float64[] | Generalized Coordinate (Imaginary Part) |
153
+ | p_r | float64[] | Conjugate Momentum (Real Part) |
154
+ | p_i | float64[] | Conjugate Momentum (Imaginary Part) |
155
+ | mass | float64[] | Inertial Coefficient |
156
+ ng | float64 | Damping factor (0.0 - 1.0). |
157
+ =======
158
+ # Initialize a field with 1,000,000 atoms
159
+ field = natumpy.create_field(1_000_000)
160
+
161
+ # Create a zero-copy view of the data
162
+ # Modifying 'data' instantly updates the C++ engine state
163
+ data = natumpy.view(field)
164
+
165
+ # Access specific properties (Structured Array)
166
+ # Fields: 'value', 'velocity', 'mass', 'damping', 'target'
167
+ print(f"Initial Mass: {data['mass'][0]}")
168
+
169
+ 2. Configuring Physics Properties
170
+ You can modify atom properties using vector operations (via NumPy) or atomic operations (via the C++ API).
171
+ # Bulk update via NumPy (Fastest for large updates)
172
+ data['mass'][:] = 2.5
173
+ data['damping'][:] = 0.05
174
+
175
+ # Atomic update via C++ API (Thread-safe)
176
+ # Syntax: set_props(field, index, mass, damping)
177
+ natumpy.NatField.set_props(field, 0, 5.0, 0.1)
178
+
179
+ # Set a target value for an atom to seek
180
+ natumpy.NatField.set_target(field, 0, 100.0)
181
+
182
+ 3. Running the Simulation
183
+ The step function advances the physics engine. This operation releases the GIL, making it suitable for background threads.
184
+ # Run 100 physics cycles with a delta-time (dt) of 0.01
185
+ natumpy.NatField.step(field, cycles=100, dt=0.01)
186
+
187
+ # Check the new state
188
+ print(f"New Value: {data['value'][0]}")
189
+
190
+ 4. Advanced Dynamics: Resonance
191
+ Couple two atoms together to simulate force transfer or resonance.
192
+ # Couple atom at index 0 and atom at index 1 with coupling strength 0.5
193
+ natumpy.NatField.resonate(field, 0, 1, 0.5)
194
+ ```
195
+
196
+ ## API Reference
197
+ natumpy.NatField Methods
198
+ | Method | Signature | Description |
199
+ |---|---|---|
200
+ | set_props | (index: int, mass: float, damping: float) | Sets physical properties for a specific atom. |
201
+ | set_target | (index: int, target: float) | Sets the target value an atom attracts towards. |
202
+ | step | (cycles: int, dt: float) | Advances the simulation. Releases GIL. |
203
+ | resonate | (idx_a: int, idx_b: int, strength: float) | Applies interaction force between two atoms. |
204
+ | force | (index: int, value: float) | Hard-resets an atom's value and clears velocity. |
205
+ | size | () | Returns the number of atoms in the field. |
206
+ Data Structure (NAT_DTYPE)
207
+ The NumPy view exposes the following structured data type:
208
+ | Field | Type | Description |
209
+ |---|---|---|
210
+ | value | float64 | Current position/value of the atom. |
211
+ | velocity | float64 | Current rate of change. |
212
+ | mass | float64 | Mass coefficient (affects inertia). |
213
+ | damping | float64 | Damping factor (0.0 - 1.0). |
214
+ >>>>>>> 2ab1e845db617a91ec8da8e83bf2d6945013c182
215
+ | target | float64 | The equilibrium point for the atom. |
@@ -0,0 +1,13 @@
1
+ import numpy as np
2
+ from . import natcore
3
+
4
+ NawaEngine = natcore.NawaEngine
5
+
6
+ def create_engine(size):
7
+ return NawaEngine(int(size))
8
+
9
+ def get_state_complex(engine):
10
+ real = engine.q_r
11
+ imag = engine.q_i
12
+ return real + 1j * imag
13
+
@@ -0,0 +1,127 @@
1
+ #define PY_SSIZE_T_CLEAN
2
+ #include <Python.h>
3
+ #include "nat_engine.hpp"
4
+
5
+ #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
6
+ #include <numpy/arrayobject.h>
7
+
8
+ typedef struct {
9
+ PyObject_HEAD
10
+ NawaEngine* engine;
11
+ } PyNawa;
12
+
13
+ static void PyNawa_dealloc(PyNawa* self) {
14
+ if (self->engine) {
15
+ delete self->engine;
16
+ }
17
+ Py_TYPE(self)->tp_free((PyObject*)self);
18
+ }
19
+
20
+ static PyObject* PyNawa_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
21
+ PyNawa* self;
22
+ self = (PyNawa*)type->tp_alloc(type, 0);
23
+ if (self != NULL) {
24
+ int size = 100;
25
+ if (!PyArg_ParseTuple(args, "|i", &size)) {
26
+ Py_DECREF(self);
27
+ return NULL;
28
+ }
29
+ self->engine = new NawaEngine((size_t)size);
30
+ }
31
+ return (PyObject*)self;
32
+ }
33
+
34
+ static PyObject* PyNawa_step(PyNawa* self, PyObject* args) {
35
+ int cycles;
36
+ if (!PyArg_ParseTuple(args, "i", &cycles)) return NULL;
37
+
38
+ Py_BEGIN_ALLOW_THREADS
39
+ self->engine->step(cycles);
40
+ Py_END_ALLOW_THREADS
41
+
42
+ Py_RETURN_NONE;
43
+ }
44
+
45
+ static PyObject* PyNawa_connect(PyNawa* self, PyObject* args) {
46
+ int u, v, type;
47
+ double w;
48
+ if (!PyArg_ParseTuple(args, "iidi", &u, &v, &w, &type)) return NULL;
49
+
50
+ self->engine->connect(u, v, w, type);
51
+ Py_RETURN_NONE;
52
+ }
53
+
54
+ static PyObject* get_array_view(NawaEngine* engine, std::vector<double>& vec) {
55
+ npy_intp dims[1] = { (npy_intp)vec.size() };
56
+ return PyArray_SimpleNewFromData(1, dims, NPY_DOUBLE, vec.data());
57
+ }
58
+
59
+ static PyObject* PyNawa_get_qr(PyNawa* self, void* closure) {
60
+ return get_array_view(self->engine, self->engine->state.q_r);
61
+ }
62
+
63
+ static PyObject* PyNawa_get_qi(PyNawa* self, void* closure) {
64
+ return get_array_view(self->engine, self->engine->state.q_i);
65
+ }
66
+
67
+ static PyObject* PyNawa_get_pr(PyNawa* self, void* closure) {
68
+ return get_array_view(self->engine, self->engine->state.p_r);
69
+ }
70
+
71
+ static PyObject* PyNawa_get_pi(PyNawa* self, void* closure) {
72
+ return get_array_view(self->engine, self->engine->state.p_i);
73
+ }
74
+
75
+ static PyMethodDef PyNawa_methods[] = {
76
+ {"step", (PyCFunction)PyNawa_step, METH_VARARGS, ""},
77
+ {"connect", (PyCFunction)PyNawa_connect, METH_VARARGS, ""},
78
+ {NULL}
79
+ };
80
+
81
+ static PyGetSetDef PyNawa_getset[] = {
82
+ {"q_r", (getter)PyNawa_get_qr, NULL, "", NULL},
83
+ {"q_i", (getter)PyNawa_get_qi, NULL, "", NULL},
84
+ {"p_r", (getter)PyNawa_get_pr, NULL, "", NULL},
85
+ {"p_i", (getter)PyNawa_get_pi, NULL, "", NULL},
86
+ {NULL}
87
+ };
88
+
89
+ static PyTypeObject PyNawaType = {
90
+ PyVarObject_HEAD_INIT(NULL, 0)
91
+ .tp_name = "natcore.NawaEngine",
92
+ .tp_basicsize = sizeof(PyNawa),
93
+ .tp_itemsize = 0,
94
+ .tp_dealloc = (destructor)PyNawa_dealloc,
95
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
96
+ .tp_methods = PyNawa_methods,
97
+ .tp_getset = PyNawa_getset,
98
+ .tp_new = PyNawa_new,
99
+ };
100
+
101
+ static struct PyModuleDef natcoremodule = {
102
+ PyModuleDef_HEAD_INIT,
103
+ "natcore",
104
+ NULL,
105
+ -1,
106
+ NULL
107
+ };
108
+
109
+ PyMODINIT_FUNC PyInit_natcore(void) {
110
+ import_array();
111
+ PyObject* m;
112
+
113
+ if (PyType_Ready(&PyNawaType) < 0) return NULL;
114
+
115
+ m = PyModule_Create(&natcoremodule);
116
+ if (m == NULL) return NULL;
117
+
118
+ Py_INCREF(&PyNawaType);
119
+ if (PyModule_AddObject(m, "NawaEngine", (PyObject*)&PyNawaType) < 0) {
120
+ Py_DECREF(&PyNawaType);
121
+ Py_DECREF(m);
122
+ return NULL;
123
+ }
124
+
125
+ return m;
126
+ }
127
+
@@ -0,0 +1,89 @@
1
+ #include "nat_engine.hpp"
2
+
3
+ void NawaEngine::set_node_state(int idx, Scalar qr, Scalar qi, Scalar pr, Scalar pi) {
4
+ if (idx >= 0 && idx < (int)state.size) {
5
+ state.q_r[idx] = qr;
6
+ state.q_i[idx] = qi;
7
+ state.p_r[idx] = pr;
8
+ state.p_i[idx] = pi;
9
+ }
10
+ }
11
+
12
+ void NawaEngine::connect(int src, int dst, Scalar weight, int type) {
13
+ if (src >= 0 && src < (int)state.size && dst >= 0 && dst < (int)state.size) {
14
+ topology.add_connection(src, dst, weight, type);
15
+ }
16
+ }
17
+
18
+ void NawaEngine::enforce_unitary_constraints() {
19
+ for (size_t i = 0; i < state.size; ++i) {
20
+ Scalar mag_sq = state.q_r[i] * state.q_r[i] + state.q_i[i] * state.q_i[i];
21
+ if (mag_sq > 1.0) {
22
+ Scalar scale = 1.0 / std::sqrt(mag_sq);
23
+ state.q_r[i] *= scale;
24
+ state.q_i[i] *= scale;
25
+ state.p_r[i] *= 0.5;
26
+ state.p_i[i] *= 0.5;
27
+ }
28
+ }
29
+ }
30
+
31
+ void NawaEngine::compute_forces(std::vector<Scalar>& force_r, std::vector<Scalar>& force_i) {
32
+ std::fill(force_r.begin(), force_r.end(), 0.0);
33
+ std::fill(force_i.begin(), force_i.end(), 0.0);
34
+
35
+ for (const auto& edge : topology.edges) {
36
+ int u = edge.src_idx;
37
+ int v = edge.dst_idx;
38
+ Scalar w = edge.weight;
39
+
40
+ Scalar dr = state.q_r[v] - state.q_r[u];
41
+ Scalar di = state.q_i[v] - state.q_i[u];
42
+
43
+ if (edge.type == 2) {
44
+ Scalar dot = state.q_r[u] * state.q_r[v] + state.q_i[u] * state.q_i[v];
45
+ Scalar phase_force = (1.0 - dot) * config.phase_coupling;
46
+
47
+ force_r[u] += phase_force * state.q_r[v];
48
+ force_i[u] += phase_force * state.q_i[v];
49
+ force_r[v] -= phase_force * state.q_r[u];
50
+ force_i[v] -= phase_force * state.q_i[u];
51
+ } else {
52
+ force_r[u] += w * dr;
53
+ force_i[u] += w * di;
54
+
55
+ force_r[v] -= w * dr;
56
+ force_i[v] -= w * di;
57
+ }
58
+ }
59
+ }
60
+
61
+ void NawaEngine::step(int cycles) {
62
+ size_t n = state.size;
63
+ std::vector<Scalar> fr(n, 0.0);
64
+ std::vector<Scalar> fi(n, 0.0);
65
+ Scalar dt = config.dt;
66
+ Scalar damping_factor = 1.0 - config.global_damping;
67
+
68
+ for (int k = 0; k < cycles; ++k) {
69
+ compute_forces(fr, fi);
70
+
71
+ for (size_t i = 0; i < n; ++i) {
72
+ Scalar inv_m = 1.0 / state.mass[i];
73
+
74
+ state.p_r[i] += fr[i] * dt;
75
+ state.p_i[i] += fi[i] * dt;
76
+
77
+ state.p_r[i] *= damping_factor;
78
+ state.p_i[i] *= damping_factor;
79
+
80
+ state.q_r[i] += (state.p_r[i] * inv_m) * dt;
81
+ state.q_i[i] += (state.p_i[i] * inv_m) * dt;
82
+ }
83
+
84
+ if (config.normalize_phase) {
85
+ enforce_unitary_constraints();
86
+ }
87
+ }
88
+ }
89
+
@@ -0,0 +1,77 @@
1
+ #pragma once
2
+
3
+ #include <vector>
4
+ #include <cmath>
5
+ #include <complex>
6
+ #include <algorithm>
7
+ #include <iostream>
8
+
9
+ using Scalar = double;
10
+
11
+ struct NawaConfig {
12
+ Scalar dt = 0.01;
13
+ Scalar global_damping = 0.05;
14
+ Scalar phase_coupling = 0.1;
15
+ bool normalize_phase = true;
16
+ };
17
+
18
+ struct NawaState {
19
+ size_t size = 0;
20
+
21
+ std::vector<Scalar> q_r;
22
+ std::vector<Scalar> q_i;
23
+
24
+ std::vector<Scalar> p_r;
25
+ std::vector<Scalar> p_i;
26
+
27
+ std::vector<Scalar> mass;
28
+
29
+ void resize(size_t n) {
30
+ size = n;
31
+ q_r.resize(n, 0.0); q_i.resize(n, 0.0);
32
+ p_r.resize(n, 0.0); p_i.resize(n, 0.0);
33
+ mass.resize(n, 1.0);
34
+ }
35
+ };
36
+
37
+ struct NawaEdge {
38
+ int src_idx;
39
+ int dst_idx;
40
+ Scalar weight;
41
+ int type;
42
+ };
43
+
44
+ struct NawaTopology {
45
+ std::vector<NawaEdge> edges;
46
+
47
+ void add_connection(int u, int v, Scalar w, int t) {
48
+ edges.push_back({u, v, w, t});
49
+ }
50
+
51
+ void clear() { edges.clear(); }
52
+ };
53
+
54
+ class NawaEngine {
55
+ public:
56
+ NawaConfig config;
57
+ NawaState state;
58
+ NawaTopology topology;
59
+
60
+ NawaEngine(size_t initial_size) {
61
+ state.resize(initial_size);
62
+ }
63
+
64
+ void step(int cycles);
65
+
66
+ void set_node_state(int idx, Scalar qr, Scalar qi, Scalar pr, Scalar pi);
67
+
68
+ void connect(int src, int dst, Scalar weight, int type);
69
+
70
+ size_t size() const { return state.size; }
71
+
72
+ void enforce_unitary_constraints();
73
+
74
+ private:
75
+ void compute_forces(std::vector<Scalar>& force_r, std::vector<Scalar>& force_i);
76
+ };
77
+
@@ -0,0 +1,9 @@
1
+ Metadata-Version: 2.4
2
+ Name: natumpy
3
+ Version: 4.0.1
4
+ Requires-Python: >=3.8
5
+ License-File: LICENSE
6
+ Requires-Dist: numpy>=1.20.0
7
+ Dynamic: license-file
8
+ Dynamic: requires-dist
9
+ Dynamic: requires-python
@@ -0,0 +1,13 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ setup.py
5
+ natumpy/__init__.py
6
+ natumpy/nat_bindings.cpp
7
+ natumpy/nat_engine.cpp
8
+ natumpy/nat_engine.hpp
9
+ natumpy.egg-info/PKG-INFO
10
+ natumpy.egg-info/SOURCES.txt
11
+ natumpy.egg-info/dependency_links.txt
12
+ natumpy.egg-info/requires.txt
13
+ natumpy.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ numpy>=1.20.0
@@ -0,0 +1 @@
1
+ natumpy
@@ -0,0 +1,4 @@
1
+ [build-system]
2
+ requires = ["setuptools>=42", "wheel", "numpy>=1.20.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
natumpy-4.0.1/setup.py ADDED
@@ -0,0 +1,34 @@
1
+ from setuptools import setup, Extension, find_packages
2
+ import sys
3
+
4
+ try:
5
+ import numpy
6
+ np_include = [numpy.get_include()]
7
+ except ImportError:
8
+ np_include = []
9
+
10
+ extra_compile_args = ['-std=c++17', '-O3', '-Wall']
11
+
12
+ if sys.platform == 'darwin':
13
+ extra_compile_args.append('-stdlib=libc++')
14
+
15
+ module = Extension(
16
+ 'natumpy.natcore',
17
+ sources=[
18
+ 'natumpy/nat_bindings.cpp',
19
+ 'natumpy/nat_engine.cpp'
20
+ ],
21
+ depends=['natumpy/nat_engine.hpp'],
22
+ include_dirs=np_include,
23
+ extra_compile_args=extra_compile_args,
24
+ language='c++'
25
+ )
26
+
27
+ setup(
28
+ name='natumpy',
29
+ version='4.0.1',
30
+ packages=find_packages(),
31
+ ext_modules=[module],
32
+ python_requires='>=3.8',
33
+ install_requires=['numpy>=1.20.0'],
34
+ )