-
Notifications
You must be signed in to change notification settings - Fork 20
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
Gradient evaluation inside surfaces sometimes returns NaNs. #127
Comments
What's the actual equation of the shape that you're evaluating? |
|
In general, I'd like a self-contained example that I can run, which only depends on the use fidget::{vm::VmShape, context::{Context, Tree}};
fn build_tree() -> Tree {
todo!()
}
fn main() {
let tree = build_tree();
let mut ctx = Context::new();
let root = ctx.import(&tree);
let shape = VmShape::new(&ctx, root)?;
let tape = shape.grad_slice_tape(Default::default());
let mut eval = VmShape::new_grad_slice_eval();
let out = tape.eval(...)?; // add arguments here
println!("{out:?}"); // look, there are NANs in this array!
} Having to figure out a different crate slows things down, and a self-contained example can easily be converted into a unit test. |
Sure this prints out use fidget::{context::{Context, Tree}, types::Grad, vm::VmShape};
fn cube(pos: [Tree; 3], size: [Tree; 3]) -> Tree {
let q = [
pos[0].abs() - size[0].clone(),
pos[1].abs() - size[1].clone(),
pos[2].abs() - size[2].clone(),
];
let q_length = (
q[0].max(0.0).square() +
q[1].max(0.0).square() +
q[2].max(0.0).square()
).sqrt();
return q_length + q[0].clone().max(q[1].clone().max(q[2].clone())).min(0.0);
}
fn main() {
let tree = cube(
[
Tree::x(),
Tree::y(),
Tree::z()
],
[
Tree::constant(1.0),
Tree::constant(1.0),
Tree::constant(1.0)
],
);
let mut ctx = Context::new();
let root = ctx.import(&tree);
let shape = VmShape::new(&ctx, root).unwrap();
let tape = shape.grad_slice_tape(Default::default());
let mut eval = VmShape::new_grad_slice_eval();
let out = eval
.eval(
&tape,
&[Grad::new(0.0, 1.0, 0.0, 0.0)],
&[Grad::new(0.0, 0.0, 1.0, 0.0)],
&[Grad::new(0.0, 0.0, 0.0, 1.0)],
)
.unwrap();
println!("{out:?}");
} |
This looks like the same issue as #15: taking derivatives of |
Ok I made the max value epsilon and it's fixed thanks 👍 |
I just replaced my cheap box evaluation with an exact box and immediately noticed that gradient evaluation returns NaNs anytime it is inside the surface of the object. This problem didn't happen with the previous box evaluation or my sphere evaluation and I can't seem to connect it to any specific operation. Is this just an unavoidable side effect of the auto differentiation in fidget or is it a bug? If it is an unavoidable side effect I can always just use numerical normals instead though.
The text was updated successfully, but these errors were encountered: