The FEEN REST API provides HTTP access to the FEEN Wave Engine's resonator network with global node access. This allows you to create, manage, and interact with phononic resonator networks over HTTP.
- Build FEEN with Python bindings:
cd build
cmake .. -DFEEN_BUILD_PYTHON=ON
make- Install Python dependencies:
cd ../python
pip install -r requirements.txt- Start the REST API server:
python3 feen_rest_api.pyThe server will start on http://localhost:5000 by default.
python3 feen_rest_api.py --help
Options:
--host HOST Host to bind to (default: 127.0.0.1 for localhost only)
--port PORT Port to bind to (default: 5000)
--debug Enable debug modeExample:
# Start on localhost (default, secure)
python3 feen_rest_api.py
# Bind to all interfaces (use with caution)
python3 feen_rest_api.py --host 0.0.0.0 --port 8080 --debugGET /api/health
Check if the API is running.
Response:
{
"status": "ok",
"service": "FEEN REST API"
}GET /api/network/status
Get the current network status.
Response:
{
"num_nodes": 3,
"time": 0.001,
"ticks": 1000
}GET /api/network/nodes
Get a list of all resonator nodes in the network.
Response:
{
"nodes": [
{
"id": 0,
"name": "osc_1kHz",
"x": 0.367879,
"v": -2309.45,
"t": 0.001,
"energy": 0.135,
"snr": 982345.2
}
],
"count": 1
}POST /api/network/nodes
Add a new resonator node to the network.
Request Body:
{
"frequency_hz": 1000.0,
"q_factor": 200.0,
"beta": 1e-4,
"name": "my_resonator"
}Parameters:
frequency_hz(required): Natural frequency in Hzq_factor(required): Quality factorbeta(required): Nonlinearity coefficient (positive = monostable, negative = bistable)name(optional): Human-readable name
Response:
{
"id": 0,
"message": "Node added successfully",
"state": {
"id": 0,
"name": "my_resonator",
"x": 0.0,
"v": 0.0,
"t": 0.0,
"energy": 0.0,
"snr": 0.0
}
}GET /api/network/nodes/{id}
Get the state of a specific node.
Response:
{
"id": 0,
"name": "my_resonator",
"x": 0.367879,
"v": -2309.45,
"t": 0.001,
"energy": 0.135,
"snr": 982345.2
}State Fields:
x: Displacement from equilibrium (m)v: Velocity (m/s)t: Current time (s)energy: Total mechanical energy (J)snr: Signal-to-noise ratio
POST /api/network/nodes/{id}/inject
Inject a signal into a specific node.
Request Body:
{
"amplitude": 1.0,
"phase": 0.0
}Parameters:
amplitude(optional, default: 1.0): Signal amplitudephase(optional, default: 0.0): Signal phase in radians
Response:
{
"message": "Signal injected into node 0",
"state": {
"id": 0,
"name": "my_resonator",
"x": 1.0,
"v": 0.0,
"t": 0.0,
"energy": 0.5,
"snr": 36347.2
}
}POST /api/network/tick
Evolve the entire network by one or more timesteps.
Request Body:
{
"dt": 1e-6,
"steps": 1000
}Parameters:
dt(optional, default: 1e-6): Timestep in secondssteps(optional, default: 1): Number of steps to evolve
Response:
{
"message": "Network evolved by 1000 steps",
"status": {
"num_nodes": 3,
"time": 0.001,
"ticks": 1000
},
"nodes": [...]
}GET /api/network/state
Get the global state vector of all nodes in the network.
Response:
{
"state_vector": [0.367879, -2309.45, 0.5, -3141.59, 0.2, -1256.64],
"format": "Interleaved [x0, v0, x1, v1, ...]",
"num_nodes": 3
}The state vector is in interleaved format: [x0, v0, x1, v1, x2, v2, ...]
POST /api/network/reset
Reset the network, clearing all nodes.
Response:
{
"message": "Network reset successfully"
}# Add a 1 kHz resonator
curl -X POST http://localhost:5000/api/network/nodes \
-H "Content-Type: application/json" \
-d '{
"frequency_hz": 1000.0,
"q_factor": 200.0,
"beta": 1e-4,
"name": "osc_1kHz"
}'
# Inject a signal
curl -X POST http://localhost:5000/api/network/nodes/0/inject \
-H "Content-Type: application/json" \
-d '{
"amplitude": 1.0,
"phase": 0.0
}'
# Simulate for 1ms (1000 steps at 1μs)
curl -X POST http://localhost:5000/api/network/tick \
-H "Content-Type: application/json" \
-d '{
"dt": 1e-6,
"steps": 1000
}'
# Check the state
curl http://localhost:5000/api/network/nodes/0import requests
# Add 10 resonators at different frequencies
for i in range(10):
freq = 1000.0 + i * 10.0 # 1000, 1010, 1020, ... Hz
requests.post('http://localhost:5000/api/network/nodes', json={
'frequency_hz': freq,
'q_factor': 1000.0,
'beta': 1e-4,
'name': f'channel_{i}'
})
# Inject signals with different amplitudes
for i in range(10):
requests.post(f'http://localhost:5000/api/network/nodes/{i}/inject', json={
'amplitude': 0.1 * (i + 1),
'phase': 0.0
})
# Evolve the network
requests.post('http://localhost:5000/api/network/tick', json={
'dt': 1e-6,
'steps': 10000
})
# Get global state
response = requests.get('http://localhost:5000/api/network/state')
state = response.json()
print(f"State vector: {state['state_vector']}")import requests
# Create a bistable resonator
requests.post('http://localhost:5000/api/network/nodes', json={
'frequency_hz': 1000.0,
'q_factor': 500.0,
'beta': -1e8, # Negative beta = bistable
'name': 'bistable_bit'
})
# Set to HIGH state
requests.post('http://localhost:5000/api/network/nodes/0/inject', json={
'amplitude': 0.01, # Initial displacement to kick into HIGH well
'phase': 0.0
})
# Let it settle
requests.post('http://localhost:5000/api/network/tick', json={
'dt': 1e-6,
'steps': 10000
})
# Read state
response = requests.get('http://localhost:5000/api/network/nodes/0')
print(f"Final state: {response.json()}")The REST API provides global node access through:
- GET /api/network/state - Access the complete state vector of all nodes simultaneously
- GET /api/network/nodes - List all nodes with their current states
- POST /api/network/tick - Evolve all nodes synchronously in a single operation
This enables:
- Parallel readout of entire network state
- Synchronized evolution of coupled resonator systems
- Batch operations on multiple nodes
- Real-time monitoring of network dynamics
Use the provided FEENClient class for easier interaction:
from examples.rest_api_demo import FEENClient
client = FEENClient('http://localhost:5000')
# Add nodes
client.add_node(frequency_hz=1000.0, q_factor=200.0, beta=1e-4)
client.inject_signal(0, amplitude=1.0)
client.tick(dt=1e-6, steps=1000)
# Get state
state = client.get_node(0)
print(f"Energy: {state['energy']}")The API returns standard HTTP status codes:
200 OK: Request successful201 Created: Node created successfully400 Bad Request: Invalid request data404 Not Found: Node not found500 Internal Server Error: Server error
Error responses include a JSON object with an error field:
{
"error": "Node 99 not found"
}The REST API is built on top of FEEN's Python bindings (pyfeen) and provides HTTP access to:
- Resonator class: Individual Duffing oscillators
- ResonatorConfig: Configuration for resonator parameters
- Network operations: Global access to multiple resonators
All physics is computed using FEEN's validated RK4 integration and thermal noise models.
- Each node tick operation involves RK4 integration (~120 ns per step)
- Network state operations scale linearly with number of nodes
- For high-performance applications, consider batching tick operations
- Use the
stepsparameter in/api/network/tickfor efficient multi-step evolution
This is a development/research API. For production use, consider:
- Rate limiting
- Input validation
- HTTPS encryption
- Network access controls