You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2013/10/04 21:08:19 UTC
svn commit: r1529262 [1/3] - in /sis/trunk: ./
application/sis-console/src/main/java/org/apache/sis/console/
core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/gml/
core/sis-metadata/src/test/java/org/apache/sis/xml/
core/sis-referencing/src/...
Author: desruisseaux
Date: Fri Oct 4 19:08:18 2013
New Revision: 1529262
URL: http://svn.apache.org/r1529262
Log:
Merge from the JDK6 branch.
Added:
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
- copied unchanged from r1529261, sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
sis/trunk/core/sis-utility/src/test/java/org/apache/sis/internal/util/CheckedArrayListTest.java
- copied unchanged from r1529261, sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/internal/util/CheckedArrayListTest.java
sis/trunk/core/sis-utility/src/test/java/org/apache/sis/internal/util/DoubleDoubleTest.java
- copied unchanged from r1529261, sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/internal/util/DoubleDoubleTest.java
Modified:
sis/trunk/ (props changed)
sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/gml/SC_VerticalCRS.java
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/gml/TM_Primitive.java
sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/xml/MetadataMarshallingTest.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrix.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Solver.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/package-info.java
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix1Test.java
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix2Test.java
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix3Test.java
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/Matrix4Test.java
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrixTest.java
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/SolverTest.java
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/Context.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/GO_CharacterString.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/Measure.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/gco/ObjectReference.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/Supervisor.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/CheckedArrayList.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/CheckedHashSet.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/UnmodifiableArrayList.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/math/MathFunctions.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties
sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java
sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
sis/trunk/core/sis-utility/src/test/java/org/apache/sis/util/ArraysExtTest.java
Propchange: sis/trunk/
------------------------------------------------------------------------------
Merged /sis/branches/JDK7:r1524815-1529257
Merged /sis/branches/JDK6:r1524817-1529261
Modified: sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java
URL: http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java?rev=1529262&r1=1529261&r2=1529262&view=diff
==============================================================================
--- sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java [UTF-8] (original)
+++ sis/trunk/application/sis-console/src/main/java/org/apache/sis/console/MetadataSC.java [UTF-8] Fri Oct 4 19:08:18 2013
@@ -17,6 +17,7 @@
package org.apache.sis.console;
import java.util.EnumSet;
+import java.io.Console;
import java.io.IOException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.JAXBException;
@@ -93,7 +94,14 @@ final class MetadataSC extends SubComman
final Marshaller marshaller = pool.acquireMarshaller();
marshaller.setProperty(XML.LOCALE, locale);
marshaller.setProperty(XML.TIMEZONE, timezone);
- marshaller.marshal(metadata, out);
+ if (isConsole()) {
+ marshaller.marshal(metadata, out);
+ } else {
+ out.flush();
+ marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding.name());
+ marshaller.marshal(metadata, System.out); // Use OutputStream instead than Writer.
+ System.out.flush();
+ }
} else {
final TreeTable tree = MetadataStandard.ISO_19115.asTreeTable(metadata, ValueExistencePolicy.NON_EMPTY);
final TreeTableFormat tf = new TreeTableFormat(locale, timezone);
@@ -104,4 +112,16 @@ final class MetadataSC extends SubComman
}
return 0;
}
+
+ /**
+ * Returns {@code true} if {@link #out} is sending its output to the console.
+ * If not, then we are probably writing to a file or the user specified his own encoding.
+ * In such case, we will send the XML output to an {@code OutputStream} instead than to a
+ * {@code Writer} and let the marshaller apply the encoding itself.
+ */
+ private boolean isConsole() {
+ if (outputBuffer != null) return true; // Special case for JUnit tests only.
+ final Console console = System.console();
+ return (console != null) && console.writer() == out;
+ }
}
Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/gml/SC_VerticalCRS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/gml/SC_VerticalCRS.java?rev=1529262&r1=1529261&r2=1529262&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/gml/SC_VerticalCRS.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/gml/SC_VerticalCRS.java [UTF-8] Fri Oct 4 19:08:18 2013
@@ -16,8 +16,6 @@
*/
package org.apache.sis.internal.jaxb.gml;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
import javax.xml.bind.annotation.XmlAnyElement;
import org.opengis.referencing.crs.VerticalCRS;
import org.apache.sis.internal.jaxb.gco.PropertyType;
@@ -116,12 +114,8 @@ public class SC_VerticalCRS extends Prop
*/
@XmlAnyElement(lax = true)
public Object getElement() {
- final LogRecord record = Errors.getResources(null).getLogRecord(Level.WARNING,
- Errors.Keys.MissingRequiredModule_1, "sis-referencing");
- record.setSourceClassName(SC_VerticalCRS.class.getName());
- record.setSourceMethodName("getElement");
- final Context context = Context.current();
- Context.warningOccured(context, metadata, record);
+ Context.warningOccured(Context.current(), metadata, SC_VerticalCRS.class, "getElement",
+ Errors.class, Errors.Keys.MissingRequiredModule_1, "sis-referencing");
return null;
}
Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/gml/TM_Primitive.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/gml/TM_Primitive.java?rev=1529262&r1=1529261&r2=1529262&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/gml/TM_Primitive.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/gml/TM_Primitive.java [UTF-8] Fri Oct 4 19:08:18 2013
@@ -17,8 +17,6 @@
package org.apache.sis.internal.jaxb.gml;
import java.util.Date;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
import javax.xml.bind.annotation.XmlElement;
import org.apache.sis.internal.geoapi.temporal.Period;
import org.apache.sis.internal.geoapi.temporal.Instant;
@@ -128,12 +126,8 @@ public final class TM_Primitive extends
* TemporalPrimitive as the source class, since it is the closest we can get
* to a public API.
*/
- final Context context = Context.current();
- final LogRecord record = Errors.getResources(context != null ? context.getLocale() : null)
- .getLogRecord(Level.WARNING, Errors.Keys.IllegalRange_2, begin, end);
- record.setSourceClassName(TemporalPrimitive.class.getName());
- record.setSourceMethodName("setTimePeriod");
- Context.warningOccured(context, this, record);
+ Context.warningOccured(Context.current(), this, TemporalPrimitive.class, "setTimePeriod",
+ Errors.class, Errors.Keys.IllegalRange_2, begin, end);
} else try {
metadata = TemporalUtilities.createPeriod(begin, end);
period.copyIdTo(metadata);
Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/xml/MetadataMarshallingTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/xml/MetadataMarshallingTest.java?rev=1529262&r1=1529261&r2=1529262&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/xml/MetadataMarshallingTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/xml/MetadataMarshallingTest.java [UTF-8] Fri Oct 4 19:08:18 2013
@@ -26,6 +26,7 @@ import javax.xml.bind.Unmarshaller;
import javax.xml.bind.JAXBException;
import org.opengis.util.InternationalString;
import org.apache.sis.util.iso.SimpleInternationalString;
+import org.apache.sis.metadata.iso.DefaultMetadata;
import org.apache.sis.metadata.iso.extent.DefaultExtent;
import org.apache.sis.metadata.iso.extent.DefaultTemporalExtent;
import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
@@ -100,6 +101,26 @@ public final strictfp class MetadataMars
}
/**
+ * Tests a collection that contains no element.
+ * This was used to cause a {@code NullPointerException} prior SIS-139 fix.
+ *
+ * @throws JAXBException If an error occurred during the during unmarshalling processes.
+ *
+ * @since 0.4
+ *
+ * @see <a href="https://issues.apache.org/jira/browse/SIS-139">SIS-139</a>
+ */
+ @Test
+ public void testEmptyCollection() throws JAXBException {
+ final String xml =
+ "<gmd:MD_Metadata xmlns:gmd=\"" + Namespaces.GMD + "\">\n" +
+ " <gmd:contact/>\n" +
+ "</gmd:MD_Metadata>";
+ final DefaultMetadata metadata = (DefaultMetadata) XML.unmarshal(xml);
+ assertTrue(metadata.getContacts().isEmpty());
+ }
+
+ /**
* Tests the (un)marshalling of a text group with a default {@code <gco:CharacterString>} element.
* This test is somewhat a duplicate of {@link FreeTextMarshallingTest}, but the context is more
* elaborated.
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java?rev=1529262&r1=1529261&r2=1529262&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java [UTF-8] Fri Oct 4 19:08:18 2013
@@ -19,8 +19,6 @@ package org.apache.sis.referencing.datum
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
import javax.measure.quantity.Length;
@@ -570,11 +568,9 @@ public class DefaultEllipsoid extends Ab
* Emits a warning telling that the given element is repeated twice.
*/
private void warnDuplicated(final String element) {
- final LogRecord record = Errors.getResources(null)
- .getLogRecord(Level.WARNING, Errors.Keys.DuplicatedElement_1, element);
- record.setSourceClassName(DefaultEllipsoid.class.getName());
- record.setSourceMethodName("unmarshal"); // We cheat a bit since there is not such method...
- Context.warningOccured(Context.current(), this, record);
+ // We cheat a bit for the "unmarshal" method name since there is not such method...
+ Context.warningOccured(Context.current(), this, DefaultEllipsoid.class, "unmarshal",
+ Errors.class, Errors.Keys.DuplicatedElement_1, element);
}
/**
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java?rev=1529262&r1=1529261&r2=1529262&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java [UTF-8] Fri Oct 4 19:08:18 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) {
@@ -85,7 +98,7 @@ class GeneralMatrix extends MatrixSIS {
*/
GeneralMatrix(final int numRow, final int numCol, final double[] elements) {
ensureValidSize(numRow, numCol);
- ensureLengthMatch(numRow*numCol, elements);
+ ensureLengthMatch(numRow * numCol, elements);
this.numRow = (short) numRow;
this.numCol = (short) numCol;
this.elements = elements.clone();
@@ -103,11 +116,7 @@ class GeneralMatrix extends MatrixSIS {
this.numRow = (short) numRow;
this.numCol = (short) numCol;
elements = new double[numRow * numCol];
- for (int k=0,j=0; j<numRow; j++) {
- for (int i=0; i<numCol; i++) {
- elements[k++] = matrix.getElement(j, i);
- }
- }
+ getElements(matrix, numRow, numCol, elements);
}
/**
@@ -120,6 +129,64 @@ class GeneralMatrix extends MatrixSIS {
}
/**
+ * Creates a new extended precision matrix of the given size.
+ *
+ * @param numRow Number of rows.
+ * @param numCol Number of columns.
+ */
+ static GeneralMatrix createExtendedPrecision(final int numRow, final int numCol) {
+ if (numRow == numCol) {
+ return new GeneralMatrix(numRow, numCol, false, 2);
+ } else {
+ return new NonSquareMatrix(numRow, numCol, false, 2);
+ }
+ }
+
+ /**
+ * Copies the elements of the given matrix in the given array.
+ * This method ignores the error terms, if any.
+ *
+ * @param matrix The matrix to copy.
+ * @param numRow The number of rows to copy (usually {@code matrix.getNumRow()}).
+ * @param numCol The number of columns to copy (usually {@code matrix.getNumCol()}).
+ * @param elements Where to copy the elements.
+ */
+ private static void getElements(final Matrix matrix, final int numRow, final int numCol, final double[] elements) {
+ if (matrix instanceof MatrixSIS) {
+ ((MatrixSIS) matrix).getElements(elements);
+ } else {
+ for (int k=0,j=0; j<numRow; j++) {
+ for (int i=0; i<numCol; i++) {
+ elements[k++] = matrix.getElement(j, i);
+ }
+ }
+ }
+ }
+
+ /**
+ * Infers all {@link DoubleDouble#error} with a default values inferred from {@link DoubleDouble#value}.
+ * For example if a matrix element is exactly 3.141592653589793, there is good chances that the user's
+ * intend was to specify the {@link Math#PI} value, in which case this method will infer that we would
+ * need to add 1.2246467991473532E-16 in order to get a value closer to π.
+ */
+ private static void inferErrors(final double[] elements) {
+ final int length = elements.length / 2;
+ for (int i=length; i<elements.length; i++) {
+ elements[i] = DoubleDouble.errorForWellKnownValue(elements[i - length]);
+ }
+ }
+
+ /**
+ * Returns the index of the first {@link DoubleDouble#error} value in the {@link #elements} array,
+ * or 0 if none. This method returns a non-zero value only if the matrix has been created in extended
+ * precision mode.
+ */
+ static int indexOfErrors(final int numRow, final int numCol, final double[] elements) {
+ assert elements.length % (numRow * numCol) == 0;
+ return (numRow * numCol) % elements.length; // A % B is for getting 0 without branching if A == B.
+ }
+
+ /**
* Ensures that the given matrix size is valid for this {@code GeneralMatrix} implementation.
*/
private static void ensureValidSize(final int numRow, final int numCol) {
@@ -169,38 +236,91 @@ class GeneralMatrix extends MatrixSIS {
@Override
public final void setElement(final int row, final int column, final double value) {
if (row >= 0 && row < numRow && column >= 0 && column < numCol) {
- elements[row * numCol + column] = value;
+ int i = row * numCol + column;
+ elements[i] = value;
+ i += numRow * numCol;
+ if (i < elements.length) {
+ elements[i] = DoubleDouble.errorForWellKnownValue(value);
+ }
} else {
throw indexOutOfBounds(row, column);
}
}
/**
+ * Returns all elements of the given matrix followed by the error terms for extended-precision arithmetic.
+ * The array will have twice the normal length. See {@link #elements} for more discussion.
+ *
+ * <p>This method may return a direct reference to the internal array. <strong>Do not modify.</strong>,
+ * unless the {@code copy} argument is {@code true}.</p>
+ *
+ * @param copy If {@code true}, then the returned array is guaranteed to be a copy, never the internal array.
+ */
+ static double[] getExtendedElements(final Matrix matrix, final int numRow, final int numCol, final boolean copy) {
+ double[] elements;
+ final int length = numRow * numCol * 2;
+ if (matrix instanceof GeneralMatrix) {
+ elements = ((GeneralMatrix) matrix).elements;
+ if (elements.length == length) {
+ if (copy) {
+ elements = elements.clone();
+ }
+ return elements; // Internal array already uses extended precision.
+ } else {
+ elements = Arrays.copyOf(elements, length);
+ }
+ } else {
+ elements = new double[length];
+ getElements(matrix, numRow, numCol, elements);
+ }
+ inferErrors(elements);
+ return elements;
+ }
+
+ /**
* {@inheritDoc}
*/
@Override
public final double[] getElements() {
- return elements.clone();
+ return Arrays.copyOf(elements, numRow*numCol);
+ }
+
+ /**
+ * Copies the matrix elements in the given flat array. This method does not verify the array length,
+ * since the destination array may contain room for {@link DoubleDouble#error} terms.
+ */
+ @Override
+ final void getElements(final double[] dest) {
+ System.arraycopy(elements, 0, dest, 0, numRow*numCol);
}
/**
* {@inheritDoc}
*/
@Override
- public final void setElements(final double[] elements) {
- ensureLengthMatch(this.elements.length, elements);
- System.arraycopy(elements, 0, this.elements, 0, elements.length);
+ public final void setElements(final double[] newValues) {
+ ensureLengthMatch(numRow*numCol, newValues);
+ System.arraycopy(newValues, 0, elements, 0, newValues.length);
+ if (elements.length != newValues.length) {
+ inferErrors(newValues);
+ }
}
/**
* {@inheritDoc}
+ *
+ * <p>This method does not check the error terms, because those terms are not visible to the user
+ * (they can not appear in the value returned by {@link #getElement(int, int)}, and are not shown
+ * by {@link #toString()}) - returning {@code false} while the matrix clearly looks like affine
+ * would be confusing for the user. Furthermore, the errors can be non-zero only in the very last
+ * element and that value always smaller than 2.3E-16.</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 +336,16 @@ class GeneralMatrix extends MatrixSIS {
/**
* {@inheritDoc}
+ *
+ * <p>This method does not check the error terms, because those terms are not visible to the user
+ * (they can not appear in the value returned by {@link #getElement(int, int)}, and are not shown
+ * by {@link #toString()}) - returning {@code false} while the matrix clearly looks like identity
+ * would be confusing for the user. Furthermore, the errors can be non-zero only on the diagonal,
+ * and those values always smaller than 2.3E-16.</p>
+ *
+ * <p>An other argument is that the extended precision is for reducing rounding errors during
+ * matrix arithmetics. But since the user provided the original data as {@code double} values,
+ * the extra precision usually have no "real" meaning.</p>
*/
@Override
public final boolean isIdentity() {
@@ -225,7 +355,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,15 +378,24 @@ class GeneralMatrix extends MatrixSIS {
public void transpose() {
final int numRow = this.numRow; // Protection against accidental changes.
final int numCol = this.numCol;
+ final int errors = indexOfErrors(numRow, numCol, elements); // Where error values start, or 0 if none.
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);
+ }
}
}
}
/**
* {@inheritDoc}
+ *
+ * <p>The current implementation discards the extended precision, if any.</p>
*/
@Override
public final void normalizeColumns() {
@@ -271,45 +411,49 @@ class GeneralMatrix extends MatrixSIS {
elements[j*numCol + i] /= m;
}
}
+ Arrays.fill(elements, numRow * numCol, elements.length, 0);
}
/**
- * {@inheritDoc}
- */
- @Override
- public MatrixSIS inverse() throws NoninvertibleMatrixException {
- return Solver.inverse(this);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public MatrixSIS solve(final Matrix matrix) throws MismatchedMatrixSizeException, NoninvertibleMatrixException {
- throw new UnsupportedOperationException(); // TODO
- }
-
- /**
- * {@inheritDoc}
+ * Sets this matrix to the product of the given matrices: {@code this = A × B}.
+ * The matrix sizes much match - this is not verified unless assertions are enabled.
*/
- @Override
- public final MatrixSIS multiply(final Matrix matrix) {
+ final void setToProduct(final MatrixSIS A, final Matrix B) {
final int numRow = this.numRow; // Protection against accidental changes.
final int numCol = this.numCol;
- final int nc = matrix.getNumCol();
- ensureNumRowMatch(numCol, matrix, nc);
- final MatrixSIS result = Matrices.createZero(numRow, nc);
- for (int j=0; j<numRow; j++) {
- final int srcOff = j * numCol;
- for (int i=0; i<nc; i++) {
- double sum = 0;
- for (int k=0; k<numCol; k++) {
- sum += elements[srcOff + k] * matrix.getElement(k, i);
+ final int nc = A.getNumCol();
+ assert B.getNumRow() == nc;
+ assert numRow == A.getNumRow() && numCol == B.getNumCol();
+ /*
+ * Get the matrix element values, together with the error terms if the matrix
+ * use extended precision (double-double arithmetic).
+ */
+ final double[] eltA = getExtendedElements(A, numRow, nc, false);
+ final double[] eltB = getExtendedElements(B, nc, numCol, false);
+ final int errorOffset = numRow * numCol; // Where error terms start.
+ final int errA = numRow * nc;
+ final int errB = nc * numCol;
+ /*
+ * Compute the product, to be stored directly in 'this'.
+ */
+ final DoubleDouble dot = new DoubleDouble();
+ final DoubleDouble sum = new DoubleDouble();
+ for (int k=0,j=0; j<numRow; j++) {
+ for (int i=0; i<numCol; i++) {
+ sum.clear();
+ int iB = i; // Index of values in a single column of B.
+ int iA = j * nc; // Index of values in a single row of A.
+ final int nextRow = iA + nc;
+ while (iA < nextRow) {
+ dot.setFrom (eltA, iA, errA);
+ dot.multiply(eltB, iB, errB);
+ sum.add(dot);
+ iB += numCol; // Move to next row of B.
+ iA++; // Move to next column of A.
}
- result.setElement(j, i, sum);
+ sum.storeTo(elements, k++, errorOffset);
}
}
- return result;
}
/**
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java?rev=1529262&r1=1529261&r2=1529262&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java [UTF-8] Fri Oct 4 19:08:18 2013
@@ -44,22 +44,20 @@ import org.apache.sis.internal.jdk7.Obje
* {@link #createIdentity createIdentity},
* {@link #createDiagonal createDiagonal},
* {@link #createZero createZero},
- * {@link #create create}.
+ * {@link #create create},
+ * {@link #copy copy}.
* </li>
* <li>Creating new matrices for coordinate operation steps:
* {@link #createTransform(Envelope, AxisDirection[], Envelope, AxisDirection[]) createTransform},
* {@link #createDimensionSelect createDimensionSelect},
* {@link #createPassThrough createPassThrough}.
* </li>
- * <li>Copies matrices to a SIS implementation:
- * {@link #copy copy},
- * {@link #castOrCopy castOrCopy}.
- * </li>
* <li>Information:
* {@link #isAffine isAffine},
* {@link #isIdentity isIdentity},
* {@link #equals(Matrix, Matrix, double, boolean) equals},
- * {@link #equals(Matrix, Matrix, ComparisonMode) equals}.
+ * {@link #equals(Matrix, Matrix, ComparisonMode) equals},
+ * {@link #toString(Matrix) toString}.
* </li>
* </ul>
*
@@ -72,7 +70,7 @@ public final class Matrices extends Stat
/**
* Number of spaces to put between columns formatted by {@link #toString(Matrix)}.
*/
- private static final int MARGIN = 2;
+ private static final int SPACING = 2;
/**
* Do not allows instantiation of this class.
@@ -101,7 +99,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);
}
}
@@ -125,7 +123,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);
}
}
@@ -150,9 +148,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);
}
/**
@@ -647,37 +645,23 @@ public final class Matrices extends Stat
* @return A copy of the given matrix, or {@code null} if the given matrix was null.
*
* @see MatrixSIS#clone()
+ * @see MatrixSIS#castOrCopy(Matrix)
*/
public static MatrixSIS copy(final Matrix matrix) {
if (matrix == null) {
return null;
}
final int size = matrix.getNumRow();
- if (size == matrix.getNumCol()) {
- switch (size) {
- case 1: return new Matrix1(matrix);
- case 2: return new Matrix2(matrix);
- case 3: return new Matrix3(matrix);
- case 4: return new Matrix4(matrix);
- }
+ if (size != matrix.getNumCol()) {
+ return new NonSquareMatrix(matrix);
}
- return new GeneralMatrix(matrix);
- }
-
- /**
- * Casts or copies the given matrix to a SIS implementation. If {@code matrix} is already
- * an instance of {@code MatrixSIS}, then it is returned unchanged. Otherwise all elements
- * are copied in a new {@code MatrixSIS} object.
- *
- * @param matrix The matrix to cast or copy, or {@code null}.
- * @return The matrix argument if it can be safely casted (including {@code null} argument),
- * or a copy of the given matrix otherwise.
- */
- public static MatrixSIS castOrCopy(final Matrix matrix) {
- if (matrix instanceof MatrixSIS) {
- return (MatrixSIS) matrix;
+ switch (size) {
+ case 1: return new Matrix1(matrix);
+ case 2: return new Matrix2(matrix);
+ case 3: return new Matrix3(matrix);
+ case 4: return new Matrix4(matrix);
}
- return copy(matrix);
+ return new GeneralMatrix(matrix);
}
/**
@@ -717,6 +701,11 @@ public final class Matrices extends Stat
* of identical size, and returning {@code true} if and only if all differences are smaller than or equal
* to {@code tolerance}.
*
+ * <p><b>Caution:</b> {@linkplain org.apache.sis.referencing.datum.BursaWolfParameters Bursa-Wolf parameters},
+ * when represented as a matrix, are close to an identity transform and could easily be confused with rounding
+ * errors. In case of doubt, it is often safer to use the strict {@link MatrixSIS#isIdentity()} method instead
+ * than this one.</p>
+ *
* @param matrix The matrix to test for identity.
* @param tolerance The tolerance value, or 0 for a strict comparison.
* @return {@code true} if this matrix is close to the identity matrix given the tolerance threshold.
@@ -843,6 +832,25 @@ public final class Matrices extends Stat
* Returns a unlocalized string representation of the given matrix.
* For each column, the numbers are aligned on the decimal separator.
*
+ * <p>The current implementation formats ±0 and ±1 without trailing {@code ".0"}, and all other values with
+ * a per-column uniform number of fraction digits. The ±0 and ±1 values are treated especially because they
+ * usually imply a "<cite>no scale</cite>", "<cite>no translation</cite>" or "<cite>orthogonal axes</cite>"
+ * meaning. A matrix in SIS is often populated mostly by ±0 and ±1 values, with a few "interesting" values.
+ * The simpler ±0 and ±1 formatting makes easier to spot the "interesting" values.</p>
+ *
+ * <p>The following example shows the string representation of an affine transform which swap
+ * (<var>latitude</var>, <var>longitude</var>) axes, converts degrees to radians and converts
+ * height values from feet to metres:</p>
+ *
+ * {@preformat math
+ * ┌ ┐
+ * │ 0 0.017453292519943295 0 0 │
+ * │ 0.017453292519943295 0 0 0 │
+ * │ 0 0 0.3048 0 │
+ * │ 0 0 0 1 │
+ * └ ┘
+ * }
+ *
* {@note Formatting on a per-column basis is convenient for the kind of matrices used in referencing by coordinates,
* because each column is typically a displacement vector in a different dimension of the source coordinate
* reference system. In addition, the last column is often a translation vector having a magnitude very
@@ -854,53 +862,92 @@ public final class Matrices extends Stat
public static String toString(final Matrix matrix) {
final int numRow = matrix.getNumRow();
final int numCol = matrix.getNumCol();
- final String[] elements = new String[numRow * numCol];
- final int[] columnWidth = new int[numCol];
- final int[] maximumFractionDigits = new int[numCol];
- final int[] maximumRemainingWidth = new int[numCol]; // Minus sign (if any) + integer digits + decimal separator + 2 spaces.
+ final String[] elements = new String [numCol * numRow];
+ final boolean[] noFractionDigits = new boolean[numCol * numRow];
+ final boolean[] hasDecimalSeparator = new boolean[numCol];
+ final int[] maximumFractionDigits = new int [numCol];
+ final int[] widthBeforeFraction = new int [numCol]; // spacing + ('-') + integerDigits + '.'
+ final int[] columnWidth = new int [numCol];
int totalWidth = 1;
/*
* Create now the string representation of all matrix elements and measure the width
* of the integer field and the fraction field, then the total width of each column.
*/
- int margin = 1; // Margin before the first column only.
+ int spacing = 1; // Spacing is 1 before the first column only, then SPACING for other columns.
for (int i=0; i<numCol; i++) {
for (int j=0; j<numRow; j++) {
- final String element = Double.toString(matrix.getElement(j,i)).replace("Infinity", "∞");
- elements[j*numCol + i] = element;
- int width = element.length();
- int s = element.lastIndexOf('.');
- if (s >= 0) {
- width = (maximumRemainingWidth[i] = Math.max(maximumRemainingWidth[i], ++s + margin))
- + (maximumFractionDigits[i] = Math.max(maximumFractionDigits[i], width - s));
+ final int flatIndex = j*numCol + i;
+ final double value = matrix.getElement(j,i);
+ String element = Double.toString(value);
+ final int width;
+ /*
+ * Special case for ±0 and ±1 (because those values appear very often and have
+ * a particular meaning): for those values, we will ignore the fraction digits.
+ * For all other values, we will format all fraction digits.
+ */
+ if (value == -1 || value == 0 || value == +1) {
+ noFractionDigits[flatIndex] = true;
+ width = spacing + element.length() - 2; // The -2 is for ignoring the trailing ".0"
+ widthBeforeFraction[i] = Math.max(widthBeforeFraction[i], width);
} else {
- // NaN or Infinity.
- width += margin;
+ /*
+ * All values other than ±0 and ±1. Store separately the width before and after
+ * the decimal separator. The width before the separator contains the spacing.
+ */
+ int s = element.lastIndexOf('.');
+ if (s >= 0) {
+ s++; // After the separator.
+ hasDecimalSeparator[i] = true;
+ width = (widthBeforeFraction [i] = Math.max(widthBeforeFraction [i], spacing + s))
+ + (maximumFractionDigits[i] = Math.max(maximumFractionDigits[i], element.length() - s));
+ } else {
+ // NaN or Infinity.
+ element = element.replace("Infinity", "∞");
+ width = spacing + element.length();
+ }
}
columnWidth[i] = Math.max(columnWidth[i], width);
+ elements[flatIndex] = element;
}
totalWidth += columnWidth[i];
- margin = MARGIN; // Margin before all columns after the first one.
+ spacing = SPACING; // Specing before all columns after the first one.
}
/*
- * Now append the formatted elements with the appropriate amount of spaces
- * and trailling zeros for each column.
+ * Now append the formatted elements with the appropriate amount of spaces before each value,
+ * and trailling zeros after each value except ±0, ±1, NaN and infinities.
*/
- final String lineSeparator = JDK7.lineSeparator();
+ final String lineSeparator = JDK7.lineSeparator();
final CharSequence whiteLine = CharSequences.spaces(totalWidth);
- final StringBuffer buffer = new StringBuffer((totalWidth + 2 + lineSeparator.length()) * (numRow + 2));
+ final StringBuilder buffer = new StringBuilder((totalWidth + 2 + lineSeparator.length()) * (numRow + 2));
buffer.append('┌').append(whiteLine).append('┐').append(lineSeparator);
- for (int k=0,j=0; j<numRow; j++) {
+ int flatIndex = 0;
+ for (int j=0; j<numRow; j++) {
buffer.append('│');
for (int i=0; i<numCol; i++) {
- final String element = elements[k++];
+ final String element = elements[flatIndex];
final int width = element.length();
- int s = element.lastIndexOf('.');
- buffer.append(CharSequences.spaces(s >= 0 ? maximumRemainingWidth[i] - ++s : columnWidth[i] - width)).append(element);
+ int spaces, s = element.lastIndexOf('.');
+ if (s >= 0) {
+ if (hasDecimalSeparator[i]) s++;
+ spaces = widthBeforeFraction[i] - s; // Number of spaces for alignment on the decimal separator
+ } else {
+ spaces = columnWidth[i] - width; // Number of spaces for right alignment (NaN or ∞ cases)
+ }
+ buffer.append(CharSequences.spaces(spaces)).append(element);
+ /*
+ * Append trailing spaces for ±0 and ±1 values,
+ * or trailing zeros for all other real values.
+ */
s += maximumFractionDigits[i] - width;
- while (--s >= 0) {
- buffer.append('0');
+ if (noFractionDigits[flatIndex]) {
+ buffer.setLength(buffer.length() - 2); // Erase the trailing ".0"
+ buffer.append(CharSequences.spaces(s + 2));
+ } else {
+ while (--s >= 0) {
+ buffer.append('0');
+ }
}
+ flatIndex++;
}
buffer.append(" │").append(lineSeparator);
}
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java?rev=1529262&r1=1529261&r2=1529262&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java [UTF-8] Fri Oct 4 19:08:18 2013
@@ -84,6 +84,9 @@ public final class Matrix1 extends Matri
*
* @param elements Elements of the matrix.
* @throws IllegalArgumentException If the given array does not have the expected length.
+ *
+ * @see #setElements(double[])
+ * @see Matrices#create(int, int, double[])
*/
public Matrix1(final double[] elements) throws IllegalArgumentException {
setElements(elements);
@@ -100,6 +103,24 @@ public final class Matrix1 extends Matri
m00 = matrix.getElement(0,0);
}
+ /**
+ * Casts or copies the given matrix to a {@code Matrix1} implementation. If the given {@code matrix}
+ * is already an instance of {@code Matrix1}, then it is returned unchanged. Otherwise this method
+ * verifies the matrix size, then copies the element in a new {@code Matrix1} object.
+ *
+ * @param matrix The matrix to cast or copy, or {@code null}.
+ * @return The matrix argument if it can be safely casted (including {@code null} argument),
+ * or a copy of the given matrix otherwise.
+ * @throws MismatchedMatrixSizeException If the size of the given matrix is not {@value #SIZE}×{@value #SIZE}.
+ */
+ public static Matrix1 castOrCopy(final Matrix matrix) throws MismatchedMatrixSizeException {
+ if (matrix == null || matrix instanceof Matrix1) {
+ return (Matrix1) matrix;
+ }
+ ensureSizeMatch(SIZE, matrix);
+ return new Matrix1(matrix);
+ }
+
/*
* The 'final' modifier in following method declarations is redundant with the 'final' modifier
* in this class declaration, but we keep them as a reminder of which methods should stay final
@@ -173,7 +194,18 @@ public final class Matrix1 extends Matri
*/
@Override
public final double[] getElements() {
- return new double[] {m00};
+ final double[] elements = new double[SIZE*SIZE];
+ getElements(elements);
+ return elements;
+ }
+
+ /**
+ * Copies the matrix elements in the given flat array.
+ * The array length shall be at least 1, may also be 2.
+ */
+ @Override
+ final void getElements(final double[] elements) {
+ elements[0] = m00;
}
/**
@@ -220,50 +252,6 @@ public final class Matrix1 extends Matri
}
/**
- * {@inheritDoc}
- */
- @Override
- public MatrixSIS inverse() throws NoninvertibleMatrixException {
- if (m00 == 0) {
- throw new NoninvertibleMatrixException();
- }
- return new Matrix1(1 / m00);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public MatrixSIS solve(final Matrix matrix) throws MismatchedMatrixSizeException, NoninvertibleMatrixException {
- final int nc = matrix.getNumCol();
- ensureNumRowMatch(SIZE, matrix, nc);
- if (m00 == 0) {
- throw new NoninvertibleMatrixException();
- }
- if (nc != SIZE) {
- final NonSquareMatrix m = new NonSquareMatrix(SIZE, nc, false);
- for (int i=0; i<nc; i++) {
- m.elements[i] = matrix.getElement(0, i) / m00;
- }
- return m;
- }
- return new Matrix1(matrix.getElement(0,0) / m00);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public MatrixSIS multiply(final Matrix matrix) {
- final int nc = matrix.getNumCol();
- ensureNumRowMatch(SIZE, matrix, nc);
- if (nc != SIZE) {
- return new NonSquareMatrix(this, matrix);
- }
- return new Matrix1(m00 * matrix.getElement(0,0));
- }
-
- /**
* Returns {@code true} if the specified object is of type {@code Matrix1} and
* all of the data members are equal to the corresponding data members in this matrix.
*
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java?rev=1529262&r1=1529261&r2=1529262&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java [UTF-8] Fri Oct 4 19:08:18 2013
@@ -81,10 +81,8 @@ public final class Matrix2 extends Matri
public Matrix2(final double m00, final double m01,
final double m10, final double m11)
{
- this.m00 = m00;
- this.m01 = m01;
- this.m10 = m10;
- this.m11 = m11;
+ this.m00 = m00; this.m01 = m01;
+ this.m10 = m10; this.m11 = m11;
}
/**
@@ -93,6 +91,9 @@ public final class Matrix2 extends Matri
*
* @param elements Elements of the matrix. Column indices vary fastest.
* @throws IllegalArgumentException If the given array does not have the expected length.
+ *
+ * @see #setElements(double[])
+ * @see Matrices#create(int, int, double[])
*/
public Matrix2(final double[] elements) throws IllegalArgumentException {
setElements(elements);
@@ -112,6 +113,24 @@ public final class Matrix2 extends Matri
m11 = matrix.getElement(1,1);
}
+ /**
+ * Casts or copies the given matrix to a {@code Matrix2} implementation. If the given {@code matrix}
+ * is already an instance of {@code Matrix2}, then it is returned unchanged. Otherwise this method
+ * verifies the matrix size, then copies all elements in a new {@code Matrix2} object.
+ *
+ * @param matrix The matrix to cast or copy, or {@code null}.
+ * @return The matrix argument if it can be safely casted (including {@code null} argument),
+ * or a copy of the given matrix otherwise.
+ * @throws MismatchedMatrixSizeException If the size of the given matrix is not {@value #SIZE}×{@value #SIZE}.
+ */
+ public static Matrix2 castOrCopy(final Matrix matrix) throws MismatchedMatrixSizeException {
+ if (matrix == null || matrix instanceof Matrix2) {
+ return (Matrix2) matrix;
+ }
+ ensureSizeMatch(SIZE, matrix);
+ return new Matrix2(matrix);
+ }
+
/*
* The 'final' modifier in following method declarations is redundant with the 'final' modifier
* in this class declaration, but we keep them as a reminder of which methods should stay final
@@ -193,7 +212,19 @@ public final class Matrix2 extends Matri
*/
@Override
public final double[] getElements() {
- return new double[] {m00, m01, m10, m11};
+ final double[] elements = new double[SIZE*SIZE];
+ getElements(elements);
+ return elements;
+ }
+
+ /**
+ * Copies the matrix elements in the given flat array.
+ * The array length shall be at least 4, may also be 8.
+ */
+ @Override
+ final void getElements(final double[] elements) {
+ elements[0] = m00; elements[1] = m01;
+ elements[2] = m10; elements[3] = m11;
}
/**
@@ -203,10 +234,8 @@ public final class Matrix2 extends Matri
@Override
public final void setElements(final double[] elements) {
ensureLengthMatch(SIZE*SIZE, elements);
- m00 = elements[0];
- m01 = elements[1];
- m10 = elements[2];
- m11 = elements[3];
+ m00 = elements[0]; m01 = elements[1];
+ m10 = elements[2]; m11 = elements[3];
}
/**
@@ -247,44 +276,6 @@ public final class Matrix2 extends Matri
}
/**
- * {@inheritDoc}
- */
- @Override
- public MatrixSIS inverse() throws NoninvertibleMatrixException {
- final double det = m00*m11 - m01*m10;
- if (det == 0) {
- throw new NoninvertibleMatrixException();
- }
- return new Matrix2(m11 / det, -m01 / det,
- -m10 / det, m00 / det);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public MatrixSIS solve(final Matrix matrix) throws MismatchedMatrixSizeException, NoninvertibleMatrixException {
- throw new UnsupportedOperationException(); // TODO
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public MatrixSIS multiply(final Matrix matrix) {
- final int nc = matrix.getNumCol();
- ensureNumRowMatch(SIZE, matrix, nc);
- if (nc != SIZE) {
- return new NonSquareMatrix(this, matrix);
- }
- final Matrix2 k = (matrix instanceof Matrix2) ? (Matrix2) matrix : new Matrix2(matrix);
- return new Matrix2(m00 * k.m00 + m01 * k.m10,
- m00 * k.m01 + m01 * k.m11,
- m10 * k.m00 + m11 * k.m10,
- m10 * k.m01 + m11 * k.m11);
- }
-
- /**
* Returns {@code true} if the specified object is of type {@code Matrix2} and
* all of the data members are equal to the corresponding data members in this matrix.
*
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java?rev=1529262&r1=1529261&r2=1529262&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java [UTF-8] Fri Oct 4 19:08:18 2013
@@ -90,19 +90,13 @@ public final class Matrix3 extends Matri
* @param m21 The second matrix element in the third row.
* @param m22 The third matrix element in the third row.
*/
- public Matrix3(double m00, double m01, double m02,
- double m10, double m11, double m12,
- double m20, double m21, double m22)
+ public Matrix3(final double m00, final double m01, final double m02,
+ final double m10, final double m11, final double m12,
+ final double m20, final double m21, final double m22)
{
- this.m00 = m00;
- this.m01 = m01;
- this.m02 = m02;
- this.m10 = m10;
- this.m11 = m11;
- this.m12 = m12;
- this.m20 = m20;
- this.m21 = m21;
- this.m22 = m22;
+ this.m00 = m00; this.m01 = m01; this.m02 = m02;
+ this.m10 = m10; this.m11 = m11; this.m12 = m12;
+ this.m20 = m20; this.m21 = m21; this.m22 = m22;
}
/**
@@ -111,6 +105,9 @@ public final class Matrix3 extends Matri
*
* @param elements Elements of the matrix. Column indices vary fastest.
* @throws IllegalArgumentException If the given array does not have the expected length.
+ *
+ * @see #setElements(double[])
+ * @see Matrices#create(int, int, double[])
*/
public Matrix3(final double[] elements) throws IllegalArgumentException {
setElements(elements);
@@ -131,6 +128,24 @@ public final class Matrix3 extends Matri
}
}
+ /**
+ * Casts or copies the given matrix to a {@code Matrix3} implementation. If the given {@code matrix}
+ * is already an instance of {@code Matrix3}, then it is returned unchanged. Otherwise this method
+ * verifies the matrix size, then copies all elements in a new {@code Matrix3} object.
+ *
+ * @param matrix The matrix to cast or copy, or {@code null}.
+ * @return The matrix argument if it can be safely casted (including {@code null} argument),
+ * or a copy of the given matrix otherwise.
+ * @throws MismatchedMatrixSizeException If the size of the given matrix is not {@value #SIZE}×{@value #SIZE}.
+ */
+ public static Matrix3 castOrCopy(final Matrix matrix) throws MismatchedMatrixSizeException {
+ if (matrix == null || matrix instanceof Matrix3) {
+ return (Matrix3) matrix;
+ }
+ ensureSizeMatch(SIZE, matrix);
+ return new Matrix3(matrix);
+ }
+
/*
* The 'final' modifier in following method declarations is redundant with the 'final' modifier
* in this class declaration, but we keep them as a reminder of which methods should stay final
@@ -222,11 +237,20 @@ public final class Matrix3 extends Matri
*/
@Override
public final double[] getElements() {
- return new double[] {
- m00, m01, m02,
- m10, m11, m12,
- m20, m21, m22
- };
+ final double[] elements = new double[SIZE*SIZE];
+ getElements(elements);
+ return elements;
+ }
+
+ /**
+ * Copies the matrix elements in the given flat array.
+ * The array length shall be at least 9, may also be 18.
+ */
+ @Override
+ final void getElements(final double[] elements) {
+ elements[0] = m00; elements[1] = m01; elements[2] = m02;
+ elements[3] = m10; elements[4] = m11; elements[5] = m12;
+ elements[6] = m20; elements[7] = m21; elements[8] = m22;
}
/**
@@ -236,15 +260,9 @@ public final class Matrix3 extends Matri
@Override
public final void setElements(final double[] elements) {
ensureLengthMatch(SIZE*SIZE, elements);
- m00 = elements[0];
- m01 = elements[1];
- m02 = elements[2];
- m10 = elements[3];
- m11 = elements[4];
- m12 = elements[5];
- m20 = elements[6];
- m21 = elements[7];
- m22 = elements[8];
+ m00 = elements[0]; m01 = elements[1]; m02 = elements[2];
+ m10 = elements[3]; m11 = elements[4]; m12 = elements[5];
+ m20 = elements[6]; m21 = elements[7]; m22 = elements[8];
}
/**
@@ -289,44 +307,6 @@ public final class Matrix3 extends Matri
}
/**
- * {@inheritDoc}
- */
- @Override
- public MatrixSIS inverse() throws NoninvertibleMatrixException {
- return Solver.inverse(this);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public MatrixSIS solve(final Matrix matrix) throws MismatchedMatrixSizeException, NoninvertibleMatrixException {
- throw new UnsupportedOperationException(); // TODO
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public MatrixSIS multiply(final Matrix matrix) {
- final int nc = matrix.getNumCol();
- ensureNumRowMatch(SIZE, matrix, nc);
- if (nc != SIZE) {
- return new NonSquareMatrix(this, matrix);
- }
- final Matrix3 k = (matrix instanceof Matrix3) ? (Matrix3) matrix : new Matrix3(matrix);
- return new Matrix3(m00 * k.m00 + m01 * k.m10 + m02 * k.m20,
- m00 * k.m01 + m01 * k.m11 + m02 * k.m21,
- m00 * k.m02 + m01 * k.m12 + m02 * k.m22,
- m10 * k.m00 + m11 * k.m10 + m12 * k.m20,
- m10 * k.m01 + m11 * k.m11 + m12 * k.m21,
- m10 * k.m02 + m11 * k.m12 + m12 * k.m22,
- m20 * k.m00 + m21 * k.m10 + m22 * k.m20,
- m20 * k.m01 + m21 * k.m11 + m22 * k.m21,
- m20 * k.m02 + m21 * k.m12 + m22 * k.m22);
- }
-
- /**
* Returns {@code true} if the specified object is of type {@code Matrix3} and
* all of the data members are equal to the corresponding data members in this matrix.
*
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java?rev=1529262&r1=1529261&r2=1529262&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java [UTF-8] Fri Oct 4 19:08:18 2013
@@ -105,27 +105,15 @@ public final class Matrix4 extends Matri
* @param m32 The third matrix element in the forth row.
* @param m33 The forth matrix element in the forth row.
*/
- public Matrix4(double m00, double m01, double m02, double m03,
- double m10, double m11, double m12, double m13,
- double m20, double m21, double m22, double m23,
- double m30, double m31, double m32, double m33)
+ public Matrix4(final double m00, final double m01, final double m02, final double m03,
+ final double m10, final double m11, final double m12, final double m13,
+ final double m20, final double m21, final double m22, final double m23,
+ final double m30, final double m31, final double m32, final double m33)
{
- this.m00 = m00;
- this.m01 = m01;
- this.m02 = m02;
- this.m03 = m03;
- this.m10 = m10;
- this.m11 = m11;
- this.m12 = m12;
- this.m13 = m13;
- this.m20 = m20;
- this.m21 = m21;
- this.m22 = m22;
- this.m23 = m23;
- this.m30 = m30;
- this.m31 = m31;
- this.m32 = m32;
- this.m33 = m33;
+ this.m00 = m00; this.m01 = m01; this.m02 = m02; this.m03 = m03;
+ this.m10 = m10; this.m11 = m11; this.m12 = m12; this.m13 = m13;
+ this.m20 = m20; this.m21 = m21; this.m22 = m22; this.m23 = m23;
+ this.m30 = m30; this.m31 = m31; this.m32 = m32; this.m33 = m33;
}
/**
@@ -134,6 +122,9 @@ public final class Matrix4 extends Matri
*
* @param elements Elements of the matrix. Column indices vary fastest.
* @throws IllegalArgumentException If the given array does not have the expected length.
+ *
+ * @see #setElements(double[])
+ * @see Matrices#create(int, int, double[])
*/
public Matrix4(final double[] elements) throws IllegalArgumentException {
setElements(elements);
@@ -147,7 +138,7 @@ public final class Matrix4 extends Matri
* @param matrix The matrix to copy.
* @throws IllegalArgumentException if the given matrix is not of the expected size.
*/
- public Matrix4(final Matrix matrix) throws IllegalArgumentException {
+ Matrix4(final Matrix matrix) throws IllegalArgumentException {
for (int j=0; j<SIZE; j++) {
for (int i=0; i<SIZE; i++) {
setElement(j,i, matrix.getElement(j,i));
@@ -155,6 +146,24 @@ public final class Matrix4 extends Matri
}
}
+ /**
+ * Casts or copies the given matrix to a {@code Matrix4} implementation. If the given {@code matrix}
+ * is already an instance of {@code Matrix4}, then it is returned unchanged. Otherwise this method
+ * verifies the matrix size, then copies all elements in a new {@code Matrix4} object.
+ *
+ * @param matrix The matrix to cast or copy, or {@code null}.
+ * @return The matrix argument if it can be safely casted (including {@code null} argument),
+ * or a copy of the given matrix otherwise.
+ * @throws MismatchedMatrixSizeException If the size of the given matrix is not {@value #SIZE}×{@value #SIZE}.
+ */
+ public static Matrix4 castOrCopy(final Matrix matrix) throws MismatchedMatrixSizeException {
+ if (matrix == null || matrix instanceof Matrix4) {
+ return (Matrix4) matrix;
+ }
+ ensureSizeMatch(SIZE, matrix);
+ return new Matrix4(matrix);
+ }
+
/*
* The 'final' modifier in following method declarations is redundant with the 'final' modifier
* in this class declaration, but we keep them as a reminder of which methods should stay final
@@ -260,12 +269,21 @@ public final class Matrix4 extends Matri
*/
@Override
public final double[] getElements() {
- return new double[] {
- m00, m01, m02, m03,
- m10, m11, m12, m13,
- m20, m21, m22, m23,
- m30, m31, m32, m33
- };
+ final double[] elements = new double[SIZE*SIZE];
+ getElements(elements);
+ return elements;
+ }
+
+ /**
+ * Copies the matrix elements in the given flat array.
+ * The array length shall be at least 16, may also be 32.
+ */
+ @Override
+ final void getElements(final double[] elements) {
+ elements[ 0] = m00; elements[ 1] = m01; elements[ 2] = m02; elements[ 3] = m03;
+ elements[ 4] = m10; elements[ 5] = m11; elements[ 6] = m12; elements[ 7] = m13;
+ elements[ 8] = m20; elements[ 9] = m21; elements[10] = m22; elements[11] = m23;
+ elements[12] = m30; elements[13] = m31; elements[14] = m32; elements[15] = m33;
}
/**
@@ -275,22 +293,10 @@ public final class Matrix4 extends Matri
@Override
public final void setElements(final double[] elements) {
ensureLengthMatch(SIZE*SIZE, elements);
- m00 = elements[ 0];
- m01 = elements[ 1];
- m02 = elements[ 2];
- m03 = elements[ 3];
- m10 = elements[ 4];
- m11 = elements[ 5];
- m12 = elements[ 6];
- m13 = elements[ 7];
- m20 = elements[ 8];
- m21 = elements[ 9];
- m22 = elements[10];
- m23 = elements[11];
- m30 = elements[12];
- m31 = elements[13];
- m32 = elements[14];
- m33 = elements[15];
+ m00 = elements[ 0]; m01 = elements[ 1]; m02 = elements[ 2]; m03 = elements[ 3];
+ m10 = elements[ 4]; m11 = elements[ 5]; m12 = elements[ 6]; m13 = elements[ 7];
+ m20 = elements[ 8]; m21 = elements[ 9]; m22 = elements[10]; m23 = elements[11];
+ m30 = elements[12]; m31 = elements[13]; m32 = elements[14]; m33 = elements[15];
}
/**
@@ -340,51 +346,6 @@ public final class Matrix4 extends Matri
}
/**
- * {@inheritDoc}
- */
- @Override
- public MatrixSIS inverse() throws NoninvertibleMatrixException {
- return Solver.inverse(this);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public MatrixSIS solve(final Matrix matrix) throws MismatchedMatrixSizeException, NoninvertibleMatrixException {
- throw new UnsupportedOperationException(); // TODO
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public MatrixSIS multiply(final Matrix matrix) {
- final int nc = matrix.getNumCol();
- ensureNumRowMatch(SIZE, matrix, nc);
- if (nc != SIZE) {
- return new NonSquareMatrix(this, matrix);
- }
- 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,
- m00 * k.m01 + m01 * k.m11 + m02 * k.m21 + m03 * k.m31,
- m00 * k.m02 + m01 * k.m12 + m02 * k.m22 + m03 * k.m32,
- m00 * k.m03 + m01 * k.m13 + m02 * k.m23 + m03 * k.m33,
- m10 * k.m00 + m11 * k.m10 + m12 * k.m20 + m13 * k.m30,
- m10 * k.m01 + m11 * k.m11 + m12 * k.m21 + m13 * k.m31,
- m10 * k.m02 + m11 * k.m12 + m12 * k.m22 + m13 * k.m32,
- m10 * k.m03 + m11 * k.m13 + m12 * k.m23 + m13 * k.m33,
- m20 * k.m00 + m21 * k.m10 + m22 * k.m20 + m23 * k.m30,
- m20 * k.m01 + m21 * k.m11 + m22 * k.m21 + m23 * k.m31,
- m20 * k.m02 + m21 * k.m12 + m22 * k.m22 + m23 * k.m32,
- m20 * k.m03 + m21 * k.m13 + m22 * k.m23 + m23 * k.m33,
- m30 * k.m00 + m31 * k.m10 + m32 * k.m20 + m33 * k.m30,
- m30 * k.m01 + m31 * k.m11 + m32 * k.m21 + m33 * k.m31,
- m30 * k.m02 + m31 * k.m12 + m32 * k.m22 + m33 * k.m32,
- m30 * k.m03 + m31 * k.m13 + m32 * k.m23 + m33 * k.m33);
- }
-
- /**
* Returns {@code true} if the specified object is of type {@code Matrix4} and
* all of the data members are equal to the corresponding data members in this matrix.
*
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java?rev=1529262&r1=1529261&r2=1529262&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java Fri Oct 4 19:08:18 2013
@@ -94,9 +94,8 @@ public abstract class MatrixSIS implemen
static void ensureNumRowMatch(final int expected, final Matrix matrix, final int numCol) {
final int actual = matrix.getNumRow();
if (actual != expected) {
- final Integer n = numCol;
throw new MismatchedMatrixSizeException(Errors.format(
- Errors.Keys.MismatchedMatrixSize_4, expected, n, actual, n));
+ Errors.Keys.MismatchedMatrixSize_4, expected, "â©", actual, numCol));
}
}
@@ -108,6 +107,24 @@ public abstract class MatrixSIS implemen
}
/**
+ * Casts or copies the given matrix to a SIS implementation. If {@code matrix} is already
+ * an instance of {@code MatrixSIS}, then it is returned unchanged. Otherwise all elements
+ * are copied in a new {@code MatrixSIS} object.
+ *
+ * @param matrix The matrix to cast or copy, or {@code null}.
+ * @return The matrix argument if it can be safely casted (including {@code null} argument),
+ * or a copy of the given matrix otherwise.
+ *
+ * @see Matrices#copy(Matrix)
+ */
+ public static MatrixSIS castOrCopy(final Matrix matrix) {
+ if (matrix == null || matrix instanceof MatrixSIS) {
+ return (MatrixSIS) matrix;
+ }
+ return Matrices.copy(matrix);
+ }
+
+ /**
* Returns a copy of all matrix elements in a flat, row-major (column indices vary fastest) array.
* The array length is <code>{@linkplain #getNumRow()} * {@linkplain #getNumCol()}</code>.
*
@@ -116,6 +133,19 @@ public abstract class MatrixSIS implemen
public abstract double[] getElements();
/**
+ * Stores all matrix elements in the given flat array. This method does not verify the array length.
+ * All subclasses in this {@code org.apache.sis.referencing.operation.matrix} package override this
+ * method with a more efficient implementation.
+ *
+ * @param dest The destination array. May be longer than necessary (this happen when the caller needs to
+ * append {@link org.apache.sis.internal.util.DoubleDouble#error} values after the elements).
+ */
+ void getElements(final double[] dest) {
+ final double[] elements = getElements();
+ System.arraycopy(elements, 0, dest, 0, elements.length);
+ }
+
+ /**
* Sets all matrix elements from a flat, row-major (column indices vary fastest) array.
* The array length shall be <code>{@linkplain #getNumRow()} * {@linkplain #getNumCol()}</code>.
*
@@ -186,7 +216,15 @@ public abstract class MatrixSIS implemen
* @throws MismatchedMatrixSizeException if the number of rows in the given matrix is not equals to the
* number of columns in this matrix.
*/
- public abstract MatrixSIS multiply(Matrix matrix) throws MismatchedMatrixSizeException;
+ public MatrixSIS multiply(final Matrix matrix) throws MismatchedMatrixSizeException {
+ final int numRow = getNumRow();
+ final int numCol = getNumCol();
+ final int nc = matrix.getNumCol();
+ ensureNumRowMatch(numCol, matrix, nc);
+ final GeneralMatrix result = GeneralMatrix.createExtendedPrecision(numRow, nc);
+ result.setToProduct(this, matrix);
+ return result;
+ }
/**
* Returns the value of <var>U</var> which solves {@code this} Ã <var>U</var> = {@code matrix}.
@@ -199,7 +237,9 @@ public abstract class MatrixSIS implemen
* to the number of columns in this matrix.
* @throws NoninvertibleMatrixException if this matrix is not invertible.
*/
- public abstract MatrixSIS solve(Matrix matrix) throws MismatchedMatrixSizeException, NoninvertibleMatrixException;
+ public MatrixSIS solve(final Matrix matrix) throws MismatchedMatrixSizeException, NoninvertibleMatrixException {
+ return Solver.solve(this, matrix);
+ }
/**
* Returns the inverse of this matrix.
@@ -209,7 +249,9 @@ public abstract class MatrixSIS implemen
*
* @see java.awt.geom.AffineTransform#createInverse()
*/
- public abstract MatrixSIS inverse() throws NoninvertibleMatrixException;
+ public MatrixSIS inverse() throws NoninvertibleMatrixException {
+ return Solver.inverse(this);
+ }
/**
* Compares the given matrices for equality, using the given absolute tolerance threshold.
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrix.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrix.java?rev=1529262&r1=1529261&r2=1529262&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrix.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrix.java [UTF-8] Fri Oct 4 19:08:18 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);
}
/**
@@ -79,39 +80,23 @@ 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);
- final int numRow = this.numRow; // Protection against accidental changes.
- final int numCol = this.numCol;
- final int common = A.getNumCol();
- ensureNumRowMatch(common, B, numCol);
- int offset = 0;
- for (int j=0; j<numRow; j++) {
- for (int i=0; i<numCol; i++) {
- double sum = 0;
- for (int k=0; k<common; k++) {
- sum += A.getElement(j, k) * B.getElement(k, i);
- }
- elements[offset++] = sum;
- }
- }
- }
-
- /**
* Sets the value of this matrix to its transpose.
*/
@Override
public void transpose() {
final short numRow = this.numRow; // Protection against accidental changes before we are done.
final short numCol = this.numCol;
+ final int errors = indexOfErrors(numRow, numCol, elements); // Where error values start, or 0 if none.
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;