Skip to content

Commit

Permalink
chore!: use ejml DMatrixRMaj instead of Jama Matrix
Browse files Browse the repository at this point in the history
* test add AffineTransformTest

BREAKING CHANGE: remove Jama dependency, use ejml
  • Loading branch information
bogovicj committed Jun 12, 2024
1 parent a62d90a commit f6a97b1
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 32 deletions.
12 changes: 10 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ Jean-Yves Tinevez and Michael Zinsmaier.</license.copyrightOwners>
<releaseProfiles>sign,deploy-to-scijava</releaseProfiles>

<imglib2.version>7.0.1</imglib2.version>
<ejml-core.version>0.41</ejml-core.version>
<ejml-ddense.version>0.41</ejml-ddense.version>
</properties>

<dependencies>
Expand All @@ -178,9 +180,15 @@ Jean-Yves Tinevez and Michael Zinsmaier.</license.copyrightOwners>
</dependency>

<!-- Third-party dependencies -->
<dependency>
<groupId>org.ejml</groupId>
<artifactId>ejml-core</artifactId>
<version>${ejml-core.version}</version>
</dependency>
<dependency>
<groupId>gov.nist.math</groupId>
<artifactId>jama</artifactId>
<groupId>org.ejml</groupId>
<artifactId>ejml-ddense</artifactId>
<version>${ejml-ddense.version}</version>
</dependency>

<!-- Test dependencies -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Expand All @@ -34,33 +34,33 @@

package net.imglib2.realtransform;

import org.ejml.data.DMatrixRMaj;

import net.imglib2.RealLocalizable;
import net.imglib2.RealPoint;
import net.imglib2.RealPositionable;
import Jama.Matrix;

/**
* An abstract implementation of an affine transformation that returns default
* values referring to the identity transformation for all fields. This
* implementation is not thread safe. Create a {@link #copy()} for each
* consumer.
*
*
* @author Stephan Saalfeld
*/
public abstract class AbstractAffineTransform implements AffineGet, AffineSet
{
final protected int n;

final protected Matrix a;
final protected DMatrixRMaj a;

final protected double[] t, tmp;

final protected RealPoint[] ds;

protected AbstractAffineTransform( final Matrix a, final double[] t )
protected AbstractAffineTransform( final DMatrixRMaj a, final double[] t )
{
assert a.getRowDimension() == t.length &&
a.getColumnDimension() == t.length: "The passed arrays must be n*n and the t-vector n.";
assert a.getNumRows() == t.length && a.getNumCols() == t.length: "The passed arrays must be n*n and the t-vector n.";

this.n = t.length;
this.a = a;
Expand All @@ -73,17 +73,17 @@ protected AbstractAffineTransform( final Matrix a, final double[] t )
updateDs();
}

public AbstractAffineTransform( final Matrix matrix )
public AbstractAffineTransform( final DMatrixRMaj matrix )
{
assert matrix.getRowDimension() == matrix.getColumnDimension() - 1: "The passed affine matrix must be of the format (n-1)*n.";
assert matrix.getNumRows() == matrix.getNumCols() - 1: "The passed affine matrix must be of the format (n-1)*n.";

n = matrix.getRowDimension();
a = new Matrix( n, n );
n = matrix.getNumRows();
a = new DMatrixRMaj( n, n );
t = new double[ n ];
tmp = new double[ n ];
ds = new RealPoint[ n ];

a.setMatrix( 0, n - 1, 0, n - 1, matrix );
a.setTo( matrix );
for ( int r = 0; r < n; ++r )
{
t[ r ] = matrix.get( r, n );
Expand All @@ -95,7 +95,7 @@ public AbstractAffineTransform( final Matrix matrix )
public AbstractAffineTransform( final int n )
{
this.n = n;
a = new Matrix( n, n );
a = new DMatrixRMaj( n, n );
t = new double[ n ];
tmp = new double[ n ];
ds = new RealPoint[ n ];
Expand Down Expand Up @@ -136,7 +136,7 @@ public int numTargetDimensions()
{
return n;
}

@Override
public void apply( final double[] source, final double[] target )
{
Expand All @@ -148,11 +148,11 @@ public void apply( final double[] source, final double[] target )
for ( int c = 0; c < n; ++c )
tmp[ r ] += source[ c ] * a.get( r, c );
}

for ( int r = 0; r < n; ++r )
target[ r ] = tmp[ r ] + t[ r ];
}

@Override
public void apply( final float[] source, final float[] target )
{
Expand All @@ -164,7 +164,7 @@ public void apply( final float[] source, final float[] target )
for ( int c = 0; c < n; ++c )
tmp[ r ] += source[ c ] * a.get( r, c );
}

for ( int r = 0; r < n; ++r )
target[ r ] = ( float )( tmp[ r ] + t[ r ] );
}
Expand All @@ -180,7 +180,7 @@ public void apply( final RealLocalizable source, final RealPositionable target )
for ( int c = 0; c < n; ++c )
tmp[ r ] += source.getDoublePosition( c ) * a.get( r, c );
}

for ( int r = 0; r < n; ++r )
target.setPosition( tmp[ r ] + t[ r ], r );
}
Expand Down
23 changes: 12 additions & 11 deletions src/main/java/net/imglib2/realtransform/AffineTransform.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Expand All @@ -34,7 +34,9 @@

package net.imglib2.realtransform;

import Jama.Matrix;
import org.ejml.data.DMatrixRMaj;
import org.ejml.dense.row.CommonOps_DDRM;

import net.imglib2.RealLocalizable;
import net.imglib2.RealPositionable;
import net.imglib2.concatenate.Concatenable;
Expand All @@ -57,7 +59,7 @@ public AffineTransform( final int n )
inverse.updateDs();
}

protected AffineTransform( final Matrix a, final double[] t )
protected AffineTransform( final DMatrixRMaj a, final double[] t )
{
super( a, t );

Expand All @@ -66,7 +68,7 @@ protected AffineTransform( final Matrix a, final double[] t )
inverse.updateDs();
}

public AffineTransform( final Matrix matrix )
public AffineTransform( final DMatrixRMaj matrix )
{
super( matrix );

Expand Down Expand Up @@ -101,8 +103,7 @@ protected void invertT()

protected void invert()
{
final Matrix ii = a.inverse();
inverse.a.setMatrix( 0, n - 1, 0, n - 1, ii );
CommonOps_DDRM.invert( a, inverse.a );
invertT();
}

Expand Down Expand Up @@ -175,7 +176,7 @@ public AffineTransform concatenate( final AffineGet affine )
{
assert affine.numSourceDimensions() == n: "Dimensions do not match.";

final Matrix matrix = new Matrix( n, n );
final DMatrixRMaj matrix = new DMatrixRMaj(n, n);
final double[] translation = new double[ n ];
for ( int r = 0; r < n; ++r )
{
Expand All @@ -191,7 +192,7 @@ public AffineTransform concatenate( final AffineGet affine )
tr += get( r, k ) * affine.get( k, n );
translation[ r ] = tr;
}
a.setMatrix( 0, n - 1, 0, n - 1, matrix );
a.setTo( matrix );
System.arraycopy( translation, 0, t, 0, t.length );

updateDs();
Expand All @@ -212,7 +213,7 @@ public AffineTransform preConcatenate( final AffineGet affine )
{
assert affine.numSourceDimensions() == n: "Dimensions do not match.";

final Matrix matrix = new Matrix( n, n );
final DMatrixRMaj matrix = new DMatrixRMaj(n, n);
final double[] translation = new double[ n ];
for ( int r = 0; r < n; ++r )
{
Expand All @@ -228,7 +229,7 @@ public AffineTransform preConcatenate( final AffineGet affine )
tr += affine.get( r, k ) * get( k, n );
translation[ r ] = tr;
}
a.setMatrix( 0, n - 1, 0, n - 1, matrix );
a.setTo( matrix );
System.arraycopy( translation, 0, t, 0, t.length );

updateDs();
Expand Down
83 changes: 83 additions & 0 deletions src/test/java/net/imglib2/realtransform/AffineTransformTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* #%L
* ImgLib2: a general-purpose, multidimensional image processing library.
* %%
* Copyright (C) 2009 - 2024 Tobias Pietzsch, Stephan Preibisch, Stephan Saalfeld,
* John Bogovic, Albert Cardona, Barry DeZonia, Christian Dietz, Jan Funke,
* Aivar Grislis, Jonathan Hale, Grant Harris, Stefan Helfrich, Mark Hiner,
* Martin Horn, Steffen Jaensch, Lee Kamentsky, Larry Lindsey, Melissa Linkert,
* Mark Longair, Brian Northan, Nick Perry, Curtis Rueden, Johannes Schindelin,
* Jean-Yves Tinevez and Michael Zinsmaier.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* #L%
*/
package net.imglib2.realtransform;

import static org.junit.Assert.assertArrayEquals;

import java.util.Random;

import org.junit.Before;
import org.junit.Test;

public class AffineTransformTest {

protected static final double EPS = 1e-9;
protected static final double[] FLAT_IDENTITY_2D = new double[]{1, 0, 0, 0, 1, 0};
protected static final double[] FLAT_IDENTITY_3D = new double[]{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0};

protected Random rnd = new Random( 0 );

/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception
{
rnd.setSeed( 0 );
}

@Test
public void testInverse()
{
// 2D
final AffineTransform affine2 = new AffineTransform(2);
affine2.set(
2 + rnd.nextDouble(), rnd.nextDouble(), rnd.nextDouble(),
rnd.nextDouble(), 3 + rnd.nextDouble(), rnd.nextDouble());

final AffineTransform id2 = affine2.preConcatenate(affine2.inverse());
assertArrayEquals(FLAT_IDENTITY_2D, id2.getRowPackedCopy(), EPS);

// 3D
final AffineTransform affine3 = new AffineTransform(3);
affine3.set(
2 + rnd.nextDouble(), rnd.nextDouble(), rnd.nextDouble(), rnd.nextDouble(),
rnd.nextDouble(), 3 + rnd.nextDouble(), rnd.nextDouble(), rnd.nextDouble(),
rnd.nextDouble(), rnd.nextDouble(), 4 + rnd.nextDouble(), rnd.nextDouble());

final AffineTransform id3 = affine3.preConcatenate(affine3.inverse());
assertArrayEquals(FLAT_IDENTITY_3D, id3.getRowPackedCopy(), EPS);
}

}

0 comments on commit f6a97b1

Please sign in to comment.