diff --git a/brainunit/_base.py b/brainunit/_base.py index 577e281..8640d87 100644 --- a/brainunit/_base.py +++ b/brainunit/_base.py @@ -32,6 +32,7 @@ 'Quantity', 'Unit', 'UnitRegistry', + 'Dimension', 'DIMENSIONLESS', 'DimensionMismatchError', 'get_or_create_dimension', @@ -458,6 +459,7 @@ def get_or_create_dimension(*args, **kwds): return new_dim +'''The dimensionless unit, used for quantities without a unit.''' DIMENSIONLESS = Dimension((0, 0, 0, 0, 0, 0, 0)) _dimensions = {(0, 0, 0, 0, 0, 0, 0): DIMENSIONLESS} diff --git a/docs/tutorials/physical_units.ipynb b/docs/tutorials/physical_units.ipynb index 444756d..f6ebb36 100644 --- a/docs/tutorials/physical_units.ipynb +++ b/docs/tutorials/physical_units.ipynb @@ -31,9 +31,9 @@ "metadata": {}, "source": [ "## Importing units\n", - "Braincore generates standard names for units, combining the unit name (e.g. “siemens”) with a prefixes (e.g. “m”), and also generates squared and cubed versions by appending a number. For example, the units “msiemens”, “siemens2”, “usiemens3” are all predefined. You can import these units from the package `briancore.units` – accordingly, an `from braincore.units import *` will result in everything being imported.\n", + "Braincore generates standard names for units, combining the unit name (e.g. “siemens”) with a prefixes (e.g. “m”), and also generates squared and cubed versions by appending a number. For example, the units “msiemens”, “siemens2”, “usiemens3” are all predefined. You can import these units from the package `brianunit` – accordingly, an `from brainunit import *` will result in everything being imported.\n", "\n", - "We recommend importing only the units you need, to have a cleaner namespace. For example, `import braincore.units as U` and then using `bu.msiemens` instead of `msiemens`." + "We recommend importing only the units you need, to have a cleaner namespace. For example, `import brainunit as bu` and then using `bu.msiemens` instead of `msiemens`." ] }, { @@ -45,10 +45,10 @@ "start_time": "2024-06-08T08:18:06.566328Z" } }, + "outputs": [], "source": [ "import brainunit as bu" - ], - "outputs": [] + ] }, { "cell_type": "markdown", @@ -62,31 +62,65 @@ "cell_type": "code", "execution_count": 2, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "20. * msecond" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "tau = 20 * bu.ms\n", "tau" - ], - "outputs": [] + ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([10., 20., 30.], dtype=float32) * hertz" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "rates = [10, 20, 30] * bu.Hz\n", "rates" - ], - "outputs": [] + ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([[10., 20., 30.],\n", + " [20., 30., 40.]], dtype=float32) * hertz" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "rates = [[10, 20, 30], [20, 30, 40]] * bu.Hz\n", "rates" - ], - "outputs": [] + ] }, { "cell_type": "markdown", @@ -99,25 +133,41 @@ "cell_type": "code", "execution_count": 5, "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cannot calculate ... += 1, units do not match (units are s and 1).\n" + ] + } + ], "source": [ "try:\n", " tau += 1 # ms? second?\n", "except Exception as e:\n", " print(e)" - ], - "outputs": [] + ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Cannot calculate 3.0 + 3.0, units do not match (units are kg and A).\n" + ] + } + ], "source": [ "try:\n", " 3 * bu.kgram + 3 * bu.amp\n", "except Exception as e:\n", " print(e)" - ], - "outputs": [] + ] }, { "cell_type": "markdown", @@ -151,37 +201,83 @@ "cell_type": "code", "execution_count": 7, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([[10., 20., 30.],\n", + " [20., 30., 40.]], dtype=float32) * hertz" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "rates" - ], - "outputs": [] + ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Array([[10., 20., 30.],\n", + " [20., 30., 40.]], dtype=float32)" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "rates.value" - ], - "outputs": [] + ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "second ** -1" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "rates.unit" - ], - "outputs": [] + ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(2, (2, 3), 6, dtype('float32'))" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "rates.ndim, rates.shape, rates.size, rates.dtype" - ], - "outputs": [] + ] }, { "cell_type": "markdown", @@ -195,12 +291,12 @@ "cell_type": "code", "execution_count": 11, "metadata": {}, + "outputs": [], "source": [ "import jax.numpy as jnp\n", "import brainstate as bst\n", "bst.environ.set(precision=64) # we recommend using 64-bit precision for better numerical stability" - ], - "outputs": [] + ] }, { "cell_type": "markdown", @@ -215,10 +311,21 @@ "cell_type": "code", "execution_count": 12, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5. * msecond" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "5 * bu.ms" - ], - "outputs": [] + ] }, { "cell_type": "markdown", @@ -231,10 +338,21 @@ "cell_type": "code", "execution_count": 13, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5. * msecond" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "jnp.float64(5) * bu.ms" - ], - "outputs": [] + ] }, { "cell_type": "markdown", @@ -247,10 +365,21 @@ "cell_type": "code", "execution_count": 14, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([1., 2., 3.]) * msecond" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "jnp.array([1, 2, 3]) * bu.ms" - ], - "outputs": [] + ] }, { "cell_type": "markdown", @@ -263,10 +392,21 @@ "cell_type": "code", "execution_count": 15, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([1., 2., 3.]) * msecond" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "[1, 2, 3] * bu.ms" - ], - "outputs": [] + ] }, { "cell_type": "markdown", @@ -286,10 +426,21 @@ "cell_type": "code", "execution_count": 16, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Quantity(5.)" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "bu.Quantity(5)" - ], - "outputs": [] + ] }, { "cell_type": "markdown", @@ -302,10 +453,21 @@ "cell_type": "code", "execution_count": 18, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5. * msecond" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "bu.Quantity(5, unit=bu.ms)" - ], - "outputs": [] + ] }, { "cell_type": "markdown", @@ -318,10 +480,21 @@ "cell_type": "code", "execution_count": 19, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([1., 2., 3.]) * msecond" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "bu.Quantity(jnp.array([1, 2, 3]), unit=bu.ms)" - ], - "outputs": [] + ] }, { "cell_type": "markdown", @@ -334,10 +507,21 @@ "cell_type": "code", "execution_count": 20, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([1., 2., 3.]) * msecond" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "bu.Quantity([1, 2, 3], unit=bu.ms)" - ], - "outputs": [] + ] }, { "cell_type": "markdown", @@ -350,10 +534,21 @@ "cell_type": "code", "execution_count": 21, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([0.5, 1. ]) * second" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "bu.Quantity([500 * bu.ms, 1 * bu.second])" - ], - "outputs": [] + ] }, { "cell_type": "markdown", @@ -366,10 +561,21 @@ "cell_type": "code", "execution_count": 22, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([0.5, 1. ]) * second" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "bu.Quantity.with_units(jnp.array([0.5, 1]), second=1)" - ], - "outputs": [] + ] }, { "cell_type": "markdown", @@ -383,28 +589,61 @@ "cell_type": "code", "execution_count": 23, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Quantity(ArrayImpl([1., 2., 3.]))" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "bu.Quantity([1, 2, 3])" - ], - "outputs": [] + ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Quantity(ArrayImpl([1., 2., 3.]))" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "bu.Quantity(jnp.array([1, 2, 3]))" - ], - "outputs": [] + ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Quantity(ArrayImpl([], dtype=float64))" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "bu.Quantity([])" - ], - "outputs": [] + ] }, { "cell_type": "markdown", @@ -418,37 +657,61 @@ "cell_type": "code", "execution_count": 26, "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "All elements must have the same unit\n" + ] + } + ], "source": [ "try:\n", " bu.Quantity([500 * bu.ms, 1])\n", "except Exception as e:\n", " print(e)" - ], - "outputs": [] + ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Value 'some' with dtype q2, q1 >= q2" - ], - "outputs": [] + ] }, { "cell_type": "markdown", @@ -1628,12 +2723,23 @@ "start_time": "2024-06-08T08:17:18.733415Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "(ArrayImpl([1., 2., 3.]) * mvolt, ArrayImpl([2., 3., 4.]) * mvolt)" + ] + }, + "execution_count": 99, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "q1 = jnp.array([1, 2, 3]) * bu.mV\n", "q2 = jnp.array([2, 3, 4]) * bu.mV\n", "q1, q2" - ], - "outputs": [] + ] }, { "cell_type": "code", @@ -1644,10 +2750,21 @@ "start_time": "2024-06-08T08:17:18.840386Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "(ArrayImpl([3., 5., 7.]) * mvolt, ArrayImpl([-1., -1., -1.]) * mvolt)" + ] + }, + "execution_count": 100, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "q1 + q2, q1 - q2" - ], - "outputs": [] + ] }, { "cell_type": "code", @@ -1658,10 +2775,21 @@ "start_time": "2024-06-08T08:17:18.927264Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([ 2., 6., 12.]) * mvolt2" + ] + }, + "execution_count": 101, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "q1 * q2" - ], - "outputs": [] + ] }, { "cell_type": "code", @@ -1672,10 +2800,23 @@ "start_time": "2024-06-08T08:17:19.045255Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "(Array([0.5 , 0.66666667, 0.75 ], dtype=float64),\n", + " Array([0., 0., 0.], dtype=float64),\n", + " ArrayImpl([1., 2., 3.]) * mvolt)" + ] + }, + "execution_count": 102, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "q1 / q2, q1 // q2, q1 % q2" - ], - "outputs": [] + ] }, { "cell_type": "code", @@ -1686,10 +2827,21 @@ "start_time": "2024-06-08T08:17:19.125338Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "(Array([0., 0., 0.], dtype=float64), ArrayImpl([1., 2., 3.]) * mvolt)" + ] + }, + "execution_count": 103, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "divmod(q1, q2)" - ], - "outputs": [] + ] }, { "cell_type": "code", @@ -1700,10 +2852,21 @@ "start_time": "2024-06-08T08:17:19.275896Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([1., 4., 9.]) * mvolt2" + ] + }, + "execution_count": 104, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "q1 ** 2" - ], - "outputs": [] + ] }, { "cell_type": "code", @@ -1714,10 +2877,21 @@ "start_time": "2024-06-08T08:17:19.334827Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "20. * mvolt2" + ] + }, + "execution_count": 105, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "q1 @ q2" - ], - "outputs": [] + ] }, { "cell_type": "code", @@ -1728,11 +2902,23 @@ "start_time": "2024-06-08T08:17:19.456793Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "(ArrayImpl([ 0., 4., 8., 12., 16.]) * volt,\n", + " ArrayImpl([0., 0., 0., 0., 1.]) * volt)" + ] + }, + "execution_count": 106, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "q1 = bu.Quantity(jnp.arange(5, dtype=jnp.int32), unit=bu.mV.unit)\n", "q1 << 2, q1 >> 2" - ], - "outputs": [] + ] }, { "cell_type": "code", @@ -1743,6 +2929,17 @@ "start_time": "2024-06-08T08:17:19.514038Z" } }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "round(80.23456, 2) : 80.23 mV\n", + "round(100.000056, 3) : 100. mV\n", + "round(-100.000056, 3) : -100. mV\n" + ] + } + ], "source": [ "q1 = 80.23456 * bu.mV\n", "q2 = 100.000056 * bu.mV\n", @@ -1750,8 +2947,7 @@ "print(\"round(80.23456, 2) : \", q1.round(5))\n", "print(\"round(100.000056, 3) : \", q2.round(6))\n", "print(\"round(-100.000056, 3) : \", q3.round(6))" - ], - "outputs": [] + ] }, { "cell_type": "markdown", @@ -1770,11 +2966,23 @@ "start_time": "2024-06-08T08:17:19.670457Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([[1., 2.],\n", + " [3., 4.]]) * mvolt" + ] + }, + "execution_count": 108, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "q = [[1, 2], [3, 4]] * bu.mV\n", "q" - ], - "outputs": [] + ] }, { "cell_type": "code", @@ -1785,10 +2993,21 @@ "start_time": "2024-06-08T08:17:19.743837Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([1., 2., 3., 4.]) * mvolt" + ] + }, + "execution_count": 109, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "q.flatten()" - ], - "outputs": [] + ] }, { "cell_type": "code", @@ -1799,10 +3018,22 @@ "start_time": "2024-06-08T08:17:19.854522Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([[1., 3.],\n", + " [2., 4.]]) * mvolt" + ] + }, + "execution_count": 110, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "q.swapaxes(0, 1)" - ], - "outputs": [] + ] }, { "cell_type": "code", @@ -1813,10 +3044,21 @@ "start_time": "2024-06-08T08:17:19.907391Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([1., 3.]) * mvolt" + ] + }, + "execution_count": 111, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "q.take(jnp.array([0, 2]))" - ], - "outputs": [] + ] }, { "cell_type": "code", @@ -1827,10 +3069,22 @@ "start_time": "2024-06-08T08:17:20.023150Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([[1., 3.],\n", + " [2., 4.]]) * mvolt" + ] + }, + "execution_count": 112, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "q.transpose()" - ], - "outputs": [] + ] }, { "cell_type": "code", @@ -1841,10 +3095,22 @@ "start_time": "2024-06-08T08:17:20.109833Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([[1., 2., 1., 2.],\n", + " [3., 4., 3., 4.]]) * mvolt" + ] + }, + "execution_count": 113, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "q.tile(2)" - ], - "outputs": [] + ] }, { "cell_type": "code", @@ -1855,10 +3121,22 @@ "start_time": "2024-06-08T08:17:20.213853Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([[[1., 2.],\n", + " [3., 4.]]]) * mvolt" + ] + }, + "execution_count": 114, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "q.unsqueeze(0)" - ], - "outputs": [] + ] }, { "cell_type": "code", @@ -1869,10 +3147,22 @@ "start_time": "2024-06-08T08:17:20.279806Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([[[1., 2.],\n", + " [3., 4.]]]) * mvolt" + ] + }, + "execution_count": 115, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "q.expand_dims(0)" - ], - "outputs": [] + ] }, { "cell_type": "code", @@ -1883,11 +3173,23 @@ "start_time": "2024-06-08T08:17:20.397348Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([[[1., 2.],\n", + " [3., 4.]]]) * mvolt" + ] + }, + "execution_count": 116, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "expand_as_shape = (1, 2, 2)\n", "q.expand_as(jnp.zeros(expand_as_shape).shape)" - ], - "outputs": [] + ] }, { "cell_type": "code", @@ -1898,12 +3200,24 @@ "start_time": "2024-06-08T08:17:20.454902Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([[ 1., 30.],\n", + " [10., 4.]]) * mvolt" + ] + }, + "execution_count": 117, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "q_put = [[1, 2], [3, 4]] * bu.mV\n", "q_put.put([[1, 0], [0, 1]], [10, 30] * bu.mV)\n", "q_put" - ], - "outputs": [] + ] }, { "cell_type": "code", @@ -1914,11 +3228,23 @@ "start_time": "2024-06-08T08:17:20.573505Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([[1., 2.],\n", + " [3., 4.]]) * mvolt" + ] + }, + "execution_count": 118, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "q_squeeze = [[1, 2], [3, 4]] * bu.mV\n", "q_squeeze.squeeze()" - ], - "outputs": [] + ] }, { "cell_type": "code", @@ -1929,11 +3255,22 @@ "start_time": "2024-06-08T08:17:20.652077Z" } }, + "outputs": [ + { + "data": { + "text/plain": [ + "[ArrayImpl([[1., 2.]]) * mvolt, ArrayImpl([[3., 4.]]) * mvolt]" + ] + }, + "execution_count": 119, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "q_spilt = [[1, 2], [3, 4]] * bu.mV\n", "q_spilt.split(2)" - ], - "outputs": [] + ] }, { "cell_type": "markdown",