From 4b6d9140614dac24becc8ad3ac50365aa2f9d322 Mon Sep 17 00:00:00 2001 From: He Sichao <1310722434@qq.com> Date: Tue, 18 Jun 2024 15:42:23 +0800 Subject: [PATCH] Update quantity.ipynb --- docs/physical_units/quantity.ipynb | 1450 +++++++++++++++++++++++++++- 1 file changed, 1449 insertions(+), 1 deletion(-) diff --git a/docs/physical_units/quantity.ipynb b/docs/physical_units/quantity.ipynb index 52432e9..04bfa74 100644 --- a/docs/physical_units/quantity.ipynb +++ b/docs/physical_units/quantity.ipynb @@ -7,6 +7,139 @@ "# Quantity" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "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 brainunit as bu` and then using `bu.msiemens` instead of `msiemens`." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import brainunit as bu" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can generate a physical quantity by multiplying a scalar or ndarray with its physical unit:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "20. * msecond" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "tau = 20 * bu.ms\n", + "tau" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([10., 20., 30.], dtype=float32) * hertz" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "rates = [10, 20, 30] * bu.Hz\n", + "rates" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([[10., 20., 30.],\n", + " [20., 30., 40.]], dtype=float32) * hertz" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "rates = [[10, 20, 30], [20, 30, 40]] * bu.Hz\n", + "rates" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Braincore will check the consistency of operations on units and raise an error for dimensionality mismatches:" + ] + }, + { + "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)" + ] + }, + { + "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)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -14,6 +147,438 @@ "## Creating Quantity Instances" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Creating a Quantity object can be accomplished in several ways, categorized based on the type of input used. Here, we present the methods grouped by their input types and characteristics for better clarity." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "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" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Scalar and Array Multiplication\n", + "- Multiplying a Scalar with a Unit" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5. * msecond" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "5 * bu.ms" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- Multiplying a Jax nunmpy value type with a Unit:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5. * msecond" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "jnp.float64(5) * bu.ms" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- Multiplying a Jax numpy array with a Unit:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([1., 2., 3.]) * msecond" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "jnp.array([1, 2, 3]) * bu.ms" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- Multiplying a List with a Unit:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([1., 2., 3.]) * msecond" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[1, 2, 3] * bu.ms" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Direct Quantity Creation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- Creating a Quantity Directly with a Value" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Quantity(5.)" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bu.Quantity(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- Creating a Quantity Directly with a Value and Unit" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5. * msecond" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bu.Quantity(5, unit=bu.ms)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- Creating a Quantity with a Jax numpy Array of Values and a Unit" + ] + }, + { + "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": [ + "bu.Quantity(jnp.array([1, 2, 3]), unit=bu.ms)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- Creating a Quantity with a List of Values and a Unit" + ] + }, + { + "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": [ + "bu.Quantity([1, 2, 3], unit=bu.ms)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- Creating a Quantity with a List of Quantities" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([0.5, 1. ]) * second" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bu.Quantity([500 * bu.ms, 1 * bu.second])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "- Using the with_units Method" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "ArrayImpl([0.5, 1. ]) * second" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bu.Quantity.with_units(jnp.array([0.5, 1]), second=1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Unitless Quantity\n", + "Quantities can be unitless, which means they have no units. If there is no unit provided, the quantity is assumed to be unitless. The following are examples of creating unitless quantities:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Quantity(ArrayImpl([1., 2., 3.]))" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bu.Quantity([1, 2, 3])" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Quantity(ArrayImpl([1., 2., 3.]))" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bu.Quantity(jnp.array([1, 2, 3]))" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Quantity(ArrayImpl([], dtype=float64))" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bu.Quantity([])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Illegal Quantity Creation\n", + "The following are examples of illegal quantity creation:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "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)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Value 'some' with dtype