Skip to main content

High-performance absent-aware n-dimensional arrays powered by NumPy and PhantomTrace.

Project description

PhantomOperator

High-performance absent-aware n-dimensional arrays powered by NumPy and PhantomTrace.

Install

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

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):

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:

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:

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:

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

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

Indexing

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:

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

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

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:

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 — array computation engine
  • PhantomTrace ≥ 0.8.0 — absence calculus framework

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

phantomoperator-0.1.2.tar.gz (7.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

phantomoperator-0.1.2-py3-none-any.whl (7.6 kB view details)

Uploaded Python 3

File details

Details for the file phantomoperator-0.1.2.tar.gz.

File metadata

  • Download URL: phantomoperator-0.1.2.tar.gz
  • Upload date:
  • Size: 7.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for phantomoperator-0.1.2.tar.gz
Algorithm Hash digest
SHA256 7fd8d4cba67924e33168a48b27b8c5c02ac3f1ee62bbcf5179d74de39c0ab2b8
MD5 d0676c206a4c27a9b2af68cdb25f6a8e
BLAKE2b-256 a909f804f365e7a0eb790f217c70b64625fa6d075c0bd0ea162dde3e1ad072f9

See more details on using hashes here.

File details

Details for the file phantomoperator-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for phantomoperator-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 73f02ee72b5f31b5ccd9714b844eeb941bec73c23ab2f5afa257f03c697a4b28
MD5 cc4bc29a62c56f24b84ea7bb564662dc
BLAKE2b-256 cda56af57e7f2da1cb3815a6af38c9e24eab9aab60d97da4f0ff8ce58a630e4a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page