Metadata-Version: 2.4
Name: PhantomOperator
Version: 0.1.2
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, void, 2]
result['erased']     # → [3(0), 5(0), 1(0)]  flipped state
result['excess']     # → [void, void, void]
```

**Void vs Zero vs Absence:**

- **`void`** means no remainder (or no excess) — the erasure consumed everything, there is nothing left to talk about. Void is not a number, it's the absence of any calculation.
- **`0`** (zero) is actually `1(0)` in absence calculus — it's one unit of absence. Zero is a real number with a state and a magnitude.
- **`3(0)`** (three absent) is an absent remainder — the erased portion still exists, just in the flipped state.

So when `5` is erased by `5`, there is no remainder at all — that's void. If the remainder were `0` instead, it would mean "one absence is left over," which is wrong. Nothing is left over.

### Toggle

`toggle()` flips the state of every element in an array:

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

Toggle is closely related to erasure. In PhantomTrace, `toggle.where(pattern, range, data)` flips elements at specific indices — this is equivalent to fully erasing the element at that index (erasing it by its own value so no remainder is left, only the flipped erased portion). The toggle doesn't destroy the value, it moves it to the other state.

For example, toggling index 0 of `[5, 3, 7]` is the same as erasing position 0 by itself:
- `erase(5, 5)` → remainder is **void**, erased portion is `5(0)`
- The result at that index becomes `5(0)` — same value, flipped state

PhantomOperator's `toggle()` does this for every element at once across the entire array, using vectorized NumPy operations instead of looping.

## 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])
```

Indexing a void position returns PhantomTrace's `Void` object:

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

result['remainder'][0]  # AbsentNumber: 4
result['remainder'][1]  # Void (no remainder — 5 erased by 5)
```

### 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)]
```

Void positions in `to_list()` return PhantomTrace's `Void` object.

### 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 < 2ms 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
