Voltar ao ranking

autodiff/autodiff

C++autodiff.github.io

automatic differentiation made easier for C++

automatic-differentiationauto-differentiationautodiffautodifferentiationdifferentiationderivativesnumerical-derivation
Crescimento de estrelas
Estrelas
1.9k
Forks
196
Crescimento semanal
Issues
92
5001k1.5k
ago. de 2018mar. de 2021nov. de 2023jul. de 2026
README

Linux build status macOS build status Windows build status

Overview

autodiff is a C++17 library that uses modern and advanced programming techniques to enable automatic computation of derivatives in an efficient, easy, and intuitive way.

Demonstration

Consider the following function f(x, y, z):

double f(double x, double y, double z)
{
    return (x + y + z) * exp(x * y * z);
}

which we use use to evaluate the variable u = f(x, y, z):

double x = 1.0;
double y = 2.0;
double z = 3.0;
double u = f(x, y, z);

How can we minimally transform this code so that not only u, but also its derivatives ∂u/∂x, ∂u/∂y, and ∂u/∂z, can be computed?

The next two sections present how this can be achieved using two automatic differentiation algorithms implemented in autodiff: forward mode and reverse mode.

Forward mode

In a forward mode automatic differentiation algorithm, both output variables and one or more of their derivatives are computed together. For example, the function evaluation f(x, y, z) can be transformed in a way that it will not only produce the value of u, the output variable, but also one or more of its derivatives (∂u/∂x, ∂u/∂y, ∂u/∂z) with respect to the input variables (x, y, z).

Enabling forward automatic differentiation for the calculation of derivatives using autodiff is relatively simple. For our previous function f, we only need to replace the floating-point type double with autodiff::dual for both input and output variables:

dual f(const dual& x, const dual& y, const dual& z)
{
    return (x + y + z) * exp(x * y * z);
}

We can now compute the derivatives ∂u/∂x, ∂u/∂y, and ∂u/∂z as follows:

dual x = 1.0;
dual y = 2.0;
dual z = 3.0;
dual u = f(x, y, z);

double dudx = derivative(f, wrt(x), at(x, y, z));
double dudy = derivative(f, wrt(y), at(x, y, z));
double dudz = derivative(f, wrt(z), at(x, y, z));

The auxiliary function autodiff::wrt, an acronym for with respect to, is used to indicate which input variable (x, y, z) is the selected one to compute the partial derivative of f. The auxiliary function autodiff::at is used to indicate where (at which values of its parameters) the derivative of f is evaluated.

Reverse mode

In a reverse mode automatic differentiation algorithm, the output variable of a function is evaluated first. During this function evaluation, all mathematical operations between the input variables are "recorded" in an expression tree. By traversing this tree from top-level (output variable as the root node) to bottom-level (input variables as the leaf nodes), it is possible to compute the contribution of each branch on the derivatives of the output variable with respect to input variables.

Thus, a single pass in a reverse mode calculation computes all derivatives, in contrast with forward mode, which requires one pass for each input variable. Note, however, that it is possible to change the behavior of a forward pass so that many (perhaps even all) derivatives of an output variable are computed simultaneously (e.g., in a single forward pass, ∂u/∂x, ∂u/∂y, and ∂u/∂z are evaluated together with u, in contrast with three forward passes, each one computing the individual derivatives).

Similar as before, we can use autodiff to enable reverse automatic differentiation for our function f by simply replacing type double with autodiff::var as follows:

var f(var x, var y, var z)
{
    return (x + y + z) * exp(x * y * z);
}

The code below demonstrates how the derivatives ∂u/∂x, ∂u/∂y, and ∂u/∂z can be calculated:

var x = 1.0;
var y = 2.0;
var z = 3.0;
var u = f(x, y, z);

Derivatives dud = derivatives(u);

double dudx = dud(x);
double dudy = dud(y);
double dudz = dud(z);

The function autodiff::derivatives will traverse the expression tree stored in variable u and compute all its derivatives with respect to the input variables (x, y, z), which are then stored in the object dud. The derivative of u with respect to input variable x (i.e., ∂u/∂x) can then be extracted from dud using dud(x). The operations dud(x), dud(y), dud(z) involve no computations! Just extraction of derivatives previously computed with a call to function autodiff::derivatives.

Documentation

Check the documentation website for more details:

License

MIT License

Copyright © 2018–2024 Allan Leal

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Repositórios relacionados
ggml-org/ggml

Tensor library for machine learning

C++MIT Licenseautomatic-differentiationlarge-language-models
15k1.7k
ggerganov/ggml

Tensor library for machine learning

C++automatic-differentiationlarge-language-models
11.5k1.1k
HIPS/autograd

Efficiently computes derivatives of NumPy code.

PythonPyPIMIT Licenseautogradautomatic-differentiation
7.5k936
gorgonia/gorgonia

Gorgonia is a library that helps facilitate machine learning in Go.

GoGo ModulesApache License 2.0machine-learningartificial-intelligence
gorgonia.org
5.9k450
stack-of-tasks/pinocchio

A fast and flexible implementation of Rigid Body Dynamics algorithms and their analytical derivatives

C++BSD 2-Clause "Simplified" Licenseroboticsdynamics
stack-of-tasks.github.io/pinocchio/
3.6k557
PennyLaneAI/pennylane

PennyLane is an open-source quantum software platform for quantum computing, quantum machine learning, and quantum chemistry. Create meaningful quantum algorithms, from inspiration to implementation.

PythonPyPIApache License 2.0quantummachine-learning
pennylane.ai
3.4k839
google/tangent

Source-to-Source Debuggable Derivatives in Pure Python

PythonPyPIApache License 2.0autodiffautomatic-differentiation
2.3k432
nlpodyssey/spago

Self-contained Machine Learning and Natural Language Processing library in Go

GoGo ModulesBSD 2-Clause "Simplified" Licensedeep-learningmachine-learning
1.9k88
ethz-adrl/control-toolbox

The Control Toolbox - An Open-Source C++ Library for Robotics, Optimal and Model Predictive Control

C++BSD 2-Clause "Simplified" Licenseoptimal-controlmodel-predictive-control
1.7k342
EnzymeAD/Enzyme

High-performance automatic differentiation of LLVM and MLIR.

LLVMOtherenzymellvm
enzyme.mit.edu
1.6k177
FluxML/Zygote.jl

21st century AD

JuliaOtherjuliajulia-compiler
fluxml.ai/Zygote.jl/
1.6k220
mratsim/Arraymancer

A fast, ergonomic and portable tensor library in Nim with a deep learning focus for CPU, GPU and embedded devices via OpenMP, Cuda and OpenCL backends

NimApache License 2.0tensornim
mratsim.github.io/Arraymancer/
1.4k101