-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Get autodiff working #2
Comments
I got autodiff working on the s_n(r,b) components. I just finished coding up the s_n function in Julia, and I implemented autodiff using the ForwardDiff package. I haven't added analytic derivatives of the elliptic integrals: ForwardDiff diffs those as well. I still haven't gotten the transformation and rotation matrices computed, but these should be straightforward. |
Fantastic! @dfm and I are going to try to get that working in C++ on Friday.
…On Wed, Apr 25, 2018, 9:59 PM Eric Agol ***@***.***> wrote:
I got autodiff working on the s_n(r,b) components. I just finished coding
up the s_n function in Julia, and I implemented autodiff using the
ForwardDiff package.
I still haven't gotten the transformation and rotation matrices computed,
but these should be straightforward.
—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub
<#2 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AI5FK0oQx6XifoQ-VTWVNWUV0C0WCAqoks5tsRwKgaJpZM4SSiiw>
.
|
This comment has been minimized.
This comment has been minimized.
@ericagol Can you create a julia folder in the top level of the repository and place your code in there? |
Yes. I just created a folder called julia/ at the top level of the repo where I placed this code and a preliminary README.md. |
Great, thanks! |
@dfm Autodiff is working beautifully! Thanks for the help. |
Currently computing gradients of the flux in this test file. Run |
@dfm How do I tell Eigen to not compute derivatives for a given variable? Say I have the function template <typename T>
T testfunction(T& x1, T& x2, T& x3) {
return x1 + x2 * x2 + x3 * x3 * x3;
} and I want to compute derivatives w/ respect to /**
* Important note:
* All ActiveScalars which are used in one computation must have
* either a common derivative vector length or a zero-length
* derivative vector.
*/ led me to believe that I could just resize |
This comment has been minimized.
This comment has been minimized.
@dfm I'm pretty sure there's a bug in Eigen: it's related to the reason we had to typecast many of the scalars in function calls to step() and the elliptic integrals to get the code to compile with autodiff. Check out this open Eigen issue and the corresponding code. I'm guessing what happens is that there's an issue with the * operator when the AutoDiffScalar variable has no derivatives. Long story short, if I change my function to template <typename T>
T testfunction(T& x1, T& x2, T& x3) {
return T(x1) + T(x2 * x2) + T(x3 * x3 * x3);
} then everything works as expected. Here's a MWE: #include <iostream>
#include <iomanip>
#include <Eigen/Core>
#include <cmath>
#include <unsupported/Eigen/AutoDiff>
#include <vector>
using namespace std;
using Grad = Eigen::AutoDiffScalar<Eigen::VectorXd>;
// Dummy function
template <typename T>
T testfunction(T& x1, T& x2, T& x3, T& x4) {
// This leads to an "Assertion failed" error:
//return x1 + x2 * x2 + x3 * x3 * x3 * x3 + x4;
// This compiles and runs fine:
return T(x1) + T(x2 * x2) + T(x3 * x3 * x3) + T(x4 * x4 * x4 * x4);
}
// Instantiate a Grad type with or without derivatives
Grad new_grad(string name, double value, vector<string>& gradients, int& ngrad) {
if(find(gradients.begin(), gradients.end(), name) != gradients.end()) {
return Grad(value, gradients.size(), ngrad++);
} else {
return Grad(value);
}
}
// Let's roll
int main() {
// The user will supply this vector of parameter names
// for which we will compute derivatives
vector<string> gradients;
gradients.push_back("x1");
gradients.push_back("x2");
// Declare our parameters: only the ones the user
// wants will be differentiated!
int ngrad = 0;
Grad x1 = new_grad("x1", 4., gradients, ngrad);
Grad x2 = new_grad("x2", 3., gradients, ngrad);
Grad x3 = new_grad("x3", 2., gradients, ngrad);
Grad x4 = new_grad("x4", 1., gradients, ngrad);
// Compute the function
Grad result = testfunction(x1, x2, x3, x4);
// Print the flux and all the derivatives
cout << result.value() << endl;
cout << result.derivatives() << endl;
return 0;
} Curiously, if I declare the number of derivatives at compile time using I'm going to keep digging -- I'd rather not add |
FYI: http://eigen.tuxfamily.org/bz/show_bug.cgi?id=1281#c1 |
You definitely won't need to manually cast everything to |
This comment has been minimized.
This comment has been minimized.
@dfm Dude: |
Dude! 🎉🎈🍻 |
Shouldn’t we be saying “Doctor” rather than “Dude”?
That looks great!
Eric Agol
Astronomy Professor
University of Washington
… On May 3, 2018, at 10:45 AM, Dan Foreman-Mackey ***@***.***> wrote:
Dude! 🎉🎈🍻
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
|
@dfm This is how I'm currently structuring the code: >>> import starry
>>> map1 = starry.Map()
>>> map1[1, 0] = 1
>>> map1.flux(axis=(0, 1, 0), theta=0.3, xo=0.1, yo=0.1, ro=0.1)
0.9626882655504516
>>> map2 = starry.grad.Map()
>>> map2[1, 0] = 1
>>> map2.flux(axis=(0, 1, 0), theta=0.3, xo=0.1, yo=0.1, ro=0.1)
array([[ 9.62688266e-01, 4.53620580e-04, 0.00000000e+00,
-6.85580453e-05, -2.99401131e-01, -3.04715096e-03,
1.48905485e-03, -2.97910667e-01]]) The modules What do you think of this? It certainly hasn't helped my code legibility... PS: I haven't finished implementing this, but |
Quick update on this. I'm slowly getting things to work with dynamically-sized derivative vectors, which is the ideal way to do this. The most important thing I've learned is that casting to type
nor does
since neither allocates space for the derivatives of the result. What I have to do is this:
where For some reason I no longer get any compiler errors -- just segfaults when I finally run the code. Debugging this is therefore super tedious. But I'm getting the hang of it. |
That does sound tedious! Let me know if there's anything that I can do to help out. |
Got the flux calculation to work all the way through! Now the user can dynamically choose which and how many derivatives to compute. Gonna take a while for me to clean the code up and push to the master branch, but I think it's downhill from here! |
Quick update on this: I'm switching back to compile-time defined derivative vector sizes. |
Closing this issue. There are things that can still be optimized, but I'm happy! |
Ultimately we want to use starry for inference, so having analytic derivatives of the light curve will be super useful.
The text was updated successfully, but these errors were encountered: