Author: desruisseaux
Date: Tue Oct 1 20:24:49 2013
New Revision: 1528208
URL: http://svn.apache.org/r1528208
Log:
Prepare for double-double matrix arithmetic: GeneralMatrix can now allocate
space for the DoubleDouble.error terms (not yet used in this commit).
Modified:
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrix.java
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/SolverTest.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
Modified:
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java?rev=1528208&r1=1528207&r2=1528208&view=diff
==============================================================================
---
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
[UTF-8] (original)
+++
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
[UTF-8] Tue Oct 1 20:24:49 2013
@@ -21,11 +21,18 @@ import org.opengis.referencing.operation
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.ArraysExt;
import org.apache.sis.math.MathFunctions;
+import org.apache.sis.internal.util.DoubleDouble;
/**
* A two dimensional array of numbers. Row and column numbering begins with
zero.
*
+ * {@section Support for extended precision}
+ * This class can optionally support extended precision using the
<cite>double-double arithmetic</cite>.
+ * In extended precision mode, the {@link #elements} array have twice its
normal length. The first half
+ * of the array contains the same value than in normal precision mode, while
the second half contains
+ * the {@link DoubleDouble#error}.
+ *
* @author Martin Desruisseaux (IRD, Geomatys)
* @since 0.4 (derived from geotk-2.2)
* @version 0.4
@@ -42,6 +49,10 @@ class GeneralMatrix extends MatrixSIS {
/**
* All matrix elements in a flat, row-major (column indices vary fastest)
array.
* The array length is <code>{@linkplain #numRow} * {@linkplain
#numCol}</code>.
+ *
+ * <p>In <cite>extended precision mode</cite>, the length of this array is
actually twice the above-cited length.
+ * The first half contains {@link DoubleDouble#value}, and the second half
contains the {@link DoubleDouble#error}
+ * for each value in the first half.</p>
*/
final double[] elements;
@@ -60,12 +71,14 @@ class GeneralMatrix extends MatrixSIS {
* @param numCol Number of columns.
* @param setToIdentity {@code true} for initializing the matrix to the
identity matrix,
* or {@code false} for leaving it initialized to zero.
+ * @param precision 1 for normal precision, or 2 for extended precision.
+ * No other value is allowed (this is not verified).
*/
- GeneralMatrix(final int numRow, final int numCol, final boolean
setToIdentity) {
+ GeneralMatrix(final int numRow, final int numCol, final boolean
setToIdentity, final int precision) {
ensureValidSize(numRow, numCol);
this.numRow = (short) numRow;
this.numCol = (short) numCol;
- elements = new double[numRow * numCol];
+ elements = new double[numRow * numCol * precision];
if (setToIdentity) {
final int stop = Math.min(numRow, numCol) * numCol;
for (int i=0; i<stop; i += numCol+1) {
@@ -82,27 +95,32 @@ class GeneralMatrix extends MatrixSIS {
* @param numRow Number of rows.
* @param numCol Number of columns.
* @param elements Initial values.
+ * @param precision 1 for normal precision, or 2 for extended precision.
+ * No other value is allowed (this is not verified).
*/
- GeneralMatrix(final int numRow, final int numCol, final double[] elements)
{
+ GeneralMatrix(final int numRow, final int numCol, final double[] elements,
final int precision) {
ensureValidSize(numRow, numCol);
- ensureLengthMatch(numRow*numCol, elements);
+ final int length = numRow * numCol;
+ ensureLengthMatch(length, elements);
this.numRow = (short) numRow;
this.numCol = (short) numCol;
- this.elements = elements.clone();
+ this.elements = Arrays.copyOf(elements, length * precision);
}
/**
* Constructs a new matrix and copies the initial values from the given
matrix.
*
* @param matrix The matrix to copy.
+ * @param precision 1 for normal precision, or 2 for extended precision.
+ * No other value is allowed (this is not verified).
*/
- GeneralMatrix(final Matrix matrix) {
+ GeneralMatrix(final Matrix matrix, final int precision) {
final int numRow = matrix.getNumRow();
final int numCol = matrix.getNumCol();
ensureValidSize(numRow, numCol);
this.numRow = (short) numRow;
this.numCol = (short) numCol;
- elements = new double[numRow * numCol];
+ elements = new double[numRow * numCol * precision];
for (int k=0,j=0; j<numRow; j++) {
for (int i=0; i<numCol; i++) {
elements[k++] = matrix.getElement(j, i);
@@ -180,7 +198,7 @@ class GeneralMatrix extends MatrixSIS {
*/
@Override
public final double[] getElements() {
- return elements.clone();
+ return Arrays.copyOf(elements, numRow*numCol);
}
/**
@@ -188,19 +206,22 @@ class GeneralMatrix extends MatrixSIS {
*/
@Override
public final void setElements(final double[] elements) {
- ensureLengthMatch(this.elements.length, elements);
+ ensureLengthMatch(numRow*numCol, elements);
System.arraycopy(elements, 0, this.elements, 0, elements.length);
}
/**
* {@inheritDoc}
+ *
+ * <p>If this matrix has extended precision, then the {@link
DoubleDouble#error} values are ignored.
+ * Only the values representable as a {@code double} are verified.</p>
*/
@Override
public final boolean isAffine() {
final int numRow = this.numRow; // Protection against accidental
changes.
final int numCol = this.numCol;
if (numRow == numCol) {
- int i = elements.length;
+ int i = numRow * numCol;
if (elements[--i] == 1) {
final int base = (numRow - 1) * numCol;
while (--i >= base) {
@@ -216,6 +237,9 @@ class GeneralMatrix extends MatrixSIS {
/**
* {@inheritDoc}
+ *
+ * <p>If this matrix has extended precision, then the {@link
DoubleDouble#error} values are ignored.
+ * Only the values representable as a {@code double} are verified.</p>
*/
@Override
public final boolean isIdentity() {
@@ -225,7 +249,8 @@ class GeneralMatrix extends MatrixSIS {
return false;
}
int di = 0; // Index of next diagonal element.
- for (int i=0; i<elements.length; i++) {
+ final int length = numRow * numCol;
+ for (int i=0; i<length; i++) {
final double element = elements[i];
if (i == di) {
if (element != 1) return false;
@@ -247,9 +272,16 @@ class GeneralMatrix extends MatrixSIS {
public void transpose() {
final int numRow = this.numRow; // Protection against accidental
changes.
final int numCol = this.numCol;
+ final int errors = (numRow * numCol) % elements.length;
for (int j=0; j<numRow; j++) {
for (int i=0; i<j; i++) {
- ArraysExt.swap(elements, j*numCol + i, i*numCol + j);
+ final int lo = j*numCol + i;
+ final int up = i*numCol + j;
+ ArraysExt.swap(elements, lo, up);
+ if (errors != 0) {
+ // Swap also the error terms in extended precision mode.
+ ArraysExt.swap(elements, lo + errors, up + errors);
+ }
}
}
}
Modified:
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java?rev=1528208&r1=1528207&r2=1528208&view=diff
==============================================================================
---
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
[UTF-8] (original)
+++
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
[UTF-8] Tue Oct 1 20:24:49 2013
@@ -97,7 +97,7 @@ public final class Matrices extends Stat
case 2: return new Matrix2();
case 3: return new Matrix3();
case 4: return new Matrix4();
- default: return new GeneralMatrix(size, size, true);
+ default: return new GeneralMatrix(size, size, true, 1);
}
}
@@ -121,7 +121,7 @@ public final class Matrices extends Stat
if (numRow == numCol) {
return createIdentity(numRow);
} else {
- return new NonSquareMatrix(numRow, numCol, true);
+ return new NonSquareMatrix(numRow, numCol, true, 1);
}
}
@@ -146,9 +146,9 @@ public final class Matrices extends Stat
case 2: return new Matrix2(false);
case 3: return new Matrix3(false);
case 4: return new Matrix4(false);
- default: return new GeneralMatrix(numRow, numCol, false);
+ default: return new GeneralMatrix(numRow, numCol, false, 1);
}
- return new NonSquareMatrix(numRow, numCol, false);
+ return new NonSquareMatrix(numRow, numCol, false, 1);
}
/**
@@ -175,9 +175,9 @@ public final class Matrices extends Stat
case 2: return new Matrix2(elements);
case 3: return new Matrix3(elements);
case 4: return new Matrix4(elements);
- default: return new GeneralMatrix(numRow, numCol, elements);
+ default: return new GeneralMatrix(numRow, numCol, elements, 1);
}
- return new NonSquareMatrix(numRow, numCol, elements);
+ return new NonSquareMatrix(numRow, numCol, elements, 1);
}
/**
@@ -658,7 +658,7 @@ public final class Matrices extends Stat
case 4: return new Matrix4(matrix);
}
}
- return new GeneralMatrix(matrix);
+ return new GeneralMatrix(matrix, 1);
}
/**
Modified:
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java?rev=1528208&r1=1528207&r2=1528208&view=diff
==============================================================================
---
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java
[UTF-8] (original)
+++
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java
[UTF-8] Tue Oct 1 20:24:49 2013
@@ -259,7 +259,7 @@ public final class Matrix1 extends Matri
throw new NoninvertibleMatrixException();
}
if (nc != SIZE) {
- final NonSquareMatrix m = new NonSquareMatrix(SIZE, nc, false);
+ final NonSquareMatrix m = new NonSquareMatrix(SIZE, nc, false, 1);
for (int i=0; i<nc; i++) {
m.elements[i] = matrix.getElement(0, i) / m00;
}
@@ -276,7 +276,7 @@ public final class Matrix1 extends Matri
final int nc = matrix.getNumCol();
ensureNumRowMatch(SIZE, matrix, nc);
if (nc != SIZE) {
- return new NonSquareMatrix(this, matrix);
+ return new NonSquareMatrix(this, matrix, 1);
}
return new Matrix1(m00 * matrix.getElement(0,0));
}
Modified:
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java?rev=1528208&r1=1528207&r2=1528208&view=diff
==============================================================================
---
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java
[UTF-8] (original)
+++
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java
[UTF-8] Tue Oct 1 20:24:49 2013
@@ -293,7 +293,7 @@ public final class Matrix2 extends Matri
final int nc = matrix.getNumCol();
ensureNumRowMatch(SIZE, matrix, nc);
if (nc != SIZE) {
- return new NonSquareMatrix(this, matrix);
+ return new NonSquareMatrix(this, matrix, 1);
}
final Matrix2 k = (matrix instanceof Matrix2) ? (Matrix2) matrix : new
Matrix2(matrix);
return new Matrix2(m00 * k.m00 + m01 * k.m10,
Modified:
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java?rev=1528208&r1=1528207&r2=1528208&view=diff
==============================================================================
---
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java
[UTF-8] (original)
+++
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java
[UTF-8] Tue Oct 1 20:24:49 2013
@@ -330,7 +330,7 @@ public final class Matrix3 extends Matri
final int nc = matrix.getNumCol();
ensureNumRowMatch(SIZE, matrix, nc);
if (nc != SIZE) {
- return new NonSquareMatrix(this, matrix);
+ return new NonSquareMatrix(this, matrix, 1);
}
final Matrix3 k = (matrix instanceof Matrix3) ? (Matrix3) matrix : new
Matrix3(matrix);
return new Matrix3(m00 * k.m00 + m01 * k.m10 + m02 * k.m20,
Modified:
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java?rev=1528208&r1=1528207&r2=1528208&view=diff
==============================================================================
---
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java
[UTF-8] (original)
+++
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java
[UTF-8] Tue Oct 1 20:24:49 2013
@@ -381,7 +381,7 @@ public final class Matrix4 extends Matri
final int nc = matrix.getNumCol();
ensureNumRowMatch(SIZE, matrix, nc);
if (nc != SIZE) {
- return new NonSquareMatrix(this, matrix);
+ return new NonSquareMatrix(this, matrix, 1);
}
final Matrix4 k = (matrix instanceof Matrix4) ? (Matrix4) matrix : new
Matrix4(matrix);
return new Matrix4(m00 * k.m00 + m01 * k.m10 + m02 * k.m20 + m03
* k.m30,
Modified:
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrix.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrix.java?rev=1528208&r1=1528207&r2=1528208&view=diff
==============================================================================
---
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrix.java
[UTF-8] (original)
+++
sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrix.java
[UTF-8] Tue Oct 1 20:24:49 2013
@@ -44,9 +44,10 @@ final class NonSquareMatrix extends Gene
* @param numCol Number of columns.
* @param setToIdentity {@code true} for initializing the matrix to the
identity matrix,
* or {@code false} for leaving it initialized to zero.
+ * @param precision 1 for normal precision, or 2 for extended precision.
*/
- NonSquareMatrix(final int numRow, final int numCol, final boolean
setToIdentity) {
- super(numRow, numCol, setToIdentity);
+ NonSquareMatrix(final int numRow, final int numCol, final boolean
setToIdentity, final int precision) {
+ super(numRow, numCol, setToIdentity, precision);
}
/**
@@ -57,18 +58,20 @@ final class NonSquareMatrix extends Gene
* @param numRow Number of rows.
* @param numCol Number of columns.
* @param elements Initial values.
+ * @param precision 1 for normal precision, or 2 for extended precision.
*/
- NonSquareMatrix(final int numRow, final int numCol, final double[]
elements) {
- super(numRow, numCol, elements);
+ NonSquareMatrix(final int numRow, final int numCol, final double[]
elements, final int precision) {
+ super(numRow, numCol, elements, precision);
}
/**
* Constructs a new matrix and copies the initial values from the given
matrix.
*
* @param matrix The matrix to copy.
+ * @param precision 1 for normal precision, or 2 for extended precision.
*/
- NonSquareMatrix(final Matrix matrix) {
- super(matrix);
+ NonSquareMatrix(final Matrix matrix, final int precision) {
+ super(matrix, precision);
}
/**
@@ -82,8 +85,8 @@ final class NonSquareMatrix extends Gene
* Initializes this matrix to the product of the given matrices.
* This constructor shall be invoked only when the result is known to be a
non-square matrix.
*/
- NonSquareMatrix(final Matrix A, final Matrix B) {
- super(A.getNumRow(), B.getNumCol(), false);
+ NonSquareMatrix(final Matrix A, final Matrix B, final int precision) {
+ super(A.getNumRow(), B.getNumCol(), false, precision);
final int numRow = this.numRow; // Protection against accidental
changes.
final int numCol = this.numCol;
final int common = A.getNumCol();
@@ -107,11 +110,17 @@ final class NonSquareMatrix extends Gene
public void transpose() {
final short numRow = this.numRow; // Protection against accidental
changes before we are done.
final short numCol = this.numCol;
+ final int errors = (numRow * numCol) % elements.length;
final double[] copy = elements.clone();
int k = 0;
for (int j=0; j<numRow; j++) {
for (int i=0; i<numCol; i++) {
- elements[i*numRow + j] = copy[k++];
+ final int t = i*numRow + j;
+ elements[t] = copy[k];
+ if (errors != 0) {
+ elements[t + errors] = copy[k + errors];
+ }
+ k++;
}
}
this.numRow = numCol;
Modified:
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/SolverTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/SolverTest.java?rev=1528208&r1=1528207&r2=1528208&view=diff
==============================================================================
---
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/SolverTest.java
[UTF-8] (original)
+++
sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/SolverTest.java
[UTF-8] Tue Oct 1 20:24:49 2013
@@ -48,7 +48,7 @@ public final strictfp class SolverTest e
* Initializes the {@link #matrix} and {@link #reference} matrices to
random values.
*/
private void createMatrices(final int numRow, final int numCol, final
Random random) {
- matrix = new GeneralMatrix(numRow, numCol, false);
+ matrix = new GeneralMatrix(numRow, numCol, false, 1);
reference = new Matrix(numRow, numCol);
for (int j=0; j<numRow; j++) {
for (int i=0; i<numCol; i++) {
Modified:
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java?rev=1528208&r1=1528207&r2=1528208&view=diff
==============================================================================
---
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
[UTF-8] (original)
+++
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
[UTF-8] Tue Oct 1 20:24:49 2013
@@ -112,7 +112,7 @@ public final class DoubleDouble extends
0.002777777777777777777777777777777778, // 1/360°
0.01,
0.01666666666666666666666666666666667, // Minute to degrees
- 0.01745329251994329576923690768488613, // Degrees to radians
+ 0.01745329251994329576923690768488613, // Degrees to radians
0.1,
0.201168, // Link to metres
0.3048, // Feet to metres