3
* This file is part of jReality. jReality is open source software, made
4
* available under a BSD license:
6
* Copyright (c) 2003-2006, jReality Group: Charles Gunn, Tim Hoffmann, Markus
7
* Schmies, Steffen Weissmann.
11
* Redistribution and use in source and binary forms, with or without
12
* modification, are permitted provided that the following conditions are met:
14
* - Redistributions of source code must retain the above copyright notice, this
15
* list of conditions and the following disclaimer.
17
* - Redistributions in binary form must reproduce the above copyright notice,
18
* this list of conditions and the following disclaimer in the documentation
19
* and/or other materials provided with the distribution.
21
* - Neither the name of jReality nor the names of its contributors nor the
22
* names of their associated organizations may be used to endorse or promote
23
* products derived from this software without specific prior written
26
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
30
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36
* POSSIBILITY OF SUCH DAMAGE.
43
import java.io.Serializable;
45
import opencog.spacetime.space.SpaceComponent;
46
import opencog.spacetime.space.Transformation;
47
import opencog.spacetime.space.data.DoubleArray;
51
* A simple wrapper class for 4x4 real matrices. The matrix is represented as a
52
* linear array of 16 values (<tt>double[16]</tt> in order to avoid problems with Java's
53
* multi-dimensional arrays. The elements are listed in row/column order and act on column vectors
54
* sitting to the right of the matrix.
57
* This class is not supposed to be a replacement for a full-fledged mathematical
58
* package. It provides a convenient wrapper for double arrays that offers some basic
59
* functionality for multiplying and inverting matrices and such, but if you want to
60
* do more involved stuff, you probably want to use a dedicated math library.
62
* @see opencog.math.Rn
63
* @see opencog.math.P3
64
* @see opencog.math.Pn
68
public class Matrix implements Serializable {
70
public final static double TOLERANCE = Rn.TOLERANCE;
71
protected double[] matrix;
75
this(Rn.setIdentityMatrix(new double[16]));
82
public Matrix(Matrix T) {
83
matrix = new double[16];
84
System.arraycopy(T.matrix, 0, matrix, 0, 16);
88
* plain wrapper for the array m; does NOT make a copy of m!
89
* @param m the double array to be wrapped by this Matrix
91
public Matrix(double[] m) {
93
m = Rn.setIdentityMatrix(new double[16]);
95
throw new IllegalArgumentException(
96
"invalid dimension for 4x4 matrix");
102
public Matrix(double x00, double x01, double x02, double x03, double x10,
103
double x11, double x12, double x13, double x20, double x21, double x22,
104
double x23, double x30, double x31, double x32, double x33) {
105
this(new double[] { x00, x01, x02, x03, x10, x11, x12, x13, x20, x21, x22,
106
x23, x30, x31, x32, x33 });
110
* this constructor copies the content of the given DoubleArray. Note: the
111
* given DoubleArray must have length == 16
114
* DoubleArray to copy and wrap
116
public Matrix(DoubleArray data) {
117
this(data.toDoubleArray(null));
121
* this constructor copies the content of the given Transformation.
122
* @param the Transformation to copy and wrap
124
public Matrix(Transformation data) {
125
this(data == null ? null : data.getMatrix());
133
public static Matrix times(Matrix A, Matrix B) {
134
return new Matrix(Rn.times(null, A.matrix, B.matrix));
142
public static Matrix sum(Matrix A, Matrix B) {
143
return new Matrix(Rn.add(null, A.matrix, B.matrix));
150
* @return B * A * B^-1
152
public static Matrix conjugate(Matrix A, Matrix B) {
153
return new Matrix(Rn.conjugateByMatrix(null, A.matrix, B.matrix));
157
* this flag is kept for extending classes, that need to know
158
* whether the matrix aray was changed. It's their responsibility
159
* to reset this flag.
161
protected transient boolean matrixChanged=true;
167
public void assignFrom(double[] initValue) {
168
matrixChanged = true;
169
System.arraycopy(initValue, 0, matrix, 0, 16);
176
public void assignFrom(Matrix initValue) {
177
matrixChanged = true;
178
System.arraycopy(initValue.matrix, 0, matrix, 0, 16);
185
public void assignFrom(DoubleArray data) {
186
matrixChanged = true;
187
if (data.getLength() != 16)
188
throw new IllegalArgumentException(
189
"invalid dimension for 4x4 matrix");
190
data.toDoubleArray(matrix);
197
public void assignFrom(Transformation trafo) {
198
matrixChanged = true;
199
trafo.getMatrix(matrix);
203
* TODO: assign single values!
205
public void assignFrom(double x00, double x01, double x02, double x03, double x10,
206
double x11, double x12, double x13, double x20, double x21, double x22,
207
double x23, double x30, double x31, double x32, double x33) {
208
assignFrom(new double[] { x00, x01, x02, x03, x10, x11, x12, x13, x20, x21, x22,
209
x23, x30, x31, x32, x33 });
213
public void assignTo(double[] array) {
214
System.arraycopy(matrix, 0, array, 0, 16);
217
public void assignTo(Matrix m) {
218
m.assignFrom(matrix);
221
public void assignTo(Transformation trafo) {
222
trafo.setMatrix(matrix);
226
* Set the matrix of the transformation of <i>comp</i> to be this instance. If <i>comp</i> has
227
* no Transformation, create one.
229
*/public void assignTo(SpaceComponent comp) {
230
Transformation t = comp.getTransformation();
231
if (t == null) comp.setTransformation(new Transformation());
232
assignTo(comp.getTransformation());
235
public void assignIdentity() {
236
matrixChanged = true;
237
Rn.setIdentityMatrix(matrix);
240
public double getDeterminant() {
241
return Rn.determinant(matrix);
244
public double getTrace() {
245
return Rn.trace(matrix);
248
public double getEntry(int row, int column) {
249
return matrix[4 * row + column];
252
public void setEntry(int row, int column, double value) {
253
if (matrix[4 * row + column] != value) matrixChanged = true;
254
matrix[4 * row + column] = value;
257
public double[] getRow(int i) {
258
return new double[] { matrix[4 * i], matrix[4 * i + 1],
259
matrix[4 * i + 2], matrix[4 * i + 3] };
262
public void setRow(int i, double[] v) {
263
matrixChanged = true;
264
matrix[4 * i] = v[0];
265
matrix[4 * i + 1] = v[1];
266
matrix[4 * i + 2] = v[2];
267
matrix[4 * i + 3] = v[3];
270
public double[] getColumn(int i) {
271
return new double[] { matrix[i], matrix[i + 4], matrix[i + 8],
276
* assigns the values of the ith column with the values from v.
277
* if v.length == 3, then the 4th entry of the column is set to 0.
281
public void setColumn(int i, double[] v) {
282
matrixChanged = true;
284
matrix[i + 4] = v[1];
285
matrix[i + 8] = v[2];
286
matrix[i + 12] = (v.length > 3) ? v[3] : 0;
291
* @return reference to the current matrix
293
public double[] getArray() {
298
* Copy the current matrix into <i>aMatrix</i> and return it.
300
* @return the filled in matrix
302
public double[] writeToArray(double[] aMatrix) {
303
if (aMatrix != null && aMatrix.length != 16)
304
throw new IllegalArgumentException("matrix must have length 16");
305
double[] copy = aMatrix == null ? new double[16] : aMatrix;
306
System.arraycopy(matrix, 0, copy, 0, 16);
311
* Let M be the current matrix. Then form the matrix product M*T and store it in M.
315
public void multiplyOnRight(double[] T) {
316
matrixChanged = true;
317
Rn.times(matrix, matrix, T);
321
* Let M be the current matrix. Then form the matrix product M*T and store it in M.
325
public void multiplyOnRight(Matrix T) {
326
multiplyOnRight(T.matrix);
330
* Let M be the current matrix. Then form the matrix product T*M and store it in M.
333
public void multiplyOnLeft(double[] T) {
334
matrixChanged = true;
335
Rn.times(matrix, T, matrix);
339
* Let M be the current matrix. Then form the matrix product T*M and store it in M.
342
public void multiplyOnLeft(Matrix T) {
343
multiplyOnLeft(T.matrix);
347
* Let M be the current Matrix.
349
* assigns T * M * T^-1
353
public void conjugateBy(Matrix T) {
354
matrixChanged = true;
355
Rn.conjugateByMatrix(matrix, matrix, T.matrix);
359
* Let M be the current Matrix.
363
* @param T the matrix to add
365
public void add(Matrix T) {
366
matrixChanged = true;
367
Rn.add(matrix, matrix, T.matrix);
371
* Let M be the current Matrix.
375
* @param T the matrix to subtract
377
public void subtract(Matrix T) {
378
matrixChanged = true;
379
Rn.subtract(matrix, matrix, T.matrix);
383
* Let M be the current Matrix.
387
* @param f the scalar to multiply M with
389
public void times(double f) {
390
matrixChanged = true;
391
Rn.times(matrix, f, matrix);
394
public Matrix getInverse() {
395
return new Matrix(Rn.inverse(null, matrix));
398
public void invert() {
399
matrixChanged = true;
400
Rn.inverse(matrix, matrix);
403
public Matrix getTranspose() {
404
return new Matrix(Rn.transpose(null, matrix));
407
public void transpose() {
408
matrixChanged = true;
409
Rn.transpose(matrix, matrix);
413
* Form the matrix-vector product <i>M.v</i> (<i>v</i> is column vector on the right).
414
* @param v the vector v
416
*/public double[] multiplyVector(double[] v) {
417
return Rn.matrixTimesVector(null, matrix, v);
421
* Form the matrix-vector product <i>M.v</i> (<i>v</i> is column vector on the right) and assign it to v.
422
* @param vector the vector to transform
423
*/public void transformVector(double[] v) {
424
Rn.matrixTimesVector(v, matrix, v);
427
public boolean equals(Matrix T) {
428
return Rn.equals(matrix, T.matrix);
431
public String toString() {
432
return Rn.matrixToString(matrix);
435
public boolean containsNanOrInfinite() {
436
for (double v : matrix) if (Double.isNaN(v) || Double.isInfinite(v)) return true;
b'\\ No newline at end of file'