JamesYang007 / FastAD

FastAD is a C++ implementation of automatic differentiation both forward and reverse mode.
MIT License
103 stars 3 forks source link

Problem using example in readme #106

Closed bradbell closed 1 year ago

bradbell commented 1 year ago

I am getting the following messages when I try to compile one of the FastAD examples:

temp.cpp: In function ‘int main()’:
temp.cpp:12:22: error: no matching function for call to ‘autodiff(ad::core::ExprBind<ad::core::BinaryNode<ad::core::Add, ad::core::UnaryNode<ad::core::Sin, ad::VarView<double, ad::scl> >, ad::core::UnaryNode<ad::core::Cos, ad::VarView<double, ad::vec> > > >&)’
   12 |     auto f = autodiff(expr_bound);
      |              ~~~~~~~~^~~~~~~~~~~~
In file included from include/fastad_bits/reverse/core.hpp:7,
                 from include/fastad_bits/reverse.hpp:3,
                 from include/fastad:4,
                 from temp.cpp:1:

Below are the steps to reproduce this:

Step 1:

git clone https://github.com/JamesYang007/FastAD.git fastad.git

Step 2:

cd fastad.git ; ./setup.sh

Step 3: Create the file temp.cpp with the following contents (from one of the FastAD readme examples):

#include <fastad>
#include <iostream>

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);

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

    return 0;
}

Step 4:

g++ temp.cpp -o temp -I include -I libs/eigen-3.3.7/build/include/eigen3
JamesYang007 commented 1 year ago

Thanks for bringing this to my attention! I just updated the new README. The issue was that the expression was a vector expression so autodiff explicitly needed a seed that was a vector as well. Only when the expression is scalar do we have a default value of 1 for the seed. The new code is:

#include <fastad>
#include <iostream>

int main()
{
    using namespace ad;

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

    // randomly generate values for v
    v.get().setRandom();

    // create AD expression bound to storage
    auto expr_bound = bind(sin(x) + cos(v));

    // seed to get gradient of function at index 2
    Eigen::Array<double, Eigen::Dynamic, 1> seed(v.size());
    seed.setZero();
    seed[2] = 1;

    // differentiate
    auto f = autodiff(expr_bound, seed);

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

    return 0;
}

Closing for now, but if you see other issues, let me know.