Skip to content

Commit

Permalink
Merge pull request #83 from JamesYang007/readme_update
Browse files Browse the repository at this point in the history
Add more complicated example
  • Loading branch information
JamesYang007 committed Jul 28, 2020
2 parents 5f35f6b + 58d16ed commit 5693f11
Showing 1 changed file with 56 additions and 8 deletions.
64 changes: 56 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,9 @@ _If the expression is not bound to any temporary storage, it will lead to segfau
To differentiate the expression, simply call the following:
```cpp
auto f = ad::autodiff(expr_bound, i, j);

// or if the raw expression is manually bound,
// auto f = ad::autodiff(expr, i, j);
```
where `i,j` refer to the `(i,j)`th element of the expression.
This will return the evaluated function value, if the user is interested.
Expand All @@ -308,22 +311,65 @@ v.get_adj(2,0); // get adjoint for v at index 2

The full code for this example is the following:
```cpp
// More low-level version:
// auto expr = (sin(x) + cos(v));
// std::vector<double> tmp(expr.bind_size());
// expr.bind(tmp.data());
#include <fastad>
#include <iostream>

auto expr_bound = ad::bind(sin(x) + cos(v));
auto f = ad::autodiff(expr_bound, 0); // differentiate first element of expr_bound
std::cout << x.get_adj(0,0) << std::endl;
std::cout << v.get_adj(2,0) << std::endl;
int main()
{
using namespace ad;

Var<double, scl> x(2);
Var<double, vec> v(5);

auto expr_bound = bind(sin(x) + cos(v));
auto f = autodiff(expr_bound, 0); // differentiate first element of expr_bound

std::cout << x.get_adj(0,0) << std::endl;
std::cout << v.get_adj(2,0) << std::endl;

return 0;
}
```

_Note: once you have differentiated an expression,
you must reset the adjoints of all variables to 0 before differentiating again.
This includes placeholder variables (see below)._
To that end, we provide a member function for `Var` called `reset_adj()`.

Here is a more complicated example:

```cpp
#include <fastad>

int main()
{
Var<double, vec> v1(6);
Var<double, vec> v2(5);
Var<double, mat> M(5, 6);
Var<double, vec> w(5);
Var<double, scl> r;

auto& v1_raw = v1.get(); // Eigen::Map
auto& v2_raw = v2.get(); // Eigen::Map
auto& M_raw = M.get(); // Eigen::Map

// initialize...

auto expr = bind((
w = ad::dot(M, v1) + v2,
r = sum(w) * sum(w * v2)
));

autodiff(expr);

std::cout << v1.get_adj(0,0) << std::endl; // adjoint of v1 at index 0
std::cout << v2.get_adj(1,0) << std::endl; // adjoint of v2 at index 1
std::cout << M.get_adj(1,2) << std::endl; // adjoint of M at index (1,2)

return 0;
}
```

#### Placeholder

Consider the following expression:
Expand All @@ -338,6 +384,8 @@ and also save a lot of memory.
Placeholder expressions are created by using `operator=` with
a `Var` and an expression:
```cpp
Var<double, scl> x;
Var<double, vec> v(5);
Var<double, vec> w(v.size());
auto expr = (
w = cos(v),
Expand Down

0 comments on commit 5693f11

Please sign in to comment.