-
Notifications
You must be signed in to change notification settings - Fork 24
Eager vs lazy composition, and transform_deriv_params #5
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
Comments
I'm also struggling with this decision. Here's one case that confounded me:
It's a toss-up if this is less efficient, and it's clear that it's a Euler rotation where you can easily read the order, so I've let them stay separate so far. Additionally for Affine transformations, I can get confused about what order you add the displacement and multiply the matrix when I'm doing both forward and reverse transforms, so I've let that stay a composition. Then it's clear that
and
I don't know - it stays clear in my head! And you don't have to change the displacement vector for the inverse! Going the other way in design space, we could define more constructors. Have no greedy compositions, and let us define e.g. function AffineTransformation(trans::ComposedTransformation)
AffineTransformation(AffineTransformation(trans.trans1), AffineTransformation(trans.trans2))
end
AffineTransformation(t1::AffineTransformation, t2::AffineTransformation) = ... # pretty obvious
AffineTransformation(rot::Rotation) = AffineTransformation(rotmatrix(rot), Vec(0, 0, 0))
AffineTransformation(t::Translation) = AffineTransformation(identity, t.dx)
# etc... Going further, |
Interesting point about the inverse and the two ways to represent an affine transformation. On the other hand, I think this problem could be addressed by providing a couple of well documented utility functions to recover the linear and translation parts of a given affine transformation: trans = B ∘ C ∘ D ∘ E
R, T = rotation_and_translation(trans) # Ugh, naming?
T, R = translation_and_rotation(trans) In the branch I started working on, I already have those utility constructors for |
Argh, wrong button. |
A lot of this has been done now in #9, and it's become clear I think that eager composition is the right thing. In particular, eager composition of an arbitrary affine transformation chain produces the same type regardless of the number of affine transformations in the chain. So storing collections of composition chains is much more efficient if the composition is eager since all the transformation types are the same. |
Agreed. I think this will turn out nicely. We will still need a replacement for |
Remaining issues here are probably better covered by #6 |
I started implementing AffineTransformation which is pretty easy, except for one tricky design decision: should composition of specific AffineTransformation types eagerly compose into a composite AffineTransformation, or should they remain apart?
For most uses, I'm guessing eager composition is better since it'll be more efficient if you're just applying the transformation to many points. However, it's not a good idea if you want to optimize the parameters of one part of the transformation chain.
My current thought is that composition should be eager by default, but we could add a wrapper type for transformations to mark them as lazy. Come to think of it, maybe the wrapper type should be the signal that we're going to want derivative information in
transform_deriv_params()
? Currently there's no way to indicate which parts of a transformation chain should be differentiated...Usage musings...
The text was updated successfully, but these errors were encountered: