ucon 0.5.1__tar.gz → 0.5.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. {ucon-0.5.1 → ucon-0.5.2}/PKG-INFO +84 -3
  2. {ucon-0.5.1 → ucon-0.5.2}/README.md +83 -2
  3. {ucon-0.5.1 → ucon-0.5.2}/ROADMAP.md +42 -32
  4. ucon-0.5.2/tests/ucon/test_basis_transform.py +521 -0
  5. ucon-0.5.2/tests/ucon/test_graph_basis_transform.py +263 -0
  6. ucon-0.5.2/tests/ucon/test_rebased_unit.py +184 -0
  7. ucon-0.5.2/tests/ucon/test_unit_system.py +174 -0
  8. ucon-0.5.2/tests/ucon/test_vector_fraction.py +185 -0
  9. {ucon-0.5.1 → ucon-0.5.2}/ucon/__init__.py +20 -2
  10. {ucon-0.5.1 → ucon-0.5.2}/ucon/algebra.py +36 -14
  11. {ucon-0.5.1 → ucon-0.5.2}/ucon/core.py +407 -0
  12. {ucon-0.5.1 → ucon-0.5.2}/ucon/graph.py +167 -10
  13. {ucon-0.5.1 → ucon-0.5.2}/ucon/units.py +28 -1
  14. {ucon-0.5.1 → ucon-0.5.2}/ucon.egg-info/PKG-INFO +84 -3
  15. {ucon-0.5.1 → ucon-0.5.2}/ucon.egg-info/SOURCES.txt +5 -0
  16. {ucon-0.5.1 → ucon-0.5.2}/.github/workflows/publish.yaml +0 -0
  17. {ucon-0.5.1 → ucon-0.5.2}/.github/workflows/tests.yaml +0 -0
  18. {ucon-0.5.1 → ucon-0.5.2}/.gitignore +0 -0
  19. {ucon-0.5.1 → ucon-0.5.2}/LICENSE +0 -0
  20. {ucon-0.5.1 → ucon-0.5.2}/NOTICE +0 -0
  21. {ucon-0.5.1 → ucon-0.5.2}/docs/decisions/composable-unit-algebra.md +0 -0
  22. {ucon-0.5.1 → ucon-0.5.2}/docs/decisions/composite-units.md +0 -0
  23. {ucon-0.5.1 → ucon-0.5.2}/docs/decisions/pseudo-dimension-tuple-values.md +0 -0
  24. {ucon-0.5.1 → ucon-0.5.2}/docs/decisions/unit-algebra-naming.md +0 -0
  25. {ucon-0.5.1 → ucon-0.5.2}/docs/decisions/unity-distance-metric-for-nearest-scale.md +0 -0
  26. {ucon-0.5.1 → ucon-0.5.2}/docs/explainers/exponent-scale-relationship.md +0 -0
  27. {ucon-0.5.1 → ucon-0.5.2}/docs/explainers/type-operation-matrix.md +0 -0
  28. {ucon-0.5.1 → ucon-0.5.2}/docs/explainers/why-algebraic-closure-matters.md +0 -0
  29. {ucon-0.5.1 → ucon-0.5.2}/docs/explainers/why-type-safety-matters.md +0 -0
  30. {ucon-0.5.1 → ucon-0.5.2}/docs/proposals/interface-unifying-the-value-layer.md +0 -0
  31. {ucon-0.5.1 → ucon-0.5.2}/docs/proposals/project_unified-algebraic-core.md +0 -0
  32. {ucon-0.5.1 → ucon-0.5.2}/docs/proposals/support-for-fractional-exponents.md +0 -0
  33. {ucon-0.5.1 → ucon-0.5.2}/docs/proposals/unified-unit-presentation.md +0 -0
  34. {ucon-0.5.1 → ucon-0.5.2}/noxfile.py +0 -0
  35. {ucon-0.5.1 → ucon-0.5.2}/requirements.txt +0 -0
  36. {ucon-0.5.1 → ucon-0.5.2}/setup.cfg +0 -0
  37. {ucon-0.5.1 → ucon-0.5.2}/setup.py +0 -0
  38. {ucon-0.5.1 → ucon-0.5.2}/tests/__init__.py +0 -0
  39. {ucon-0.5.1 → ucon-0.5.2}/tests/ucon/__init__.py +0 -0
  40. {ucon-0.5.1 → ucon-0.5.2}/tests/ucon/conversion/__init__.py +0 -0
  41. {ucon-0.5.1 → ucon-0.5.2}/tests/ucon/conversion/test_graph.py +0 -0
  42. {ucon-0.5.1 → ucon-0.5.2}/tests/ucon/conversion/test_map.py +0 -0
  43. {ucon-0.5.1 → ucon-0.5.2}/tests/ucon/test_algebra.py +0 -0
  44. {ucon-0.5.1 → ucon-0.5.2}/tests/ucon/test_core.py +0 -0
  45. {ucon-0.5.1 → ucon-0.5.2}/tests/ucon/test_default_graph_conversions.py +0 -0
  46. {ucon-0.5.1 → ucon-0.5.2}/tests/ucon/test_dimensionless_units.py +0 -0
  47. {ucon-0.5.1 → ucon-0.5.2}/tests/ucon/test_quantity.py +0 -0
  48. {ucon-0.5.1 → ucon-0.5.2}/tests/ucon/test_uncertainty.py +0 -0
  49. {ucon-0.5.1 → ucon-0.5.2}/tests/ucon/test_units.py +0 -0
  50. {ucon-0.5.1 → ucon-0.5.2}/ucon/maps.py +0 -0
  51. {ucon-0.5.1 → ucon-0.5.2}/ucon/quantity.py +0 -0
  52. {ucon-0.5.1 → ucon-0.5.2}/ucon.egg-info/dependency_links.txt +0 -0
  53. {ucon-0.5.1 → ucon-0.5.2}/ucon.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ucon
3
- Version: 0.5.1
3
+ Version: 0.5.2
4
4
  Summary: a tool for dimensional analysis: a "Unit CONverter"
5
5
  Home-page: https://github.com/withtwoemms/ucon
6
6
  Author: Emmanuel I. Obi
@@ -92,6 +92,9 @@ To best answer this question, we turn to an age-old technique ([dimensional anal
92
92
  | **`Ratio`** | `ucon.core` | Represents the division of two `Number` objects; captures relationships between quantities. | Expressing rates, densities, efficiencies (e.g., energy / time = power, length / time = velocity). |
93
93
  | **`Map`** hierarchy | `ucon.maps` | Composable conversion morphisms: `LinearMap`, `AffineMap`, `ComposedMap`. | Defining conversion functions between units (e.g., meter→foot, celsius→kelvin). |
94
94
  | **`ConversionGraph`** | `ucon.graph` | Registry of unit conversion edges with BFS path composition. | Converting between units via `Number.to(target)`; managing default and custom graphs. |
95
+ | **`UnitSystem`** | `ucon.core` | Named mapping from dimensions to base units (e.g., SI, Imperial). | Defining coherent unit systems; grouping base units by dimension. |
96
+ | **`BasisTransform`** | `ucon.core` | Matrix-based transformation between dimensional exponent spaces. | Converting between incompatible dimensional structures; exact arithmetic with `Fraction`. |
97
+ | **`RebasedUnit`** | `ucon.core` | A unit rebased to another system's dimension, preserving provenance. | Cross-basis conversions; tracking original unit through basis changes. |
95
98
  | **`units` module** | `ucon.units` | Defines canonical unit instances (SI, imperial, information, and derived units). | Quick access to standard physical units (`units.meter`, `units.foot`, `units.byte`, etc.). |
96
99
 
97
100
  ### Under the Hood
@@ -235,6 +238,83 @@ length_ft = length.to(units.foot)
235
238
  print(length_ft) # <4.048... ± 0.0164... ft>
236
239
  ```
237
240
 
241
+ Unit systems and basis transforms enable conversions between incompatible dimensional structures.
242
+ This goes beyond simple unit conversion (meter → foot) into structural transformation:
243
+
244
+ ```python
245
+ from fractions import Fraction
246
+ from ucon import BasisTransform, Dimension, Unit, UnitSystem, units
247
+ from ucon.graph import ConversionGraph
248
+ from ucon.maps import LinearMap
249
+
250
+ # The realm of Valdris has three fundamental dimensions:
251
+ # - Aether (A): magical energy substrate
252
+ # - Resonance (R): vibrational frequency of magic
253
+ # - Substance (S): physical matter
254
+ #
255
+ # These combine into SI dimensions via a transformation matrix:
256
+ #
257
+ # | L | | 2 0 0 | | A |
258
+ # | M | = | 1 0 1 | × | R |
259
+ # | T | |-2 -1 0 | | S |
260
+ #
261
+ # Reading the columns:
262
+ # - 1 aether contributes: L², M, T⁻² (energy-like)
263
+ # - 1 resonance contributes: T⁻¹ (frequency-like)
264
+ # - 1 substance contributes: M (mass-like)
265
+
266
+ # Fantasy base units
267
+ mote = Unit(name='mote', dimension=Dimension.energy, aliases=('mt',))
268
+ chime = Unit(name='chime', dimension=Dimension.frequency, aliases=('ch',))
269
+ ite = Unit(name='ite', dimension=Dimension.mass, aliases=('it',))
270
+
271
+ valdris = UnitSystem(
272
+ name="Valdris",
273
+ bases={
274
+ Dimension.energy: mote,
275
+ Dimension.frequency: chime,
276
+ Dimension.mass: ite,
277
+ }
278
+ )
279
+
280
+ # The basis transform encodes how Valdris dimensions compose into SI
281
+ valdris_to_si = BasisTransform(
282
+ src=valdris,
283
+ dst=units.si,
284
+ src_dimensions=(Dimension.energy, Dimension.frequency, Dimension.mass),
285
+ dst_dimensions=(Dimension.energy, Dimension.frequency, Dimension.mass),
286
+ matrix=(
287
+ (2, 0, 0), # energy: 2 × aether
288
+ (1, 0, 1), # frequency: aether + substance
289
+ (-2, -1, 0), # mass: -2×aether - resonance
290
+ ),
291
+ )
292
+
293
+ # Physical calibration: how many SI units per fantasy unit
294
+ graph = ConversionGraph()
295
+ graph.connect_systems(
296
+ basis_transform=valdris_to_si,
297
+ edges={
298
+ (mote, units.joule): LinearMap(42), # 1 mote = 42 J
299
+ (chime, units.hertz): LinearMap(7), # 1 chime = 7 Hz
300
+ (ite, units.kilogram): LinearMap(Fraction(1, 2)), # 1 ite = 0.5 kg
301
+ }
302
+ )
303
+
304
+ # Game engine converts between physics systems
305
+ energy_map = graph.convert(src=mote, dst=units.joule)
306
+ energy_map(10) # 420 joules from 10 motes
307
+
308
+ # Inverse: display real-world values in game units
309
+ joule_to_mote = graph.convert(src=units.joule, dst=mote)
310
+ joule_to_mote(420) # 10 motes
311
+
312
+ # The transform is invertible with exact Fraction arithmetic
313
+ valdris_to_si.is_invertible # True
314
+ ```
315
+
316
+ This enables fantasy game physics, or any field where the dimensional structure differs from SI.
317
+
238
318
  ---
239
319
 
240
320
  ## Roadmap Highlights
@@ -245,8 +325,9 @@ print(length_ft) # <4.048... ± 0.0164... ft>
245
325
  | **0.4.x** | Conversion System | `ConversionGraph`, `Number.to()`, callable units | ✅ Complete |
246
326
  | **0.5.0** | Dimensionless Units | Pseudo-dimensions for angle, solid angle, ratio | ✅ Complete |
247
327
  | **0.5.x** | Uncertainty | Propagation through arithmetic and conversions | ✅ Complete |
248
- | **0.5.x** | Unit Systems | `BasisMap`, `UnitSystem` | 🚧 In Progress |
249
- | **0.7.x** | Pydantic Integration | Type-safe quantity validation | ⏳ Planned |
328
+ | **0.5.x** | Unit Systems | `BasisTransform`, `UnitSystem`, cross-basis conversion | Complete |
329
+ | **0.6.x** | Pydantic Integration | Type-safe quantity validation | ⏳ Planned |
330
+ | **0.7.x** | NumPy Arrays | Vectorized conversion and arithmetic | ⏳ Planned |
250
331
 
251
332
  See full roadmap: [ROADMAP.md](./ROADMAP.md)
252
333
 
@@ -55,6 +55,9 @@ To best answer this question, we turn to an age-old technique ([dimensional anal
55
55
  | **`Ratio`** | `ucon.core` | Represents the division of two `Number` objects; captures relationships between quantities. | Expressing rates, densities, efficiencies (e.g., energy / time = power, length / time = velocity). |
56
56
  | **`Map`** hierarchy | `ucon.maps` | Composable conversion morphisms: `LinearMap`, `AffineMap`, `ComposedMap`. | Defining conversion functions between units (e.g., meter→foot, celsius→kelvin). |
57
57
  | **`ConversionGraph`** | `ucon.graph` | Registry of unit conversion edges with BFS path composition. | Converting between units via `Number.to(target)`; managing default and custom graphs. |
58
+ | **`UnitSystem`** | `ucon.core` | Named mapping from dimensions to base units (e.g., SI, Imperial). | Defining coherent unit systems; grouping base units by dimension. |
59
+ | **`BasisTransform`** | `ucon.core` | Matrix-based transformation between dimensional exponent spaces. | Converting between incompatible dimensional structures; exact arithmetic with `Fraction`. |
60
+ | **`RebasedUnit`** | `ucon.core` | A unit rebased to another system's dimension, preserving provenance. | Cross-basis conversions; tracking original unit through basis changes. |
58
61
  | **`units` module** | `ucon.units` | Defines canonical unit instances (SI, imperial, information, and derived units). | Quick access to standard physical units (`units.meter`, `units.foot`, `units.byte`, etc.). |
59
62
 
60
63
  ### Under the Hood
@@ -198,6 +201,83 @@ length_ft = length.to(units.foot)
198
201
  print(length_ft) # <4.048... ± 0.0164... ft>
199
202
  ```
200
203
 
204
+ Unit systems and basis transforms enable conversions between incompatible dimensional structures.
205
+ This goes beyond simple unit conversion (meter → foot) into structural transformation:
206
+
207
+ ```python
208
+ from fractions import Fraction
209
+ from ucon import BasisTransform, Dimension, Unit, UnitSystem, units
210
+ from ucon.graph import ConversionGraph
211
+ from ucon.maps import LinearMap
212
+
213
+ # The realm of Valdris has three fundamental dimensions:
214
+ # - Aether (A): magical energy substrate
215
+ # - Resonance (R): vibrational frequency of magic
216
+ # - Substance (S): physical matter
217
+ #
218
+ # These combine into SI dimensions via a transformation matrix:
219
+ #
220
+ # | L | | 2 0 0 | | A |
221
+ # | M | = | 1 0 1 | × | R |
222
+ # | T | |-2 -1 0 | | S |
223
+ #
224
+ # Reading the columns:
225
+ # - 1 aether contributes: L², M, T⁻² (energy-like)
226
+ # - 1 resonance contributes: T⁻¹ (frequency-like)
227
+ # - 1 substance contributes: M (mass-like)
228
+
229
+ # Fantasy base units
230
+ mote = Unit(name='mote', dimension=Dimension.energy, aliases=('mt',))
231
+ chime = Unit(name='chime', dimension=Dimension.frequency, aliases=('ch',))
232
+ ite = Unit(name='ite', dimension=Dimension.mass, aliases=('it',))
233
+
234
+ valdris = UnitSystem(
235
+ name="Valdris",
236
+ bases={
237
+ Dimension.energy: mote,
238
+ Dimension.frequency: chime,
239
+ Dimension.mass: ite,
240
+ }
241
+ )
242
+
243
+ # The basis transform encodes how Valdris dimensions compose into SI
244
+ valdris_to_si = BasisTransform(
245
+ src=valdris,
246
+ dst=units.si,
247
+ src_dimensions=(Dimension.energy, Dimension.frequency, Dimension.mass),
248
+ dst_dimensions=(Dimension.energy, Dimension.frequency, Dimension.mass),
249
+ matrix=(
250
+ (2, 0, 0), # energy: 2 × aether
251
+ (1, 0, 1), # frequency: aether + substance
252
+ (-2, -1, 0), # mass: -2×aether - resonance
253
+ ),
254
+ )
255
+
256
+ # Physical calibration: how many SI units per fantasy unit
257
+ graph = ConversionGraph()
258
+ graph.connect_systems(
259
+ basis_transform=valdris_to_si,
260
+ edges={
261
+ (mote, units.joule): LinearMap(42), # 1 mote = 42 J
262
+ (chime, units.hertz): LinearMap(7), # 1 chime = 7 Hz
263
+ (ite, units.kilogram): LinearMap(Fraction(1, 2)), # 1 ite = 0.5 kg
264
+ }
265
+ )
266
+
267
+ # Game engine converts between physics systems
268
+ energy_map = graph.convert(src=mote, dst=units.joule)
269
+ energy_map(10) # 420 joules from 10 motes
270
+
271
+ # Inverse: display real-world values in game units
272
+ joule_to_mote = graph.convert(src=units.joule, dst=mote)
273
+ joule_to_mote(420) # 10 motes
274
+
275
+ # The transform is invertible with exact Fraction arithmetic
276
+ valdris_to_si.is_invertible # True
277
+ ```
278
+
279
+ This enables fantasy game physics, or any field where the dimensional structure differs from SI.
280
+
201
281
  ---
202
282
 
203
283
  ## Roadmap Highlights
@@ -208,8 +288,9 @@ print(length_ft) # <4.048... ± 0.0164... ft>
208
288
  | **0.4.x** | Conversion System | `ConversionGraph`, `Number.to()`, callable units | ✅ Complete |
209
289
  | **0.5.0** | Dimensionless Units | Pseudo-dimensions for angle, solid angle, ratio | ✅ Complete |
210
290
  | **0.5.x** | Uncertainty | Propagation through arithmetic and conversions | ✅ Complete |
211
- | **0.5.x** | Unit Systems | `BasisMap`, `UnitSystem` | 🚧 In Progress |
212
- | **0.7.x** | Pydantic Integration | Type-safe quantity validation | ⏳ Planned |
291
+ | **0.5.x** | Unit Systems | `BasisTransform`, `UnitSystem`, cross-basis conversion | Complete |
292
+ | **0.6.x** | Pydantic Integration | Type-safe quantity validation | ⏳ Planned |
293
+ | **0.7.x** | NumPy Arrays | Vectorized conversion and arithmetic | ⏳ Planned |
213
294
 
214
295
  See full roadmap: [ROADMAP.md](./ROADMAP.md)
215
296
 
@@ -24,9 +24,9 @@ ucon is a dimensional analysis library for engineers building systems where unit
24
24
  | v0.4.x | Core Conversion + Information | Complete |
25
25
  | v0.5.0 | Dimensionless Units | Complete |
26
26
  | v0.5.x | Uncertainty Propagation | Complete |
27
- | v0.5.x | BasisMap + UnitSystem | Planned |
28
- | v0.6.0 | NumPy Array Support | Planned |
29
- | v0.7.0 | Pydantic + Serialization | Planned |
27
+ | v0.5.x | BasisTransform + UnitSystem | Complete |
28
+ | v0.6.0 | Pydantic + Serialization | Planned |
29
+ | v0.7.0 | NumPy Array Support | Planned |
30
30
  | v0.8.0 | String Parsing | Planned |
31
31
  | v0.9.0 | Constants + Logarithmic Units | Planned |
32
32
  | v0.10.0 | DataFrame Integration | Planned |
@@ -34,18 +34,21 @@ ucon is a dimensional analysis library for engineers building systems where unit
34
34
 
35
35
  ---
36
36
 
37
- ## Current Version: **v0.5.x** (in progress)
37
+ ## Current Version: **v0.5.x** (complete)
38
38
 
39
39
  Building on v0.5.0 baseline:
40
- - `ucon.core` (`Dimension`, `Scale`, `Unit`, `UnitFactor`, `UnitProduct`, `Number`, `Ratio`)
40
+ - `ucon.core` (`Dimension`, `Scale`, `Unit`, `UnitFactor`, `UnitProduct`, `Number`, `Ratio`, `UnitSystem`, `BasisTransform`, `RebasedUnit`)
41
41
  - `ucon.maps` (`Map`, `LinearMap`, `AffineMap`, `ComposedMap` with `derivative()`)
42
- - `ucon.graph` (`ConversionGraph`, default graph, `get_default_graph()`, `using_graph()`)
43
- - `ucon.units` (SI + imperial + information + angle + ratio units, callable syntax)
42
+ - `ucon.graph` (`ConversionGraph`, default graph, `get_default_graph()`, `using_graph()`, cross-basis conversion)
43
+ - `ucon.units` (SI + imperial + information + angle + ratio units, callable syntax, `si` and `imperial` systems)
44
+ - `ucon.algebra` (`Vector` with `Fraction` exponents, `Exponent`)
44
45
  - Callable unit API: `meter(5)`, `(mile / hour)(60)`
45
46
  - `Number.simplify()` for base-scale normalization
46
47
  - `Dimension.information` with `units.bit`, `units.byte`
47
48
  - Pseudo-dimensions: `angle`, `solid_angle`, `ratio` with semantic isolation
48
49
  - Uncertainty propagation: `meter(1.234, uncertainty=0.005)` with quadrature arithmetic
50
+ - `BasisTransform` for cross-system dimensional mapping with exact matrix arithmetic
51
+ - `UnitSystem` for named dimension-to-unit groupings
49
52
 
50
53
  ---
51
54
 
@@ -134,40 +137,31 @@ Building on v0.5.0 baseline:
134
137
 
135
138
  ---
136
139
 
137
- ## v0.5.x — BasisMap + UnitSystem
140
+ ## v0.5.x — BasisTransform + UnitSystem (Complete)
138
141
 
139
142
  **Theme:** Cross-system architecture.
140
143
 
141
- - [ ] `UnitSystem` class (named grouping of base units)
142
- - [ ] `BasisMap` class (structural equivalence between systems)
143
- - [ ] Prebuilt systems: `si`, `imperial`, `cgs`
144
- - [ ] `graph.connect_systems()` for bulk edge creation
145
- - [ ] Support for custom domain dimensions
144
+ - [x] `Vector` with `Fraction` exponents for exact arithmetic
145
+ - [x] `UnitSystem` class (named dimension-to-unit mapping)
146
+ - [x] `BasisTransform` class (matrix-based dimensional basis transformation)
147
+ - [x] `RebasedUnit` class (provenance-preserving cross-basis unit)
148
+ - [x] `NonInvertibleTransform` exception for surjective transforms
149
+ - [x] Prebuilt systems: `units.si`, `units.imperial`
150
+ - [x] `graph.add_edge()` with `basis_transform` parameter
151
+ - [x] `graph.connect_systems()` for bulk edge creation
152
+ - [x] Cross-basis conversion via rebased paths
153
+ - [x] Introspection: `list_transforms()`, `list_rebased_units()`, `edges_for_transform()`
146
154
 
147
155
  **Outcomes:**
148
- - `BasisMap` enables system-aware "express in base units" functionality
156
+ - `BasisTransform` enables conversions between incompatible dimensional structures
157
+ - Matrix operations with exact `Fraction` arithmetic (no floating-point drift)
158
+ - Invertibility detection with clear error messages for surjective transforms
149
159
  - Named unit systems for domain-specific workflows
150
- - Foundation for plugin-style system extensions
160
+ - Foundation for custom dimension domains
151
161
 
152
162
  ---
153
163
 
154
- ## v0.6.0 — NumPy Array Support
155
-
156
- **Theme:** Scientific computing integration.
157
-
158
- - [ ] `Number` wraps `np.ndarray` values
159
- - [ ] Vectorized conversion
160
- - [ ] Vectorized arithmetic with uncertainty propagation
161
- - [ ] Performance benchmarks
162
-
163
- **Outcomes:**
164
- - Seamless integration with NumPy-based scientific workflows
165
- - Efficient batch conversions for large datasets
166
- - Performance characteristics documented and optimized
167
-
168
- ---
169
-
170
- ## v0.7.0 — Pydantic + Serialization
164
+ ## v0.6.0 — Pydantic + Serialization
171
165
 
172
166
  **Theme:** API and persistence integration.
173
167
 
@@ -183,6 +177,22 @@ Building on v0.5.0 baseline:
183
177
 
184
178
  ---
185
179
 
180
+ ## v0.7.0 — NumPy Array Support
181
+
182
+ **Theme:** Scientific computing integration.
183
+
184
+ - [ ] `Number` wraps `np.ndarray` values
185
+ - [ ] Vectorized conversion
186
+ - [ ] Vectorized arithmetic with uncertainty propagation
187
+ - [ ] Performance benchmarks
188
+
189
+ **Outcomes:**
190
+ - Seamless integration with NumPy-based scientific workflows
191
+ - Efficient batch conversions for large datasets
192
+ - Performance characteristics documented and optimized
193
+
194
+ ---
195
+
186
196
  ## v0.8.0 — String Parsing
187
197
 
188
198
  **Theme:** Ergonomic input.