Skip to content
/ chisa Public

A Logic-Driven Dimensional Algebra And Strict Physics Modeling Framework For Python, With Seamless NumPy Vectorization

License

Notifications You must be signed in to change notification settings

rannd1nt/chisa

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

75 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Chisa - Dimensional Algebra & Physics Modelling Framework

Python NumPy License

Maintenance Version

Chisa is a logic-driven dimensional algebra and strict physics modeling framework for Python, powered by seamless NumPy vectorization. It merges the accessibility of a fluent conversion API with the rigorous architectural guardrails of an Object-Oriented physics engine.

Going beyond standard unit conversion, Chisa acts as a Dimensional Integrity Enforcer for your application. It features the Axiom Engine for modeling real-world physical limits, Bidirectional Type Inferencing to eliminate unit ambiguity, and native C-Struct Array bypassing for high-performance machine learning and data science workloads.


Why a "Framework" and not just a Library?

A standard conversion library provides passive tools you call to multiply a number by a constant. Chisa dictates the architecture of your physical data. By utilizing Inversion of Control via Python decorators, Chisa provides a foundation where you define the rules of reality.

You construct mathematical constraints (e.g., Temperature cannot drop below Absolute Zero), derive complex units using physical formulas ($W = J/s$), and rely on the engine to autonomously intercept and prevent cross-dimensional logic errors before they corrupt your scientific pipelines.


Key Features

  • Dual Engine API: Use the Fluent API for quick, readable conversions, or the Explicit OOP API for strict mathematical operations.
  • Native Vectorization: Drop multi-dimensional numpy.ndarray objects directly into Chisa. It bypasses scalar bottlenecks and processes millions of data points instantly.
  • The Axiom Ruleset: Python class decorators (@axiom) that govern physical boundaries, dynamic context-scaling (e.g., Mach speed relative to temperature), and dimension synthesis.
  • Smart Inferencing: Resolves ambiguous abbreviations (e.g., 'm' for meter vs. minute) dynamically based on the target context.

The Core Architecture (How Chisa Thinks)

At its absolute core, Chisa normalizes every unit into a universal "Base Value" using a highly optimized linear transformation. When you instantiate a unit, the engine calculates its true physical magnitude using this equation:

$$ y = (x + c) \cdot m $$

Where:

  • $x$ — The input magnitude provided by the user.
  • $c$ — base_offset (e.g., -273.15 for converting Celsius to Kelvin). Controlled dynamically by @axiom.shift.
  • $m$ — The base_multiplier (e.g., 1000 for converting Kilometers to Meters). Controlled dynamically by @axiom.scale and @axiom.derive.
  • $y$ — The normalized absolute Base Value safely stored in the engine.

By exposing decorators rather than raw classes, Chisa allows you to dynamically inject physical variables into $c$ and $m$ at runtime.


Precision & Type Safety (.mag vs .exact)

Chisa dynamically juggles standard float, ultra-precise decimal.Decimal, and vectorized numpy.ndarray. To prevent cross-type calculation crashes in complex physics formulas, Chisa forces you to be explicit about your extraction strategy:

  • unit.mag (Magnitude - Best for Math & ML): Strips high-precision Decimals down to standard Python float (or leaves ndarray intact). Use this 95% of the time for safe, cross-dimensional physics calculations (e.g., Area * Length), Matplotlib charting, or machine learning pipelines.

  • unit.exact (Absolute Precision - Best for Audits): Returns the raw, unadulterated decimal.Decimal. Use this strictly for financial tracking, database storage, or extreme precision logging. Warning: Multiplying a Decimal .exact with a standard Python float will intentionally trigger a TypeError to prevent precision drift.


Quick Start

1. The Fluent API

A highly readable, chainable interface for straightforward conversions and aesthetic string formatting.

from chisa import convert

# Simple scalar conversion
speed = convert(120, 'km/h').to('m/s').resolve()
print(speed) # 33.333333333333336

# Powerful cosmetic formatting for UI/Logs
text = convert(1000, 'm').to('cm').use(format='verbose', delim=True).resolve()
print(text) # "1,000 m = 100,000 cm"

2. High-Performance Vectorization

Pass NumPy arrays directly. Chisa safely bypasses string logic to maintain pure float64 matrix performance.

import numpy as np
from chisa import convert

# Raw arrays from sensors or datasets
data = np.array([1, 10, 100, 1000])

# Fully vectorized mathematical conversion
res_array = convert(data, 'm').to('cm').use(format='raw').resolve()

print(repr(res_array))
# array([   100.,   1000.,  10000., 100000.])

3. Explicit OOP & Dimensional Mathematics

Treat units as first-class physical entities. Chisa automatically normalizes bases and prevents cross-dimensional logic errors.

from chisa.units.length import Meter, Centimeter, Kilometer
from chisa.units.mass import Kilogram
from chisa import DimensionMismatchError

# 1. Seamless cross-unit math (Auto-normalization)
total_length = Meter(10.5) + Centimeter(500)
print(total_length) # <Meter: 15.5 m>

# 2. Precision Extraction (Method Chaining)
distance = Kilometer(2.5)

# .mag returns a standard Python float (Safe for external math & NumPy)
math_safe_val = distance.to(Meter).mag
print(repr(math_safe_val)) # 2500.0

# .exact returns a decimal.Decimal (For strict audits & extreme precision)
audit_safe_val = distance.to(Meter).exact
print(repr(audit_safe_val)) # Decimal('2500.0')

# 3. Dimensional Guardrails in action
try:
    invalid_math = Meter(10) + Kilogram(5)
except DimensionMismatchError as e:
    print(e) # "Dimension mismatch (Addition (+)). Expected 'length', but got 'mass'."

Advanced Physics Modeling (Domain-Driven Design)

Chisa's true power lies in its explicit OOP API. Below is a three-part demonstration of modeling complex astrophysics using dynamic contexts, unit synthesis, and strict type guards.

Part 1: Contextual Scaling (Gravitational Time Dilation)

Let's model how time slows down near a massive object using the Schwarzschild equation:

$$ \text{Scale Factor} = \sqrt{ \max\left( 1 - \frac{2 G M}{r c^2}, 0 \right) } $$

import numpy as np
from chisa import axiom, const, vmath
from chisa.units.time import TimeUnit, Second
from chisa.units.mass import Kilogram
from chisa.units.length import Meter

# 1. @prepare forces inputs into required Base Units safely before math execution
@axiom.prepare(mass=Kilogram, length=Meter)
def calc_time_dilation(mass=0.0, length=const.INF):
    r = vmath.maximum(length, 1.0)
    rs_term = (2 * const.GRAVITATIONAL_CONSTANT * mass) / (r * vmath.power(const.SPEED_OF_LIGHT, 2))
    safe_term = vmath.maximum(1.0 - rs_term, 0.0)
    return vmath.sqrt(safe_term)

# 2. @scale binds the physics formula to the unit's base multiplier
@axiom.scale(formula=calc_time_dilation)
class DilatedSecond(TimeUnit):
    symbol = "s_dil"
    base_multiplier = 1.0

# 3. Execution using Polymorphic Context Arrays
theoretical_time = DilatedSecond(
    10.0,
    context={
        "mass": Kilogram(1e25),
        "length": Meter(np.array([10_000_000.0, 5_000_000.0, 1_000_000.0])),
    },
)

print(theoretical_time.to(Second).mag)
# Output: [9.99999999  9.99999999  9.99999993]

Part 2: Axiom Stacking & Derivation (Stellar Radiation)

We can derive complex units from simple ones (Watts = Joules / Seconds) and stack Axioms to calculate stellar flux based on the Stefan-Boltzmann law:

$$ \text{Flux} = \left(\sigma T^4\right)\cos(\theta) $$

from chisa import axiom, const, vmath, C
from chisa.units.power import PowerUnit, Watt
from chisa.units.energy import Joule
from chisa.units.temperature import Celsius, Kelvin

@axiom.prepare(temperature=Kelvin)
def calc_stellar_emission(temperature=0.0, view_angle=0.0):
    flux = const.STEFAN_BOLTZMANN * vmath.power(temperature, 4)
    return flux * vmath.cos(view_angle)

# Axiom Stacking: Deriving W = J/s, applying a dynamic shift (noise), and scaling by physics!
@axiom.derive(mul=[Joule], div=[Second])
@axiom.shift(formula=C("power_noise", default=0.0))
@axiom.scale(formula=calc_stellar_emission)
class StellarRadiance(PowerUnit):
    symbol = "W_str"

# User passes Celsius; Chisa automatically normalizes it to Kelvin for the formula
emission = StellarRadiance(
    2.5,
    context={
        "temperature": Celsius(4726.85), # Equals exactly 5000 Kelvin
        "view_angle": 0.5, 
        "power_noise": Watt(1500.0), 
    },
)

print(emission.to(Watt).mag)
# Output: 77754964.21099459

Part 3: Strict Function Guardrails (@require)

Never write manual if type(x) != y checks again. Let Chisa enforce dimensional integrity for your own domain logic.

@axiom.require(duration=TimeUnit, radiation=PowerUnit)
def compute_total_energy(duration: TimeUnit, radiation: PowerUnit) -> Joule:
    # Safely extract .mag (floats/arrays) to perform cross-dimensional physics
    total_joules_raw = duration.to(Second).mag * radiation.to(Watt).mag
    return Joule(total_joules_raw)

# Calculate Energy = Array (Time) * Float (Power)
total_energy_array = compute_total_energy(theoretical_time, emission)

print(total_energy_array.mag)
# Output: [7.77549642e+08  7.77549641e+08  7.77549636e+08]

Axiom Decorator Glossary

  • @axiom.derive(mul=[], div=[]): Synthesizes the base multiplier of a unit by multiplying/dividing existing Chisa unit classes.
  • @axiom.bound(min_val, max_val): Enforces absolute physical limits (e.g., Temperature cannot fall below 0 Kelvin) during instantiation.
  • @axiom.scale(formula/ctx): Dynamically mutates the unit's multiplier based on runtime environmental context.
  • @axiom.shift(formula/ctx): Dynamically mutates the unit's offset base based on runtime environmental context.
  • @axiom.require(**kwargs): Function decorator that strictly guards argument inputs, ensuring they match specified dimensions or BaseUnit classes.
  • @axiom.prepare(**kwargs): Function decorator that pre-processes incoming Chisa objects, converting them to the required unit and extracting their math-safe .mag value automatically.

Built-in Physics Utilities

To support the Axiom Engine and ensure safe cross-type mathematics (Scalars vs. NumPy Arrays), Chisa provides built-in utility modules optimized for scientific computing:

  • CtxProxy (aliased as C): A declarative Context Variable proxy. It allows you to build lazy-evaluated mathematical formulas directly inside decorators. For example, C('power_noise') * 2 will wait until runtime to extract the 'power_noise' value from the unit's context dictionary and multiply it.

  • chisa.vmath: A universal math wrapper. Python's math.sqrt crashes on arrays, and numpy.sqrt can be overkill for pure scalars. vmath automatically detects the input type and routes the calculation to the safest, fastest engine (handling maximum, power, cos, sqrt, etc.) without you having to write a single if statement.

  • chisa.const: A comprehensive, high-precision constants library (SPEED_OF_LIGHT, GRAVITATIONAL_CONSTANT, STEFAN_BOLTZMANN, ABSOLUTE_ZERO_K, INF, etc.). It eliminates "magic numbers" in your physics formulas.


Root Helper Methods (Registry Introspection)

Chisa exposes lightweight utility functions directly at the root level. These helpers allow you to quickly interrogate the internal UnitRegistry without digging through the source code:

import chisa
from chisa.units.temperature import Celsius

# 1. dimof(): Identify the dimension of a string alias, Class, or Instance!
print(chisa.dimof('celsius'))   # 'temperature'
print(chisa.dimof(Celsius))     # 'temperature'
print(chisa.dimof(Celsius(10))) # 'temperature'

# 2. dims(): List all physical dimensions currently loaded in the engine
print(chisa.dims()) 
# ['area', 'energy', 'length', 'mass', 'power', ...]

# 3. unitsin(): Discover all available unit symbols within a specific dimension
print(chisa.unitsin('mass')) 
# ['kg', 'g', 'lb', 'oz', 'MetricTon', ...]

# Pass `ascls=True` to retrieve the actual OOP Class objects for dynamic instantiation
mass_classes = chisa.unitsin('mass', ascls=True) 
# [<class 'Gram'>, <class 'Kilogram'>, ...]

# 4. baseof(): Identify the absolute computational baseline class for a dimension
print(chisa.baseof('temperature')) 
# <class 'chisa.units.temperature.Celsius'>

Installation

Install via pip:

pip install chisa

Requirements:

  • Python 3.8+
  • numpy

Roadmap & TODOs

  • Enhanced Dimensional Synthesis: Overhauling the @axiom.derive decorator to support native, highly readable mathematical syntax (e.g., @axiom.derive(Joule / Second) instead of passing lists).

  • Safe Cross-Dimensional OOP: Unlocking the currently restricted NotImplementedError for cross-dimensional operations. This will allow natural OOP multiplication and division (e.g., Meter(10) / Second(2) -> <SpeedUnit: 5.0 m/s>) while strictly preserving dimensional integrity.

  • Global Context Manager: (with chisa.conf()) Introduce a global state override to temporarily force data types (e.g., dtype='float32') or ignore bounding rules across the entire computational environment.

  • Submodule Separation: Refactoring the @axiom namespace into domain-specific submodules (e.g., @axiom.unit... for class definitions and @axiom.formula... for function injection) to enforce stricter separation of concerns.


Contributing

Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make to Chisa are greatly appreciated.

If you have a suggestion that would make this framework better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star!

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'feat: Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

Distributed under the MIT License. See the LICENSE file for more information.


"Measuring the universe, one dimension at a time."

About

A Logic-Driven Dimensional Algebra And Strict Physics Modeling Framework For Python, With Seamless NumPy Vectorization

Topics

Resources

License

Stars

Watchers

Forks

Languages