A Python wrapper for an efficient C++ library that is used for Auto Differentiation
Project description
First, Acknowledgment
In case you're wondering, our project's name is chosen because we wanted to highlight a brilliant mathematician, Emmy Noether. In the late 19th to early 20th centry, she contributed a lot to the field of mathematics, including Noether's Theorm, and with very little recoginition while she was alive.
Installing the NoetherAutoDiff python library
Option 1:
- Use pip install to install directory from PyPI (TODO)
pip install NoetherAutoDiff
Option 2:
-
Download the NoetherAutoDiff python module along with the C++
.so
shared object from our github repo. The package is contained inside the /py/bin subdirectory in our repo. Inside it has a few *.py files and NoetherAutoDiff.so C/C++ shared library. You don't need anything else. -
Then find out what environement path Python checks on your machine. To do this follow this steps:
$ python
Next, import the sys module:
>>> import sys
Then have Python print out the system path:
>>> print(sys.path)
From the output on your python interpreter, look for something like this:
'/usr/.../.../lib/python3.5/site-packages'
-
Next, move the folder you downloaded into this location. All the files should stay inside the NoetherAD sub directory except for the NoetherAD.py file. Put the NoetherAD.py file at the same level as the NoetherAutoDiff directory. It should look like below:
/usr/.../python3.6/site-packages/NoetherAutoDiff <--- everthing else inside the folder /usr/...python3.6/site-packages/NoetherAD.py <--- the file that contains all *import* statements
Basic Usage (Tutorial)
Once installed using either Option 1 or Option 2 mentioned above, you can type import NoetherAutoDiff
from the $ python
command line as follows:
>>> import NoetherAutoDiff as nad
Then you can instantiate any of these classes NoetherAutoDiff
, NoetherAutoDiff_Vector
, NoetherAutoDiff_V
, NoetherAutoDiff_V_Vector
by providing the correct input arguments at instantiation. Here are a few examples on how to find the directional or none directional derivatives the Auto Differentiation algorithm.
The NoetherAutoDiff
class take four inputs. They have the following types:
input
- a string representing the function to be evaluatedmode
- the integer 0 for (for forward mode), or a 1 (for reverse mode) evaluation of auto diffinits
- are key (char
) and value (double
) pair of the variables' representation (the point where the derivative will be evaluated at)seeds
- represents the seed vector (the direction of the vector for directional derivatives)
Now, let's try an ugle looking function from the python interpreter line:
>>> function = "sin(x)^cos(x-5/3+4^x*y/z)/tan(3*x)+exp(3*x-1)"
>>> mode = 0
>>> inits = {'x': 1.4, 'y': 2.4, 'z': 3.4}
>>> seeds = {'x': 1, 'y': 1, 'z': 1}
>>> n = nad.NoetherAutoDiff(function, mode, inits, seeds)
We now have our NoetherAutoDiff
object. Here is how we can access the value of the function:
>>> n.val
25.095548918554428
Here is how we can get the derivaties with respect to all variables:
>>> n.deriv
{'x': 69.57424922848773, 'y': -0.016870006832635686, 'z': 0.0119082401171546}
or we can pretty print all the inputs and outputs using .print()
as follows:
>>> n.print()
Input function:
f = sin(x)^cos(x-5/3+4^x*y/z)/tan(3*x)+exp(3*x-1)
Evaluated at:
x=1.4
y=2.4
z=3.4
Numeric Value:
f = 25.095548918554428
Derivates:
df/dx = 69.57424922848773
df/dy = -0.016870006832635686
df/dz = 0.0119082401171546
Comparison operations are suppoerted. To check weather or not two NoetherAutoDiff
objects are the same, do this:
>>> n == n
True
The main difference between the NoetherAutoDiff
and NoetherAutoDiff_Vector
classes is that the latter takes vector positional inputs as opposed to key/value dictionary as inits
and seeds
. For that to work, the variables in the input function have to be provided as x0, x1, ...
as below:
>>> function = "sin(x0)^cos(x0-5/3+4^x0*x1/x2)/tan(3*x0)+exp(3*x0-1)"
>>> inits_v = [1.0, 2.0, 3.0]
>>> seeds_v = [1, 1, 1]
>>> n_v = nad.NoetherAutoDiff_Vector(function, mode, inits_v, seeds_v)
>>> n_v.val
-0.14862974395913575
>>> n_v.deriv
[-143.23486622993053, -1.577367720808487, 1.0515784805389914]
We can again pretty print the input and outputs as follows.
>>> n_v.print()
Input function:
f = sin(x0)^cos(x0-5/3+4^x0*x1/x2)/tan(3*x0)+exp(3*x0-1)
Evaluated at:
x0=1.0
x1=2.0
x2=3.0
Numeric Value:
f = -0.14862974395913575
Derivates:
df/dx0 = -143.23486622993053
df/dx1 = -1.577367720808487
df/dx2 = 1.0515784805389914
Let's try comparions n
and n_v
:
>>> n == n_v
False
Aha! Notice the init values are not the same. Otherwise the above would print True
.
The other two classes we haven't talked about yet have similar behavior except that these take a number of function (a system of equations). The NoetherAutoDiff_V
take a python list of string each representing a function, and key/value inits
and seeds
, same as NoetherAutoDiff
. The NoetherAutoDiff_V_Vector
class takes in a list of equation strings (with variables represented as x0, x1, ...) and a python list of positional values for
initsand
seeds`.
Todos
- Add more features (like printing trace and graph)
- Write more tests
- Add more tutorial, and demo use cases that demonstrate the value of AutoDiff
- Support complex numbers?
License
MIT
Free Software, Hell Yeah!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for NoetherAutoDiff-0.0.1-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 977af8937dbc20e5941c2ca362bce0646743f6248532b3fae4e5d07fc513ee54 |
|
MD5 | 3d2249aa31bbc266291f817914565914 |
|
BLAKE2b-256 | 6c389cc5bb6358050b46457b96e9bd6566759a52855deb2a1e9bc4c9e65e3082 |