Skip to content
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

DM-9598: Allow Transform to return a matrix of derivatives #200

Merged
merged 1 commit into from Mar 29, 2017

Conversation

kfindeisen
Copy link
Member

This commit implements Transform::getJacobian. The unit tests in test_transform.py were modified slightly to make the test transform non-linear, so that the Jacobian is not constant. A supplementary test was added as test_transform.cc to make absolutely sure that the matrix dimensions are what they should be, since conversion to ndarray loses some of that information.

@kfindeisen kfindeisen requested a review from r-owen March 29, 2017 02:01
Copy link
Contributor

@r-owen r-owen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I had a few minor suggestions. I'm sorry that a C++ test was deemed necessary and that apparently the Python will not reliably return a 2-dimensional array.

@@ -118,6 +120,25 @@ Transform<ToEndpoint, FromEndpoint> Transform<FromEndpoint, ToEndpoint>::getInve
}

template <typename FromEndpoint, typename ToEndpoint>
Eigen::MatrixXd Transform<FromEndpoint, ToEndpoint>::getJacobian(FromPoint const &x) const {
try {
size_t const nIn = _fromEndpoint.getNAxes();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should you add an explicit cast to avoid compiler warnings, since getNAxes returns an int?

}
return jacobian;
} catch (std::bad_alloc const &e) {
std::throw_with_nested(pex::exceptions::MemoryError("Could not allocate Jacobian."));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this desirable? If the program cannot allocate a matrix as small as this then the program is in deep trouble, and the fact that the first hint was here is not likely to be of very much interest.

Also is this a reasonable way to construct a pex_exception exception? We typically use a macro so line #s and such are recorded and that information will be missing, which worries me. (I realize one can construct the exception this way; my question is whether we ought to be doing so.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is mainly for API consistency. We have a dedicated MemoryError exception, so presumably we should emit it in preference to std::bad_alloc. Although perhaps now that pybind11 gives us better exception wrapping than Swig did, we should push for deprecation of MemoryError as part of DM-9435.

As for constructing the exception, it looks like LSST_EXCEPT evaluates to an exception object rather than a throw statement, so I can do that.

assert coeffs.ndim == 2
assert coeffs.shape == (nOut, nIn)
# Avoid spurious errors when comparing to a simplified array
return coeffs.squeeze()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it will be less confusing having makeJacobian return the expected 2-dimensional array. The fact that the pybind11 wrapper may return something else for the Jacobian is a misfeature (one I hope we can eventually figure out a workaround for) that we need not emulate here. Instead consider putting the squeeze where the two matrices are compared.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad to hear it. The impression I got from @TallJimbo on #dm-pybind11 was that numpy changing the dimensions was to be considered a feature rather than a bug.

Copy link
Member

@TallJimbo TallJimbo Mar 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

numpy generally (or at least occasionally) considers that a feature; I'm not sure I do, but I didn't want to try to fight numpy's conventions.

Copy link
Contributor

@r-owen r-owen Mar 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TallJimbo I filed https://jira.lsstcorp.org/browse/DM-10011 in hopes you might change your mind about fighting this. It is very undesirable behavior in this case and it's a pain to have to add a python wrapper to work around it (especially since it is a templated class with many instantiations).

@@ -609,12 +636,45 @@ def checkInverseFrameSet(self, clsTransform, frameIn, frameOut):
self.assertEqual(reverseFrames.getFrame(4).getIdent(), "currFrame",
msg=baseMsg)

def checkGetJacobian(self, fromName, toName):
"""Test Transform<fromName>To<toName>.getInverse
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy/paste error?

@kfindeisen kfindeisen force-pushed the tickets/DM-9598 branch 2 times, most recently from 588dc43 to d0630d5 Compare March 29, 2017 22:40
@kfindeisen kfindeisen merged commit 303d572 into master Mar 29, 2017
@kfindeisen kfindeisen deleted the tickets/DM-9598 branch August 22, 2018 19:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants