From 642fbff72d538956301a59e476a87c2305a8b82a Mon Sep 17 00:00:00 2001 From: Gernot Bauer Date: Fri, 13 Dec 2024 19:31:21 +0100 Subject: [PATCH] use uv and mkdocs, add dependencies to pyproject.toml, restructured source, added stub --- .gitignore | 8 +- Cargo.toml | 17 ++- pyproject.toml | 7 -- si-units/.python-version | 1 + si-units/Cargo.toml | 59 +++++----- si-units/README.md | 4 +- si-units/docs/Makefile | 20 ---- si-units/docs/api.md | 25 +++++ si-units/docs/api.rst | 109 ------------------ si-units/docs/base.md | 26 +++++ si-units/docs/conf.py | 65 ----------- si-units/docs/derived.md | 61 ++++++++++ si-units/docs/examples.md | 117 +++++++++++++++++++ si-units/docs/examples.rst | 96 ---------------- si-units/docs/index.md | 76 +++++++++++++ si-units/docs/index.rst | 30 ----- si-units/docs/javascript/mathjax.js | 19 ++++ si-units/docs/prefixes.md | 34 ++++++ si-units/license-apache | 2 +- si-units/license-mit | 2 +- si-units/mkdocs.yml | 82 ++++++++++++++ si-units/pyproject.toml | 46 ++++++++ si-units/src/lib.rs | 66 +---------- si-units/src/si_units/__init__.py | 167 ++++++++++++++++++++++++++++ si-units/src/si_units/_core.pyi | 134 ++++++++++++++++++++++ si-units/src/si_units/py.typed | 0 26 files changed, 845 insertions(+), 428 deletions(-) delete mode 100644 pyproject.toml create mode 100644 si-units/.python-version delete mode 100644 si-units/docs/Makefile create mode 100644 si-units/docs/api.md delete mode 100644 si-units/docs/api.rst create mode 100644 si-units/docs/base.md delete mode 100644 si-units/docs/conf.py create mode 100644 si-units/docs/derived.md create mode 100644 si-units/docs/examples.md delete mode 100644 si-units/docs/examples.rst create mode 100644 si-units/docs/index.md delete mode 100644 si-units/docs/index.rst create mode 100644 si-units/docs/javascript/mathjax.js create mode 100644 si-units/docs/prefixes.md create mode 100644 si-units/mkdocs.yml create mode 100644 si-units/pyproject.toml create mode 100644 si-units/src/si_units/__init__.py create mode 100644 si-units/src/si_units/_core.pyi create mode 100644 si-units/src/si_units/py.typed diff --git a/.gitignore b/.gitignore index 21e096c..89ce790 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,12 @@ Cargo.lock *.so si-units/docs/_build si-units/docs/generated -/venv .ipynb_checkpoints *.ipynb __pycache__ -test_readme.py \ No newline at end of file +test_readme.py +*.lock + +# venv +/venv +.venv diff --git a/Cargo.toml b/Cargo.toml index 2d14098..b5c17d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,18 @@ +[workspace] +resolver = "2" +members = ["si-units", "example/extend_quantity"] + +[workspace.package] +version = "0.10.0" +authors = [ + "Philipp Rehner ", + "Gernot Bauer ", +] +edition = "2021" +license = "MIT OR Apache-2.0" +repository = "https://github.com/itt-ustutt/quantity" + + [package] name = "quantity" version = "0.10.0" @@ -20,8 +35,6 @@ exclude = ["/.github/*", "*.ipynb", "/docs"] features = ["python_numpy", "num-dual", "approx"] rustdoc-args = ["--html-in-header", "./src/docs-header.html"] -[workspace] -members = ["si-units", "example/extend_quantity"] [dependencies] typenum = "1.17" diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index 69fe497..0000000 --- a/pyproject.toml +++ /dev/null @@ -1,7 +0,0 @@ -[build-system] -requires = ["maturin>=1.0,<2.0"] -build-backend = "maturin" - -[tool.maturin] -bindings = "pyo3" -manifest-path = "si-units/Cargo.toml" diff --git a/si-units/.python-version b/si-units/.python-version new file mode 100644 index 0000000..c8cfe39 --- /dev/null +++ b/si-units/.python-version @@ -0,0 +1 @@ +3.10 diff --git a/si-units/Cargo.toml b/si-units/Cargo.toml index cd8224d..148d3b8 100644 --- a/si-units/Cargo.toml +++ b/si-units/Cargo.toml @@ -1,31 +1,28 @@ -[package] -name = "si-units" -version = "0.10.0" -authors = [ - "Philipp Rehner ", - "Gernot Bauer ", -] -rust-version = "1.81" -edition = "2021" -license = "MIT OR Apache-2.0" -description = "Representation of SI unit valued scalars and arrays." -homepage = "https://github.com/itt-ustutt/quantity/tree/master/si-units" -readme = "README.md" -repository = "https://github.com/itt-ustutt/quantity" -keywords = ["physics", "units", "SI"] -categories = ["data-structures", "science"] -exclude = ["*.ipynb", "/docs"] - -[lib] -name = "si_units" -crate-type = ["cdylib"] - -[dependencies] -ndarray = "0.16" -numpy = "0.23" -thiserror = "2.0" -regex = "1.10" - -[dependencies.pyo3] -version = "0.23" -features = ["extension-module", "abi3", "abi3-py37"] +[package] +name = "si-units" +version = "0.10.0" +authors = [ + "Philipp Rehner ", + "Gernot Bauer ", +] +rust-version = "1.81" +edition = "2021" +license = "MIT OR Apache-2.0" +description = "Representation of SI unit valued scalars and arrays." +homepage = "https://github.com/itt-ustutt/quantity/tree/master/si-units" +readme = "README.md" +repository = "https://github.com/itt-ustutt/quantity" +keywords = ["physics", "units", "SI"] +categories = ["data-structures", "science"] +exclude = ["*.ipynb", "/docs"] + +[lib] +name = "_core" +crate-type = ["cdylib"] + +[dependencies] +ndarray = "0.16" +numpy = "0.23" +pyo3 = { version = "0.23", features = ["extension-module", "abi3-py39"] } +regex = "1.11" +thiserror = "2.0" diff --git a/si-units/README.md b/si-units/README.md index bab3b41..a70bacc 100644 --- a/si-units/README.md +++ b/si-units/README.md @@ -3,7 +3,7 @@ [![documentation](https://img.shields.io/badge/docs-github--pages-blue)](https://itt-ustutt.github.io/quantity/index.html) [![PyPI version](https://badge.fury.io/py/si_units.svg)](https://badge.fury.io/py/si_units) -Representation of quantities with SI units. +Representation of quantities with SI units. The package is written with flexibility in mind and is able to represent arbitrarily complex units. In addition to simple scalar quantities, it can be used to decorate any complex data type (numpy arrays, PyTorch tensors) to provide unit checks. @@ -47,4 +47,4 @@ print(sqms) # [4, 9, 16] m² ## Documentation -For the documentation, see [here](https://itt-ustutt.github.io/quantity/index.html). +For the documentation, see [here](https://itt-ustutt.github.io/quantity/index.html). \ No newline at end of file diff --git a/si-units/docs/Makefile b/si-units/docs/Makefile deleted file mode 100644 index d4bb2cb..0000000 --- a/si-units/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/si-units/docs/api.md b/si-units/docs/api.md new file mode 100644 index 0000000..f98c67e --- /dev/null +++ b/si-units/docs/api.md @@ -0,0 +1,25 @@ +# API + +::: si_units._core.SIObject + options: + show_symbol_type_heading: true + members: + - __init__ + - cbrt + - sqrt + - has_unit + summary: + attributes: false + functions: true + +::: si_units._core.SIArray1 + options: + show_symbol_type_heading: true + members: + - __call__ + - linspace + - logspace + summary: + attributes: false + functions: true + diff --git a/si-units/docs/api.rst b/si-units/docs/api.rst deleted file mode 100644 index 3238b6c..0000000 --- a/si-units/docs/api.rst +++ /dev/null @@ -1,109 +0,0 @@ -API ---- - -.. currentmodule:: si_units - -.. contents:: Table of Contents - :depth: 3 - -SI Base Units and Associated Constants -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. csv-table:: Seven SI base units and their associated, exact-valued constants. - :header: "Unit", "Unit symbol", "Quantity", "Associated constant", "Associated constant name", "Associated constant value" - :widths: auto - - .. autoclass:: SECOND, :math:`\text{s}`, "time", .. autoclass:: DVCS, "Hyperfine transition frequency of Cs", :math:`\Delta\nu_\text{Cs}=9192631770~\text{Hz}` - .. autoclass:: METER, :math:`\text{m}`, length, .. autoclass:: CLIGHT, Speed of light, :math:`c=299792458~\frac{\text{m}}{\text{s}}` - .. autoclass:: KILOGRAM, :math:`\text{kg}`, mass, .. autoclass:: PLANCK, Planck constant, :math:`h=6.62607015\times 10^{-34}~\text{J}\cdot\text{s}` - .. autoclass:: AMPERE, :math:`\text{A}`, electric current, .. autoclass:: QE, Elementary charge, :math:`e=1.602176634\times 10^{-19}~\text{C}` - .. autoclass:: KELVIN, :math:`\text{K}`, thermodynamic temperature, .. autoclass:: KB, Boltzmann constant, :math:`k_\text{B}=1.380649\times 10^{-23}~\frac{\text{J}}{\text{K}}` - .. autoclass:: MOL, :math:`\text{mol}`, amount of substance, .. autoclass:: NAV, Avogadro constant, :math:`N_\text{A}=6.02214076\times 10^{23}~\text{mol}^{-1}` - .. autoclass:: CANDELA, :math:`\text{cd}`, luminous intensity, .. autoclass:: KCD, Luminous efficacy of :math:`540~\text{THz}` radiation, :math:`K_\text{cd}=683~\frac{\text{lm}}{\text{W}}` - -Derived Units -~~~~~~~~~~~~~ - -.. csv-table:: - :header: "Unit", "Unit symbol", "Quantity", "Definition" - :widths: auto - - .. autoclass:: HERTZ, :math:`\text{Hz}`, frequency, :math:`\text{s}^{-1}` - .. autoclass:: NEWTON, :math:`\text{N}`, force; weight, :math:`\text{kg}\frac{\text{m}}{\text{s}^2}` - .. autoclass:: PASCAL, :math:`\text{Pa}`, pressure; stress, :math:`\frac{\text{N}}{\text{m}^2}` - .. autoclass:: JOULE, :math:`\text{J}`, energy; work; heat, :math:`\text{N}\text{m}` - .. autoclass:: WATT, :math:`\text{W}`, power; radiant flux, :math:`\frac{\text{J}}{\text{s}}` - .. autoclass:: COULOMB, :math:`\text{C}`, electric charge, :math:`\text{A}\text{s}` - .. autoclass:: VOLT, :math:`\text{V}`, electrical potential difference, :math:`\frac{\text{W}}{\text{A}}` - .. autoclass:: FARAD, :math:`\text{F}`, capacitance, :math:`\frac{\text{C}}{\text{V}}` - .. autoclass:: OHM, :math:`\text{Ω}`, resistance; impedance; reactance, :math:`\frac{\text{V}}{\text{A}}` - .. autoclass:: SIEMENS, :math:`\text{S}`, electrical conductance, :math:`\text{Ω}^{-1}` - .. autoclass:: WEBER, :math:`\text{Wb}`, magnetic flux, :math:`\text{V}\text{s}` - .. autoclass:: TESLA, :math:`\text{T}`, magnetic flux density, :math:`\frac{\text{Wb}}{\text{m}^2}` - .. autoclass:: HENRY, :math:`\text{H}`, inductance, :math:`\frac{\text{Wb}}{\text{A}}` - -Additional Units -~~~~~~~~~~~~~~~~ - -For convenience, a number of commonly used units that are not directly combinations of SI base units is also included. -These constants simplify the specification of properties, that are not given in SI units. However, as the representation -of quantities is unique, they do not appear in formatted outputs. - -.. csv-table:: - :header: "Unit", "Unit symbol", "Quantity", "Definition" - :widths: auto - - .. autoclass:: ANGSTROM, :math:`\text{Å}`, length, :math:`10^{-10}~\text{m}` - .. autoclass:: AMU, :math:`\text{u}`, mass, :math:`1.6605390671738466\times 10^{-27}~\text{kg}` - .. autoclass:: AU, :math:`\text{au}`, length, :math:`149597870700~\text{m}` - .. autoclass:: BAR, :math:`\text{bar}`, pressure, :math:`10^5~\text{Pa}` - .. autoclass:: CALORIE, :math:`\text{cal}`, energy, :math:`4.184~\text{J}` - .. autoclass:: DAY, :math:`\text{d}`, time, :math:`86400~\text{s}` - .. autoclass:: DEBYE, :math:`\text{De}`, dipole moment, :math:`\sqrt{10^{-19}~\text{JÅ}^3}` - .. autoclass:: DEGREES, :math:`^\circ`, angle, :math:`\frac{\pi}{180}~\text{rad}` - .. autoclass:: GRAM, :math:`\text{g}`, mass, :math:`10^{-3}~\text{kg}` - .. autoclass:: HOUR, :math:`\text{h}`, time, :math:`3600~\text{s}` - .. autoclass:: LITER, :math:`\text{l}`, volume, :math:`10^{-3}~\text{m}^3` - .. autoclass:: MINUTE, :math:`\text{min}`, time, :math:`60~\text{s}` - .. autoclass:: RADIANS, :math:`\text{rad}`, angle, - -Additional Constants -~~~~~~~~~~~~~~~~~~~~ - -.. csv-table:: - :header: "Constant", "Name", "Symbol", "Value" - :widths: auto - - .. autoclass:: G, Gravitational constant, :math:`G`, :math:`6.6743\times 10^{-11}~\frac{\text{m}^3}{\text{kg}\cdot\text{s}^2}` - .. autoclass:: RGAS, Ideal gas constant, :math:`R=N_\text{Av}k_\text{B}`, :math:`8.31446261815324~\frac{\text{J}}{\text{mol}\cdot\text{K}}` - -Prefixes -~~~~~~~~ - -All units can be combined with the following prefixes: - -.. csv-table:: - :header: "Prefix", "Prefix symbol", "Value", "Prefix", "Prefix symbol", "Value" - :widths: auto - - .. autoclass:: DECI, :math:`\text{d}`, :math:`10^{-1}`, .. autoclass:: DECA, :math:`\text{da}`, :math:`10^{1}` - .. autoclass:: CENTI, :math:`\text{c}`, :math:`10^{-2}`, .. autoclass:: HECTO, :math:`\text{h}`, :math:`10^{2}` - .. autoclass:: MILLI, :math:`\text{m}`, :math:`10^{-3}`, .. autoclass:: KILO, :math:`\text{k}`, :math:`10^{3}` - .. autoclass:: MICRO, :math:`\text{µ}`, :math:`10^{-6}`, .. autoclass:: MEGA, :math:`\text{M}`, :math:`10^{6}` - .. autoclass:: NANO, :math:`\text{n}`, :math:`10^{-9}`, .. autoclass:: GIGA, :math:`\text{G}`, :math:`10^{9}` - .. autoclass:: PICO, :math:`\text{p}`, :math:`10^{-12}`, .. autoclass:: TERA, :math:`\text{T}`, :math:`10^{12}` - .. autoclass:: FEMTO, :math:`\text{f}`, :math:`10^{-15}`, .. autoclass:: PETA, :math:`\text{P}`, :math:`10^{15}` - .. autoclass:: ATTO, :math:`\text{a}`, :math:`10^{-18}`, .. autoclass:: EXA, :math:`\text{E}`, :math:`10^{18}` - .. autoclass:: ZEPTO, :math:`\text{z}`, :math:`10^{-21}`, .. autoclass:: ZETTA, :math:`\text{Z}`, :math:`10^{21}` - .. autoclass:: YOCTO, :math:`\text{y}`, :math:`10^{-24}`, .. autoclass:: YOTTA, :math:`\text{Y}`, :math:`10^{24}` - .. autoclass:: RONTO, :math:`\text{r}`, :math:`10^{-27}`, .. autoclass:: RONNA, :math:`\text{R}`, :math:`10^{27}` - .. autoclass:: QUECTO, :math:`\text{q}`, :math:`10^{-30}`, .. autoclass:: QUETTA, :math:`\text{Q}`, :math:`10^{30}` - -Datatypes -~~~~~~~~~ - -.. autosummary:: - :toctree: generated/ - - PySIObject - SIArray1 diff --git a/si-units/docs/base.md b/si-units/docs/base.md new file mode 100644 index 0000000..006616c --- /dev/null +++ b/si-units/docs/base.md @@ -0,0 +1,26 @@ +# SI Base Units and Associated Constants (AC) + +All capitalized entries in the `Unit` and `AC` (associated constants) columns from the table below can be imported: + + +| Unit | Symbol | Quantity | AC | AC Name | AC value | +| -------- | ------------ | ------------------------- | ------ | ----------------------------------------------- | -------------------------------------------------------------- | +| SECOND | $\text{s}$ | time | DVCS | Hyperfine transition frequency of Cs | $\Delta\nu_\text{Cs}=9192631770~\text{Hz}$ | +| METER | $\text{m}$ | length | CLIGHT | Speed of light | $c=299792458~\frac{\text{m}}{\text{s}}$ | +| KILOGRAM | $\text{kg}$ | mass | PLANCK | Planck constant | $h=6.62607015\times 10^{-34}~\text{J}\cdot\text{s}$ | +| AMPERE | $\text{A}$ | electric current | QE | Elementary charge | $e=1.602176634\times 10^{-19}~\text{C}$ | +| KELVIN | $\text{K}$ | thermodynamic temperature | KB | Boltzmann constant | $k_\text{B}=1.380649\times 10^{-23}~\frac{\text{J}}{\text{K}}$ | +| MOL | $\text{mol}$ | amount of substance | NAV | Avogadro constant | $N_\text{A}=6.02214076\times 10^{23}~\text{mol}^{-1}$ | +| CANDELA | $\text{cd}$ | luminous intensity | KCD | Luminous efficacy of $540~\text{THz}$ radiation | $K_\text{cd}=683~\frac{\text{lm}}{\text{W}}$ | + +## Example + +```py linenums="1" +from si_units import SECOND, DVCS +print(SECOND) +print(DVCS) +``` +``` +1 s +9.19263177 GHz +``` \ No newline at end of file diff --git a/si-units/docs/conf.py b/si-units/docs/conf.py deleted file mode 100644 index 97678d0..0000000 --- a/si-units/docs/conf.py +++ /dev/null @@ -1,65 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -import os -import sys -import si_units - -sys.path.append(os.path.abspath(os.path.join(__file__, "../.."))) -sys.path.insert(0, os.path.abspath('.')) - - -# -- Project information ----------------------------------------------------- - -project = 'si_units' -copyright = '2021, Philipp Rehner, Gernot Bauer' -author = 'Philipp Rehner, Gernot Bauer' - -# The full version, including alpha/beta/rc tags -release = si_units.__version__ - - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.autosummary', - 'sphinx.ext.doctest', - 'sphinx.ext.mathjax', - 'numpydoc', -] - -autosummary_generate = True -numpydoc_show_class_members = False - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'sphinx_rtd_theme' - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -# html_static_path = ['_static'] diff --git a/si-units/docs/derived.md b/si-units/docs/derived.md new file mode 100644 index 0000000..94cdf0a --- /dev/null +++ b/si-units/docs/derived.md @@ -0,0 +1,61 @@ +# Derived Units + +| Unit | Unit symbol | Quantity | Definition | +| ------- | ----------- | -------------------------------- | -------------------------------------- | +| HERTZ | $\text{Hz}$ | frequency | $\text{s}^{-1}$ | +| NEWTON | $\text{N}$ | force; weight | $\text{kg}\frac{\text{m}}{\text{s}^2}$ | +| PASCAL | $\text{Pa}$ | pressure; stress | $\frac{\text{N}}{\text{m}^2}$ | +| JOULE | $\text{J}$ | energy; work; heat | $\text{N}\text{m}$ | +| WATT | $\text{W}$ | power; radiant flux | $\frac{\text{J}}{\text{s}}$ | +| COULOMB | $\text{C}$ | electric charge | $\text{A}\text{s}$ | +| VOLT | $\text{V}$ | electrical potential difference | $\frac{\text{W}}{\text{A}}$ | +| FARAD | $\text{F}$ | capacitance | $\frac{\text{C}}{\text{V}}$ | +| OHM | $\text{Ω}$ | resistance; impedance; reactance | $\frac{\text{V}}{\text{A}}$ | +| SIEMENS | $\text{S}$ | electrical conductance | $\text{Ω}^{-1}$ | +| WEBER | $\text{Wb}$ | magnetic flux | $\text{V}\text{s}$ | +| TESLA | $\text{T}$ | magnetic flux density | $\frac{\text{Wb}}{\text{m}^2}$ | +| HENRY | $\text{H}$ | inductance | $\frac{\text{Wb}}{\text{A}}$ | + + +## Additional Units + +For convenience, a number of commonly used units that are not directly combinations of SI base units is also included. +These constants simplify the specification of properties, that are not given in SI units. However, as the representation +of quantities is unique, they do not appear in formatted outputs. + +| Unit | Unit symbol | Quantity | Definition | +| -------- | ------------ | ------------- | --------------------------------------------- | +| ANGSTROM | $\text{Å}$ | length | $10^{-10}~\text{m}$ | +| AMU | $\text{u}$ | mass | $1.6605390671738466\times 10^{-27}~\text{kg}$ | +| AU | $\text{au}$ | length | $149597870700~\text{m}$ | +| BAR | $\text{bar}$ | pressure | $10^5~\text{Pa}$ | +| CALORIE | $\text{cal}$ | energy | $4.184~\text{J}$ | +| DAY | $\text{d}$ | time | $86400~\text{s}$ | +| DEBYE | $\text{De}$ | dipole moment | $\sqrt{10^{-19}~\text{JÅ}^3}$ | +| DEGREES | $^\circ$ | angle | $\frac{\pi}{180}~\text{rad}$ | +| GRAM | $\text{g}$ | mass | $10^{-3}~\text{kg}$ | +| HOUR | $\text{h}$ | time | $3600~\text{s}$ | +| LITER | $\text{l}$ | volume | $10^{-3}~\text{m}^3$ | +| MINUTE | $\text{min}$ | time | $60~\text{s}$ | +| RADIANS | $\text{rad}$ | angle | | + +## Additional Constants + +| Constant | Name | Symbol | Value | +| -------- | ---------------------- | ------------------------- | ------------------------------------------------------------------- | +| G | Gravitational constant | $G$ | $6.6743\times 10^{-11}~\frac{\text{m}^3}{\text{kg}\cdot\text{s}^2}$ | +| RGAS | Ideal gas constant | $R=N_\text{Av}k_\text{B}$ | $8.31446261815324~\frac{\text{J}}{\text{mol}\cdot\text{K}}$ | + +### Example + +```py linenums="1" +from si_units import RGAS, CALORIE +from si_units import KILO # see prefixes +print(RGAS) +KCAL = KILO * CALORIE +print(KCAL) +``` +``` +8.31446261815324 J/mol/K +4.184 kJ +``` diff --git a/si-units/docs/examples.md b/si-units/docs/examples.md new file mode 100644 index 0000000..ea27d1a --- /dev/null +++ b/si-units/docs/examples.md @@ -0,0 +1,117 @@ +## Pressure of an ideal gas + +```py linenums="1" +from si_units import * +temperature = 298.15 * KELVIN +volume = 1.5 * METER**3 +moles = 75.0 * MOL +pressure = moles * RGAS * temperature / volume +print(pressure) +``` + +``` +123.94785148011941 kPa +``` + +You can use division to perform unit conversions. + +```py linenums="1" hl_lines="6-8" +from si_units import * +temperature = 298.15 * KELVIN +volume = 1.5 * METER**3 +moles = 75.0 * MOL +pressure = moles * RGAS * temperature / volume +print('pressure / bar: ', pressure / BAR) +print('pressure / mN/A^2:', pressure / (MILLI * NEWTON / ANGSTROM**2)) +print('volume / l: ', volume / LITER) +``` + +``` +pressure / bar: 1.2394785148011942 +pressure / mN/A^2: 1.239478514801194e-12 +volume / l: 1500.0 +``` + +## Gravitational pull of the moon on the earth + +```py linenums="1" +from si_units import * +mass_earth = 5.9724e24 * KILOGRAM +mass_moon = 7.346e22 * KILOGRAM +distance = 383.398 * KILO * METER +force = G * mass_earth * mass_moon / distance**2 +print(force) +``` + +``` +1.992075748302325e26 N +``` + +## Pressure distribution in the atmosphere + +Using the barometric formula. +This example demonstrates how dimensioned arrays can be constructed using numpy.ndarray's. + +```py linenums="1" +from si_units import * +import numpy as np + +z = np.linspace(1.0, 70.0e3, 10) * METER +g = 9.81 * METER / SECOND**2 +m = 28.949 * GRAM / MOL +t = 283.15 * KELVIN +p0 = BAR +pressure = p0 * np.exp((-z * m * g) / (RGAS * t)) + +# dividing with the unit of an SIObject returns a numpy.ndarray +# iteration is currently not implemented. +for zi, pi in zip(z / METER, pressure / (KILO * PASCAL)): + print(f'z = {zi:16.10f} p = {pi:16.10f}') +``` + +```title="Output" +z = 1.0000000000 p = 99.9879378249 +z = 7778.6666666667 p = 39.1279560236 +z = 15556.3333333333 p = 15.3118163640 +z = 23334.0000000000 p = 5.9919235296 +z = 31111.6666666667 p = 2.3448000375 +z = 38889.3333333333 p = 0.9175830080 +z = 46667.0000000000 p = 0.3590747881 +z = 54444.6666666667 p = 0.1405155744 +z = 62222.3333333333 p = 0.0549875048 +z = 70000.0000000000 p = 0.0215180823 +``` + +## Using `numpy` or `torch` functions + +Functions such as `exp`, `sqrt` and `cbrt` work with methods or the equivalent numpy functions. + +```py linenums="1" +from si_units import * +import numpy as np + +sqm = METER**2 +print(np.sqrt(sqm)) +print(sqm.sqrt()) # this is equivalent +``` + +``` +1 m +1 m +``` + +This also works with `torch.tensor`'s. + +```py linenums="1" +from si_units import * +import torch +ms = torch.tensor([2.0, 3.0, 4.0]) * METER +sqms = ms**2 +print(sqms) +print(sqms.sqrt()) +``` + +``` +tensor([ 4., 9., 16.]) m² +tensor([2., 3., 4.]) m +``` diff --git a/si-units/docs/examples.rst b/si-units/docs/examples.rst deleted file mode 100644 index 14e1f68..0000000 --- a/si-units/docs/examples.rst +++ /dev/null @@ -1,96 +0,0 @@ -Examples --------- - -Pressure of an ideal gas -~~~~~~~~~~~~~~~~~~~~~~~~ - - >>> from si_units import * - >>> temperature = 298.15 * KELVIN - >>> volume = 1.5 * METER**3 - >>> moles = 75.0 * MOL - >>> pressure = moles * RGAS * temperature / volume - >>> print(pressure) - 123.94785148011941 kPa - -You can use division to perform unit conversions. - - >>> from si_units import * - >>> temperature = 298.15 * KELVIN - >>> volume = 1.5 * METER**3 - >>> moles = 75.0 * MOL - >>> pressure = moles * RGAS * temperature / volume - >>> print(pressure / BAR) - 1.2394785148011942 - >>> print(pressure / (MILLI * NEWTON / ANGSTROM**2)) - 1.239478514801194e-12 - >>> print(volume / LITER) - 1500.0 - -Gravitational pull of the moon on the earth -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - >>> from si_units import * - >>> mass_earth = 5.9724e24 * KILOGRAM - >>> mass_moon = 7.346e22 * KILOGRAM - >>> distance = 383.398 * KILO * METER - >>> force = G * mass_earth * mass_moon / distance**2 - >>> print(force) - 1.992075748302325e26 N - -Pressure distribution in the atmosphere -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Using the barometric formula. -This example demonstrates how dimensioned arrays can be constructed using numpy.ndarray's. - -.. code-block:: python - - >>> from si_units import * - >>> import numpy as np - - >>> z = np.linspace(1.0, 70.0e3, 10) * METER - >>> g = 9.81 * METER / SECOND**2 - >>> m = 28.949 * GRAM / MOL - >>> t = 283.15 * KELVIN - >>> p0 = BAR - >>> pressure = p0 * np.exp((-z * m * g) / (RGAS * t)) - >>> - >>> # dividing with the unit of an SIArray returns a numpy.ndarray - >>> # iteration is currently not implemented. - >>> for zi, pi in zip(z / METER, pressure / (KILO * PASCAL)): - >>> print(f'z = {zi:16.10f} p = {pi:16.10f}') - - z = 1.0000000000 p = 99.9879378249 - z = 7778.6666666667 p = 39.1279560236 - z = 15556.3333333333 p = 15.3118163640 - z = 23334.0000000000 p = 5.9919235296 - z = 31111.6666666667 p = 2.3448000375 - z = 38889.3333333333 p = 0.9175830080 - z = 46667.0000000000 p = 0.3590747881 - z = 54444.6666666667 p = 0.1405155744 - z = 62222.3333333333 p = 0.0549875048 - z = 70000.0000000000 p = 0.0215180823 - -Using `numpy` or `torch` Functions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Functions such as `exp`, `sqrt` and `cbrt` work with methods or the equivalent numpy functions. - - >>> from si_units import * - >>> import numpy as np - >>> sqm = METER**2 - >>> np.sqrt(sqm) - 1 m - >>> sqm.sqrt() # this is equivalent - 1 m - -This also works with torch.Tensor's. - - >>> from si_units import * - >>> import torch - >>> ms = torch.tensor([2.0, 3.0, 4.0]) * METER - >>> sqms = ms**2 - >>> sqms - tensor([ 4., 9., 16.]) m² - >>> sqms.sqrt() - tensor([2., 3., 4.]) m diff --git a/si-units/docs/index.md b/si-units/docs/index.md new file mode 100644 index 0000000..fa1a57d --- /dev/null +++ b/si-units/docs/index.md @@ -0,0 +1,76 @@ +# Welcome to `si-units` + +This package provides representations of quantities with SI units. +It is written with flexibility in mind and is able to represent arbitrarily complex units. +In addition to simple scalar quantities, it can be used to decorate any complex data type (numpy arrays, PyTorch tensors) to provide unit checks. + +## Usage + +```py title="Ideal gas pressure" linenums="1" +from si_units import * +temperature = 25.0 * CELSIUS +volume = 1.5 * METER**3 +moles = 75.0 * MOL +pressure = moles * RGAS * temperature / volume +print(pressure) +``` + +``` +123.94785148011941 kPa +``` + +This also works with `numpy.ndarray`: + +```py title="Using numpy" linenums="1" +from si_units import * +import numpy as np +ms = np.linspace(2.0, 4.0, 3) * METER +sqms = ms**2 +print(sqms) +``` + +``` +[4, 9, 16] m² +``` + +When you divide a quantity by its unit, the value +(i.e. `float` for scalars or `numpy.ndarray[flaot]` for arrays) is returned. +You can use this to convert units: + +```py title="Unit conversion" linenums="1" +from si_units import MOL, METER, ANGSTROM, NAV + +molar_density = 3000 * MOL / METER**3 +particle_density = molar_density * NAV +nparticles = 16_000 +volume = nparticles / particle_density + +# make sure we actually have a volume +# this checks the quantity (here length**3), not the actual unit +# i.e. we could have used volume.has_unit(METER**3) for the same effect. +assert volume.has_unit(METER**3), "Something went wrong." +print(f'V = {volume / ANGSTROM**3:.2g} A^3') +``` + +``` +V = 8.9e+06 A^3 +``` + +See [Examples](examples.md) section for more use cases. + +## Installation + +You can install `si-units` from pypi using `pip`: + +``` +pip install si-units +``` + +## Build from source + +To build the code from source, you need the [rust compiler](https://www.rust-lang.org/tools/install) and [maturin](https://github.com/PyO3/maturin). +You can then install the latest master directly from github: + +``` +pip install git+https://github.com/itt-ustutt/quantity +``` diff --git a/si-units/docs/index.rst b/si-units/docs/index.rst deleted file mode 100644 index c4272e4..0000000 --- a/si-units/docs/index.rst +++ /dev/null @@ -1,30 +0,0 @@ -Welcome to si-units -=================== - -This package enables calculation with dimensioned values. - -Installation ------------- - -You can install `si-units` from pypi using `pip`: - -``` -pip install si-units -``` - -Build from source -~~~~~~~~~~~~~~~~~ - -To build the code from source, you need the `rust compiler `_ and `maturin `_. -You can then install the latest master directly from github: - -``` -pip install git+https://github.com/itt-ustutt/quantity -``` - -.. toctree:: - - examples - api - -* :ref:`search` diff --git a/si-units/docs/javascript/mathjax.js b/si-units/docs/javascript/mathjax.js new file mode 100644 index 0000000..3d0d925 --- /dev/null +++ b/si-units/docs/javascript/mathjax.js @@ -0,0 +1,19 @@ +window.MathJax = { + tex: { + inlineMath: [["\\(", "\\)"]], + displayMath: [["\\[", "\\]"]], + processEscapes: true, + processEnvironments: true + }, + options: { + ignoreHtmlClass: ".*|", + processHtmlClass: "arithmatex" + } + }; + + document$.subscribe(() => { + MathJax.startup.output.clearCache() + MathJax.typesetClear() + MathJax.texReset() + MathJax.typesetPromise() + }) \ No newline at end of file diff --git a/si-units/docs/prefixes.md b/si-units/docs/prefixes.md new file mode 100644 index 0000000..e63d28e --- /dev/null +++ b/si-units/docs/prefixes.md @@ -0,0 +1,34 @@ +# Prefixes + +All units can be combined with the following prefixes (capitalized): + +| Prefix | Prefix symbol | Value | Prefix | Prefix symbol | Value | +| ------ | ------------- | ---------- | ------ | ------------- | --------- | +| DECI | $\text{d}$ | $10^{-1}$ | DECA | $\text{da}$ | $10^{1}$ | +| CENTI | $\text{c}$ | $10^{-2}$ | HECTO | $\text{h}$ | $10^{2}$ | +| MILLI | $\text{m}$ | $10^{-3}$ | KILO | $\text{k}$ | $10^{3}$ | +| MICRO | $\text{µ}$ | $10^{-6}$ | MEGA | $\text{M}$ | $10^{6}$ | +| NANO | $\text{n}$ | $10^{-9}$ | GIGA | $\text{G}$ | $10^{9}$ | +| PICO | $\text{p}$ | $10^{-12}$ | TERA | $\text{T}$ | $10^{12}$ | +| FEMTO | $\text{f}$ | $10^{-15}$ | PETA | $\text{P}$ | $10^{15}$ | +| ATTO | $\text{a}$ | $10^{-18}$ | EXA | $\text{E}$ | $10^{18}$ | +| ZEPTO | $\text{z}$ | $10^{-21}$ | ZETTA | $\text{Z}$ | $10^{21}$ | +| YOCTO | $\text{y}$ | $10^{-24}$ | YOTTA | $\text{Y}$ | $10^{24}$ | +| RONTO | $\text{r}$ | $10^{-27}$ | RONNA | $\text{R}$ | $10^{27}$ | +| QUECTO | $\text{q}$ | $10^{-30}$ | QUETTA | $\text{Q}$ | $10^{30}$ | + +## Example + +```py linenums="1" +from si_units import MICRO, SECOND, MEGA, PASCAL +dt = 15 * MICRO * SECOND +print(dt) + +MPA = MEGA * PASCAL +pressure = 20 * MPA +print(pressure) +``` +``` +15 µs +20 MPa +``` diff --git a/si-units/license-apache b/si-units/license-apache index fffb378..67e3ce6 120000 --- a/si-units/license-apache +++ b/si-units/license-apache @@ -1 +1 @@ -license-apache \ No newline at end of file +../license-apache \ No newline at end of file diff --git a/si-units/license-mit b/si-units/license-mit index a949aa4..137b4b1 120000 --- a/si-units/license-mit +++ b/si-units/license-mit @@ -1 +1 @@ -license-mit \ No newline at end of file +../license-mit \ No newline at end of file diff --git a/si-units/mkdocs.yml b/si-units/mkdocs.yml new file mode 100644 index 0000000..0186f76 --- /dev/null +++ b/si-units/mkdocs.yml @@ -0,0 +1,82 @@ +theme: + name: material + font: + text: Fira Sans + code: Fira Sans Mono + features: + - navigation.sections + - toc.integrate + - header.autohide + - content.code.copy + palette: + # Palette toggle for automatic mode + - media: '(prefers-color-scheme)' + toggle: + icon: material/brightness-auto + name: Switch to light mode + + # Palette toggle for light mode + - media: '(prefers-color-scheme: light)' + scheme: default + toggle: + icon: material/brightness-7 + name: Switch to dark mode + + # Palette toggle for dark mode + - media: '(prefers-color-scheme: dark)' + scheme: slate + toggle: + icon: material/brightness-4 + name: Switch to system preference + icon: + repo: fontawesome/brands/github + +site_name: si-units +site_url: https://itt-ustutt.github.io/quantity + +repo_url: https://github.com/itt-ustutt/quantity/tree/master/si-units + +markdown_extensions: + - pymdownx.arithmatex: # Render LaTeX via MathJax + generic: true + - pymdownx.superfences # Seems to enable syntax highlighting when used with the Material theme. + - pymdownx.details # Allowing hidden expandable regions denoted by ??? + - pymdownx.snippets: # Include one Markdown file into another + base_path: docs + - admonition + - tables + +extra_javascript: + - javascript/mathjax.js + - https://unpkg.com/mathjax@3/es5/tex-mml-chtml.js + +plugins: + - search # default search plugin; needs manually re-enabling when using any other plugins + - mkdocstrings: + handlers: + python: + paths: [src] + docstring_style: goodle + show_signature_annotations: true + options: + find_stubs_package: true + heading_level: 2 + show_root_heading: true + show_root_full_path: false + docstring_section_style: spacy + merge_init_into_class: true + show_docstring_description: true + annotations_path: brief + docstring_options: + ignore_init_summary: false + trim_doctest_flags: true + +nav: + - Start Here: 'index.md' + - Examples: 'examples.md' + - API: + - Classes: 'api.md' + - Units, Constants, Prefixes: + - Base Units: 'base.md' + - Derived Units & Constants: 'derived.md' + - Prefixes: 'prefixes.md' diff --git a/si-units/pyproject.toml b/si-units/pyproject.toml new file mode 100644 index 0000000..421017c --- /dev/null +++ b/si-units/pyproject.toml @@ -0,0 +1,46 @@ +[project] +name = "si-units" +version = "0.10.0" +description = "Add your description here" +readme = "README.md" +authors = [ + { name = "Philipp Rehner", email = "prehner@ethz.ch" }, + { name = "Gernot Bauer", email = "bauer@itt.uni-stuttgart.de" } +] +requires-python = ">=3.10" +dependencies = [ + "maturin>=1.0", + "numpy>=2.2", +] + +[tool.maturin] +module-name = "si_units._core" +python-packages = ["si_units"] +python-source = "src" + +[build-system] +requires = ["maturin>=1.0,<2.0"] +build-backend = "maturin" + +[dependency-groups] +dev = [ + "ipykernel>=6.29.5", + "mkdocs-material>=9.5.48", + "mkdocstrings>=0.27.0", + "mkdocstrings-python>=1.12.2", + "ruff>=0.8.3", +] + +[tool.ruff] +line-length = 80 + +[tool.ruff.lint] +extend-select = [ + "D", # pydocstyle +] + +[tool.ruff.lint.pydocstyle] +convention = "google" # https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings + +[tool.ruff.lint.pycodestyle] +max-doc-length = 80 diff --git a/si-units/src/lib.rs b/si-units/src/lib.rs index b2ac81c..c25e351 100644 --- a/si-units/src/lib.rs +++ b/si-units/src/lib.rs @@ -26,7 +26,7 @@ pub enum QuantityError { DebyePower, } -#[pyclass(name = "SIObject", module = "si_units", frozen)] +#[pyclass(name = "SIObject", module = "si_units._core", frozen)] pub struct PySIObject { value: PyObject, unit: SIUnit, @@ -104,15 +104,6 @@ impl PySIObject { }) } - /// Try to calculate the square root of self. - /// - /// Examples - /// -------- - /// - /// >>> import si - /// >>> m2 = METER**2 - /// >>> m2.sqrt() - /// 1 m pub fn sqrt(&self, py: Python) -> PyResult { let value = if let Ok(v) = self.value.extract::(py) { PyFloat::new(py, v.sqrt()).into_any().unbind() @@ -122,15 +113,6 @@ impl PySIObject { Ok(Self::new(value, self.unit.sqrt()?)) } - /// Try to calculate the cubic root of self. - /// - /// Examples - /// -------- - /// - /// >>> import si - /// >>> m3 = METER**3 - /// >>> m3.cbrt() - /// 1 m pub fn cbrt(&self, py: Python) -> PyResult { let value = if let Ok(v) = self.value.extract::(py) { PyFloat::new(py, v.cbrt()).into_any().unbind() @@ -140,16 +122,6 @@ impl PySIObject { Ok(Self::new(value, self.unit.cbrt()?)) } - /// Test if the quantity has the same unit as the argument. - /// - /// Parameters - /// ---------- - /// other : SINumber - /// The unit that is compared. - /// - /// Returns - /// ------- - /// bool pub fn has_unit(&self, other: PyRef<'_, Self>) -> bool { self.unit.eq(&other.unit) } @@ -321,7 +293,7 @@ impl<'py> FromPyObject<'py> for SINumber { } } -#[pyclass] +#[pyclass(name = "SIArray1", module = "si_units._core", frozen)] struct SIArray1; #[pymethods] @@ -353,21 +325,6 @@ impl SIArray1 { } } - /// Create a linearly spaced SIArray. - /// - /// Parameters - /// ---------- - /// start: SINumber - /// The lowest value of the Array. - /// end: SINumber - /// The highest value of the Array. - /// n: int - /// The number of points. - /// - /// Returns - /// ------- - /// SIArray1 - /// #[staticmethod] fn linspace( py: Python, @@ -387,21 +344,6 @@ impl SIArray1 { } } - /// Create a logarithmically spaced SIArray. - /// - /// Parameters - /// ---------- - /// start: SINumber - /// The lowest value of the Array. - /// end: SINumber - /// The highest value of the Array. - /// n: int - /// The number of points. - /// - /// Returns - /// ------- - /// SIArray1 - /// #[staticmethod] fn logspace( py: Python, @@ -501,12 +443,12 @@ pub const RONNA: f64 = 1e27; pub const QUETTA: f64 = 1e30; #[pymodule] -pub fn si_units(m: &Bound<'_, PyModule>) -> PyResult<()> { +pub fn _core(m: &Bound<'_, PyModule>) -> PyResult<()> { m.add("__version__", env!("CARGO_PKG_VERSION"))?; m.add_class::()?; m.add_class::()?; - m.add("SIArray1", SIArray1)?; + m.add_class::()?; add_constant(m, "SECOND", 1.0, _SECOND)?; add_constant(m, "METER", 1.0, _METER)?; diff --git a/si-units/src/si_units/__init__.py b/si-units/src/si_units/__init__.py new file mode 100644 index 0000000..a1b41b1 --- /dev/null +++ b/si-units/src/si_units/__init__.py @@ -0,0 +1,167 @@ +"""Representation of quantities with SI units. + +`si_units` provides the `SIObject` class that represents physical quantities +as values with units. Values can be any Python data types that are suitable +for arithmetic operations, such as `float`, `numpy.ndarray` or `torch.tensor`. +Usually, a `SIObject` is created by multiplying a value by a `SIObject` that +represents a unit. + +Examples: + Calculate the ideal gas pressure and convert to bar. + + >>> from si_units import CELSIUS, METER, MOL, RGAS, BAR + >>> temperature = 25.0 * CELSIUS + >>> volume = 1.5 * METER**3 + >>> moles = 75.0 * MOL + >>> pressure = moles * RGAS * temperature / volume + >>> print(f"The pressure is {pressure / BAR:.2f} bar") + "The pressure is 1.24 bar" +""" +# from si_units._core import SIObject +from si_units._core import ( + SIObject, + SIArray1, + Angle, + SECOND, + METER, + KILOGRAM, + AMPERE, + KELVIN, + CELSIUS, + DEBYE, + DEGREES, + RADIANS, + DAY, + MOL, + CANDELA, + DVCS, + CLIGHT, + PLANCK, + QE, + KB, + NAV, + KCD, + HERTZ, + NEWTON, + PASCAL, + JOULE, + WATT, + COULOMB, + VOLT, + FARAD, + OHM, + SIEMENS, + WEBER, + TESLA, + HENRY, + ANGSTROM, + AMU, + AU, + BAR, + CALORIE, + GRAM, + HOUR, + LITER, + MINUTE, + G, + RGAS, + QUECTO, + RONTO, + YOCTO, + ZEPTO, + ATTO, + FEMTO, + PICO, + NANO, + MICRO, + MILLI, + CENTI, + DECI, + DECA, + HECTO, + KILO, + MEGA, + GIGA, + TERA, + PETA, + EXA, + ZETTA, + YOTTA, + RONNA, + QUETTA, + __version__, +) + +__all__ = [ + "SIObject", + "SIArray1", + "Angle", + "SECOND", + "METER", + "KILOGRAM", + "AMPERE", + "KELVIN", + "CELSIUS", + "DEBYE", + "DEGREES", + "RADIANS", + "DAY", + "MOL", + "CANDELA", + "DVCS", + "CLIGHT", + "PLANCK", + "QE", + "KB", + "NAV", + "KCD", + "HERTZ", + "NEWTON", + "PASCAL", + "JOULE", + "WATT", + "COULOMB", + "VOLT", + "FARAD", + "OHM", + "SIEMENS", + "WEBER", + "TESLA", + "HENRY", + "ANGSTROM", + "AMU", + "AU", + "BAR", + "CALORIE", + "GRAM", + "HOUR", + "LITER", + "MINUTE", + "G", + "RGAS", + "QUECTO", + "RONTO", + "YOCTO", + "ZEPTO", + "ATTO", + "FEMTO", + "PICO", + "NANO", + "MICRO", + "MILLI", + "CENTI", + "DECI", + "DECA", + "HECTO", + "KILO", + "MEGA", + "GIGA", + "TERA", + "PETA", + "EXA", + "ZETTA", + "YOTTA", + "RONNA", + "QUETTA", + "__version__", +] diff --git a/si-units/src/si_units/_core.pyi b/si-units/src/si_units/_core.pyi new file mode 100644 index 0000000..426c93d --- /dev/null +++ b/si-units/src/si_units/_core.pyi @@ -0,0 +1,134 @@ +from typing import Self, Any + +class SIObject: + """Combination of value and unit. + + The value can be any Python object that can be used for arithmetic + operations such as a float, numpy.ndarray or torch.tensor. + + When a SIObject is divided by its unit, the value is returned. + This is usefull to convert units or when operations are needed + that are not implemented for SIObject. + """ + + def __init__(self, value: float | Any, unit: list[int]) -> None: + """Constructs a new quantity. + + Warning: Don't use the default constructor + This constructor should not be used to construct a quantity. + Instead, multiply the value (float or array of floats) + by the appropriate unit. + + Args: + value: + The numerical value(s). Can be a scalar or an array + such as a numpy.ndarray or a torch.tensor. + unit: List of 7 exponents for SI base units. + + Raises: + RuntimeError: When unit has the wrong format. + """ + ... + + def sqrt(self) -> Self: + """Calculates the square root. + + Returns: + Square root of the quantity. + + Raises: + RuntimeError: When exponents of units are not multiples of two. + AttributeError: When the inner data type has no 'sqrt' method. + + Examples: + >>> from si_units import METER + >>> square = METER**2 + >>> length = square.sqrt() + """ + ... + + def cbrt(self) -> Self: + """Calculate the cubic root. + + Returns: + Cubic root of the quantity. + + Raises: + RuntimeError: When exponents of units are not multiples of three. + AttributeError: When the inner data type has no 'cbrt' method. + + Examples: + >>> from si_units import METER + >>> volume = METER**2 + >>> length = volume.sqrt() + """ + ... + + def has_unit(self, other: Self) -> bool: + """Tests if the quantity has the same unit as the argument. + + Args: + other: The quantity to compare to. + + Returns: + Wheter the units of the compared quantities are the same or not. + """ + ... + +class SIArray1: + """Builder for SIObjects with numpy.narray as value storage.""" + + def __call__(self, value: SIObject | list[SIObject]) -> SIObject: + """Build SIObject from scalar or list. + + Args: + value: Values to store. Must all have the same unit. + + Returns: + The quantity with values stored within array, even + if value is given as a scalar. + + Raises: + RuntimeError: If the elements of value have different units. + """ + ... + + @staticmethod + def linspace(start: SIObject, end: SIObject, n: int) -> SIObject: + """Linearly spaced quantities. + + Args: + start: Lowest value. + end: Highest value. + n: The (positive) number of points. + + Returns: + Linearly spaced values with the same unit. + + Raises: + RuntimeError: + If start and end values are not scalars and if they don't have + the same unit. + If n is not positive. + """ + ... + + @staticmethod + def logspace(start: SIObject, end: SIObject, n: int) -> SIObject: + """Logarithmically spaced quantities. + + Args: + start: Lowest value. + end: Highest value. + n: The (positive) number of points. + + Returns: + Logarithmically spaced values with the same unit. + + Raises: + RuntimeError: + If start and end values are not scalars and if they don't have + the same unit. + If n is not positive. + """ + ... diff --git a/si-units/src/si_units/py.typed b/si-units/src/si_units/py.typed new file mode 100644 index 0000000..e69de29