A Python library for simulating and analyzing fluxes in complex systems.
Project description
Fluxed
Fluxed is a Python package for defining N-dimensional shapes and computing the flux of arbitrary intensity distributions through them. It features a powerful tool to numerically find distribution parameters that match a desired flux value, enabling comparisons across different geometries and distributions.
Built on numpy and scipy, Fluxed provides an intuitive, array-based interface for complex spatial analysis.
Key Features
- N-Dimensional Shapes: Define complex shapes and borders in any number of dimensions using simple NumPy arrays.
- Automated Boundary Detection: Automatically determines if a shape's border is closed and encloses a valid region for flux calculation.
- Flux Computation: Calculates the integrated flux (sum of intensity) within a closed shape for any given intensity distribution.
- Rich Distribution Library: Comes with common distributions like
Normal,Uniform,Linear, andExponentialin 1D and 2D. - Custom Distributions: Easily extend the framework with your own custom, callable distribution functions.
- Flux Matching: The core feature—numerically optimize the parameters of a target distribution to match the flux of a source shape. This is perfect for modeling, simulation, and comparative analysis.
Installation
Fluxed is available on PyPI. You can install it using pip:
pip install Fluxed
The package requires numpy and scipy, which will be installed automatically as dependencies.
Core Concepts
1. NdShape
An NdShape object represents a shape in N-dimensional space. You create it from a NumPy array where 1s define the border and 0s represent empty space. The class can automatically determine if the border is is_closed and can calculate the flux within this enclosed region.
2. Distribution
A Distribution is a callable object that returns an intensity value for a given coordinate. The library provides several ready-to-use distributions (e.g., NormalDistribution2D), and you can easily create your own by inheriting from the Distribution base class.
3. Flux
In the context of this package, "flux" is the sum of all intensity values from a Distribution over the discrete points inside the enclosed region of an NdShape. It's a discrete integral of the intensity over the shape's area or volume.
Quickstart
Let's walk through a complete example, from calculating a simple flux to using the advanced flux-matching feature.
Step 1: Define a Shape
First, let's create a simple 2D shape: a 3x3 hollow square within a 5x5 grid.
import numpy as np
from Fluxed.shapes import NdShape
# 1s are the border, 0s are the interior/exterior
border_array = np.array([
[1, 1, 1, 1, 1],
[1, 0, 0, 0, 1],
[1, 0, 0, 0, 1],
[1, 0, 0, 0, 1],
[1, 1, 1, 1, 1],
], dtype=int)
my_shape = NdShape(border_array)
print(f"Shape is {my_shape.dimensions}D")
print(f"Is the shape closed? {my_shape.is_closed}")
# > Shape is 2D
# > Is the shape closed? True
Step 2: Calculate a Simple Flux
Now, let's calculate the flux using a UniformDistribution. With a value of 1.0, the flux will be equal to the enclosed area.
from Fluxed.distributions import UniformDistribution
# Create a distribution where the intensity is 1.0 everywhere
uniform_dist = UniformDistribution(value=1.0)
# Calculate the flux
total_flux = my_shape.get_flux(uniform_dist)
# The enclosed area is 3x3 = 9. The flux should be 9.0.
print(f"Total flux for uniform distribution: {total_flux}")
# > Total flux for uniform distribution: 9.0
Step 3: Match Flux with a Different Distribution
This is where Fluxed shines. Let's say we have a source of energy that produces a total flux of 90.0. We want to model this energy source on our shape using a NormalDistribution2D (a Gaussian). What should the parameters of the Gaussian be (mean, stddev) to produce the same total flux?
The match_flux_parameters function solves this for us.
from Fluxed.distributions import NormalDistribution2D
from Fluxed.match import match_flux_parameters
# --- Source ---
# Our source is a uniform distribution with value 10.0
# The enclosed area is 9, so the target flux is 9 * 10.0 = 90.0
source_dist = UniformDistribution(value=10.0)
# --- Target ---
# We want to find the parameters for a NormalDistribution2D
# that will also produce a flux of 90.0 on the same shape.
TargetDistClass = NormalDistribution2D
# We want the optimizer to find the standard deviations.
# We'll fix the mean to be the center of the grid (2, 2).
# To do this, we create a simple wrapper.
class CenteredNormal(NormalDistribution2D):
def __init__(self, stddev_x: float = 1.0, stddev_y: float = 1.0):
# Fix the mean to the center of our 5x5 grid
super().__init__(mean_x=2.0, mean_y=2.0, stddev_x=stddev_x, stddev_y=stddev_y)
# Parameters for the optimizer to find
params_to_find = ['stddev_x', 'stddev_y']
initial_guess = [1.0, 1.0] # An initial guess for the standard deviations
bounds = [(0.1, None), (0.1, None)] # Stddev must be positive
# --- Run the optimizer ---
result = match_flux_parameters(
source_shape=my_shape,
source_dist=source_dist,
target_shape=my_shape,
TargetDistClass=CenteredNormal,
param_names=params_to_find,
initial_guess=initial_guess,
bounds=bounds
)
# --- Analyze the result ---
if result['success']:
print("Optimization successful!")
print(f"Target Flux: {result['target_flux']:.4f}")
print(f"Achieved Flux: {result['final_flux']:.4f}")
print("Found optimal parameters:")
for param, value in result['parameters'].items():
print(f" {param}: {value:.4f}")
else:
print(f"Optimization failed: {result['message']}")
Example Output:
Calculating target flux from source shape and UniformDistribution...
Target Flux = 90.0000
Optimizing parameters ['stddev_x', 'stddev_y'] for CenteredNormal...
Optimization successful!
Target Flux: 90.0000
Achieved Flux: 90.0000
Found optimal parameters:
stddev_x: 1.2585
stddev_y: 1.2585
The result tells us that a 2D Normal distribution centered at (2, 2) with a standard deviation of approximately 1.26 along both axes will produce the same total flux as a uniform distribution of value 10.
Creating a Custom Distribution
It's easy to define your own distributions. Just inherit from Distribution and provide a callable function.
Let's create a 1D distribution that varies with the sine of the x-coordinate.
import numpy as np
from Fluxed.distributions import Distribution
class SineDistribution1D(Distribution):
"""A custom distribution where intensity varies sinusoidally."""
def __init__(self, frequency: float = 1.0, amplitude: float = 1.0):
# The function must accept arguments corresponding to the dimensions
# of the space it will be used in.
def sine_func(x):
# We add `amplitude` to ensure intensity is always non-negative
return amplitude * np.sin(frequency * x) + amplitude
# Call the parent constructor
super().__init__("SineDistribution1D", sine_func)
self.frequency = frequency
self.amplitude = amplitude
# --- Usage ---
shape_1d = NdShape(np.array([1, 0, 0, 0, 1])) # A simple 1D enclosed space
my_sine_dist = SineDistribution1D(frequency=np.pi/2, amplitude=10)
# The function will be evaluated at x=1, 2, 3
# sin(pi/2*1) = 1 -> intensity = 10*1 + 10 = 20
# sin(pi/2*2) = 0 -> intensity = 10*0 + 10 = 10
# sin(pi/2*3) = -1 -> intensity = 10*(-1) + 10 = 0
# Expected flux = 20 + 10 + 0 = 30
flux = shape_1d.get_flux(my_sine_dist)
print(f"Flux for custom sine distribution: {flux}")
# > Flux for custom sine distribution: 30.0
Running Tests
To run the test suite from a local clone of the repository, install the development dependencies and run pytest.
git clone https://github.com/CrazeXD/Fluxed.git
cd Fluxed
pip install -r requirements.txt # Or similar for dev dependencies
pip install pytest
pytest
Contributing
Contributions are welcome! If you have ideas for new features, distributions, or improvements, please open an issue to discuss it first. Pull requests are also appreciated.
License
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fluxed-1.0.0.tar.gz.
File metadata
- Download URL: fluxed-1.0.0.tar.gz
- Upload date:
- Size: 29.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d0f678ba53d94329c2e675d020f473466239e0b7f1a17c5a00f0aee33d281394
|
|
| MD5 |
c120f63da1137c155eab4ca8f0206f77
|
|
| BLAKE2b-256 |
48bf0efa0f57657dea9ba3a4f5d69c7035849c4e78f2cb3259bd544fd4dc5300
|
Provenance
The following attestation bundles were made for fluxed-1.0.0.tar.gz:
Publisher:
python-publish.yml on CrazeXD/Fluxed
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fluxed-1.0.0.tar.gz -
Subject digest:
d0f678ba53d94329c2e675d020f473466239e0b7f1a17c5a00f0aee33d281394 - Sigstore transparency entry: 366228169
- Sigstore integration time:
-
Permalink:
CrazeXD/Fluxed@0b1fae8e45e9b754b412b4a610c85184fe732d5e -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/CrazeXD
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@0b1fae8e45e9b754b412b4a610c85184fe732d5e -
Trigger Event:
release
-
Statement type:
File details
Details for the file fluxed-1.0.0-py3-none-any.whl.
File metadata
- Download URL: fluxed-1.0.0-py3-none-any.whl
- Upload date:
- Size: 25.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
209adcb7d1f7b1898ceeb53b6df2702106da09c07aecb8902266753a65e6d8af
|
|
| MD5 |
28648114dc27023e236d64ebf43891fa
|
|
| BLAKE2b-256 |
566c567471b0e6503a2469c06106511bd94b4d490808133a9f09a987eaf05cb2
|
Provenance
The following attestation bundles were made for fluxed-1.0.0-py3-none-any.whl:
Publisher:
python-publish.yml on CrazeXD/Fluxed
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fluxed-1.0.0-py3-none-any.whl -
Subject digest:
209adcb7d1f7b1898ceeb53b6df2702106da09c07aecb8902266753a65e6d8af - Sigstore transparency entry: 366228177
- Sigstore integration time:
-
Permalink:
CrazeXD/Fluxed@0b1fae8e45e9b754b412b4a610c85184fe732d5e -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/CrazeXD
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@0b1fae8e45e9b754b412b4a610c85184fe732d5e -
Trigger Event:
release
-
Statement type: