WEdiff
WEdiff: A Python and C++ package for automatic differentiation - Published in JOSS (2018)
Science Score: 87.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
○CITATION.cff file
-
○codemeta.json file
-
○.zenodo.json file
-
✓DOI references
Found 4 DOI reference(s) in README and JOSS metadata -
✓Academic publication links
Links to: joss.theoj.org -
○Committers with academic emails
-
○Institutional organization owner
-
✓JOSS paper metadata
Published in Journal of Open Source Software
Last synced: 10 months ago
·
JSON representation
Repository
WEdiff Automatic Differentiation Library
Basic Info
Statistics
- Stars:
- Forks:
- Open Issues:
- Releases: 0
Created almost 9 years ago
https://bitbucket.org/cdegroot/wediff/blob/master/
[](https://doi.org/10.21105/joss.00820)
# WEdiff Automatic Differentiation Library
WEdiff is a set of tools for automatically differentiating templated C++ code using the method of operator overloading. Automatic differentiation allows derivatives of arbitrarily complex expressions to be evaluated with machine precision.
The project is led by Prof. C.T. DeGroot in the Faculty of Engineering (WE = Western Engineering) at Western University in London, Canada.
## Getting Started
### Installation
On MacOS, WEdiff can be installed using conda:
```
conda install -c cdegroo5 wediff
```
On MacOS and Linux, it can be installed from the command line. WEdiff requires the following packages to be installed:
- [Boost](http://www.boost.org)
- [pytest](https://pytest.org/)
- [SWIG](http://www.swig.org)
- [SCons](https://scons.org)
Optionally, to enable profiling of the code [gperftools](https://github.com/gperftools/gperftools) is required. In addition, a C++ compiler and Python 3 interpreter are required.
Boost is used for unit testing the C++ code and can be installed, once downloaded from [http://www.boost.org](http://www.boost.org), using:
```
>>> ./bootstrap.sh
>>> ./b2 install --layout=tagged
>>> ./b2 headers
```
gperftools is used for profiling and can be installed using:
```
>>> apt-get install google-perftools libgoogle-perftools-dev
```
pytest is used for unit testing the Python code and can be installed using:
```
>>> pip3 install pytest
```
SWIG is used to build the Python bindings for the C++ code. Installation instructions can be found at [http://www.swig.org](http://www.swig.org).
SCons is the build tool used for WEdiff and can be installed using:
```
>>> apt-get install scons
```
Before building the code, a number of environment variables must be set, as outlined in the following table:
| Variable | Description | Required? | Default |
| -------- | ----------- | --------- | ------- |
| `BOOST_INCLUDE_DIR` | Location of Boost headers | No | `/usr/local/include/boost` |
| `BOOST_LIB_DIR` | Location of Boost libraries | No | `/usr/local/lib` |
| `PYTHON_INCLUDE_DIR` | Location of Python headers (i.e. `Python.h`) | Yes | N/A |
| `PYTHON_LIB_DIR` | Location of Python libraries (e.g. `libpython.so`) | No | `/usr/local/lib` |
| `PYTHON_SITE_PACKAGES` | Location of Python modules (where `wediff` will be installed) | Yes | N/A |
| `PYTHON_VERSION` | Location of Python headers (i.e. `Python.h`) | No | Empty (no version) |
| `WEDIFF_INST_DIR` | Location to install WEdiff headers and libraries | No | `/usr/local/` |
| `WEDIFF_PROFILING` | Flag to enable gperftools profiling (set to 'true' to enable) | No | Empty (off) |
On Linux, `PYTHON_INCLUDE_DIR` is commonly `/usr/local/pythonX.Ym`, where `X.Y` represents the Python version. It is assumed that the Python shared library file is named `libpython.so` on Linux systems (or `libpython.dylib` on Mac). Sometimes, the library file name includes the version number in the form `libpythonX.Y.so`. If this is the case, the `PYTHON_VERSION` must be set to specify the version number:
With SCons installed and the environment variables defined, the tests and examples are built as:
```
>>> scons
```
After building the code, SCons will run the C++ unit tests automatically and report the results. Binaries of the unit tests and examples will be built and located in the `bin` directory within the root code directory. To run the Python unit tests, manually run `pytest $PYTHON_SITE_PACKAGES/wediff` to run the tests that are installed into the `wediff` module directory.
To install the shared libraries and Python modules, so they may be used in external programs and scripts, use:
```
>>> scons install
```
If you do not have permissions to install to `/usr/local`, run:
```
>>> sudo -E scons install
```
where the `-E` preserves the environment variables. Alternatively, a different install directory can be specified through the environment variable `WEDIFF_INST_DIR`, which defaults to `/usr/local` if it is not specified. Be sure to add `$WEDIFF_INST_DIR/lib/WEdiff/` to `PYTHONPATH`.
### Building and Running the Tests
WEdiff includes a comprehensive suite of unit tests, which make use of the Boost unit testing framework. The unit tests are executed automatically after being built by SCons. To run manually, run:
```
>>> ./bin/unit_tests
```
Python unit tests are also provided using pytest. After building the code with SCons, the tests are installed into the `wediff` module directory. To run the tests, execute:
```
>>> pytest $PYTHON_SITE_PACKAGES/wediff
```
where `$PYTHON_SITE_PACKAGES` is set as described above.
### Building and Running the Examples
WEdiff includes a C++ example located in the `examples` directory. After it is built by SCons, it will be installed in the `bin` directory. Users are encouraged to study the example code, as well as the tests, to learn more about using the library.
## Documentation
The code is documented using Doxygen. To build the documentation locally, execute
```
>>> doxygen Doxyfile
```
This will generate html documentation of the code within the `html` directory. Open the file `index.html` to begin navigating the documentation.
A hosted version of the documentation can be found at [http://publish.uwo.ca/~cdegroo5/WEdiff/](http://publish.uwo.ca/~cdegroo5/WEdiff/)
## Basic Example
This example is based on the code `src/FwdDiff/examples/example01.cpp`. Suppose that one had a function such as:
```
double f(const double& x)
{
return x*sin(pow(x, 2.0)) + x;
}
```
For a relatively simple function such as this, the exact derivative df/dx could be manually derived and coded. However, to demonstrate the WEdiff library, the derivative will be calculated automatically and compared with the exact value. To start, the function above must be templated so that it can work with arbitrary data types, including the FwdDiff class defined in this library. Therefore, the function is rewritten as:
```
template
T f(const T& x)
{
return x*sin(pow(x, 2.0)) + x;
}
```
To compute the derivate of the function with respect to x, we simply need to work with FwdDiff numbers and initialize the derivative component of x to 1 to mark it as the independent variable. The following code will compute df/dx at x=2.0:
```
// Create a variable of type FwdDiff
FwdDiff x;
// Initialize the independent variable
x.setVal(2.0);
x.setDx(1.0);
// Evaluate function
FwdDiff y = f(x);
// Report the derivative
std::cout << "df/dx at x = 2.0: " << y.dx(0) << std::endl;
```
The same thing can also be done in Python:
```
from wediff.double import FwdDiff
from wediff.double import math
def f(x):
"""Generic mathematical function"""
return x*math.sin(math.pow(x, 2.0)) + x
# Create a FwdDiff number
x = FwdDiff(2.0, [1.0])
# Evaluate the function
y = f(x)
# Report the derivative
print("df/dx at x = 2.0: {}".format(y.dx(0)))
```
The code in example01.cpp loops through a range of x-values and reports the exact and automatically differentiated derivates. The output of the program should be something like:
```
+---------------------------------------------------------------+
| x | f(x) | df/dx [exact] | df/dx [auto] |
+---------------------------------------------------------------+
| 0 | 0 | 1 | 1 |
| 0.2 | 0.207998 | 1.11993 | 1.11993 |
| 0.4 | 0.463727 | 1.47523 | 1.47523 |
| 0.6 | 0.811365 | 2.02612 | 2.02612 |
| 0.8 | 1.27776 | 2.62388 | 2.62388 |
| 1 | 1.84147 | 2.92208 | 2.92208 |
| 1.2 | 2.38975 | 2.36708 | 2.36708 |
| 1.4 | 2.6953 | 0.437761 | 0.437761 |
| 1.6 | 2.47897 | -2.72886 | -2.72886 |
| 1.8 | 1.62315 | -5.5469 | -5.5469 |
| 2 | 0.486395 | -4.98595 | -4.98595 |
+---------------------------------------------------------------+
```
More Python examples can be found in the Jupyter notebook `PythonExamples.ipynb`, which is located in the main directory of this repository.
## Contributing, Issue Reporting, and Feature Requests
If you have a feature request or an issue to report, please create a new issue. If you would like to contribute to `WEdiff` please make a pull request. For further support, please contact the author at the link below.
## Authors
- [Chris DeGroot](http://www.eng.uwo.ca/mechanical/faculty/degroot_c/index.html)
## License
This project is licensed under the GNU General Public License, version 3 (GPL-3.0). See LICENSE.txt for details.
## Acknowledgments
- This work is supported by a research grant from the Natural Sciences and Engineering Research Council of Canada (NSERC) through the Discovery Grants program
JOSS Publication
WEdiff: A Python and C++ package for automatic differentiation
Published
November 25, 2018
Volume 3, Issue 31, Page 820
Authors
Tags
Automatic differentiationCommitters
Last synced: 11 months ago
Top Committers
| Name | Commits | |
|---|---|---|
| Chris DeGroot | c****5@u****a | 110 |
| Kyle Niemeyer | k****r@g****m | 1 |
Committer Domains (Top 20 + Academic)
uwo.ca: 1
Issues and Pull Requests
Last synced: 10 months ago
