Closed Aerokaur closed 1 year ago
Hi, you're certainly using it wrong, but it might be useful to know what you're trying to do mathematically. The simplest operation is shown on the Adept Wikipedia page, or on page 9 on the v2.1 user guide. You record your algorithm first, which could be (in a very simple scalar case) with
adouble x = 10.0; stack.new_recording(); adouble y = algorithm(x); // Some scalar algorithm computing y from x
At this point we have the differential statements relating y to x in memory. You can then compute the gradient dy_dx in either of two ways:
x.set_gradient(1.0); stack.forward(); // same as compute_tangent_linear() double dy_dx = y.get_gradient();
or
y.set_gradient(1.0); stack.reverse(); // same as compute_adjoint() double dy_dx = x.get_gradient()
If you put 2.0 instead of 1.0 in set_gradient, you will get the same result but scaled by 2.0. Perhaps this is what you mean by "user-defined gradient"?
Ok.. here is an example code of what I am trying. I have y = x^2 - r^2 + 4.0
, x= 4r^2
and I want to find the derivative of y
w.r.t r
. So my question is, can I use x_a.set_gradient(16.0)
to overwrite the gradient of x_a
provided by the adept ? Please let me know if I am doing something wrong here.
#include <iostream>
#include <iomanip>
#include <fstream>
#include "adept.h"
using adept::adouble;
adept::Stack stack;
adouble computeFy(adouble r_a)
{
adouble x_a = 4.0 * r_a * r_a;
return x_a;
}
adouble computeSens(adouble r_a)
{
adouble x_a = computeFy(r_a);
// stack.new_recording(); // set_gradient works only when I start new recording
x_a.set_gradient(16.0); // set the gradient of x_a explicitly
adouble y_a = x_a * x_a + 4.0 - r_a * r_a;
return y_a;
}
int main(int argc, char *argv[])
{
adouble r_a = 2.0;
stack.new_recording();
adouble y_a = computeSens(r_a);
double dy_dr;
r_a.set_gradient(1.0);
stack.compute_tangent_linear();
y_a.get_gradient(dy_dr);
std::cout << "dy_dr " << dy_dr << std::endl;
return 0;
}
Just to give you context on why I need to provide a derivative myself: I am differentiating a C++ library that uses Lapack for some functions. I cannot use adept to differentiate the Lapack part of the code; however, I do have analytical expressions for those derivatives that I can provide.
You can do that by changing your code as follows:
// Ordinary function (not active) double computeFy(double r_a) { double x_a = 4.0 r_a r_a; return x_a; }
adouble computeSens(adouble r_a) { // Extract the double underlying r_a using value(r_a), in order to // pass it to an ordinary function double x_a_passive = computeFy(value(r_a)); adouble x_a; // Assign to x_a without adding derivative to the stack x_a.set_value(x_a_passive); // Set the gradient of x_a explicitly x_a.add_derivative_dependence(r_a, 16.0);
adouble y_a = x_a x_a + 4.0 - r_a r_a; return y_a; }
See sections 2.7 and 2.9 of the v2.1 user guide for more information.
That seems to work. Thank you so much for your help.
Hello I am trying to perform automatic differentiation of a code using Adept. However, I am not able to provide a user-defined gradient to Adept. I have a function that I want to differentiate using Adept but I want to provide my gradient for a variable, say, x_a . I use x_a.set_gradient(xgrad) where
xgrad
is user-defined gradient value. It seems like I have to do stack.new_recording() to make adept use my gradient, but isn't stack.new_recording() clears all the previous gradients calculated so far using Adept ? Can you please let me know if I am doing this wrong ?Thanks and Regards Sharan