-
Notifications
You must be signed in to change notification settings - Fork 8
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
Implement realMinMax() and minMax() methods to fix adapting interval performances #63
Conversation
…ethods but realMinMax there
@tpietzsch I implemented:
and changed all sub-classes that they only implement this method, while all the other work is done within |
* Let AbstractAdpatingInterval extends AbstractAdaptingRealInterval and implement the realMinMax method in terms of the (abstract) minMax method. * Override the various min/max variants in AbstractAdpatingInterval (Implementations still TODO) * Add a few TODO comments in RealTransformRealInterval
I added a commit where I let
I added stubs for all the
|
Also |
Thanks @tpietzsch for having a look! I am truly impressed that you spotted
you have to explain me at some point how you find such stuff! I can do all the requested changes, however not to screw anything up I would like to understand this part of the code:
Frankly, I don't see how anything that happens in the while loop would affect the loop's conditional. In other words, could this be rewritten without a while loop? Probably I am overlooking something?! |
I think the idea is that the So yes, I think it should be rewritten without the while loop. |
OK, I will rewrite it then. There are several things though that I don't get...
|
(at least, i would only change |
First of all, this isn't originally my code, and it's been a few years since I reviewed it... So I'm also guessing a bit.
Yes, let's assume that! (In principle, I think that you might want to be able to have a 3D source and apply a 2D transformation that leaves the 3rd dimension untouched. But that wouldn't work with the current code. And I think it would make things a lot more complicated for marginal benefit).
Neither
Yes, sounds good.
no return statement after what? Thanks for digging into it!!! 👍 |
source.realMax( cachedSourceMax ); | ||
source.realMin( cachedSourceMin ); | ||
min[ d ] = minCorner; | ||
max[ d ] = maxCorner; | ||
} | ||
} | ||
|
||
private double[][] createCorners() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tpietzsch
I don't understand the code here. If the code is good, shouldn't we put it as a static method somewhere? Something like RealInterval ... = TransformHelper.estimateBounds( RealTransform ..., RealInterval ... );
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't we put it as a static method somewhere
I'd like that, as well as an implementation that would work for non-linear transformations too
imglib/imglib2-realtransform#37
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I refactored this a bit, and it should be clearer now what happens.
This method computes the corners of the source interval (see javadoc for explanation how)
imglib2-roi/src/main/java/net/imglib2/roi/Bounds.java
Lines 873 to 892 in 46e8890
/** | |
* Compute the corners of a RealInterval given by {@code min} and {@code max}. | |
* <p> | |
* A n-dimensional interval has {@code 2^n} corners. | |
* <p> | |
* The index of a corner is interpreted as a binary number where bit 0 | |
* corresponds to X, bit 1 corresponds to Y, etc. A zero bit means min in the | |
* corresponding dimension, a one bit means max in the corresponding dimension. | |
*/ | |
private static double[][] corners( final double[] min, final double[] max ) | |
{ | |
assert min.length == max.length; | |
final int n = min.length; | |
final int numCorners = 1 << n; | |
final double[][] corners = new double[ numCorners ][ n ]; | |
for ( int index = 0; index < numCorners; index++ ) | |
for ( int d = 0, mask = numCorners >> 1; d < n; ++d, mask >>= 1 ) | |
corners[ index ][ d ] = ( index & mask ) == 0 ? min[ d ] : max[ d ]; | |
return corners; | |
} |
Then this method takes the corners and puts them through the transformation
imglib2-roi/src/main/java/net/imglib2/roi/Bounds.java
Lines 858 to 865 in 46e8890
private double[][] createCorners() | |
{ | |
final double[][] cornersTransformed = corners( cachedSourceMin, cachedSourceMax ); | |
final double[][] points = new double[ cornersTransformed.length ][ n ]; | |
for ( int i = 0; i < points.length; i++ ) | |
transformToSource.inverse().apply( cornersTransformed[ i ], points[ i ] ); | |
return points; | |
} |
Finally, this method puts computes the bounding box of the transformed corners
imglib2-roi/src/main/java/net/imglib2/roi/Bounds.java
Lines 841 to 855 in 46e8890
final double[][] transformedCorners = createCorners(); | |
final int numTransformedCorners = transformedCorners.length; | |
for ( int d = 0; d < n; d++ ) | |
{ | |
double maxCorner = transformedCorners[ 0 ][ d ]; | |
double minCorner = transformedCorners[ 0 ][ d ]; | |
for ( int i = 1; i < numTransformedCorners; i++ ) | |
{ | |
minCorner = Math.min( minCorner, transformedCorners[ i ][ d ] ); | |
maxCorner = Math.max( maxCorner, transformedCorners[ i ][ d ] ); | |
} | |
min[ d ] = minCorner; | |
max[ d ] = maxCorner; | |
} |
OK, I think I did everything: Tests are passing. I have one question, which I added as a comment to the last commit. |
Work along the outline provided here: #60