Package: imks
iMKS is an IPython extension to allows the use of physical quantities
(Value’s) in mathematical expressions.  A physical quantity is simply a number
(typically, a float number) followed by a unit specification.  Within iMKS,
one can use physical quantities in normal expressions: the result will be a
physical quantity with the correct unit.Main FeaturesAllow the use of physical quantities in mathematical expressions and
performs consistency checks (so that, for example, an error is generated if
one tries to add a length with a time).Unit systems make it easy to perform conversions of physical quantities in
different units.  A unit system provides a list of units that should be
used, alone or in combination, to represent physical values.  Large unit
systems are effectively useful to define preferences in unit
representations.Completely modular: one can define base units, prefixes, derived units, and
unit systems using magic commands.  Definitions can be stored in an external
file for reuse.Currencies are considered as physical units.  Automatically retrieves a
large list of currencies and exchange rates from openexchangerates.org and
stores them in a file for offline use.A list of physical constants can be retrieved from the NIST serverhttp://physics.nist.gov/constantsand are available as variable in
interactive mode.Add autocompletion for units and constants.Allow the use of documentation strings for all quantities (base units,
prefixes, units, unit systems, and values) using the … # “doc string”
notation.Optionally allow the use of the standard exponent (caret, ^) in mathematical
expressions in addition to the Python notation (**).  Also, optionally allow
the use of unicode characters in identifiers, units, and prefixes.Physical quantities are displayed in a proper way (using the LaTeX notation)
in the notebook.Allow the use of “lazy” quantities (variables, units, prefixes) whose value is
evaluated each time the quantity is required.Add an easy way to write documentation strings for any quantity, including
variables.Several mathematical engines can be used: the standard Python math module,
mpmath, fpmath (mpmath with fixed point arithmetic), numpy, and umath (based
on the uncertanties package), soerp (higher order error analysis), and mcerp
(Monte Carlo error analysis).  The engines are used to perform calculations
involving mathematical functions.Engines with error analysis (umath, soerp, and mcerp) will keep track of the
error propagation within all define variables or physical constants.Advanced input transformations and output formats for special quantities such
as angles in sexagesimal format, times, dates…Use of iMKSiMKS extends the standard Python syntax in several ways:Physical quantities can be entered using the format 9.8[m s^-2] or
9.8[m/s^2], i.e. with a number followed by a unit specification in brackets.
In simple cases, quantities can also be entered without the brackets:
9.8 m/s^2 or 9.8 m s^-2.  This shorter notation however can generate
ambiguities when the quantity is exponentiated (2m^2 is 2[m^2], while 2[m]^2
is 4[m^2]) or when a unit has the same name of a variable (12 km/h is a
speed, 12[km/h] or 12[km] over the Planck constant?).  Moreover, in the
shorter notation parentheses in units, such as 3[m/(s K)], are not accepted.A unit specification follows a standard notation: it is a space-separated
list of prefixed units followed by an optional exponent.  A prefixed unit is
a unit with a prefix, such as [km] = prefix k + simple unit m.  The exponent
in the unit must be a simple number or a fraction: it cannot involve any
other term (for example, [km^a] is not a valid unit, while [km^2/3] is).  In
a unit specification one can use an arbitrary number of parentheses; within
a parenthesis, a single division can be used, as in 9.8[m/s^2]. Additionally,
a unit specification can contain (at most) one divide (/) sign: in this case
all units following the sign will have their exponents reversed.Physical quantities can be used in expressions with the standard operators.The result of an expression can be converted into a different unit by using
the @ operator:> 12 m + 3 cm @ km --> 0.01203[km]Multiple units can be used after the @ operator: in that case, they are
combined as necessary to obtain the requested quantity:> 20[m/s] @ [km|hour] --> 72.0[km hour^-1]When the quantity can be represented using multiple combinations, the
shorter one is used (i.e., the one that involves the smallest number of
elements in the list at the right of the @ operator):> 20[m/s] @ [km|hour|mph] --> 44.738725841088[mph]In some cases, it might be useful to use a variable as a unit.  To do this,
one can use single quotes around a variable name in the unit specification:> 5[s 'c'] @ [km] --> 1498962.29[km]
> 3['g'] --> 29.41995[m s^-2]The same operation can be performed in the argument of the at (@) operator:> 300000[km] @ [s 'c'] --> 1.00069228559446[s 'c']
> 1e30[kg] @ ['c'|'G'] --> 742.564845009288['c'^2 m 'G'^-1]
> 1K @ ['k'|eV] --> 8.61733238496096e-5[eV 'k'^-1]The output unit, set by the @ operator, can also contain double quoted
variables.  In this case the value is completely transformed using the
appropriate combination of the variables, thus removing any appearance of
the variable in the final result.  This technique generally changes the
unit of the quantity (and not only the displayed unit):> 300000[km] @ [s|"c"] --> 1.00069228559446[s]
> 1e30[kg] @ ["c"|"G"] --> 742.564845009288[m]iMKS understands special units, such as the temperature related ones, that
are defined together with a zero point, i.e. in terms of an affine
transformation.  Quantities involving these units alone are called absolute:> 300[K] @ [Celsius] --> 26.85[Celsius]
> 122°F @ °C --> 50.0[°C]Absolute quantities can be made relative (and vice-versa) by using the tilde
(~) operator.  For example, 300[K] is understood as an absolute temperature,
but ~300[K] as a relative one (i.e. a temperature difference):> ~300[K] @ [Celsius] --> ~300.0[Celsius]Another example of absolute quantities are calendar dates or datetimes:> %load_imks_ext calendars
> Egyptian("today") + 2[day] --> 1 First of Akhet (Thoth) 2764The @ operator can be used to force the display of a result using a specific
prefix or a set of prefixes.  For this, one can just specify the desired
prefix(es) after the @ inside the brackets:> 1200[s] @ [k] --> 1.2[ks]If multiple prefixes are used, the most convenient one is selected:> 1200[s] @ [k|M] --> 1.2[ks]A dot (.) can be used to specify that no prefix is also accepted; a star (*)
to select all known prefixes:> 8[m] @ [.|k|M] --> 8.0[m]
> 0.12[cm] @ [m|*] --> 1.2[mm]Note that if a prefix has the same name as a valid unit, one needs to use a
star after the prefix name, to indicate that the name must be understood as a
prefix rather than a unit:> 12[cm] @ [m] --> 0.12[m]
> 12[cm] @ [m*] --> 120.0[mm]The star can also be used within a single unit to indicate that an arbitrary
prefix is allowed:> 1200[m] @ [*m] --> 12.0[km]Unit systems work just like list of units that can be used after the @
operator:> 72[km/hour] @ [SI] --> 20.0[m s^-1]A star prepended or appended to a unit system indicates that a prefix among
all known ones can be used to make the expression simpler; the same effect is
obtained if the star is specified within the brackets with the unit system:> 5600[K] @ [*SI] --> 5.6[kK]
> 5600[K] @ [SI|*] --> 5.6[kK]Unit systems containing multiple units are especially convenient to reduce
expressions to the simplest form:> %newsystem easy=[m|s|kg|K|A|lx|mol|EUR|N|J|W|Pa|C|V|ohm|F|H|T|lx]
> 6.63e-34[kg m^2 s^-1] @ [easy] --> 6.63e-34[s J]Unit systems can also contain variable units: this is especially useful to
define natural unit systems:> %newsystem planck=["c"|"hbar"|"G"|"ke"|"k"] # "Planck's natural system"
> 1[m] @ [planck] --> 6.18735589978243e+34The reverse conversion can be performed by indicating the output unit at the
beginning of the unit specification, and by adding the unit system:> 6.2e34 @ [m|planck] --> 1.00204353853607[m]
> 1 @ [kg|planck] --> 2.17650925244531e-8[kg]Note that this notation is an exception to the general rule that pure numbers
are not influenced by unit specifications.  Note also that the order is
relevant here: first the final unit, than all the natural system:> 1 @ [planck|kg] --> 1
> 1 @ [kg/m|"c"|"G"] --> 1.34668373640485e+27[kg m^-1]
> 1 @ [kg|m|"c"|"G"] --> 1When a natural unit system is used enclosed within single or double quotes,
all the quotes of the unit system are replaced by the one used: hence,
[‘planck’] is identical to [‘c’|’hbar’|’G’|’ke’|’k’].  This is useful to
explicitly show all the converting factors in the result:> 1 @ [kg|'planck'] --> 2.17650925244531e-8['G'^1/2 'c'^-1/2 'hbar'^-1/2 kg]
> 2.17650925244531e-8['G'^1/2 'c'^-1/2 'hbar'^-1/2 kg] --> 0.999999999999999The @ operator can also be used in variable definitions to set the default
display unit to be used for a variable:> v = 20[m/s] @ [km|hour]
> v --> 72.0[km hour^-1]When an engine with error analysis is used (umath, soerp, or mcerp), the
special syntax value +/- error can be used to input quantities with errors:> %imks -c umath
> %reset
> v = (3+/-0.1)[m/s]
> v^2 @ [mph] --> (45.0+/-3.0)[mph^2]Uncertainties are silently ignored with engines not supporting them.  The
same quantity, (3+/-0.1)[m/s] can also be entered without parentheses,
3+/-0.1m/s, using the ± sign instead of the +/-, or using a shorter notation
3.0(1)[m/s] (see uncertainties for a list of formats accepted).Correlation among variables is automatically taken into account:> w = (3+/-0.1)[m/s]
> v + w --> (6.00+/-0.14)[m s^-1]
> v + v --> (6.00+/-0.20)[m s^-1]Input transformer make it easy to enter special quantities such as
sexagesimal angles or times:> 18d 24' 32" --> 0.321295722745
> 12h 34m 56s --> 45296.0[s]The reverse is also possible using output formats:> 1[rad] @ [dms] --> 57d 17' 44.806s"
> 10[ks] @ [hms] --> 2h 46m 40sDocumentation strings can be entered even for variables:> v = 50[km/hour] # "Standard maximum speed within towns"Configuration fileWhen launched, iMKS load definitions from the configuration file Startup.imks.
This file is searched in the current directory, and if not found in the
~/.imks directory.  The file should contain the standard definitions that one
is likely to need for any computation.  Typically the file uses the following
magic commands:%newbaseunit <name>Define a new base unit.  Base units are the building blocks for all
subsequent units definitions.  A base unit does not have a value: for
example, one cannot express a meter in any other unit if no unit of length
is known.%newbasecurrency <name>Define a new base currency, used for all currency conversions.  A base
currency is also a base unit.%newprefix <name>=<expression>Define a new prefix.  The <expression> value evaluate to a simple number.%newunit <name>=<expression>Define a new unit.  <expression> should evaluate to a Value’d number.  To
define a new absolute unit, expression should evaluate to a 2-tuple with
identical units (indicating the zero-point, and the scale).%newsystem <name>=[u1], [u2], …Define a new unit system.  A unit system is simply a list of units.%defaultsystem <name>Set the unit system to use in case no @ is used.%newtransformer <name>=”regex”:<transformer>Define a new input transformer: the regular expression regex is applied to
each input line, and if a match is found the <transformer> function is
called together with all named matching groups which must return the
transformed input.%newformat <name>=<transformer>Define a new output format.  When <name> is entered (alone) in a unit
specification, <transformer> is called with the result of the expression: it
must return a string that will be displayed on the screen.Other magic commands%imks [<options>]Show this help page or set configuration options for iMKS.%delprefix, %delunit, %delsystem, %deltransformer, or %delformat <name>Delete a previously define prefix, unit, unit system, transformer, or format.%lazy <name>=<expression>Define the variable <name> as <expression> lazily: that is, <expression> is
evaluated only when <name> is used or displayed.  This is implemented by
making <name> a function with no arguments, and by automatically adding a
function call name() when name is used in the input.%dellazy <name>Delete a previously defined %lazy variable.%lazyvalue <name>=<expression>Define the variable <name> as <expression> lazily: that is, <expression> is
evaluated only when <name> is used or displayed.  This only works for simple
values, and not for more general objects such as %lazy.%lazyprefix <name>=<expression>Define a lazy prefix (whose <expression> is evaluate only when the prefix is
used).%lazyunit <name>=<expression>Define a lazy unit (whose <expression> is evaluated only when the unit is
used).%compatible <stuff>Find out the known variables or units that are compatible to <stuff>.
<stuff> can be either a unit (in brackets) or an expression.%load_imks <filename>Load an external <filename> with definitions in iMKS format.%load_imks_ext <filename>Load an imks extension.%uinfo <name>Display an help page for a prefix, unit, or unit system.  This is the
equivalent of %pinfo (which works for objects in the user namespace).  A
short notation for %uinfo <name> is <name>! (i.e., the name of an imks
object followed by the exclamation mark).  When used with the -a flag,
as in %uinfo -a <text>, shows all quantities with <text> in their docstring.
The same effect is achieved using <text>!!%pickle <filename>Save all current variables into a filename, in the Python pickle format.%unpickle <filename>Load all previously %pickle’d variables from a filename.%resetPerform a full reset of the iMKS interpreter.ExtensionsiMKS comes with a number of extensions that define new commands, new
variables, or new units.  Extensions are loaded with the command
%load_imks_ext.  The currently defined extensions arecalendars: defines several new functions, one for each calendar (for example
Gregorian, Julian, Roman, Egyptian…).  Each calendar accepts a date in
several formats: as an integer (number of days from 1 January 1 C.E.), one of
the strings “today”, “tomorrow”, “yesterday”, or “now”, as a year followed by
a holiday name such as Gregorian(2017, “Easter”), or as a full year (with a
number of arguments depending on the calendar).  Optionally, one can also
add a time, counted from midnight, noon, sunset, or sunrise depending on the
specification of the calendar.  When calendars are loaded, one can input a
date using dot-separated integers.  For example, 1973.5.7 is interpreted as
May 7th, 1973.  The default calendar used to interpret dates is the Gregorian
one, but it can be changed using %imks -d <calendar>.  A date can be also
followed by a time, in the format hh:mm[:ss.d].constants: loads a large list of constants from the NIST database.  Constants
are then inserted into the variable const, a dictionary.currencies: loads a large list of currencies from the online database
openexachangerages.org.  Currencies are then used as usual units.  Note that
in order this to work, you first need to set a variable called
openexchangerates_id as a string holding your id.geolocation: defines two functions to set the current geographic location and
to retrieve it.jpl: loads the JPL database and creates two dictionaries, planets and moons,
where it stores the physical and orbital data.  Additionally, it defines a
function called minorplanet, which allows one to search a minor body database.wiki: experimental interface to Wikipedia.InternalsInternally, iMKS works by converting an input string into Python expressions.
The following rules are used:Physical quantities are converted into Value’s:> 72[km hour^-1] --> Value(72,"km hour^-1")The @ operator is converted into the | operator, and what follows is put in
a unit System:> 72[km hour^-1] @ [m], [s] --> Value(72,"km hour^-1") | System("m", "s")Quoted comments, used to enter documentation strings, are transformed into
the & operator followed by a Doc object:> a=2 # "Simple string" --> a=2 & Doc("Simple string")Normal Python operator precedence applies to @=| and to #=&: that is, @ has
a quite low precedence, which makes it possible to write expressions like:> v = 15[m/s] + 10[m]/2[s] @ [km/hour]with the unit specification after @ applying to the result of the other
operations.  Note also that since&binds stronger than|, in theory a
# documentation string after the @ operator would apply to the unit
specification, and not the the expression: however, this is handled
internally by System (that is, the documentation string that System gets
from the #=& operator is actually transferred to the result of the unit
conversion).The ! operator, if used at the end of a string, is converted into a %uinfo
magic (this is similar to the ? operator, that is converted by ipython into
a %pinfo magic):> hour! --> %uinfo hourIf used alone, instead, it is equivalent to %imks -h.  Note that the same !
symbol can still be used to perform shell operations if used at the beginning
of a line:> !lsTwo exclamation marks are converted into the %uinfo -a magic:> mile!! --> mile, mph, nmi, miUnicode characters appearing outside strings are converted into strings of
the form _uTf_xx_xx_xx…, where each xx is the hexadecimal representation
of a byte of the character in UTF8 encoding.Value, System, and Doc are defined in units.py, and for these objects the
standard operators are redefined to include tracking of physical units.If necessary, one can directly use the Value, System, and Doc objects to
make more complicated expressions.The know prefixes, units, and unit systems are stored in the dictionaries
prefixes, units, and systems, freely accessible from the user space.