You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mahout.apache.org by gs...@apache.org on 2009/11/23 16:14:38 UTC
svn commit: r883365 [28/47] - in /lucene/mahout/trunk: ./ examples/ matrix/
matrix/src/ matrix/src/main/ matrix/src/main/java/
matrix/src/main/java/org/ matrix/src/main/java/org/apache/
matrix/src/main/java/org/apache/mahout/ matrix/src/main/java/org/a...
Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleMatrix3D.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleMatrix3D.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleMatrix3D.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleMatrix3D.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,973 @@
+/*
+Copyright � 1999 CERN - European Organization for Nuclear Research.
+Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose
+is hereby granted without fee, provided that the above copyright notice appear in all copies and
+that both that copyright notice and this permission notice appear in supporting documentation.
+CERN makes no representations about the suitability of this software for any purpose.
+It is provided "as is" without expressed or implied warranty.
+*/
+package org.apache.mahout.colt.matrix;
+
+import org.apache.mahout.colt.list.DoubleArrayList;
+import org.apache.mahout.colt.list.IntArrayList;
+import org.apache.mahout.colt.matrix.impl.AbstractMatrix3D;
+/**
+Abstract base class for 3-d matrices holding <tt>double</tt> elements.
+First see the <a href="package-summary.html">package summary</a> and javadoc <a href="package-tree.html">tree view</a> to get the broad picture.
+<p>
+A matrix has a number of slices, rows and columns, which are assigned upon instance construction - The matrix's size is then <tt>slices()*rows()*columns()</tt>.
+Elements are accessed via <tt>[slice,row,column]</tt> coordinates.
+Legal coordinates range from <tt>[0,0,0]</tt> to <tt>[slices()-1,rows()-1,columns()-1]</tt>.
+Any attempt to access an element at a coordinate <tt>slice<0 || slice>=slices() || row<0 || row>=rows() || column<0 || column>=column()</tt> will throw an <tt>IndexOutOfBoundsException</tt>.
+<p>
+<b>Note</b> that this implementation is not synchronized.
+
+@author wolfgang.hoschek@cern.ch
+@version 1.0, 09/24/99
+*/
+/**
+ * @deprecated until unit tests are in place. Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public abstract class DoubleMatrix3D extends AbstractMatrix3D {
+/**
+ * Makes this class non instantiable, but still let's others inherit from it.
+ */
+protected DoubleMatrix3D() {}
+/**
+Applies a function to each cell and aggregates the results.
+Returns a value <tt>v</tt> such that <tt>v==a(size())</tt> where <tt>a(i) == aggr( a(i-1), f(get(slice,row,column)) )</tt> and terminators are <tt>a(1) == f(get(0,0,0)), a(0)==Double.NaN</tt>.
+<p>
+<b>Example:</b>
+<pre>
+org.apache.mahout.jet.math.Functions F = org.apache.mahout.jet.math.Functions.functions;
+2 x 2 x 2 matrix
+0 1
+2 3
+
+4 5
+6 7
+
+// Sum( x[slice,row,col]*x[slice,row,col] )
+matrix.aggregate(F.plus,F.square);
+--> 140
+</pre>
+For further examples, see the <a href="package-summary.html#FunctionObjects">package doc</a>.
+
+@param aggr an aggregation function taking as first argument the current aggregation and as second argument the transformed current cell value.
+@param f a function transforming the current cell value.
+@return the aggregated measure.
+@see org.apache.mahout.jet.math.Functions
+*/
+public double aggregate(org.apache.mahout.colt.function.DoubleDoubleFunction aggr, org.apache.mahout.colt.function.DoubleFunction f) {
+ if (size()==0) return Double.NaN;
+ double a = f.apply(getQuick(slices-1,rows-1,columns-1));
+ int d = 1; // last cell already done
+ for (int slice=slices; --slice >= 0; ) {
+ for (int row=rows; --row >= 0; ) {
+ for (int column=columns-d; --column >= 0; ) {
+ a = aggr.apply(a, f.apply(getQuick(slice,row,column)));
+ }
+ d = 0;
+ }
+ }
+ return a;
+}
+/**
+Applies a function to each corresponding cell of two matrices and aggregates the results.
+Returns a value <tt>v</tt> such that <tt>v==a(size())</tt> where <tt>a(i) == aggr( a(i-1), f(get(slice,row,column),other.get(slice,row,column)) )</tt> and terminators are <tt>a(1) == f(get(0,0,0),other.get(0,0,0)), a(0)==Double.NaN</tt>.
+<p>
+<b>Example:</b>
+<pre>
+org.apache.mahout.jet.math.Functions F = org.apache.mahout.jet.math.Functions.functions;
+x = 2 x 2 x 2 matrix
+0 1
+2 3
+
+4 5
+6 7
+
+y = 2 x 2 x 2 matrix
+0 1
+2 3
+
+4 5
+6 7
+
+// Sum( x[slice,row,col] * y[slice,row,col] )
+x.aggregate(y, F.plus, F.mult);
+--> 140
+
+// Sum( (x[slice,row,col] + y[slice,row,col])^2 )
+x.aggregate(y, F.plus, F.chain(F.square,F.plus));
+--> 560
+</pre>
+For further examples, see the <a href="package-summary.html#FunctionObjects">package doc</a>.
+
+@param aggr an aggregation function taking as first argument the current aggregation and as second argument the transformed current cell values.
+@param f a function transforming the current cell values.
+@return the aggregated measure.
+@throws IllegalArgumentException if <tt>slices() != other.slices() || rows() != other.rows() || columns() != other.columns()</tt>
+@see org.apache.mahout.jet.math.Functions
+*/
+public double aggregate(DoubleMatrix3D other, org.apache.mahout.colt.function.DoubleDoubleFunction aggr, org.apache.mahout.colt.function.DoubleDoubleFunction f) {
+ checkShape(other);
+ if (size()==0) return Double.NaN;
+ double a = f.apply(getQuick(slices-1,rows-1,columns-1),other.getQuick(slices-1,rows-1,columns-1));
+ int d = 1; // last cell already done
+ for (int slice=slices; --slice >= 0; ) {
+ for (int row=rows; --row >= 0; ) {
+ for (int column=columns-d; --column >= 0; ) {
+ a = aggr.apply(a, f.apply(getQuick(slice,row,column), other.getQuick(slice,row,column)));
+ }
+ d = 0;
+ }
+ }
+ return a;
+}
+/**
+ * Sets all cells to the state specified by <tt>values</tt>.
+ * <tt>values</tt> is required to have the form <tt>values[slice][row][column]</tt>
+ * and have exactly the same number of slices, rows and columns as the receiver.
+ * <p>
+ * The values are copied. So subsequent changes in <tt>values</tt> are not reflected in the matrix, and vice-versa.
+ *
+ * @param values the values to be filled into the cells.
+ * @return <tt>this</tt> (for convenience only).
+ * @throws IllegalArgumentException if <tt>values.length != slices() || for any 0 <= slice < slices(): values[slice].length != rows()</tt>.
+ * @throws IllegalArgumentException if <tt>for any 0 <= column < columns(): values[slice][row].length != columns()</tt>.
+ */
+public DoubleMatrix3D assign(double[][][] values) {
+ if (values.length != slices) throw new IllegalArgumentException("Must have same number of slices: slices="+values.length+"slices()="+slices());
+ for (int slice=slices; --slice >= 0;) {
+ double[][] currentSlice = values[slice];
+ if (currentSlice.length != rows) throw new IllegalArgumentException("Must have same number of rows in every slice: rows="+currentSlice.length+"rows()="+rows());
+ for (int row=rows; --row >= 0;) {
+ double[] currentRow = currentSlice[row];
+ if (currentRow.length != columns) throw new IllegalArgumentException("Must have same number of columns in every row: columns="+currentRow.length+"columns()="+columns());
+ for (int column=columns; --column >= 0;) {
+ setQuick(slice,row,column,currentRow[column]);
+ }
+ }
+ }
+ return this;
+}
+/**
+ * Sets all cells to the state specified by <tt>value</tt>.
+ * @param value the value to be filled into the cells.
+ * @return <tt>this</tt> (for convenience only).
+ */
+public DoubleMatrix3D assign(double value) {
+ for (int slice=slices; --slice >= 0;) {
+ for (int row=rows; --row >= 0;) {
+ for (int column=columns; --column >= 0;) {
+ setQuick(slice,row,column,value);
+ }
+ }
+ }
+ return this;
+}
+/**
+Assigns the result of a function to each cell; <tt>x[slice,row,col] = function(x[slice,row,col])</tt>.
+<p>
+<b>Example:</b>
+<pre>
+matrix = 1 x 2 x 2 matrix
+0.5 1.5
+2.5 3.5
+
+// change each cell to its sine
+matrix.assign(org.apache.mahout.jet.math.Functions.sin);
+-->
+1 x 2 x 2 matrix
+0.479426 0.997495
+0.598472 -0.350783
+</pre>
+For further examples, see the <a href="package-summary.html#FunctionObjects">package doc</a>.
+
+@param function a function object taking as argument the current cell's value.
+@return <tt>this</tt> (for convenience only).
+@see org.apache.mahout.jet.math.Functions
+*/
+public DoubleMatrix3D assign(org.apache.mahout.colt.function.DoubleFunction function) {
+ for (int slice=slices; --slice >= 0; ) {
+ for (int row=rows; --row >= 0; ) {
+ for (int column=columns; --column >= 0; ) {
+ setQuick(slice,row,column, function.apply(getQuick(slice,row,column)));
+ }
+ }
+ }
+ return this;
+}
+/**
+ * Replaces all cell values of the receiver with the values of another matrix.
+ * Both matrices must have the same number of slices, rows and columns.
+ * If both matrices share the same cells (as is the case if they are views derived from the same matrix) and intersect in an ambiguous way, then replaces <i>as if</i> using an intermediate auxiliary deep copy of <tt>other</tt>.
+ *
+ * @param other the source matrix to copy from (may be identical to the receiver).
+ * @return <tt>this</tt> (for convenience only).
+ * @throws IllegalArgumentException if <tt>slices() != other.slices() || rows() != other.rows() || columns() != other.columns()</tt>
+ */
+public DoubleMatrix3D assign(DoubleMatrix3D other) {
+ if (other==this) return this;
+ checkShape(other);
+ if (haveSharedCells(other)) other = other.copy();
+
+ for (int slice=slices; --slice >= 0;) {
+ for (int row=rows; --row >= 0;) {
+ for (int column=columns; --column >= 0;) {
+ setQuick(slice,row,column,other.getQuick(slice,row,column));
+ }
+ }
+ }
+ return this;
+}
+/**
+Assigns the result of a function to each cell; <tt>x[row,col] = function(x[row,col],y[row,col])</tt>.
+<p>
+<b>Example:</b>
+<pre>
+// assign x[row,col] = x[row,col]<sup>y[row,col]</sup>
+m1 = 1 x 2 x 2 matrix
+0 1
+2 3
+
+m2 = 1 x 2 x 2 matrix
+0 2
+4 6
+
+m1.assign(m2, org.apache.mahout.jet.math.Functions.pow);
+-->
+m1 == 1 x 2 x 2 matrix
+ 1 1
+16 729
+</pre>
+For further examples, see the <a href="package-summary.html#FunctionObjects">package doc</a>.
+
+@param y the secondary matrix to operate on.
+@param function a function object taking as first argument the current cell's value of <tt>this</tt>,
+and as second argument the current cell's value of <tt>y</tt>,
+@return <tt>this</tt> (for convenience only).
+@throws IllegalArgumentException if <tt>slices() != other.slices() || rows() != other.rows() || columns() != other.columns()</tt>
+@see org.apache.mahout.jet.math.Functions
+*/
+public DoubleMatrix3D assign(DoubleMatrix3D y, org.apache.mahout.colt.function.DoubleDoubleFunction function) {
+ checkShape(y);
+ for (int slice=slices; --slice >= 0; ) {
+ for (int row=rows; --row >= 0; ) {
+ for (int column=columns; --column >= 0; ) {
+ setQuick(slice,row,column, function.apply(getQuick(slice,row,column), y.getQuick(slice,row,column)));
+ }
+ }
+ }
+ return this;
+}
+/**
+ * Returns the number of cells having non-zero values; ignores tolerance.
+ */
+public int cardinality() {
+ int cardinality = 0;
+ for (int slice=slices; --slice >= 0;) {
+ for (int row=rows; --row >= 0;) {
+ for (int column=columns; --column >= 0;) {
+ if (getQuick(slice,row,column) != 0) cardinality++;
+ }
+ }
+ }
+ return cardinality;
+}
+/**
+ * Constructs and returns a deep copy of the receiver.
+ * <p>
+ * <b>Note that the returned matrix is an independent deep copy.</b>
+ * The returned matrix is not backed by this matrix, so changes in the returned matrix are not reflected in this matrix, and vice-versa.
+ *
+ * @return a deep copy of the receiver.
+ */
+public DoubleMatrix3D copy() {
+ return like().assign(this);
+}
+/**
+ * Returns whether all cells are equal to the given value.
+ *
+ * @param value the value to test against.
+ * @return <tt>true</tt> if all cells are equal to the given value, <tt>false</tt> otherwise.
+ */
+public boolean equals(double value) {
+ return org.apache.mahout.colt.matrix.linalg.Property.DEFAULT.equals(this,value);
+}
+/**
+ * Compares this object against the specified object.
+ * The result is <code>true</code> if and only if the argument is
+ * not <code>null</code> and is at least a <code>DoubleMatrix3D</code> object
+ * that has the same number of slices, rows and columns as the receiver and
+ * has exactly the same values at the same coordinates.
+ * @param obj the object to compare with.
+ * @return <code>true</code> if the objects are the same;
+ * <code>false</code> otherwise.
+ */
+public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (!(obj instanceof DoubleMatrix3D)) return false;
+
+ return org.apache.mahout.colt.matrix.linalg.Property.DEFAULT.equals(this,(DoubleMatrix3D) obj);
+}
+/**
+ * Returns the matrix cell value at coordinate <tt>[slice,row,column]</tt>.
+ *
+ * @param slice the index of the slice-coordinate.
+ * @param row the index of the row-coordinate.
+ * @param column the index of the column-coordinate.
+ * @return the value of the specified cell.
+ * @throws IndexOutOfBoundsException if <tt>slice<0 || slice>=slices() || row<0 || row>=rows() || column<0 || column>=column()</tt>.
+ */
+public double get(int slice, int row, int column) {
+ if (slice<0 || slice>=slices || row<0 || row>=rows || column<0 || column>=columns) throw new IndexOutOfBoundsException("slice:"+slice+", row:"+row+", column:"+column);
+ return getQuick(slice,row,column);
+}
+/**
+ * Returns the content of this matrix if it is a wrapper; or <tt>this</tt> otherwise.
+ * Override this method in wrappers.
+ */
+protected DoubleMatrix3D getContent() {
+ return this;
+}
+/**
+Fills the coordinates and values of cells having non-zero values into the specified lists.
+Fills into the lists, starting at index 0.
+After this call returns the specified lists all have a new size, the number of non-zero values.
+<p>
+In general, fill order is <i>unspecified</i>.
+This implementation fill like: <tt>for (slice = 0..slices-1) for (row = 0..rows-1) for (column = 0..colums-1) do ... </tt>.
+However, subclasses are free to us any other order, even an order that may change over time as cell values are changed.
+(Of course, result lists indexes are guaranteed to correspond to the same cell).
+For an example, see {@link DoubleMatrix2D#getNonZeros(IntArrayList,IntArrayList,DoubleArrayList)}.
+
+@param sliceList the list to be filled with slice indexes, can have any size.
+@param rowList the list to be filled with row indexes, can have any size.
+@param columnList the list to be filled with column indexes, can have any size.
+@param valueList the list to be filled with values, can have any size.
+*/
+public void getNonZeros(IntArrayList sliceList, IntArrayList rowList, IntArrayList columnList, DoubleArrayList valueList) {
+ sliceList.clear();
+ rowList.clear();
+ columnList.clear();
+ valueList.clear();
+ int s = slices;
+ int r = rows;
+ int c = columns;
+ for (int slice=0; slice < s; slice++) {
+ for (int row=0; row < r; row++) {
+ for (int column=0; column < c; column++) {
+ double value = getQuick(slice,row,column);
+ if (value != 0) {
+ sliceList.add(slice);
+ rowList.add(row);
+ columnList.add(column);
+ valueList.add(value);
+ }
+ }
+ }
+ }
+}
+/**
+ * Returns the matrix cell value at coordinate <tt>[slice,row,column]</tt>.
+ *
+ * <p>Provided with invalid parameters this method may return invalid objects without throwing any exception.
+ * <b>You should only use this method when you are absolutely sure that the coordinate is within bounds.</b>
+ * Precondition (unchecked): <tt>slice<0 || slice>=slices() || row<0 || row>=rows() || column<0 || column>=column()</tt>.
+ *
+ * @param slice the index of the slice-coordinate.
+ * @param row the index of the row-coordinate.
+ * @param column the index of the column-coordinate.
+ * @return the value at the specified coordinate.
+ */
+public abstract double getQuick(int slice, int row, int column);
+/**
+ * Returns <tt>true</tt> if both matrices share at least one identical cell.
+ */
+protected boolean haveSharedCells(DoubleMatrix3D other) {
+ if (other==null) return false;
+ if (this==other) return true;
+ return getContent().haveSharedCellsRaw(other.getContent());
+}
+/**
+ * Returns <tt>true</tt> if both matrices share at least one identical cell.
+ */
+protected boolean haveSharedCellsRaw(DoubleMatrix3D other) {
+ return false;
+}
+/**
+ * Construct and returns a new empty matrix <i>of the same dynamic type</i> as the receiver, having the same number of slices, rows and columns.
+ * For example, if the receiver is an instance of type <tt>DenseDoubleMatrix3D</tt> the new matrix must also be of type <tt>DenseDoubleMatrix3D</tt>,
+ * if the receiver is an instance of type <tt>SparseDoubleMatrix3D</tt> the new matrix must also be of type <tt>SparseDoubleMatrix3D</tt>, etc.
+ * In general, the new matrix should have internal parametrization as similar as possible.
+ *
+ * @return a new empty matrix of the same dynamic type.
+ */
+public DoubleMatrix3D like() {
+ return like(slices,rows,columns);
+}
+/**
+ * Construct and returns a new empty matrix <i>of the same dynamic type</i> as the receiver, having the specified number of slices, rows and columns.
+ * For example, if the receiver is an instance of type <tt>DenseDoubleMatrix3D</tt> the new matrix must also be of type <tt>DenseDoubleMatrix3D</tt>,
+ * if the receiver is an instance of type <tt>SparseDoubleMatrix3D</tt> the new matrix must also be of type <tt>SparseDoubleMatrix3D</tt>, etc.
+ * In general, the new matrix should have internal parametrization as similar as possible.
+ *
+ * @param slices the number of slices the matrix shall have.
+ * @param rows the number of rows the matrix shall have.
+ * @param columns the number of columns the matrix shall have.
+ * @return a new empty matrix of the same dynamic type.
+ */
+public abstract DoubleMatrix3D like(int slices, int rows, int columns);
+/**
+ * Construct and returns a new 2-d matrix <i>of the corresponding dynamic type</i>, sharing the same cells.
+ * For example, if the receiver is an instance of type <tt>DenseDoubleMatrix3D</tt> the new matrix must also be of type <tt>DenseDoubleMatrix2D</tt>,
+ * if the receiver is an instance of type <tt>SparseDoubleMatrix3D</tt> the new matrix must also be of type <tt>SparseDoubleMatrix2D</tt>, etc.
+ *
+ * @param rows the number of rows the matrix shall have.
+ * @param columns the number of columns the matrix shall have.
+ * @param rowZero the position of the first element.
+ * @param columnZero the position of the first element.
+ * @param rowStride the number of elements between two rows, i.e. <tt>index(i+1,j)-index(i,j)</tt>.
+ * @param columnStride the number of elements between two columns, i.e. <tt>index(i,j+1)-index(i,j)</tt>.
+ * @return a new matrix of the corresponding dynamic type.
+ */
+protected abstract DoubleMatrix2D like2D(int rows, int columns, int rowZero, int columnZero, int rowStride, int columnStride);
+/**
+ * Sets the matrix cell at coordinate <tt>[slice,row,column]</tt> to the specified value.
+ *
+ * @param slice the index of the slice-coordinate.
+ * @param row the index of the row-coordinate.
+ * @param column the index of the column-coordinate.
+ * @param value the value to be filled into the specified cell.
+ * @throws IndexOutOfBoundsException if <tt>row<0 || row>=rows() || slice<0 || slice>=slices() || column<0 || column>=column()</tt>.
+ */
+public void set(int slice, int row, int column, double value) {
+ if (slice<0 || slice>=slices || row<0 || row>=rows || column<0 || column>=columns) throw new IndexOutOfBoundsException("slice:"+slice+", row:"+row+", column:"+column);
+ setQuick(slice,row,column,value);
+}
+/**
+ * Sets the matrix cell at coordinate <tt>[slice,row,column]</tt> to the specified value.
+ *
+ * <p>Provided with invalid parameters this method may access illegal indexes without throwing any exception.
+ * <b>You should only use this method when you are absolutely sure that the coordinate is within bounds.</b>
+ * Precondition (unchecked): <tt>slice<0 || slice>=slices() || row<0 || row>=rows() || column<0 || column>=column()</tt>.
+ *
+ * @param slice the index of the slice-coordinate.
+ * @param row the index of the row-coordinate.
+ * @param column the index of the column-coordinate.
+ * @param value the value to be filled into the specified cell.
+ */
+public abstract void setQuick(int slice, int row, int column, double value);
+/**
+ * Constructs and returns a 2-dimensional array containing the cell values.
+ * The returned array <tt>values</tt> has the form <tt>values[slice][row][column]</tt>
+ * and has the same number of slices, rows and columns as the receiver.
+ * <p>
+ * The values are copied. So subsequent changes in <tt>values</tt> are not reflected in the matrix, and vice-versa.
+ *
+ * @return an array filled with the values of the cells.
+ */
+public double[][][] toArray() {
+ double[][][] values = new double[slices][rows][columns];
+ for (int slice=slices; --slice >= 0;) {
+ double[][] currentSlice = values[slice];
+ for (int row=rows; --row >= 0;) {
+ double[] currentRow = currentSlice[row];
+ for (int column=columns; --column >= 0;) {
+ currentRow[column] = getQuick(slice,row,column);
+ }
+ }
+ }
+ return values;
+}
+/**
+ * Returns a string representation using default formatting.
+ * @see org.apache.mahout.colt.matrix.doublealgo.Formatter
+ */
+public String toString() {
+ return new org.apache.mahout.colt.matrix.doublealgo.Formatter().toString(this);
+}
+/**
+ * Constructs and returns a new view equal to the receiver.
+ * The view is a shallow clone. Calls <code>clone()</code> and casts the result.
+ * <p>
+ * <b>Note that the view is not a deep copy.</b>
+ * The returned matrix is backed by this matrix, so changes in the returned matrix are reflected in this matrix, and vice-versa.
+ * <p>
+ * Use {@link #copy()} if you want to construct an independent deep copy rather than a new view.
+ *
+ * @return a new view of the receiver.
+ */
+protected DoubleMatrix3D view() {
+ return (DoubleMatrix3D) clone();
+}
+/**
+Constructs and returns a new 2-dimensional <i>slice view</i> representing the slices and rows of the given column.
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa.
+<p>
+To obtain a slice view on subranges, construct a sub-ranging view (<tt>view().part(...)</tt>), then apply this method to the sub-range view.
+To obtain 1-dimensional views, apply this method, then apply another slice view (methods <tt>viewColumn</tt>, <tt>viewRow</tt>) on the intermediate 2-dimensional view.
+To obtain 1-dimensional views on subranges, apply both steps.
+
+@param column the index of the column to fix.
+@return a new 2-dimensional slice view.
+@throws IndexOutOfBoundsException if <tt>column < 0 || column >= columns()</tt>.
+@see #viewSlice(int)
+@see #viewRow(int)
+*/
+public DoubleMatrix2D viewColumn(int column) {
+ checkColumn(column);
+ int sliceRows = this.slices;
+ int sliceColumns = this.rows;
+
+ //int sliceOffset = index(0,0,column);
+ int sliceRowZero = sliceZero;
+ int sliceColumnZero = rowZero + _columnOffset(_columnRank(column));
+
+ int sliceRowStride = this.sliceStride;
+ int sliceColumnStride = this.rowStride;
+ return like2D(sliceRows,sliceColumns,sliceRowZero,sliceColumnZero,sliceRowStride,sliceColumnStride);
+}
+/**
+Constructs and returns a new <i>flip view</i> along the column axis.
+What used to be column <tt>0</tt> is now column <tt>columns()-1</tt>, ..., what used to be column <tt>columns()-1</tt> is now column <tt>0</tt>.
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa.
+
+@return a new flip view.
+@see #viewSliceFlip()
+@see #viewRowFlip()
+*/
+public DoubleMatrix3D viewColumnFlip() {
+ return (DoubleMatrix3D) (view().vColumnFlip());
+}
+/**
+Constructs and returns a new <i>dice view</i>; Swaps dimensions (axes); Example: 3 x 4 x 5 matrix --> 4 x 3 x 5 matrix.
+The view has dimensions exchanged; what used to be one axis is now another, in all desired permutations.
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa.
+
+@param axis0 the axis that shall become axis 0 (legal values 0..2).
+@param axis1 the axis that shall become axis 1 (legal values 0..2).
+@param axis2 the axis that shall become axis 2 (legal values 0..2).
+@return a new dice view.
+@throws IllegalArgumentException if some of the parameters are equal or not in range 0..2.
+*/
+public DoubleMatrix3D viewDice(int axis0, int axis1, int axis2) {
+ return (DoubleMatrix3D) (view().vDice(axis0,axis1,axis2));
+}
+/**
+Constructs and returns a new <i>sub-range view</i> that is a <tt>depth x height x width</tt> sub matrix starting at <tt>[slice,row,column]</tt>;
+Equivalent to <tt>view().part(slice,row,column,depth,height,width)</tt>; Provided for convenience only.
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa.
+
+@param slice The index of the slice-coordinate.
+@param row The index of the row-coordinate.
+@param column The index of the column-coordinate.
+@param depth The depth of the box.
+@param height The height of the box.
+@param width The width of the box.
+@throws IndexOutOfBoundsException if <tt>slice<0 || depth<0 || slice+depth>slices() || row<0 || height<0 || row+height>rows() || column<0 || width<0 || column+width>columns()</tt>
+@return the new view.
+
+*/
+public DoubleMatrix3D viewPart(int slice, int row, int column, int depth, int height, int width) {
+ return (DoubleMatrix3D) (view().vPart(slice,row,column,depth,height,width));
+}
+/**
+Constructs and returns a new 2-dimensional <i>slice view</i> representing the slices and columns of the given row.
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa.
+<p>
+To obtain a slice view on subranges, construct a sub-ranging view (<tt>view().part(...)</tt>), then apply this method to the sub-range view.
+To obtain 1-dimensional views, apply this method, then apply another slice view (methods <tt>viewColumn</tt>, <tt>viewRow</tt>) on the intermediate 2-dimensional view.
+To obtain 1-dimensional views on subranges, apply both steps.
+
+@param row the index of the row to fix.
+@return a new 2-dimensional slice view.
+@throws IndexOutOfBoundsException if <tt>row < 0 || row >= row()</tt>.
+@see #viewSlice(int)
+@see #viewColumn(int)
+*/
+public DoubleMatrix2D viewRow(int row) {
+ checkRow(row);
+ int sliceRows = this.slices;
+ int sliceColumns = this.columns;
+
+ //int sliceOffset = index(0,row,0);
+ int sliceRowZero = sliceZero ;
+ int sliceColumnZero = columnZero + _rowOffset(_rowRank(row));
+
+ int sliceRowStride = this.sliceStride;
+ int sliceColumnStride = this.columnStride;
+ return like2D(sliceRows,sliceColumns,sliceRowZero,sliceColumnZero,sliceRowStride,sliceColumnStride);
+}
+/**
+Constructs and returns a new <i>flip view</i> along the row axis.
+What used to be row <tt>0</tt> is now row <tt>rows()-1</tt>, ..., what used to be row <tt>rows()-1</tt> is now row <tt>0</tt>.
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa.
+
+@return a new flip view.
+@see #viewSliceFlip()
+@see #viewColumnFlip()
+*/
+public DoubleMatrix3D viewRowFlip() {
+ return (DoubleMatrix3D) (view().vRowFlip());
+}
+/**
+Constructs and returns a new <i>selection view</i> that is a matrix holding the indicated cells.
+There holds <tt>view.slices() == sliceIndexes.length, view.rows() == rowIndexes.length, view.columns() == columnIndexes.length</tt> and
+<tt>view.get(k,i,j) == this.get(sliceIndexes[k],rowIndexes[i],columnIndexes[j])</tt>.
+Indexes can occur multiple times and can be in arbitrary order.
+For an example see {@link DoubleMatrix2D#viewSelection(int[],int[])}.
+<p>
+Note that modifying the index arguments after this call has returned has no effect on the view.
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa.
+
+@param sliceIndexes The slices of the cells that shall be visible in the new view. To indicate that <i>all</i> slices shall be visible, simply set this parameter to <tt>null</tt>.
+@param rowIndexes The rows of the cells that shall be visible in the new view. To indicate that <i>all</i> rows shall be visible, simply set this parameter to <tt>null</tt>.
+@param columnIndexes The columns of the cells that shall be visible in the new view. To indicate that <i>all</i> columns shall be visible, simply set this parameter to <tt>null</tt>.
+@return the new view.
+@throws IndexOutOfBoundsException if <tt>!(0 <= sliceIndexes[i] < slices())</tt> for any <tt>i=0..sliceIndexes.length()-1</tt>.
+@throws IndexOutOfBoundsException if <tt>!(0 <= rowIndexes[i] < rows())</tt> for any <tt>i=0..rowIndexes.length()-1</tt>.
+@throws IndexOutOfBoundsException if <tt>!(0 <= columnIndexes[i] < columns())</tt> for any <tt>i=0..columnIndexes.length()-1</tt>.
+*/
+public DoubleMatrix3D viewSelection(int[] sliceIndexes, int[] rowIndexes, int[] columnIndexes) {
+ // check for "all"
+ if (sliceIndexes==null) {
+ sliceIndexes = new int[slices];
+ for (int i=slices; --i >= 0; ) sliceIndexes[i] = i;
+ }
+ if (rowIndexes==null) {
+ rowIndexes = new int[rows];
+ for (int i=rows; --i >= 0; ) rowIndexes[i] = i;
+ }
+ if (columnIndexes==null) {
+ columnIndexes = new int[columns];
+ for (int i=columns; --i >= 0; ) columnIndexes[i] = i;
+ }
+
+ checkSliceIndexes(sliceIndexes);
+ checkRowIndexes(rowIndexes);
+ checkColumnIndexes(columnIndexes);
+
+ int[] sliceOffsets = new int[sliceIndexes.length];
+ int[] rowOffsets = new int[rowIndexes.length];
+ int[] columnOffsets = new int[columnIndexes.length];
+
+ for (int i=sliceIndexes.length; --i >= 0; ) {
+ sliceOffsets[i] = _sliceOffset(_sliceRank(sliceIndexes[i]));
+ }
+ for (int i=rowIndexes.length; --i >= 0; ) {
+ rowOffsets[i] = _rowOffset(_rowRank(rowIndexes[i]));
+ }
+ for (int i=columnIndexes.length; --i >= 0; ) {
+ columnOffsets[i] = _columnOffset(_columnRank(columnIndexes[i]));
+ }
+
+ return viewSelectionLike(sliceOffsets,rowOffsets,columnOffsets);
+}
+/**
+Constructs and returns a new <i>selection view</i> that is a matrix holding all <b>slices</b> matching the given condition.
+Applies the condition to each slice and takes only those where <tt>condition.apply(viewSlice(i))</tt> yields <tt>true</tt>.
+To match rows or columns, use a dice view.
+<p>
+<b>Example:</b>
+<br>
+<pre>
+// extract and view all slices which have an aggregate sum > 1000
+matrix.viewSelection(
+ new DoubleMatrix2DProcedure() {
+ public final boolean apply(DoubleMatrix2D m) { return m.zSum > 1000; }
+ }
+);
+</pre>
+For further examples, see the <a href="package-summary.html#FunctionObjects">package doc</a>.
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa.
+
+@param condition The condition to be matched.
+@return the new view.
+*/
+public DoubleMatrix3D viewSelection(DoubleMatrix2DProcedure condition) {
+ IntArrayList matches = new IntArrayList();
+ for (int i=0; i < slices; i++) {
+ if (condition.apply(viewSlice(i))) matches.add(i);
+ }
+
+ matches.trimToSize();
+ return viewSelection(matches.elements(), null, null); // take all rows and columns
+}
+/**
+ * Construct and returns a new selection view.
+ *
+ * @param sliceOffsets the offsets of the visible elements.
+ * @param rowOffsets the offsets of the visible elements.
+ * @param columnOffsets the offsets of the visible elements.
+ * @return a new view.
+ */
+protected abstract DoubleMatrix3D viewSelectionLike(int[] sliceOffsets, int[] rowOffsets, int[] columnOffsets);
+/**
+Constructs and returns a new 2-dimensional <i>slice view</i> representing the rows and columns of the given slice.
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa.
+<p>
+To obtain a slice view on subranges, construct a sub-ranging view (<tt>view().part(...)</tt>), then apply this method to the sub-range view.
+To obtain 1-dimensional views, apply this method, then apply another slice view (methods <tt>viewColumn</tt>, <tt>viewRow</tt>) on the intermediate 2-dimensional view.
+To obtain 1-dimensional views on subranges, apply both steps.
+
+@param slice the index of the slice to fix.
+@return a new 2-dimensional slice view.
+@throws IndexOutOfBoundsException if <tt>slice < 0 || slice >= slices()</tt>.
+@see #viewRow(int)
+@see #viewColumn(int)
+*/
+public DoubleMatrix2D viewSlice(int slice) {
+ checkSlice(slice);
+ int sliceRows = this.rows;
+ int sliceColumns = this.columns;
+
+ //int sliceOffset = index(slice,0,0);
+ int sliceRowZero = rowZero;
+ int sliceColumnZero = columnZero + _sliceOffset(_sliceRank(slice));
+
+ int sliceRowStride = this.rowStride;
+ int sliceColumnStride = this.columnStride;
+ return like2D(sliceRows,sliceColumns,sliceRowZero,sliceColumnZero,sliceRowStride,sliceColumnStride);
+}
+/**
+Constructs and returns a new <i>flip view</i> along the slice axis.
+What used to be slice <tt>0</tt> is now slice <tt>slices()-1</tt>, ..., what used to be slice <tt>slices()-1</tt> is now slice <tt>0</tt>.
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa.
+
+@return a new flip view.
+@see #viewRowFlip()
+@see #viewColumnFlip()
+*/
+public DoubleMatrix3D viewSliceFlip() {
+ return (DoubleMatrix3D) (view().vSliceFlip());
+}
+/**
+Sorts the matrix slices into ascending order, according to the <i>natural ordering</i> of the matrix values in the given <tt>[row,column]</tt> position.
+This sort is guaranteed to be <i>stable</i>.
+For further information, see {@link org.apache.mahout.colt.matrix.doublealgo.Sorting#sort(DoubleMatrix3D,int,int)}.
+For more advanced sorting functionality, see {@link org.apache.mahout.colt.matrix.doublealgo.Sorting}.
+@return a new sorted vector (matrix) view.
+@throws IndexOutOfBoundsException if <tt>row < 0 || row >= rows() || column < 0 || column >= columns()</tt>.
+*/
+public DoubleMatrix3D viewSorted(int row, int column) {
+ return org.apache.mahout.colt.matrix.doublealgo.Sorting.mergeSort.sort(this,row,column);
+}
+/**
+Constructs and returns a new <i>stride view</i> which is a sub matrix consisting of every i-th cell.
+More specifically, the view has <tt>this.slices()/sliceStride</tt> slices and <tt>this.rows()/rowStride</tt> rows and <tt>this.columns()/columnStride</tt> columns
+holding cells <tt>this.get(k*sliceStride,i*rowStride,j*columnStride)</tt> for all <tt>k = 0..slices()/sliceStride - 1, i = 0..rows()/rowStride - 1, j = 0..columns()/columnStride - 1</tt>.
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa.
+
+@param sliceStride the slice step factor.
+@param rowStride the row step factor.
+@param columnStride the column step factor.
+@return a new view.
+@throws IndexOutOfBoundsException if <tt>sliceStride<=0 || rowStride<=0 || columnStride<=0</tt>.
+*/
+public DoubleMatrix3D viewStrides(int sliceStride, int rowStride, int columnStride) {
+ return (DoubleMatrix3D) (view().vStrides(sliceStride, rowStride, columnStride));
+}
+/**
+ * Applies a procedure to each cell's value.
+ * Iterates downwards from <tt>[slices()-1,rows()-1,columns()-1]</tt> to <tt>[0,0,0]</tt>,
+ * as demonstrated by this snippet:
+ * <pre>
+ * for (int slice=slices; --slice >=0;) {
+ * for (int row=rows; --row >= 0;) {
+ * for (int column=columns; --column >= 0;) {
+ * if (!procedure.apply(get(slice,row,column))) return false;
+ * }
+ * }
+ * }
+ * return true;
+ * </pre>
+ * Note that an implementation may use more efficient techniques, but must not use any other order.
+ *
+ * @param procedure a procedure object taking as argument the current cell's value. Stops iteration if the procedure returns <tt>false</tt>, otherwise continues.
+ * @return <tt>false</tt> if the procedure stopped before all elements where iterated over, <tt>true</tt> otherwise.
+ */
+private boolean xforEach(final org.apache.mahout.colt.function.DoubleProcedure procedure) {
+ for (int slice=slices; --slice >= 0;) {
+ for (int row=rows; --row >= 0;) {
+ for (int column=columns; --column >= 0;) {
+ if (!procedure.apply(getQuick(slice,row,column))) return false;
+ }
+ }
+ }
+ return true;
+}
+/**
+ * Applies a procedure to each cell's coordinate.
+ * Iterates downwards from <tt>[slices()-1,rows()-1,columns()-1]</tt> to <tt>[0,0,0]</tt>,
+ * as demonstrated by this snippet:
+ * <pre>
+ * for (int slice=slices; --slice >=0;) {
+ * for (int row=rows; --row >= 0;) {
+ * for (int column=columns; --column >= 0;) {
+ * if (!procedure.apply(slice,row,column)) return false;
+ * }
+ * }
+ * }
+ * return true;
+ * </pre>
+ * Note that an implementation may use more efficient techniques, but must not use any other order.
+ *
+ * @param procedure a procedure object taking as first argument the current slice, as second argument the current row, and as third argument the current column. Stops iteration if the procedure returns <tt>false</tt>, otherwise continues.
+ * @return <tt>false</tt> if the procedure stopped before all elements where iterated over, <tt>true</tt> otherwise.
+ */
+private boolean xforEachCoordinate(final org.apache.mahout.colt.function.IntIntIntProcedure procedure) {
+ for (int column=columns; --column >= 0;) {
+ for (int slice=slices; --slice >=0;) {
+ for (int row=rows; --row >= 0;) {
+ if (!procedure.apply(slice,row,column)) return false;
+ }
+ }
+ }
+ return true;
+}
+/**
+27 neighbor stencil transformation. For efficient finite difference operations.
+Applies a function to a moving <tt>3 x 3 x 3</tt> window.
+Does nothing if <tt>rows() < 3 || columns() < 3 || slices() < 3</tt>.
+<pre>
+B[k,i,j] = function.apply(
+ A[k-1,i-1,j-1], A[k-1,i-1,j], A[k-1,i-1,j+1],
+ A[k-1,i, j-1], A[k-1,i, j], A[k-1,i, j+1],
+ A[k-1,i+1,j-1], A[k-1,i+1,j], A[k-1,i+1,j+1],
+
+ A[k ,i-1,j-1], A[k ,i-1,j], A[k ,i-1,j+1],
+ A[k ,i, j-1], A[k ,i, j], A[k ,i, j+1],
+ A[k ,i+1,j-1], A[k ,i+1,j], A[k ,i+1,j+1],
+
+ A[k+1,i-1,j-1], A[k+1,i-1,j], A[k+1,i-1,j+1],
+ A[k+1,i, j-1], A[k+1,i, j], A[k+1,i, j+1],
+ A[k+1,i+1,j-1], A[k+1,i+1,j], A[k+1,i+1,j+1]
+ )
+
+x x x - - x x x - - - -
+x o x - - x o x - - - -
+x x x - - x x x ... - x x x
+- - - - - - - - - x o x
+- - - - - - - - - x x x
+</pre>
+Make sure that cells of <tt>this</tt> and <tt>B</tt> do not overlap.
+In case of overlapping views, behaviour is unspecified.
+</pre>
+<p>
+<b>Example:</b>
+<pre>
+final double alpha = 0.25;
+final double beta = 0.75;
+
+org.apache.mahout.colt.function.Double27Function f = new org.apache.mahout.colt.function.Double27Function() {
+ public final double apply(
+ double a000, double a001, double a002,
+ double a010, double a011, double a012,
+ double a020, double a021, double a022,
+
+ double a100, double a101, double a102,
+ double a110, double a111, double a112,
+ double a120, double a121, double a122,
+
+ double a200, double a201, double a202,
+ double a210, double a211, double a212,
+ double a220, double a221, double a222) {
+ return beta*a111 + alpha*(a000 + ... + a222);
+ }
+};
+A.zAssign27Neighbors(B,f);
+</pre>
+
+@param B the matrix to hold the results.
+@param function the function to be applied to the 27 cells.
+@throws NullPointerException if <tt>function==null</tt>.
+@throws IllegalArgumentException if <tt>rows() != B.rows() || columns() != B.columns() || slices() != B.slices() </tt>.
+*/
+public void zAssign27Neighbors(DoubleMatrix3D B, org.apache.mahout.colt.function.Double27Function function) {
+ if (function==null) throw new NullPointerException("function must not be null.");
+ checkShape(B);
+ if (rows<3 || columns<3 || slices<3) return; // nothing to do
+ int r = rows-1;
+ int c = columns-1;
+ double a000, a001, a002;
+ double a010, a011, a012;
+ double a020, a021, a022;
+
+ double a100, a101, a102;
+ double a110, a111, a112;
+ double a120, a121, a122;
+
+ double a200, a201, a202;
+ double a210, a211, a212;
+ double a220, a221, a222;
+
+ for (int k=1; k<slices-1; k++) {
+ for (int i=1; i<r; i++) {
+ a000=getQuick(k-1,i-1,0); a001=getQuick(k-1,i-1,1);
+ a010=getQuick(k-1,i, 0); a011=getQuick(k-1,i, 1);
+ a020=getQuick(k-1,i+1,0); a021=getQuick(k-1,i+1,1);
+
+ a100=getQuick(k-1,i-1,0); a101=getQuick(k ,i-1,1);
+ a110=getQuick(k ,i, 0); a111=getQuick(k ,i, 1);
+ a120=getQuick(k ,i+1,0); a121=getQuick(k ,i+1,1);
+
+ a200=getQuick(k+1,i-1,0); a201=getQuick(k+1,i-1,1);
+ a210=getQuick(k+1,i, 0); a211=getQuick(k+1,i, 1);
+ a220=getQuick(k+1,i+1,0); a221=getQuick(k+1,i+1,1);
+
+ for (int j=1; j<c; j++) {
+ // in each step 18 cells can be remembered in registers - they don't need to be reread from slow memory
+ // in each step 9 instead of 27 cells need to be read from memory.
+ a002=getQuick(k-1,i-1,j+1);
+ a012=getQuick(k-1,i, j+1);
+ a022=getQuick(k-1,i+1,j+1);
+
+ a102=getQuick(k ,i-1,j+1);
+ a112=getQuick(k ,i, j+1);
+ a122=getQuick(k ,i+1,j+1);
+
+ a202=getQuick(k+1,i-1,j+1);
+ a212=getQuick(k+1,i, j+1);
+ a222=getQuick(k+1,i+1,j+1);
+
+ B.setQuick(k,i,j, function.apply(
+ a000, a001, a002,
+ a010, a011, a012,
+ a020, a021, a022,
+
+ a100, a101, a102,
+ a110, a111, a112,
+ a120, a121, a122,
+
+ a200, a201, a202,
+ a210, a211, a212,
+ a220, a221, a222));
+
+ a000=a001; a001=a002;
+ a010=a011; a011=a012;
+ a020=a021; a021=a022;
+
+ a100=a101; a101=a102;
+ a110=a111; a111=a112;
+ a120=a121; a121=a122;
+
+ a200=a201; a201=a202;
+ a210=a211; a211=a212;
+ a220=a221; a221=a222;
+ }
+ }
+ }
+}
+/**
+ * Returns the sum of all cells; <tt>Sum( x[i,j,k] )</tt>.
+ * @return the sum.
+ */
+public double zSum() {
+ if (size()==0) return 0;
+ return aggregate(org.apache.mahout.jet.math.Functions.plus, org.apache.mahout.jet.math.Functions.identity);
+}
+}
Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleMatrix3D.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleMatrix3DProcedure.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleMatrix3DProcedure.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleMatrix3DProcedure.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleMatrix3DProcedure.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,32 @@
+/*
+Copyright 1999 CERN - European Organization for Nuclear Research.
+Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose
+is hereby granted without fee, provided that the above copyright notice appear in all copies and
+that both that copyright notice and this permission notice appear in supporting documentation.
+CERN makes no representations about the suitability of this software for any purpose.
+It is provided "as is" without expressed or implied warranty.
+*/
+package org.apache.mahout.colt.matrix;
+
+/**
+ * Interface that represents a condition or procedure object: takes
+ * a single argument and returns a boolean value.
+ */
+/**
+ * @deprecated until unit tests are in place. Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public interface DoubleMatrix3DProcedure {
+/**
+ * Applies a procedure to an argument.
+ * Optionally can return a boolean flag to inform the object calling the procedure.
+ *
+ * <p>Example: forEach() methods often use procedure objects.
+ * To signal to a forEach() method whether iteration should continue normally or terminate (because for example a matching element has been found),
+ * a procedure can return <tt>false</tt> to indicate termination and <tt>true</tt> to indicate continuation.
+ *
+ * @param element element passed to the procedure.
+ * @return a flag to inform the object calling the procedure.
+ */
+abstract public boolean apply(DoubleMatrix3D element);
+}
Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleMatrix3DProcedure.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectFactory1D.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectFactory1D.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectFactory1D.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectFactory1D.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,148 @@
+/*
+Copyright � 1999 CERN - European Organization for Nuclear Research.
+Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose
+is hereby granted without fee, provided that the above copyright notice appear in all copies and
+that both that copyright notice and this permission notice appear in supporting documentation.
+CERN makes no representations about the suitability of this software for any purpose.
+It is provided "as is" without expressed or implied warranty.
+*/
+package org.apache.mahout.colt.matrix;
+
+import org.apache.mahout.colt.matrix.impl.DenseObjectMatrix1D;
+import org.apache.mahout.colt.matrix.impl.SparseObjectMatrix1D;
+/**
+Factory for convenient construction of 1-d matrices holding <tt>Object</tt> cells.
+Use idioms like <tt>ObjectFactory1D.dense.make(1000)</tt> to construct dense matrices,
+<tt>ObjectFactory1D.sparse.make(1000)</tt> to construct sparse matrices.
+
+If the factory is used frequently it might be useful to streamline the notation.
+For example by aliasing:
+<table>
+<td class="PRE">
+<pre>
+ObjectFactory1D F = ObjectFactory1D.dense;
+F.make(1000);
+...
+</pre>
+</td>
+</table>
+
+@author wolfgang.hoschek@cern.ch
+@version 1.0, 09/24/99
+*/
+/**
+ * @deprecated until unit tests are in place. Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public class ObjectFactory1D extends org.apache.mahout.colt.PersistentObject {
+ /**
+ * A factory producing dense matrices.
+ */
+ public static final ObjectFactory1D dense = new ObjectFactory1D();
+
+ /**
+ * A factory producing sparse matrices.
+ */
+ public static final ObjectFactory1D sparse = new ObjectFactory1D();
+/**
+ * Makes this class non instantiable, but still let's others inherit from it.
+ */
+protected ObjectFactory1D() {}
+/**
+C = A||B; Constructs a new matrix which is the concatenation of two other matrices.
+Example: <tt>0 1</tt> append <tt>3 4</tt> --> <tt>0 1 3 4</tt>.
+*/
+public ObjectMatrix1D append(ObjectMatrix1D A, ObjectMatrix1D B) {
+ // concatenate
+ ObjectMatrix1D matrix = make(A.size()+B.size());
+ matrix.viewPart(0,A.size()).assign(A);
+ matrix.viewPart(A.size(),B.size()).assign(B);
+ return matrix;
+}
+/**
+Constructs a matrix which is the concatenation of all given parts.
+Cells are copied.
+*/
+public ObjectMatrix1D make(ObjectMatrix1D[] parts) {
+ if (parts.length==0) return make(0);
+
+ int size = 0;
+ for (int i=0; i < parts.length; i++) size += parts[i].size();
+
+ ObjectMatrix1D vector = make(size);
+ size = 0;
+ for (int i=0; i < parts.length; i++) {
+ vector.viewPart(size,parts[i].size()).assign(parts[i]);
+ size += parts[i].size();
+ }
+
+ return vector;
+}
+/**
+ * Constructs a matrix with the given cell values.
+ * The values are copied. So subsequent changes in <tt>values</tt> are not reflected in the matrix, and vice-versa.
+ *
+ * @param values The values to be filled into the new matrix.
+ */
+public ObjectMatrix1D make(Object[] values) {
+ if (this==sparse) return new SparseObjectMatrix1D(values);
+ else return new DenseObjectMatrix1D(values);
+}
+/**
+ * Constructs a matrix with the given shape, each cell initialized with zero.
+ */
+public ObjectMatrix1D make(int size) {
+ if (this==sparse) return new SparseObjectMatrix1D(size);
+ return new DenseObjectMatrix1D(size);
+}
+/**
+ * Constructs a matrix with the given shape, each cell initialized with the given value.
+ */
+public ObjectMatrix1D make(int size, Object initialValue) {
+ return make(size).assign(initialValue);
+}
+/**
+ * Constructs a matrix from the values of the given list.
+ * The values are copied. So subsequent changes in <tt>values</tt> are not reflected in the matrix, and vice-versa.
+ *
+ * @param values The values to be filled into the new matrix.
+ * @return a new matrix.
+ */
+public ObjectMatrix1D make(org.apache.mahout.colt.list.ObjectArrayList values) {
+ int size = values.size();
+ ObjectMatrix1D vector = make(size);
+ for (int i=size; --i >= 0; ) vector.set(i, values.get(i));
+ return vector;
+}
+/**
+C = A||A||..||A; Constructs a new matrix which is concatenated <tt>repeat</tt> times.
+Example:
+<pre>
+0 1
+repeat(3) -->
+0 1 0 1 0 1
+</pre>
+*/
+public ObjectMatrix1D repeat(ObjectMatrix1D A, int repeat) {
+ int size = A.size();
+ ObjectMatrix1D matrix = make(repeat * size);
+ for (int i=repeat; --i >= 0; ) {
+ matrix.viewPart(size*i,size).assign(A);
+ }
+ return matrix;
+}
+/**
+ * Constructs a list from the given matrix.
+ * The values are copied. So subsequent changes in <tt>values</tt> are not reflected in the list, and vice-versa.
+ *
+ * @param values The values to be filled into the new list.
+ * @return a new list.
+ */
+public org.apache.mahout.colt.list.ObjectArrayList toList(ObjectMatrix1D values) {
+ int size = values.size();
+ org.apache.mahout.colt.list.ObjectArrayList list = new org.apache.mahout.colt.list.ObjectArrayList(size);
+ list.setSize(size);
+ for (int i=size; --i >= 0; ) list.set(i, values.get(i));
+ return list;
+}
+}
Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectFactory1D.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectFactory2D.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectFactory2D.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectFactory2D.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectFactory2D.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,616 @@
+/*
+Copyright � 1999 CERN - European Organization for Nuclear Research.
+Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose
+is hereby granted without fee, provided that the above copyright notice appear in all copies and
+that both that copyright notice and this permission notice appear in supporting documentation.
+CERN makes no representations about the suitability of this software for any purpose.
+It is provided "as is" without expressed or implied warranty.
+*/
+package org.apache.mahout.colt.matrix;
+
+import org.apache.mahout.colt.matrix.impl.DenseObjectMatrix2D;
+import org.apache.mahout.colt.matrix.impl.SparseObjectMatrix2D;
+/**
+Factory for convenient construction of 2-d matrices holding <tt>Object</tt>
+ cells. Also provides convenient methods to compose (concatenate) and decompose
+ (split) matrices from/to constituent blocks. </p>
+<p> </p>
+<table border="0" cellspacing="0">
+ <tr align="left" valign="top">
+ <td><i>Construction</i></td>
+ <td>Use idioms like <tt>ObjectFactory2D.dense.make(4,4)</tt> to construct
+ dense matrices, <tt>ObjectFactory2D.sparse.make(4,4)</tt> to construct sparse
+ matrices.</td>
+ </tr>
+ <tr align="left" valign="top">
+ <td><i> Construction with initial values </i></td>
+ <td>Use other <tt>make</tt> methods to construct matrices with given initial
+ values. </td>
+ </tr>
+ <tr align="left" valign="top">
+ <td><i> Appending rows and columns </i></td>
+ <td>Use methods {@link #appendColumns(ObjectMatrix2D,ObjectMatrix2D) appendColumns},
+ {@link #appendColumns(ObjectMatrix2D,ObjectMatrix2D) appendRows} and {@link
+ #repeat(ObjectMatrix2D,int,int) repeat} to append rows and columns. </td>
+ </tr>
+ <tr align="left" valign="top">
+ <td><i> General block matrices </i></td>
+ <td>Use methods {@link #compose(ObjectMatrix2D[][]) compose} and {@link #decompose(ObjectMatrix2D[][],ObjectMatrix2D)
+ decompose} to work with general block matrices. </td>
+ </tr>
+ <tr align="left" valign="top">
+ <td><i> Diagonal block matrices </i></td>
+ <td>Use method {@link #composeDiagonal(ObjectMatrix2D,ObjectMatrix2D,ObjectMatrix2D)
+ composeDiagonal} to work with diagonal block matrices. </td>
+ </tr>
+</table>
+<p> </p>
+<p>If the factory is used frequently it might be useful to streamline the notation.
+ For example by aliasing: </p>
+<table>
+ <td class="PRE">
+ <pre>
+ObjectFactory2D F = ObjectFactory2D.dense;
+F.make(4,4);
+...
+</pre>
+ </td>
+</table>
+
+@author wolfgang.hoschek@cern.ch
+@version 1.0, 09/24/99
+*/
+/**
+ * @deprecated until unit tests are in place. Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public class ObjectFactory2D extends org.apache.mahout.colt.PersistentObject {
+ /**
+ * A factory producing dense matrices.
+ */
+ public static final ObjectFactory2D dense = new ObjectFactory2D();
+
+ /**
+ * A factory producing sparse matrices.
+ */
+ public static final ObjectFactory2D sparse = new ObjectFactory2D();
+/**
+ * Makes this class non instantiable, but still let's others inherit from it.
+ */
+protected ObjectFactory2D() {}
+/**
+C = A||B; Constructs a new matrix which is the column-wise concatenation of two other matrices.
+<pre>
+0 1 2
+3 4 5
+appendColumns
+6 7
+8 9
+-->
+0 1 2 6 7
+3 4 5 8 9
+</pre>
+*/
+public ObjectMatrix2D appendColumns(ObjectMatrix2D A, ObjectMatrix2D B) {
+ // force both to have maximal shared number of rows.
+ if (B.rows() > A.rows()) B = B.viewPart(0,0,A.rows(),B.columns());
+ else if (B.rows() < A.rows()) A = A.viewPart(0,0,B.rows(),A.columns());
+
+ // concatenate
+ int ac = A.columns();
+ int bc = B.columns();
+ int r = A.rows();
+ ObjectMatrix2D matrix = make(r,ac+bc);
+ matrix.viewPart(0,0,r,ac).assign(A);
+ matrix.viewPart(0,ac,r,bc).assign(B);
+ return matrix;
+}
+/**
+C = A||B; Constructs a new matrix which is the row-wise concatenation of two other matrices.
+<pre>
+0 1
+2 3
+4 5
+appendRows
+6 7
+8 9
+-->
+0 1
+2 3
+4 5
+6 7
+8 9
+</pre>
+*/
+public ObjectMatrix2D appendRows(ObjectMatrix2D A, ObjectMatrix2D B) {
+ // force both to have maximal shared number of columns.
+ if (B.columns() > A.columns()) B = B.viewPart(0,0,B.rows(),A.columns());
+ else if (B.columns() < A.columns()) A = A.viewPart(0,0,A.rows(),B.columns());
+
+ // concatenate
+ int ar = A.rows();
+ int br = B.rows();
+ int c = A.columns();
+ ObjectMatrix2D matrix = make(ar+br, c);
+ matrix.viewPart(0,0,ar,c).assign(A);
+ matrix.viewPart(ar,0,br,c).assign(B);
+ return matrix;
+}
+/**
+Checks whether the given array is rectangular, that is, whether all rows have the same number of columns.
+@throws IllegalArgumentException if the array is not rectangular.
+*/
+protected static void checkRectangularShape(ObjectMatrix2D[][] array) {
+ int columns = -1;
+ for (int row=array.length; --row >= 0; ) {
+ if (array[row] != null) {
+ if (columns == -1) columns = array[row].length;
+ if (array[row].length != columns) throw new IllegalArgumentException("All rows of array must have same number of columns.");
+ }
+ }
+}
+/**
+Checks whether the given array is rectangular, that is, whether all rows have the same number of columns.
+@throws IllegalArgumentException if the array is not rectangular.
+*/
+protected static void checkRectangularShape(Object[][] array) {
+ int columns = -1;
+ for (int row=array.length; --row >= 0; ) {
+ if (array[row] != null) {
+ if (columns == -1) columns = array[row].length;
+ if (array[row].length != columns) throw new IllegalArgumentException("All rows of array must have same number of columns.");
+ }
+ }
+}
+/**
+Constructs a block matrix made from the given parts.
+The inverse to method {@link #decompose(ObjectMatrix2D[][], ObjectMatrix2D)}.
+<p>
+All matrices of a given column within <tt>parts</tt> must have the same number of columns.
+All matrices of a given row within <tt>parts</tt> must have the same number of rows.
+Otherwise an <tt>IllegalArgumentException</tt> is thrown.
+Note that <tt>null</tt>s within <tt>parts[row,col]</tt> are an exception to this rule: they are ignored.
+Cells are copied.
+Example:
+<table border="1" cellspacing="0">
+ <tr align="left" valign="top">
+ <td><tt>Code</tt></td>
+ <td><tt>Result</tt></td>
+ </tr>
+ <tr align="left" valign="top">
+ <td>
+ <pre>
+ObjectMatrix2D[][] parts1 =
+{
+ { null, make(2,2,1), null },
+ { make(4,4,2), null, make(4,3,3) },
+ { null, make(2,2,4), null }
+};
+System.out.println(compose(parts1));
+</pre>
+ </td>
+ <td><tt>8 x 9 matrix<br>
+ 0 0 0 0 1 1 0 0 0<br>
+ 0 0 0 0 1 1 0 0 0<br>
+ 2 2 2 2 0 0 3 3 3<br>
+ 2 2 2 2 0 0 3 3 3<br>
+ 2 2 2 2 0 0 3 3 3<br>
+ 2 2 2 2 0 0 3 3 3<br>
+ 0 0 0 0 4 4 0 0 0<br>
+ 0 0 0 0 4 4 0 0 0</tt></td>
+ </tr>
+ <tr align="left" valign="top">
+ <td>
+ <pre>
+ObjectMatrix2D[][] parts3 =
+{
+ { identity(3), null, },
+ { null, identity(3).viewColumnFlip() },
+ { identity(3).viewRowFlip(), null }
+};
+System.out.println("\n"+make(parts3));
+</pre>
+ </td>
+ <td><tt>9 x 6 matrix<br>
+ 1 0 0 0 0 0<br>
+ 0 1 0 0 0 0<br>
+ 0 0 1 0 0 0<br>
+ 0 0 0 0 0 1<br>
+ 0 0 0 0 1 0<br>
+ 0 0 0 1 0 0<br>
+ 0 0 1 0 0 0<br>
+ 0 1 0 0 0 0<br>
+ 1 0 0 0 0 0 </tt></td>
+ </tr>
+ <tr align="left" valign="top">
+ <td>
+ <pre>
+ObjectMatrix2D A = ascending(2,2);
+ObjectMatrix2D B = descending(2,2);
+ObjectMatrix2D _ = null;
+
+ObjectMatrix2D[][] parts4 =
+{
+ { A, _, A, _ },
+ { _, A, _, B }
+};
+System.out.println("\n"+make(parts4));
+</pre>
+ </td>
+ <td><tt>4 x 8 matrix<br>
+ 1 2 0 0 1 2 0 0<br>
+ 3 4 0 0 3 4 0 0<br>
+ 0 0 1 2 0 0 3 2<br>
+ 0 0 3 4 0 0 1 0 </tt></td>
+ </tr>
+ <tr align="left" valign="top">
+ <td>
+ <pre>
+ObjectMatrix2D[][] parts2 =
+{
+ { null, make(2,2,1), null },
+ { make(4,4,2), null, make(4,3,3) },
+ { null, make(2,3,4), null }
+};
+System.out.println("\n"+Factory2D.make(parts2));
+</pre>
+ </td>
+ <td><tt>IllegalArgumentException<br>
+ A[0,1].cols != A[2,1].cols<br>
+ (2 != 3)</tt></td>
+ </tr>
+</table>
+@throws IllegalArgumentException subject to the conditions outlined above.
+*/
+public ObjectMatrix2D compose(ObjectMatrix2D[][] parts) {
+ checkRectangularShape(parts);
+ int rows = parts.length;
+ int columns = 0;
+ if (parts.length > 0) columns = parts[0].length;
+ ObjectMatrix2D empty = make(0,0);
+
+ if (rows==0 || columns==0) return empty;
+
+ // determine maximum column width of each column
+ int[] maxWidths = new int[columns];
+ for (int column=columns; --column >= 0; ) {
+ int maxWidth = 0;
+ for (int row=rows; --row >= 0; ) {
+ ObjectMatrix2D part = parts[row][column];
+ if (part != null) {
+ int width = part.columns();
+ if (maxWidth>0 && width>0 && width!=maxWidth) throw new IllegalArgumentException("Different number of columns.");
+ maxWidth = Math.max(maxWidth,width);
+ }
+ }
+ maxWidths[column] = maxWidth;
+ }
+
+ // determine row height of each row
+ int[] maxHeights = new int[rows];
+ for (int row=rows; --row >= 0; ) {
+ int maxHeight = 0;
+ for (int column=columns; --column >= 0; ) {
+ ObjectMatrix2D part = parts[row][column];
+ if (part != null) {
+ int height = part.rows();
+ if (maxHeight>0 && height>0 && height!=maxHeight) throw new IllegalArgumentException("Different number of rows.");
+ maxHeight = Math.max(maxHeight,height);
+ }
+ }
+ maxHeights[row] = maxHeight;
+ }
+
+
+ // shape of result
+ int resultRows = 0;
+ for (int row=rows; --row >= 0; ) resultRows += maxHeights[row];
+ int resultCols = 0;
+ for (int column=columns; --column >= 0; ) resultCols += maxWidths[column];
+
+ ObjectMatrix2D matrix = make(resultRows,resultCols);
+
+ // copy
+ int r=0;
+ for (int row=0; row < rows; row++) {
+ int c=0;
+ for (int column=0; column < columns; column++) {
+ ObjectMatrix2D part = parts[row][column];
+ if (part != null) {
+ matrix.viewPart(r,c,part.rows(),part.columns()).assign(part);
+ }
+ c += maxWidths[column];
+ }
+ r += maxHeights[row];
+ }
+
+ return matrix;
+}
+/**
+Constructs a diagonal block matrix from the given parts (the <i>direct sum</i> of two matrices).
+That is the concatenation
+<pre>
+A 0
+0 B
+</pre>
+(The direct sum has <tt>A.rows()+B.rows()</tt> rows and <tt>A.columns()+B.columns()</tt> columns).
+Cells are copied.
+@return a new matrix which is the direct sum.
+*/
+public ObjectMatrix2D composeDiagonal(ObjectMatrix2D A, ObjectMatrix2D B) {
+ int ar = A.rows(); int ac = A.columns();
+ int br = B.rows(); int bc = B.columns();
+ ObjectMatrix2D sum = make(ar+br, ac+bc);
+ sum.viewPart(0,0,ar,ac).assign(A);
+ sum.viewPart(ar,ac,br,bc).assign(B);
+ return sum;
+}
+/**
+Constructs a diagonal block matrix from the given parts.
+The concatenation has the form
+<pre>
+A 0 0
+0 B 0
+0 0 C
+</pre>
+from the given parts.
+Cells are copied.
+*/
+public ObjectMatrix2D composeDiagonal(ObjectMatrix2D A, ObjectMatrix2D B, ObjectMatrix2D C) {
+ ObjectMatrix2D diag = make(A.rows()+B.rows()+C.rows(), A.columns()+B.columns()+C.columns());
+ diag.viewPart(0,0,A.rows(),A.columns()).assign(A);
+ diag.viewPart(A.rows(),A.columns(),B.rows(),B.columns()).assign(B);
+ diag.viewPart(A.rows()+B.rows(),A.columns()+B.columns(),C.rows(),C.columns()).assign(C);
+ return diag;
+}
+/**
+Splits a block matrix into its constituent blocks; Copies blocks of a matrix into the given parts.
+The inverse to method {@link #compose(ObjectMatrix2D[][])}.
+<p>
+All matrices of a given column within <tt>parts</tt> must have the same number of columns.
+All matrices of a given row within <tt>parts</tt> must have the same number of rows.
+Otherwise an <tt>IllegalArgumentException</tt> is thrown.
+Note that <tt>null</tt>s within <tt>parts[row,col]</tt> are an exception to this rule: they are ignored.
+Cells are copied.
+Example:
+<table border="1" cellspacing="0">
+ <tr align="left" valign="top">
+ <td><tt>Code</tt></td>
+ <td><tt>matrix</tt></td>
+ <td><tt>--> parts </tt></td>
+ </tr>
+ <tr align="left" valign="top">
+ <td>
+ <pre>
+ObjectMatrix2D matrix = ... ;
+ObjectMatrix2D _ = null;
+ObjectMatrix2D A,B,C,D;
+A = make(2,2); B = make (4,4);
+C = make(4,3); D = make (2,2);
+ObjectMatrix2D[][] parts =
+{
+ { _, A, _ },
+ { B, _, C },
+ { _, D, _ }
+};
+decompose(parts,matrix);
+System.out.println("\nA = "+A);
+System.out.println("\nB = "+B);
+System.out.println("\nC = "+C);
+System.out.println("\nD = "+D);
+</pre>
+ </td>
+ <td><tt>8 x 9 matrix<br>
+ 9 9 9 9 1 1 9 9 9<br>
+ 9 9 9 9 1 1 9 9 9<br>
+ 2 2 2 2 9 9 3 3 3<br>
+ 2 2 2 2 9 9 3 3 3<br>
+ 2 2 2 2 9 9 3 3 3<br>
+ 2 2 2 2 9 9 3 3 3<br>
+ 9 9 9 9 4 4 9 9 9<br>
+ 9 9 9 9 4 4 9 9 9</tt></td>
+ <td>
+ <p><tt>A = 2 x 2 matrix<br>
+ 1 1<br>
+ 1 1</tt></p>
+ <p><tt>B = 4 x 4 matrix<br>
+ 2 2 2 2<br>
+ 2 2 2 2<br>
+ 2 2 2 2<br>
+ 2 2 2 2</tt></p>
+ <p><tt>C = 4 x 3 matrix<br>
+ 3 3 3<br>
+ 3 3 3<br>
+ </tt><tt>3 3 3<br>
+ </tt><tt>3 3 3</tt></p>
+ <p><tt>D = 2 x 2 matrix<br>
+ 4 4<br>
+ 4 4</tt></p>
+ </td>
+ </tr>
+</table>
+@throws IllegalArgumentException subject to the conditions outlined above.
+*/
+public void decompose(ObjectMatrix2D[][] parts, ObjectMatrix2D matrix) {
+ checkRectangularShape(parts);
+ int rows = parts.length;
+ int columns = 0;
+ if (parts.length > 0) columns = parts[0].length;
+ if (rows==0 || columns==0) return;
+
+ // determine maximum column width of each column
+ int[] maxWidths = new int[columns];
+ for (int column=columns; --column >= 0; ) {
+ int maxWidth = 0;
+ for (int row=rows; --row >= 0; ) {
+ ObjectMatrix2D part = parts[row][column];
+ if (part != null) {
+ int width = part.columns();
+ if (maxWidth>0 && width>0 && width!=maxWidth) throw new IllegalArgumentException("Different number of columns.");
+ maxWidth = Math.max(maxWidth,width);
+ }
+ }
+ maxWidths[column] = maxWidth;
+ }
+
+ // determine row height of each row
+ int[] maxHeights = new int[rows];
+ for (int row=rows; --row >= 0; ) {
+ int maxHeight = 0;
+ for (int column=columns; --column >= 0; ) {
+ ObjectMatrix2D part = parts[row][column];
+ if (part != null) {
+ int height = part.rows();
+ if (maxHeight>0 && height>0 && height!=maxHeight) throw new IllegalArgumentException("Different number of rows.");
+ maxHeight = Math.max(maxHeight,height);
+ }
+ }
+ maxHeights[row] = maxHeight;
+ }
+
+
+ // shape of result parts
+ int resultRows = 0;
+ for (int row=rows; --row >= 0; ) resultRows += maxHeights[row];
+ int resultCols = 0;
+ for (int column=columns; --column >= 0; ) resultCols += maxWidths[column];
+
+ if (matrix.rows() < resultRows || matrix.columns() < resultCols) throw new IllegalArgumentException("Parts larger than matrix.");
+
+ // copy
+ int r=0;
+ for (int row=0; row < rows; row++) {
+ int c=0;
+ for (int column=0; column < columns; column++) {
+ ObjectMatrix2D part = parts[row][column];
+ if (part != null) {
+ part.assign(matrix.viewPart(r,c,part.rows(),part.columns()));
+ }
+ c += maxWidths[column];
+ }
+ r += maxHeights[row];
+ }
+
+}
+/**
+Constructs a new diagonal matrix whose diagonal elements are the elements of <tt>vector</tt>.
+Cells values are copied. The new matrix is not a view.
+Example:
+<pre>
+5 4 3 -->
+5 0 0
+0 4 0
+0 0 3
+</pre>
+@return a new matrix.
+*/
+public ObjectMatrix2D diagonal(ObjectMatrix1D vector) {
+ int size = vector.size();
+ ObjectMatrix2D diag = make(size,size);
+ for (int i=size; --i >= 0; ) {
+ diag.setQuick(i,i, vector.getQuick(i));
+ }
+ return diag;
+}
+/**
+Constructs a new vector consisting of the diagonal elements of <tt>A</tt>.
+Cells values are copied. The new vector is not a view.
+Example:
+<pre>
+5 0 0 9
+0 4 0 9
+0 0 3 9
+--> 5 4 3
+</pre>
+@param A the matrix, need not be square.
+@return a new vector.
+*/
+public ObjectMatrix1D diagonal(ObjectMatrix2D A) {
+ int min = Math.min(A.rows(),A.columns());
+ ObjectMatrix1D diag = make1D(min);
+ for (int i=min; --i >= 0; ) {
+ diag.setQuick(i, A.getQuick(i,i));
+ }
+ return diag;
+}
+/**
+ * Constructs a matrix with the given cell values.
+ * <tt>values</tt> is required to have the form <tt>values[row][column]</tt>
+ * and have exactly the same number of columns in every row.
+ * <p>
+ * The values are copied. So subsequent changes in <tt>values</tt> are not reflected in the matrix, and vice-versa.
+ *
+ * @param values The values to be filled into the new matrix.
+ * @throws IllegalArgumentException if <tt>for any 1 <= row < values.length: values[row].length != values[row-1].length</tt>.
+ */
+public ObjectMatrix2D make(Object[][] values) {
+ if (this==sparse) return new SparseObjectMatrix2D(values);
+ else return new DenseObjectMatrix2D(values);
+}
+/**
+Construct a matrix from a one-dimensional column-major packed array, ala Fortran.
+Has the form <tt>matrix.get(row,column) == values[row + column*rows]</tt>.
+The values are copied.
+
+@param values One-dimensional array of Objects, packed by columns (ala Fortran).
+@param rows the number of rows.
+@exception IllegalArgumentException <tt>values.length</tt> must be a multiple of <tt>rows</tt>.
+*/
+public ObjectMatrix2D make(Object values[], int rows) {
+ int columns = (rows != 0 ? values.length/rows : 0);
+ if (rows*columns != values.length)
+ throw new IllegalArgumentException("Array length must be a multiple of m.");
+
+ ObjectMatrix2D matrix = make(rows,columns);
+ for (int row=0; row < rows; row++) {
+ for (int column=0; column < columns; column++) {
+ matrix.setQuick(row,column, values[row + column*rows]);
+ }
+ }
+ return matrix;
+}
+/**
+ * Constructs a matrix with the given shape, each cell initialized with zero.
+ */
+public ObjectMatrix2D make(int rows, int columns) {
+ if (this==sparse) return new SparseObjectMatrix2D(rows,columns);
+ else return new DenseObjectMatrix2D(rows,columns);
+}
+/**
+ * Constructs a matrix with the given shape, each cell initialized with the given value.
+ */
+public ObjectMatrix2D make(int rows, int columns, Object initialValue) {
+ if (initialValue == null) return make(rows,columns);
+ return make(rows,columns).assign(initialValue);
+}
+/**
+ * Constructs a 1d matrix of the right dynamic type.
+ */
+protected ObjectMatrix1D make1D(int size) {
+ return make(0,0).like1D(size);
+}
+/**
+C = A||A||..||A; Constructs a new matrix which is duplicated both along the row and column dimension.
+Example:
+<pre>
+0 1
+2 3
+repeat(2,3) -->
+0 1 0 1 0 1
+2 3 2 3 2 3
+0 1 0 1 0 1
+2 3 2 3 2 3
+</pre>
+*/
+public ObjectMatrix2D repeat(ObjectMatrix2D A, int rowRepeat, int columnRepeat) {
+ int r = A.rows();
+ int c = A.columns();
+ ObjectMatrix2D matrix = make(r*rowRepeat, c*columnRepeat);
+ for (int i=rowRepeat; --i >= 0; ) {
+ for (int j=columnRepeat; --j >= 0; ) {
+ matrix.viewPart(r*i,c*j,r,c).assign(A);
+ }
+ }
+ return matrix;
+}
+}
Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectFactory2D.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectFactory3D.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectFactory3D.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectFactory3D.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectFactory3D.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,80 @@
+/*
+Copyright � 1999 CERN - European Organization for Nuclear Research.
+Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose
+is hereby granted without fee, provided that the above copyright notice appear in all copies and
+that both that copyright notice and this permission notice appear in supporting documentation.
+CERN makes no representations about the suitability of this software for any purpose.
+It is provided "as is" without expressed or implied warranty.
+*/
+package org.apache.mahout.colt.matrix;
+
+import org.apache.mahout.colt.matrix.impl.DenseObjectMatrix3D;
+import org.apache.mahout.colt.matrix.impl.SparseObjectMatrix3D;
+/**
+Factory for convenient construction of 3-d matrices holding <tt>Object</tt> cells.
+Use idioms like <tt>ObjectFactory3D.dense.make(4,4,4)</tt> to construct dense matrices,
+<tt>ObjectFactory3D.sparse.make(4,4,4)</tt> to construct sparse matrices.
+
+If the factory is used frequently it might be useful to streamline the notation.
+For example by aliasing:
+<table>
+<td class="PRE">
+<pre>
+ObjectFactory3D F = ObjectFactory3D.dense;
+F.make(4,4,4);
+...
+</pre>
+</td>
+</table>
+
+@author wolfgang.hoschek@cern.ch
+@version 1.0, 09/24/99
+*/
+/**
+ * @deprecated until unit tests are in place. Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public class ObjectFactory3D extends org.apache.mahout.colt.PersistentObject {
+ /**
+ * A factory producing dense matrices.
+ */
+ public static final ObjectFactory3D dense = new ObjectFactory3D();
+
+ /**
+ * A factory producing sparse matrices.
+ */
+ public static final ObjectFactory3D sparse = new ObjectFactory3D();
+/**
+ * Makes this class non instantiable, but still let's others inherit from it.
+ */
+protected ObjectFactory3D() {}
+/**
+ * Constructs a matrix with the given cell values.
+ * <tt>values</tt> is required to have the form <tt>values[slice][row][column]</tt>
+ * and have exactly the same number of slices, rows and columns as the receiver.
+ * <p>
+ * The values are copied. So subsequent changes in <tt>values</tt> are not reflected in the matrix, and vice-versa.
+ *
+ * @param values the values to be filled into the cells.
+ * @return <tt>this</tt> (for convenience only).
+ * @throws IllegalArgumentException if <tt>values.length != slices() || for any 0 <= slice < slices(): values[slice].length != rows()</tt>.
+ * @throws IllegalArgumentException if <tt>for any 0 <= column < columns(): values[slice][row].length != columns()</tt>.
+ */
+public ObjectMatrix3D make(Object[][][] values) {
+ if (this==sparse) return new SparseObjectMatrix3D(values);
+ return new DenseObjectMatrix3D(values);
+}
+/**
+ * Constructs a matrix with the given shape, each cell initialized with zero.
+ */
+public ObjectMatrix3D make(int slices, int rows, int columns) {
+ if (this==sparse) return new SparseObjectMatrix3D(slices,rows,columns);
+ return new DenseObjectMatrix3D(slices,rows,columns);
+}
+/**
+ * Constructs a matrix with the given shape, each cell initialized with the given value.
+ */
+public ObjectMatrix3D make(int slices, int rows, int columns, Object initialValue) {
+ return make(slices,rows,columns).assign(initialValue);
+}
+}
Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectFactory3D.java
------------------------------------------------------------------------------
svn:eol-style = native