Metadata-Version: 2.4
Name: PhantomOperator
Version: 0.1.0
Summary: High-performance absent-aware n-dimensional arrays powered by NumPy and PhantomTrace.
Author: PhantomTrace Project
License-Expression: MIT
Project-URL: Homepage, https://github.com/jordanbeitchman-spec/PhantomOperator
Project-URL: Repository, https://github.com/jordanbeitchman-spec/PhantomOperator
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Classifier: Topic :: Scientific/Engineering :: Mathematics
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy
Requires-Dist: PhantomTrace>=0.8.0
Dynamic: license-file

# PhantomOperator

High-performance absent-aware n-dimensional arrays powered by [NumPy](https://numpy.org/) and [PhantomTrace](https://pypi.org/project/PhantomTrace/).

## Install

```bash
pip install phantomoperator
```

This automatically installs NumPy and PhantomTrace as dependencies.

## What It Does

PhantomOperator brings NumPy-level performance to PhantomTrace's absence calculus. Instead of looping through Python lists of individual `AbsentNumber` objects, operations run on compact NumPy arrays — two arrays side by side: one for values, one for states (present/absent).

## Quick Start

```python
from phantom_operator import AbsentArray, absent_array, arange, ones
from phantom_operator import add, subtract, multiply, divide, erase, toggle

# Create arrays
a = absent_array([1, 2, 3, 4, 5])                          # all present
b = absent_array([1, 2, 3, 4, 5], states=[0, 1, 0, 1, 0])  # mixed states

# Or use convenience functions
c = arange(1, 10)          # [1, 2, 3, ..., 10] all present
d = arange(1, 10, state=1) # [1, 2, 3, ..., 10] all absent
e = ones(1000)             # 1000 ones, all present
```

## Operations

All five PhantomTrace operations work element-wise on arrays:

### Addition & Subtraction

Same-state elements combine magnitudes. Mixed-state elements stay unresolved (stored as the first operand's value for the fast path):

```python
a = absent_array([5, 3, 7], states=[0, 0, 1])
b = absent_array([2, 4, 3], states=[0, 0, 1])

add(a, b)       # → [7, 7, 10(0)]
subtract(a, b)  # → [3, -1, 4(0)]
```

### Multiplication & Division

State combination rule: present × present = present, present × absent = absent, absent × absent = present:

```python
a = absent_array([5, 4, 6], states=[0, 1, 1])
b = absent_array([3, 3, 2], states=[0, 0, 1])

multiply(a, b)  # → [15, 12(0), 12]  (absent × absent = present)
divide(a, b)    # → [1, 1(0), 3]
```

### Erasure

Erasure flips the state of the erased portion. Returns a dict with `remainder`, `erased`, and `excess`:

```python
a = absent_array([7, 5, 3])
b = absent_array([3, 5, 1])

result = erase(a, b)
result['remainder']  # → [4, 0, 2]      what's left (keeps state)
result['erased']     # → [3(0), 5(0), 1(0)]  flipped state
result['excess']     # → [0, 0, 0]       over-erasure debt
```

### Toggle

Flip the state of every element:

```python
a = absent_array([1, 2, 3], states=[0, 1, 0])
toggle(a)  # → [1(0), 2, 3(0)]
```

## Array Features

### Shapes & Dimensions

```python
a = absent_array([[1, 2, 3], [4, 5, 6]])
a.shape   # (2, 3)
a.ndim    # 2
a.size    # 6
```

### Indexing

```python
a = absent_array([10, 20, 30, 40, 50])
a[0]      # AbsentNumber: 10
a[1:3]    # AbsentArray([20, 30])
```

### Conversion

```python
from absence_calculator import n

# From PhantomTrace AbsentNumbers
a = absent_array([n(5), n(3)(0), n(7)])

# Back to PhantomTrace
a.to_list()  # → [AbsentNumber(5), AbsentNumber(3, 1), AbsentNumber(7)]
```

### Querying State

```python
from phantom_operator import count_present, present_mask, absent_mask

a = absent_array([1, 2, 3, 4, 5], states=[0, 1, 0, 1, 0])

count_present(a)  # 3
present_mask(a)   # [True, False, True, False, True]
absent_mask(a)    # [False, True, False, True, False]
```

## Performance

PhantomOperator is built on NumPy's C arrays, so operations on large arrays are orders of magnitude faster than looping through individual AbsentNumbers:

```python
from phantom_operator import arange, multiply
import time

a = arange(1, 100000)
b = arange(1, 100000)

start = time.time()
result = multiply(a, b)  # 100,000 multiplications
elapsed = time.time() - start
# Typically < 1ms vs seconds with plain Python lists
```

## Dependencies

- [NumPy](https://numpy.org/) — array computation engine
- [PhantomTrace](https://pypi.org/project/PhantomTrace/) ≥ 0.8.0 — absence calculus framework

## License

MIT
