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&lt;0 || slice&gt;=slices() || row&lt;0 || row&gt;=rows() || column&lt;0 || column&gt;=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 &lt;= slice &lt; slices(): values[slice].length != rows()</tt>.
+ * @throws IllegalArgumentException if <tt>for any 0 &lt;= column &lt; 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&lt;0 || slice&gt;=slices() || row&lt;0 || row&gt;=rows() || column&lt;0 || column&gt;=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&lt;0 || slice&gt;=slices() || row&lt;0 || row&gt;=rows() || column&lt;0 || column&gt;=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&lt;0 || row&gt;=rows() || slice&lt;0 || slice&gt;=slices() || column&lt;0 || column&gt;=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&lt;0 || slice&gt;=slices() || row&lt;0 || row&gt;=rows() || column&lt;0 || column&gt;=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( 
+&nbsp;&nbsp;&nbsp;new DoubleMatrix2DProcedure() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public final boolean apply(DoubleMatrix2D m) { return m.zSum > 1000; }
+&nbsp;&nbsp;&nbsp;}
+);
+</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(
+&nbsp;&nbsp;&nbsp;A[k-1,i-1,j-1], A[k-1,i-1,j], A[k-1,i-1,j+1],
+&nbsp;&nbsp;&nbsp;A[k-1,i,  j-1], A[k-1,i,  j], A[k-1,i,  j+1],
+&nbsp;&nbsp;&nbsp;A[k-1,i+1,j-1], A[k-1,i+1,j], A[k-1,i+1,j+1],
+
+&nbsp;&nbsp;&nbsp;A[k  ,i-1,j-1], A[k  ,i-1,j], A[k  ,i-1,j+1],
+&nbsp;&nbsp;&nbsp;A[k  ,i,  j-1], A[k  ,i,  j], A[k  ,i,  j+1],
+&nbsp;&nbsp;&nbsp;A[k  ,i+1,j-1], A[k  ,i+1,j], A[k  ,i+1,j+1],
+
+&nbsp;&nbsp;&nbsp;A[k+1,i-1,j-1], A[k+1,i-1,j], A[k+1,i-1,j+1],
+&nbsp;&nbsp;&nbsp;A[k+1,i,  j-1], A[k+1,i,  j], A[k+1,i,  j+1],
+&nbsp;&nbsp;&nbsp;A[k+1,i+1,j-1], A[k+1,i+1,j], A[k+1,i+1,j+1]
+&nbsp;&nbsp;&nbsp;)
+
+x x x - &nbsp;&nbsp;&nbsp; - x x x &nbsp;&nbsp;&nbsp; - - - - 
+x o x - &nbsp;&nbsp;&nbsp; - x o x &nbsp;&nbsp;&nbsp; - - - - 
+x x x - &nbsp;&nbsp;&nbsp; - x x x ... - x x x 
+- - - - &nbsp;&nbsp;&nbsp; - - - - &nbsp;&nbsp;&nbsp; - x o x 
+- - - - &nbsp;&nbsp;&nbsp; - - - - &nbsp;&nbsp;&nbsp; - 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() {
+&nbsp;&nbsp;&nbsp;public final double apply(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double a000, double a001, double a002,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double a010, double a011, double a012,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double a020, double a021, double a022,
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double a100, double a101, double a102,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double a110, double a111, double a112,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double a120, double a121, double a122,
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double a200, double a201, double a202,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double a210, double a211, double a212,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double a220, double a221, double a222) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return beta*a111 + alpha*(a000 + ... + a222);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
+};
+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>&nbsp; </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>&nbsp;</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 = 
+{
+&nbsp;&nbsp;&nbsp;{ null,        make(2,2,1), null        },
+&nbsp;&nbsp;&nbsp;{ make(4,4,2), null,        make(4,3,3) },
+&nbsp;&nbsp;&nbsp;{ null,        make(2,2,4), null        }
+};
+System.out.println(compose(parts1));
+</pre>
+	</td>
+	<td><tt>8&nbsp;x&nbsp;9&nbsp;matrix<br>
+	  0&nbsp;0&nbsp;0&nbsp;0&nbsp;1&nbsp;1&nbsp;0&nbsp;0&nbsp;0<br>
+	  0&nbsp;0&nbsp;0&nbsp;0&nbsp;1&nbsp;1&nbsp;0&nbsp;0&nbsp;0<br>
+	  2&nbsp;2&nbsp;2&nbsp;2&nbsp;0&nbsp;0&nbsp;3&nbsp;3&nbsp;3<br>
+	  2&nbsp;2&nbsp;2&nbsp;2&nbsp;0&nbsp;0&nbsp;3&nbsp;3&nbsp;3<br>
+	  2&nbsp;2&nbsp;2&nbsp;2&nbsp;0&nbsp;0&nbsp;3&nbsp;3&nbsp;3<br>
+	  2&nbsp;2&nbsp;2&nbsp;2&nbsp;0&nbsp;0&nbsp;3&nbsp;3&nbsp;3<br>
+	  0&nbsp;0&nbsp;0&nbsp;0&nbsp;4&nbsp;4&nbsp;0&nbsp;0&nbsp;0<br>
+	  0&nbsp;0&nbsp;0&nbsp;0&nbsp;4&nbsp;4&nbsp;0&nbsp;0&nbsp;0</tt></td>
+  </tr>
+  <tr align="left" valign="top"> 
+	<td> 
+	  <pre>
+ObjectMatrix2D[][] parts3 = 
+{
+&nbsp;&nbsp;&nbsp;{ identity(3),               null,                        },
+&nbsp;&nbsp;&nbsp;{ null,                      identity(3).viewColumnFlip() },
+&nbsp;&nbsp;&nbsp;{ identity(3).viewRowFlip(), null                         }
+};
+System.out.println("\n"+make(parts3));
+</pre>
+	</td>
+	<td><tt>9&nbsp;x&nbsp;6&nbsp;matrix<br>
+	  1&nbsp;0&nbsp;0&nbsp;0&nbsp;0&nbsp;0<br>
+	  0&nbsp;1&nbsp;0&nbsp;0&nbsp;0&nbsp;0<br>
+	  0&nbsp;0&nbsp;1&nbsp;0&nbsp;0&nbsp;0<br>
+	  0&nbsp;0&nbsp;0&nbsp;0&nbsp;0&nbsp;1<br>
+	  0&nbsp;0&nbsp;0&nbsp;0&nbsp;1&nbsp;0<br>
+	  0&nbsp;0&nbsp;0&nbsp;1&nbsp;0&nbsp;0<br>
+	  0&nbsp;0&nbsp;1&nbsp;0&nbsp;0&nbsp;0<br>
+	  0&nbsp;1&nbsp;0&nbsp;0&nbsp;0&nbsp;0<br>
+	  1&nbsp;0&nbsp;0&nbsp;0&nbsp;0&nbsp;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 = 
+{
+&nbsp;&nbsp;&nbsp;{ A, _, A, _ },
+&nbsp;&nbsp;&nbsp;{ _, A, _, B }
+};
+System.out.println("\n"+make(parts4));
+</pre>
+	</td>
+	<td><tt>4&nbsp;x&nbsp;8&nbsp;matrix<br>
+	  1&nbsp;2&nbsp;0&nbsp;0&nbsp;1&nbsp;2&nbsp;0&nbsp;0<br>
+	  3&nbsp;4&nbsp;0&nbsp;0&nbsp;3&nbsp;4&nbsp;0&nbsp;0<br>
+	  0&nbsp;0&nbsp;1&nbsp;2&nbsp;0&nbsp;0&nbsp;3&nbsp;2<br>
+	  0&nbsp;0&nbsp;3&nbsp;4&nbsp;0&nbsp;0&nbsp;1&nbsp;0 </tt></td>
+  </tr>
+  <tr align="left" valign="top"> 
+	<td> 
+	  <pre>
+ObjectMatrix2D[][] parts2 = 
+{
+&nbsp;&nbsp;&nbsp;{ null,        make(2,2,1), null        },
+&nbsp;&nbsp;&nbsp;{ make(4,4,2), null,        make(4,3,3) },
+&nbsp;&nbsp;&nbsp;{ 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>--&gt; 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 = 
+{
+&nbsp;&nbsp;&nbsp;{ _, A, _ },
+&nbsp;&nbsp;&nbsp;{ B, _, C },
+&nbsp;&nbsp;&nbsp;{ _, D, _ }
+};
+decompose(parts,matrix);
+System.out.println(&quot;\nA = &quot;+A);
+System.out.println(&quot;\nB = &quot;+B);
+System.out.println(&quot;\nC = &quot;+C);
+System.out.println(&quot;\nD = &quot;+D);
+</pre>
+	</td>
+	<td><tt>8&nbsp;x&nbsp;9&nbsp;matrix<br>
+	  9&nbsp;9&nbsp;9&nbsp;9&nbsp;1&nbsp;1&nbsp;9&nbsp;9&nbsp;9<br>
+	  9&nbsp;9&nbsp;9&nbsp;9&nbsp;1&nbsp;1&nbsp;9&nbsp;9&nbsp;9<br>
+	  2&nbsp;2&nbsp;2&nbsp;2&nbsp;9&nbsp;9&nbsp;3&nbsp;3&nbsp;3<br>
+	  2&nbsp;2&nbsp;2&nbsp;2&nbsp;9&nbsp;9&nbsp;3&nbsp;3&nbsp;3<br>
+	  2&nbsp;2&nbsp;2&nbsp;2&nbsp;9&nbsp;9&nbsp;3&nbsp;3&nbsp;3<br>
+	  2&nbsp;2&nbsp;2&nbsp;2&nbsp;9&nbsp;9&nbsp;3&nbsp;3&nbsp;3<br>
+	  9&nbsp;9&nbsp;9&nbsp;9&nbsp;4&nbsp;4&nbsp;9&nbsp;9&nbsp;9<br>
+	  9&nbsp;9&nbsp;9&nbsp;9&nbsp;4&nbsp;4&nbsp;9&nbsp;9&nbsp;9</tt></td>
+	<td> 
+	  <p><tt>A = 2&nbsp;x&nbsp;2&nbsp;matrix<br>
+		1&nbsp;1<br>
+		1&nbsp;1</tt></p>
+	  <p><tt>B = 4&nbsp;x&nbsp;4&nbsp;matrix<br>
+		2&nbsp;2&nbsp;2&nbsp;2<br>
+		2&nbsp;2&nbsp;2&nbsp;2<br>
+		2&nbsp;2&nbsp;2&nbsp;2<br>
+		2&nbsp;2&nbsp;2&nbsp;2</tt></p>
+	  <p><tt>C = 4&nbsp;x&nbsp;3&nbsp;matrix<br>
+		3&nbsp;3&nbsp;3<br>
+		3&nbsp;3&nbsp;3<br>
+		</tt><tt>3&nbsp;3&nbsp;3<br>
+		</tt><tt>3&nbsp;3&nbsp;3</tt></p>
+	  <p><tt>D = 2&nbsp;x&nbsp;2&nbsp;matrix<br>
+		4&nbsp;4<br>
+		4&nbsp;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 &lt;= row &lt; 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 &lt;= slice &lt; slices(): values[slice].length != rows()</tt>.
+ * @throws IllegalArgumentException if <tt>for any 0 &lt;= column &lt; 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