001: /* AUTO-GENERATED */
002: package JSci.maths.matrices;
003:
004: import JSci.GlobalSettings;
005: import JSci.maths.ExtraMath;
006: import JSci.maths.Mapping;
007: import JSci.maths.DimensionException;
008: import JSci.maths.vectors.AbstractIntegerVector;
009: import JSci.maths.vectors.IntegerVector;
010: import JSci.maths.groups.AbelianGroup;
011: import JSci.maths.algebras.*;
012: import JSci.maths.fields.*;
013:
014: /**
015: * The AbstractIntegerMatrix class provides an object for encapsulating integer matrices.
016: * @version 2.2
017: * @author Mark Hale
018: */
019: public abstract class AbstractIntegerMatrix extends Matrix {
020: /**
021: * Constructs a matrix.
022: */
023: protected AbstractIntegerMatrix(final int rows, final int cols) {
024: super (rows, cols);
025: }
026:
027: /**
028: * Compares two ${nativeTyp} matrices for equality.
029: * @param obj a int matrix
030: */
031: public final boolean equals(Object obj) {
032: if (obj instanceof AbstractIntegerMatrix) {
033: return equals((AbstractIntegerMatrix) obj);
034: } else {
035: return false;
036: }
037: }
038:
039: /**
040: * Compares two ${nativeTyp} matrices for equality.
041: * Two matrices are considered to be equal if the Frobenius norm of their difference is within the zero tolerance.
042: * @param m a int matrix
043: */
044: public final boolean equals(AbstractIntegerMatrix m) {
045: return equals(m, GlobalSettings.ZERO_TOL);
046: }
047:
048: public boolean equals(AbstractIntegerMatrix m, double tol) {
049: if (m != null && numRows == m.rows() && numCols == m.columns()) {
050: int sumSqr = 0;
051: for (int i = 0; i < numRows; i++) {
052: for (int j = 0; j < numCols; j++) {
053: int delta = getElement(i, j) - m.getElement(i, j);
054: sumSqr += delta * delta;
055: }
056: }
057: return (sumSqr <= tol * tol);
058: } else {
059: return false;
060: }
061: }
062:
063: /**
064: * Returns a string representing this matrix.
065: */
066: public String toString() {
067: final StringBuffer buf = new StringBuffer(5 * numRows * numCols);
068: for (int i = 0; i < numRows; i++) {
069: for (int j = 0; j < numCols; j++) {
070: buf.append(getElement(i, j));
071: buf.append(' ');
072: }
073: buf.append('\n');
074: }
075: return buf.toString();
076: }
077:
078: /**
079: * Returns a hashcode for this matrix.
080: */
081: public int hashCode() {
082: return (int) Math.exp(infNorm());
083: }
084:
085: /**
086: * Converts this matrix to a double matrix.
087: * @return a double matrix
088: */
089: public AbstractDoubleMatrix toDoubleMatrix() {
090: final double ans[][] = new double[numRows][numCols];
091: for (int i = 0; i < numRows; i++) {
092: for (int j = 0; j < numCols; j++)
093: ans[i][j] = getElement(i, j);
094: }
095: return new DoubleMatrix(ans);
096: }
097:
098: /**
099: * Converts this matrix to a complex matrix.
100: * @return a complex matrix
101: */
102: public AbstractComplexMatrix toComplexMatrix() {
103: ComplexMatrix cm = new ComplexMatrix(numRows, numCols);
104: for (int i = 0; i < numRows; i++) {
105: for (int j = 0; j < numCols; j++)
106: cm.setElement(i, j, getElement(i, j), 0.0);
107: }
108: return cm;
109: }
110:
111: /**
112: * Returns an element of the matrix.
113: * @param i row index of the element
114: * @param j column index of the element
115: * @exception MatrixDimensionException If attempting to access an invalid element.
116: */
117: public abstract int getElement(int i, int j);
118:
119: /**
120: * Sets the value of an element of the matrix.
121: * Should only be used to initialise this matrix.
122: * @param i row index of the element
123: * @param j column index of the element
124: * @param x a number
125: * @exception MatrixDimensionException If attempting to access an invalid element.
126: */
127: public abstract void setElement(int i, int j, int x);
128:
129: public final Object getSet() {
130: return IntegerMatrixAlgebra.get(numRows, numCols);
131: }
132:
133: /**
134: * Returns the l<sup><img border=0 alt="infinity" src="doc-files/infinity.gif"></sup>-norm.
135: * @author Taber Smith
136: */
137: public int infNorm() {
138: int result = 0, tmpResult;
139: for (int i = 0; i < numRows; i++) {
140: tmpResult = 0;
141: for (int j = 0; j < numCols; j++)
142: tmpResult += Math.abs(getElement(i, j));
143: if (tmpResult > result)
144: result = tmpResult;
145: }
146: return result;
147: }
148:
149: /**
150: * Returns the Frobenius or Hilbert-Schmidt (l<sup>2</sup>) norm.
151: * @jsci.planetmath FrobeniusMatrixNorm
152: */
153: public double frobeniusNorm() {
154: double result = 0.0;
155: for (int j, i = 0; i < numRows; i++) {
156: for (j = 0; j < numCols; j++)
157: result = ExtraMath.hypot(result, getElement(i, j));
158: }
159: return result;
160: }
161:
162: //============
163: // OPERATIONS
164: //============
165:
166: /**
167: * Returns the negative of this matrix.
168: */
169: public AbelianGroup.Member negate() {
170: final int array[][] = new int[numRows][numCols];
171: for (int i = 0; i < numRows; i++) {
172: array[i][0] = -getElement(i, 0);
173: for (int j = 1; j < numCols; j++)
174: array[i][j] = -getElement(i, j);
175: }
176: return new IntegerMatrix(array);
177: }
178:
179: // ADDITION
180:
181: /**
182: * Returns the addition of this matrix and another.
183: */
184: public final AbelianGroup.Member add(final AbelianGroup.Member m) {
185: if (m instanceof AbstractIntegerMatrix)
186: return add((AbstractIntegerMatrix) m);
187: else
188: throw new IllegalArgumentException(
189: "Member class not recognised by this method.");
190: }
191:
192: /**
193: * Returns the addition of this matrix and another.
194: * @param m a int matrix
195: * @exception MatrixDimensionException If the matrices are different sizes.
196: */
197: public AbstractIntegerMatrix add(final AbstractIntegerMatrix m) {
198: if (numRows == m.rows() && numCols == m.columns()) {
199: final int array[][] = new int[numRows][numCols];
200: for (int i = 0; i < numRows; i++) {
201: array[i][0] = getElement(i, 0) + m.getElement(i, 0);
202: for (int j = 1; j < numCols; j++)
203: array[i][j] = getElement(i, j) + m.getElement(i, j);
204: }
205: return new IntegerMatrix(array);
206: } else {
207: throw new MatrixDimensionException(
208: "Matrices are different sizes.");
209: }
210: }
211:
212: // SUBTRACTION
213:
214: /**
215: * Returns the subtraction of this matrix by another.
216: */
217: public final AbelianGroup.Member subtract(
218: final AbelianGroup.Member m) {
219: if (m instanceof AbstractIntegerMatrix)
220: return subtract((AbstractIntegerMatrix) m);
221: else
222: throw new IllegalArgumentException(
223: "Member class not recognised by this method.");
224: }
225:
226: /**
227: * Returns the subtraction of this matrix by another.
228: * @param m a int matrix
229: * @exception MatrixDimensionException If the matrices are different sizes.
230: */
231: public AbstractIntegerMatrix subtract(final AbstractIntegerMatrix m) {
232: if (numRows == m.rows() && numCols == m.columns()) {
233: final int array[][] = new int[numRows][numCols];
234: for (int i = 0; i < numRows; i++) {
235: array[i][0] = getElement(i, 0) - m.getElement(i, 0);
236: for (int j = 1; j < numCols; j++)
237: array[i][j] = getElement(i, j) - m.getElement(i, j);
238: }
239: return new IntegerMatrix(array);
240: } else {
241: throw new MatrixDimensionException(
242: "Matrices are different sizes.");
243: }
244: }
245:
246: // SCALAR MULTIPLICATION
247:
248: /**
249: * Returns the multiplication of this matrix by a scalar.
250: */
251: public final Module.Member scalarMultiply(Ring.Member x) {
252: if (x instanceof Number) {
253: return scalarMultiply(((Number) x).intValue());
254: } else {
255: throw new IllegalArgumentException(
256: "Member class not recognised by this method.");
257: }
258: }
259:
260: /**
261: * Returns the multiplication of this matrix by a scalar.
262: * @param x a int.
263: * @return a int matrix.
264: */
265: public AbstractIntegerMatrix scalarMultiply(final int x) {
266: final int array[][] = new int[numRows][numCols];
267: for (int i = 0; i < numRows; i++) {
268: array[i][0] = x * getElement(i, 0);
269: for (int j = 1; j < numCols; j++)
270: array[i][j] = x * getElement(i, j);
271: }
272: return new IntegerMatrix(array);
273: }
274:
275: // SCALAR DIVISON
276:
277: /**
278: * Returns the division of this matrix by a scalar.
279: * Always throws an exception.
280: */
281: public final VectorSpace.Member scalarDivide(Field.Member x) {
282: throw new UnsupportedOperationException("Not an algebra");
283: }
284:
285: // SCALAR PRODUCT
286:
287: /**
288: * Returns the scalar product of this matrix and another.
289: * @param m a int matrix.
290: * @exception MatrixDimensionException If the matrices are different sizes.
291: */
292: public int scalarProduct(final AbstractIntegerMatrix m) {
293: if (numRows == m.rows() && numCols == m.columns()) {
294: int ans = 0;
295: for (int i = 0; i < numRows; i++) {
296: ans += getElement(i, 0) * m.getElement(i, 0);
297: for (int j = 1; j < numCols; j++)
298: ans += getElement(i, j) * m.getElement(i, j);
299: }
300: return ans;
301: } else {
302: throw new MatrixDimensionException(
303: "Matrices are different sizes.");
304: }
305: }
306:
307: // MATRIX MULTIPLICATION
308:
309: /**
310: * Returns the multiplication of a vector by this matrix.
311: * @param v a int vector.
312: * @exception DimensionException If the matrix and vector are incompatible.
313: */
314: public AbstractIntegerVector multiply(final AbstractIntegerVector v) {
315: if (numCols == v.dimension()) {
316: final int array[] = new int[numRows];
317: for (int i = 0; i < numRows; i++) {
318: array[i] = getElement(i, 0) * v.getComponent(0);
319: for (int j = 1; j < numCols; j++)
320: array[i] += getElement(i, j) * v.getComponent(j);
321: }
322: return new IntegerVector(array);
323: } else {
324: throw new DimensionException(
325: "Matrix and vector are incompatible.");
326: }
327: }
328:
329: /**
330: * Returns the multiplication of this matrix and another.
331: */
332: public final Ring.Member multiply(final Ring.Member m) {
333: if (m instanceof AbstractIntegerMatrix)
334: return multiply((AbstractIntegerMatrix) m);
335: else
336: throw new IllegalArgumentException(
337: "Member class not recognised by this method.");
338: }
339:
340: /**
341: * Returns the multiplication of this matrix and another.
342: * @param m a int matrix
343: * @return a AbstractIntegerMatrix or a AbstractIntegerSquareMatrix as appropriate
344: * @exception MatrixDimensionException If the matrices are incompatible.
345: */
346: public AbstractIntegerMatrix multiply(final AbstractIntegerMatrix m) {
347: if (numCols == m.rows()) {
348: final int mColumns = m.columns();
349: final int array[][] = new int[numRows][mColumns];
350: for (int j = 0; j < numRows; j++) {
351: for (int k = 0; k < mColumns; k++) {
352: array[j][k] = getElement(j, 0) * m.getElement(0, k);
353: for (int n = 1; n < numCols; n++)
354: array[j][k] += getElement(j, n)
355: * m.getElement(n, k);
356: }
357: }
358: if (numRows == mColumns)
359: return new IntegerSquareMatrix(array);
360: else
361: return new IntegerMatrix(array);
362: } else {
363: throw new MatrixDimensionException("Incompatible matrices.");
364: }
365: }
366:
367: // DIRECT SUM
368:
369: /**
370: * Returns the direct sum of this matrix and another.
371: */
372: public AbstractIntegerMatrix directSum(final AbstractIntegerMatrix m) {
373: final int array[][] = new int[numRows + m.numRows][numCols
374: + m.numCols];
375: for (int i = 0; i < numRows; i++) {
376: for (int j = 0; j < numCols; j++)
377: array[i][j] = getElement(i, j);
378: }
379: for (int i = 0; i < m.numRows; i++) {
380: for (int j = 0; j < m.numCols; j++)
381: array[i + numRows][j + numCols] = m.getElement(i, j);
382: }
383: return new IntegerMatrix(array);
384: }
385:
386: // TENSOR PRODUCT
387:
388: /**
389: * Returns the tensor product of this matrix and another.
390: */
391: public AbstractIntegerMatrix tensor(final AbstractIntegerMatrix m) {
392: final int array[][] = new int[numRows * m.numRows][numCols
393: * m.numCols];
394: for (int i = 0; i < numRows; i++) {
395: for (int j = 0; j < numCols; j++) {
396: for (int k = 0; k < m.numRows; j++) {
397: for (int l = 0; l < m.numCols; l++)
398: array[i * m.numRows + k][j * m.numCols + l] = getElement(
399: i, j)
400: * m.getElement(k, l);
401: }
402: }
403: }
404: return new IntegerMatrix(array);
405: }
406:
407: // TRANSPOSE
408:
409: /**
410: * Returns the transpose of this matrix.
411: * @return a int matrix
412: */
413: public Matrix transpose() {
414: final int array[][] = new int[numCols][numRows];
415: for (int i = 0; i < numRows; i++) {
416: array[0][i] = getElement(i, 0);
417: for (int j = 1; j < numCols; j++)
418: array[j][i] = getElement(i, j);
419: }
420: return new IntegerMatrix(array);
421: }
422:
423: }
|