quantia 0.1.0__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 (35) hide show
  1. quantia-0.1.0/LICENSE +21 -0
  2. quantia-0.1.0/PKG-INFO +276 -0
  3. quantia-0.1.0/README.md +239 -0
  4. quantia-0.1.0/pyproject.toml +27 -0
  5. quantia-0.1.0/quantia/__init__.py +42 -0
  6. quantia-0.1.0/quantia/_array.py +173 -0
  7. quantia-0.1.0/quantia/_compound.py +416 -0
  8. quantia-0.1.0/quantia/_config.py +67 -0
  9. quantia-0.1.0/quantia/_exceptions.py +24 -0
  10. quantia-0.1.0/quantia/_io.py +53 -0
  11. quantia-0.1.0/quantia/_registry.py +80 -0
  12. quantia-0.1.0/quantia/_scalar.py +145 -0
  13. quantia-0.1.0/quantia/math.py +337 -0
  14. quantia-0.1.0/quantia/prob/__init__.py +3 -0
  15. quantia-0.1.0/quantia/prob/_array.py +184 -0
  16. quantia-0.1.0/quantia/prob/_config.py +1 -0
  17. quantia-0.1.0/quantia/prob/_copula.py +123 -0
  18. quantia-0.1.0/quantia/prob/_distributions.py +58 -0
  19. quantia-0.1.0/quantia/prob/_scalar.py +253 -0
  20. quantia-0.1.0/quantia/profiling/benchmark.py +331 -0
  21. quantia-0.1.0/quantia/units/__init__.py +9 -0
  22. quantia-0.1.0/quantia/units/common.py +14 -0
  23. quantia-0.1.0/quantia/units/data.py +11 -0
  24. quantia-0.1.0/quantia/units/imperial.py +24 -0
  25. quantia-0.1.0/quantia/units/petroleum.py +39 -0
  26. quantia-0.1.0/quantia/units/si.py +70 -0
  27. quantia-0.1.0/quantia.egg-info/PKG-INFO +276 -0
  28. quantia-0.1.0/quantia.egg-info/SOURCES.txt +33 -0
  29. quantia-0.1.0/quantia.egg-info/dependency_links.txt +1 -0
  30. quantia-0.1.0/quantia.egg-info/top_level.txt +5 -0
  31. quantia-0.1.0/setup.cfg +4 -0
  32. quantia-0.1.0/tests/test_algebra.py +46 -0
  33. quantia-0.1.0/tests/test_config.py +40 -0
  34. quantia-0.1.0/tests/test_core.py +127 -0
  35. quantia-0.1.0/tests/test_serialization.py +118 -0
quantia-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Juan Ignacio Sivori
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
quantia-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,276 @@
1
+ Metadata-Version: 2.4
2
+ Name: quantia
3
+ Version: 0.1.0
4
+ Summary: Unit-aware arithmetic with Monte Carlo uncertainty propagation
5
+ Author: Juan Ignacio Sivori
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Juan Ignacio Sivori
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/JuaniSivo/quantia
29
+ Keywords: units,dimensional analysis,monte carlo,uncertainty
30
+ Classifier: Programming Language :: Python :: 3
31
+ Classifier: License :: OSI Approved :: MIT License
32
+ Classifier: Operating System :: OS Independent
33
+ Requires-Python: >=3.11
34
+ Description-Content-Type: text/markdown
35
+ License-File: LICENSE
36
+ Dynamic: license-file
37
+
38
+ # quantia
39
+
40
+ A pure-Python library for **unit-aware arithmetic** with first-class support for **Monte Carlo uncertainty propagation**.
41
+
42
+ No numpy required. No dependencies beyond the standard library.
43
+
44
+ ---
45
+
46
+ ## Installation
47
+
48
+ ```bash
49
+ pip install quantia
50
+ ```
51
+
52
+ ---
53
+
54
+ ## The Four Types
55
+
56
+ | Type | Use when |
57
+ |------|----------|
58
+ | `UnitFloat` | exact scalar with a unit |
59
+ | `UnitArray` | exact vector with a unit |
60
+ | `ProbUnitFloat` | uncertain scalar (Monte Carlo samples) |
61
+ | `ProbUnitArray` | uncertain vector of the same quantity |
62
+
63
+ ---
64
+
65
+ ## Quick Start
66
+
67
+ ### Exact scalars
68
+
69
+ ```python
70
+ import quantia as qu
71
+
72
+ d = qu.Q(100.0, "m")
73
+ t = qu.Q(9.81, "s")
74
+ v = d / t # UnitFloat(10.19…, 'm/s')
75
+
76
+ v.to("km/h") # unit conversion
77
+ v.to_si() # always works
78
+
79
+ qu.Q(100.0, "°C").to("K") # UnitFloat(373.15, 'K')
80
+ qu.Q(100.0, "°C").to("°F") # UnitFloat(212.0, '°F')
81
+ ```
82
+
83
+ ### Exact arrays
84
+
85
+ ```python
86
+ heights = qu.QA([1.75, 1.80, 1.65], "m")
87
+
88
+ heights.mean() # UnitFloat(1.733…, 'm')
89
+ heights.sum()
90
+ heights.to("cm")
91
+
92
+ # Boolean mask filtering
93
+ tall = heights[heights > qu.Q(1.78, "m")] # UnitArray([1.80], 'm')
94
+ ```
95
+
96
+ ### Uncertainty propagation
97
+
98
+ ```python
99
+ with qu.config(n_samples=2000, seed=42):
100
+ efficiency = qu.ProbUnitFloat.uniform(0.88, 0.95, "1")
101
+ power_in = qu.ProbUnitFloat.normal(500.0, 10.0, "W")
102
+
103
+ power_out = efficiency * power_in
104
+
105
+ power_out.mean() # UnitFloat(~457 W)
106
+ power_out.std()
107
+ power_out.interval(0.95) # (lo, hi) 95% CI as UnitFloat tuple
108
+ power_out.percentile(10)
109
+ ```
110
+
111
+ ### Correlated inputs
112
+
113
+ When inputs are not independent, use a Gaussian copula:
114
+
115
+ ```python
116
+ src = qu.CorrelatedSource(n_vars=2, rho=0.8)
117
+
118
+ x = src.draw(0, "normal", "m", mean=10, std=1)
119
+ y = src.draw(1, "uniform", "s", low=1, high=3)
120
+
121
+ speed = x / y # ProbUnitFloat, correlated samples
122
+ ```
123
+
124
+ Or pass a full correlation matrix:
125
+
126
+ ```python
127
+ src = qu.CorrelatedSource(corr_matrix=[
128
+ [1.0, 0.7, 0.4],
129
+ [0.7, 1.0, 0.3],
130
+ [0.4, 0.3, 1.0],
131
+ ])
132
+ ```
133
+
134
+ ---
135
+
136
+ ## Unit Expressions
137
+
138
+ quantia parses unit strings with a full tokenizer:
139
+
140
+ ```python
141
+ qu.Q(9.81, "m/s^2")
142
+ qu.Q(1.0, "kg·m/s^2") # · or * for multiplication
143
+ qu.Q(4.0, "m^(1/2)") # rational exponents
144
+ qu.Q(1.0, "kg/m^2/s") # chained division
145
+ ```
146
+
147
+ ### Built-in unit domains
148
+
149
+ | Domain | Examples |
150
+ |--------|---------|
151
+ | SI base | `m`, `kg`, `s`, `K`, `A`, `mol` |
152
+ | SI derived | `N`, `J`, `W`, `Pa`, `V`, `Ω`, `Hz` |
153
+ | Temperature | `°C`, `°F`, `K` |
154
+ | Imperial | `ft`, `lb`, `psi`, `BTU`, `hp`, `mph` |
155
+ | Petroleum | `bbl`, `Mbbl`, `psi_g`, `scf`, `Mscf`, `°API` |
156
+ | Data | `B`, `KB`, `MB`, `GB`, `TB`, `bit` |
157
+
158
+ ### Semantic / tagged units
159
+
160
+ Dimensionally equal but semantically distinct units that won't cancel:
161
+
162
+ ```python
163
+ from quantia import register_tagged
164
+
165
+ register_tagged("Sm3_res", "m3", "reservoir")
166
+ register_tagged("Sm3_st", "m3", "stock_tank")
167
+
168
+ Rs = qu.Q(150.0, "Sm3_res") / qu.Q(1.0, "Sm3_st")
169
+ # UnitFloat(150.0, 'Sm3_res/Sm3_st') — does not reduce to 1
170
+ ```
171
+
172
+ ---
173
+
174
+ ## Math Functions
175
+
176
+ `quantia.math` is a drop-in replacement for the stdlib `math` module that dispatches transparently on all four types:
177
+
178
+ ```python
179
+ import quantia.math as mmath
180
+
181
+ mmath.log10(x) # float, UnitFloat, ProbUnitFloat, UnitArray, ProbUnitArray
182
+ mmath.exp(x)
183
+ mmath.sqrt(x) # preserves units: sqrt(m^2) → m
184
+ mmath.sin(x) # requires angle unit on UnitFloat; raises DimensionError otherwise
185
+ mmath.cos(x)
186
+ mmath.atan2(y, x)
187
+ ```
188
+
189
+ ---
190
+
191
+ ## Configuration
192
+
193
+ ```python
194
+ with qu.config(n_samples=5000, seed=42):
195
+ x = qu.ProbUnitFloat.normal(10.0, 1.0, "m")
196
+ y = qu.ProbUnitFloat.uniform(0.0, 1.0, "s")
197
+ # config restored on exit; contexts nest cleanly
198
+ ```
199
+
200
+ ---
201
+
202
+ ## Serialization
203
+
204
+ ```python
205
+ # Save and load any quantia object
206
+ qu.save(power_out, "result.json")
207
+ result = qu.load("result.json")
208
+
209
+ # Dict round-trip
210
+ d = power_out.to_dict()
211
+ pf2 = qu.from_dict(d)
212
+ ```
213
+
214
+ ### CSV export
215
+
216
+ ```python
217
+ # UnitArray — single column of values
218
+ heights.to_csv("heights.csv")
219
+
220
+ # ProbUnitArray — mean, std, CI bounds per element
221
+ layer_thicknesses = qu.QPA([t1, t2, t3]) # must be same unit
222
+ layer_thicknesses.to_csv("stats.csv", confidence=0.90)
223
+ layer_thicknesses.samples_to_csv("raw.csv")
224
+ ```
225
+
226
+ ---
227
+
228
+ ## Error Handling
229
+
230
+ quantia raises named exceptions from `quantia._exceptions`:
231
+
232
+ ```python
233
+ from quantia import IncompatibleUnitsError, DimensionError, UnknownUnitError
234
+
235
+ qu.Q(1.0, "m") + qu.Q(1.0, "s") # → IncompatibleUnitsError
236
+ mmath.sin(qu.Q(1.0, "m")) # → DimensionError
237
+ qu.Q(1.0, "furlongs") # → UnknownUnitError
238
+ ```
239
+
240
+ ---
241
+
242
+ ## Running Tests
243
+
244
+ ```bash
245
+ pip install pytest
246
+ pytest tests/ -v
247
+ ```
248
+
249
+ 56 tests covering scalar arithmetic, array operations, probabilistic math,
250
+ unit algebra invariants, serialization, and the config system.
251
+
252
+ ---
253
+
254
+ ## Benchmarks
255
+
256
+ ```bash
257
+ python -m quantia.profiling.benchmark
258
+ python -m quantia.profiling.benchmark --profile # cProfile detail at n=10k
259
+ python -m quantia.profiling.benchmark --n 10000 # single sample size
260
+ ```
261
+
262
+ Typical throughput on a modern laptop (stdlib backend, no numpy):
263
+
264
+ | Operation | n=10k |
265
+ |-----------|-------|
266
+ | Scalar arithmetic chain | ~1ms |
267
+ | `ProbUnitFloat.normal` construction | ~4ms |
268
+ | `mean()` | ~0.1ms |
269
+ | `interval(0.95)` | ~0ms (cached sort) |
270
+ | Gaussian copula k=3 | ~33ms |
271
+
272
+ ---
273
+
274
+ ## License
275
+
276
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,239 @@
1
+ # quantia
2
+
3
+ A pure-Python library for **unit-aware arithmetic** with first-class support for **Monte Carlo uncertainty propagation**.
4
+
5
+ No numpy required. No dependencies beyond the standard library.
6
+
7
+ ---
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ pip install quantia
13
+ ```
14
+
15
+ ---
16
+
17
+ ## The Four Types
18
+
19
+ | Type | Use when |
20
+ |------|----------|
21
+ | `UnitFloat` | exact scalar with a unit |
22
+ | `UnitArray` | exact vector with a unit |
23
+ | `ProbUnitFloat` | uncertain scalar (Monte Carlo samples) |
24
+ | `ProbUnitArray` | uncertain vector of the same quantity |
25
+
26
+ ---
27
+
28
+ ## Quick Start
29
+
30
+ ### Exact scalars
31
+
32
+ ```python
33
+ import quantia as qu
34
+
35
+ d = qu.Q(100.0, "m")
36
+ t = qu.Q(9.81, "s")
37
+ v = d / t # UnitFloat(10.19…, 'm/s')
38
+
39
+ v.to("km/h") # unit conversion
40
+ v.to_si() # always works
41
+
42
+ qu.Q(100.0, "°C").to("K") # UnitFloat(373.15, 'K')
43
+ qu.Q(100.0, "°C").to("°F") # UnitFloat(212.0, '°F')
44
+ ```
45
+
46
+ ### Exact arrays
47
+
48
+ ```python
49
+ heights = qu.QA([1.75, 1.80, 1.65], "m")
50
+
51
+ heights.mean() # UnitFloat(1.733…, 'm')
52
+ heights.sum()
53
+ heights.to("cm")
54
+
55
+ # Boolean mask filtering
56
+ tall = heights[heights > qu.Q(1.78, "m")] # UnitArray([1.80], 'm')
57
+ ```
58
+
59
+ ### Uncertainty propagation
60
+
61
+ ```python
62
+ with qu.config(n_samples=2000, seed=42):
63
+ efficiency = qu.ProbUnitFloat.uniform(0.88, 0.95, "1")
64
+ power_in = qu.ProbUnitFloat.normal(500.0, 10.0, "W")
65
+
66
+ power_out = efficiency * power_in
67
+
68
+ power_out.mean() # UnitFloat(~457 W)
69
+ power_out.std()
70
+ power_out.interval(0.95) # (lo, hi) 95% CI as UnitFloat tuple
71
+ power_out.percentile(10)
72
+ ```
73
+
74
+ ### Correlated inputs
75
+
76
+ When inputs are not independent, use a Gaussian copula:
77
+
78
+ ```python
79
+ src = qu.CorrelatedSource(n_vars=2, rho=0.8)
80
+
81
+ x = src.draw(0, "normal", "m", mean=10, std=1)
82
+ y = src.draw(1, "uniform", "s", low=1, high=3)
83
+
84
+ speed = x / y # ProbUnitFloat, correlated samples
85
+ ```
86
+
87
+ Or pass a full correlation matrix:
88
+
89
+ ```python
90
+ src = qu.CorrelatedSource(corr_matrix=[
91
+ [1.0, 0.7, 0.4],
92
+ [0.7, 1.0, 0.3],
93
+ [0.4, 0.3, 1.0],
94
+ ])
95
+ ```
96
+
97
+ ---
98
+
99
+ ## Unit Expressions
100
+
101
+ quantia parses unit strings with a full tokenizer:
102
+
103
+ ```python
104
+ qu.Q(9.81, "m/s^2")
105
+ qu.Q(1.0, "kg·m/s^2") # · or * for multiplication
106
+ qu.Q(4.0, "m^(1/2)") # rational exponents
107
+ qu.Q(1.0, "kg/m^2/s") # chained division
108
+ ```
109
+
110
+ ### Built-in unit domains
111
+
112
+ | Domain | Examples |
113
+ |--------|---------|
114
+ | SI base | `m`, `kg`, `s`, `K`, `A`, `mol` |
115
+ | SI derived | `N`, `J`, `W`, `Pa`, `V`, `Ω`, `Hz` |
116
+ | Temperature | `°C`, `°F`, `K` |
117
+ | Imperial | `ft`, `lb`, `psi`, `BTU`, `hp`, `mph` |
118
+ | Petroleum | `bbl`, `Mbbl`, `psi_g`, `scf`, `Mscf`, `°API` |
119
+ | Data | `B`, `KB`, `MB`, `GB`, `TB`, `bit` |
120
+
121
+ ### Semantic / tagged units
122
+
123
+ Dimensionally equal but semantically distinct units that won't cancel:
124
+
125
+ ```python
126
+ from quantia import register_tagged
127
+
128
+ register_tagged("Sm3_res", "m3", "reservoir")
129
+ register_tagged("Sm3_st", "m3", "stock_tank")
130
+
131
+ Rs = qu.Q(150.0, "Sm3_res") / qu.Q(1.0, "Sm3_st")
132
+ # UnitFloat(150.0, 'Sm3_res/Sm3_st') — does not reduce to 1
133
+ ```
134
+
135
+ ---
136
+
137
+ ## Math Functions
138
+
139
+ `quantia.math` is a drop-in replacement for the stdlib `math` module that dispatches transparently on all four types:
140
+
141
+ ```python
142
+ import quantia.math as mmath
143
+
144
+ mmath.log10(x) # float, UnitFloat, ProbUnitFloat, UnitArray, ProbUnitArray
145
+ mmath.exp(x)
146
+ mmath.sqrt(x) # preserves units: sqrt(m^2) → m
147
+ mmath.sin(x) # requires angle unit on UnitFloat; raises DimensionError otherwise
148
+ mmath.cos(x)
149
+ mmath.atan2(y, x)
150
+ ```
151
+
152
+ ---
153
+
154
+ ## Configuration
155
+
156
+ ```python
157
+ with qu.config(n_samples=5000, seed=42):
158
+ x = qu.ProbUnitFloat.normal(10.0, 1.0, "m")
159
+ y = qu.ProbUnitFloat.uniform(0.0, 1.0, "s")
160
+ # config restored on exit; contexts nest cleanly
161
+ ```
162
+
163
+ ---
164
+
165
+ ## Serialization
166
+
167
+ ```python
168
+ # Save and load any quantia object
169
+ qu.save(power_out, "result.json")
170
+ result = qu.load("result.json")
171
+
172
+ # Dict round-trip
173
+ d = power_out.to_dict()
174
+ pf2 = qu.from_dict(d)
175
+ ```
176
+
177
+ ### CSV export
178
+
179
+ ```python
180
+ # UnitArray — single column of values
181
+ heights.to_csv("heights.csv")
182
+
183
+ # ProbUnitArray — mean, std, CI bounds per element
184
+ layer_thicknesses = qu.QPA([t1, t2, t3]) # must be same unit
185
+ layer_thicknesses.to_csv("stats.csv", confidence=0.90)
186
+ layer_thicknesses.samples_to_csv("raw.csv")
187
+ ```
188
+
189
+ ---
190
+
191
+ ## Error Handling
192
+
193
+ quantia raises named exceptions from `quantia._exceptions`:
194
+
195
+ ```python
196
+ from quantia import IncompatibleUnitsError, DimensionError, UnknownUnitError
197
+
198
+ qu.Q(1.0, "m") + qu.Q(1.0, "s") # → IncompatibleUnitsError
199
+ mmath.sin(qu.Q(1.0, "m")) # → DimensionError
200
+ qu.Q(1.0, "furlongs") # → UnknownUnitError
201
+ ```
202
+
203
+ ---
204
+
205
+ ## Running Tests
206
+
207
+ ```bash
208
+ pip install pytest
209
+ pytest tests/ -v
210
+ ```
211
+
212
+ 56 tests covering scalar arithmetic, array operations, probabilistic math,
213
+ unit algebra invariants, serialization, and the config system.
214
+
215
+ ---
216
+
217
+ ## Benchmarks
218
+
219
+ ```bash
220
+ python -m quantia.profiling.benchmark
221
+ python -m quantia.profiling.benchmark --profile # cProfile detail at n=10k
222
+ python -m quantia.profiling.benchmark --n 10000 # single sample size
223
+ ```
224
+
225
+ Typical throughput on a modern laptop (stdlib backend, no numpy):
226
+
227
+ | Operation | n=10k |
228
+ |-----------|-------|
229
+ | Scalar arithmetic chain | ~1ms |
230
+ | `ProbUnitFloat.normal` construction | ~4ms |
231
+ | `mean()` | ~0.1ms |
232
+ | `interval(0.95)` | ~0ms (cached sort) |
233
+ | Gaussian copula k=3 | ~33ms |
234
+
235
+ ---
236
+
237
+ ## License
238
+
239
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,27 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "quantia"
7
+ version = "0.1.0"
8
+ requires-python = ">=3.11"
9
+ description = "Unit-aware arithmetic with Monte Carlo uncertainty propagation"
10
+ readme = "README.md"
11
+ license = { file = "LICENSE" }
12
+ authors = [{ name = "Juan Ignacio Sivori" }]
13
+ keywords = ["units", "dimensional analysis", "monte carlo", "uncertainty"]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ ]
19
+
20
+ [project.urls]
21
+ Homepage = "https://github.com/JuaniSivo/quantia" # TODO
22
+
23
+ [tool.setuptools.packages.find]
24
+ where = ["."]
25
+
26
+ [tool.pytest.ini_options]
27
+ pythonpath = ["."]
@@ -0,0 +1,42 @@
1
+ import quantia.units # noqa: F401 — populates registry + aliases
2
+
3
+ from quantia._scalar import UnitFloat
4
+ from quantia._array import UnitArray
5
+ from quantia.prob._scalar import ProbUnitFloat
6
+ from quantia.prob._array import ProbUnitArray
7
+ from quantia.prob._copula import CorrelatedSource
8
+ from quantia._exceptions import (
9
+ UnknownUnitError, IncompatibleUnitsError, DimensionError, UnitParseError
10
+ )
11
+ from quantia._compound import parse_unit, register_alias, register_tagged
12
+ from quantia._registry import register, get_unit, registered_symbols
13
+ from quantia._io import save, load, from_dict
14
+ from quantia._config import config
15
+
16
+
17
+ def Q(value: float, unit) -> UnitFloat:
18
+ """Exact scalar: Q(9.81, 'm/s^2')"""
19
+ return UnitFloat(value, unit)
20
+
21
+ def QA(values, unit) -> UnitArray:
22
+ """Exact array: QA([1.0, 2.0, 3.0], 'km')"""
23
+ return UnitArray(values, unit)
24
+
25
+ def QP(low: float, high: float, unit, n: int = None) -> ProbUnitFloat:
26
+ """Probabilistic scalar, uniform: QP(0.92, 0.96, '1')"""
27
+ return ProbUnitFloat.uniform(low, high, unit, n)
28
+
29
+ def QPA(elements) -> ProbUnitArray:
30
+ """Probabilistic array: QPA([p1, p2, p3])"""
31
+ return ProbUnitArray(elements)
32
+
33
+ __all__ = [
34
+ "Q", "QA", "QP", "QPA",
35
+ "UnitFloat", "UnitArray", "ProbUnitFloat", "ProbUnitArray",
36
+ "CorrelatedSource",
37
+ "parse_unit", "register_alias", "register_tagged",
38
+ "register", "get_unit", "registered_symbols",
39
+ "UnknownUnitError", "IncompatibleUnitsError", "DimensionError", "UnitParseError",
40
+ "save", "load", "from_dict",
41
+ "config",
42
+ ]