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 [30/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/ObjectMatrix3D.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectMatrix3D.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectMatrix3D.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectMatrix3D.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,860 @@
+/*
+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.IntArrayList;
+import org.apache.mahout.colt.list.ObjectArrayList;
+import org.apache.mahout.colt.matrix.impl.AbstractMatrix3D;
+/**
+Abstract base class for 3-d matrices holding <tt>Object</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 ObjectMatrix3D extends AbstractMatrix3D {
+/**
+ * Makes this class non instantiable, but still let's others inherit from it.
+ */
+protected ObjectMatrix3D() {}
+/**
+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)==null</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 Object aggregate(org.apache.mahout.colt.function.ObjectObjectFunction aggr, org.apache.mahout.colt.function.ObjectFunction f) {
+	if (size()==0) return null;
+	Object 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)==null</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 Object aggregate(ObjectMatrix3D other, org.apache.mahout.colt.function.ObjectObjectFunction aggr, org.apache.mahout.colt.function.ObjectObjectFunction f) {
+	checkShape(other);
+	if (size()==0) return null;
+	Object 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 ObjectMatrix3D assign(Object[][][] 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;) {
+		Object[][] 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;) {
+			Object[] 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;
+}
+/**
+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 ObjectMatrix3D assign(org.apache.mahout.colt.function.ObjectFunction 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 ObjectMatrix3D assign(ObjectMatrix3D 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 ObjectMatrix3D assign(ObjectMatrix3D y, org.apache.mahout.colt.function.ObjectObjectFunction 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;
+}
+/**
+ * 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 ObjectMatrix3D assign(Object 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;
+}
+/**
+ * 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) != null) 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 ObjectMatrix3D copy() {
+	return like().assign(this);
+}
+/**
+* Compares the specified Object with the receiver for equality.
+* Equivalent to <tt>equals(otherObj,true)</tt>.  
+*
+* @param otherObj the Object to be compared for equality with the receiver.
+* @return true if the specified Object is equal to the receiver.
+*/
+public boolean equals(Object otherObj) { //delta
+	return equals(otherObj, true);
+}
+/**
+* Compares the specified Object with the receiver for equality.
+* Returns true if and only if the specified Object is also at least an ObjectMatrix3D, both matrices have the
+* same size, and all corresponding pairs of cells in the two matrices are the same.
+* In other words, two matrices are defined to be equal if they contain the
+* same cell values in the same order.
+* Tests elements for equality or identity as specified by <tt>testForEquality</tt>.
+* When testing for equality, two elements <tt>e1</tt> and
+* <tt>e2</tt> are <i>equal</i> if <tt>(e1==null ? e2==null :
+* e1.equals(e2))</tt>.)  
+*
+* @param otherObj the Object to be compared for equality with the receiver.
+* @param testForEquality if true -> tests for equality, otherwise for identity.
+* @return true if the specified Object is equal to the receiver.
+*/
+public boolean equals(Object otherObj, boolean testForEquality) { //delta
+	if (! (otherObj instanceof ObjectMatrix3D)) {return false;}
+	if (this==otherObj) return true;
+	if (otherObj==null) return false;
+	ObjectMatrix3D other = (ObjectMatrix3D) otherObj;
+	if (rows!=other.rows()) return false;
+	if (columns!=other.columns()) return false;
+
+	if (! testForEquality) {
+		for (int slice=slices; --slice >= 0; ) {
+			for (int row=rows; --row >= 0; ) {
+				for (int column=columns; --column >= 0; ) {
+					if (getQuick(slice,row,column) != other.getQuick(slice,row,column)) return false;
+				}
+			}
+		}
+	}
+	else {
+		for (int slice=slices; --slice >= 0; ) {
+			for (int row=rows; --row >= 0; ) {
+				for (int column=columns; --column >= 0; ) {
+				if (!(getQuick(slice,row,column)==null ? other.getQuick(slice,row,column)==null : getQuick(slice,row,column).equals(other.getQuick(slice,row,column)))) return false;
+				}
+			}
+		}
+	}
+	
+	return true;
+}
+/**
+ * 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 Object 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 ObjectMatrix3D 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 ObjectMatrix2D#getNonZeros(IntArrayList,IntArrayList,ObjectArrayList)}.
+
+@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, ObjectArrayList 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++) {
+				Object value = getQuick(slice,row,column);
+				if (value != null) {
+					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 Object getQuick(int slice, int row, int column);
+/**
+ * Returns <tt>true</tt> if both matrices share at least one identical cell.
+ */
+protected boolean haveSharedCells(ObjectMatrix3D 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(ObjectMatrix3D 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>DenseObjectMatrix3D</tt> the new matrix must also be of type <tt>DenseObjectMatrix3D</tt>,
+ * if the receiver is an instance of type <tt>SparseObjectMatrix3D</tt> the new matrix must also be of type <tt>SparseObjectMatrix3D</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 ObjectMatrix3D 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>DenseObjectMatrix3D</tt> the new matrix must also be of type <tt>DenseObjectMatrix3D</tt>,
+ * if the receiver is an instance of type <tt>SparseObjectMatrix3D</tt> the new matrix must also be of type <tt>SparseObjectMatrix3D</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 ObjectMatrix3D 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>DenseObjectMatrix3D</tt> the new matrix must also be of type <tt>DenseObjectMatrix2D</tt>,
+ * if the receiver is an instance of type <tt>SparseObjectMatrix3D</tt> the new matrix must also be of type <tt>SparseObjectMatrix2D</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 ObjectMatrix2D 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, Object 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, Object 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 Object[][][] toArray() {
+	Object[][][] values = new Object[slices][rows][columns];
+	for (int slice=slices; --slice >= 0;) {
+		Object[][] currentSlice = values[slice];
+		for (int row=rows; --row >= 0;) {
+			Object[] 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.objectalgo.Formatter
+ */
+public String toString() {
+	return new org.apache.mahout.colt.matrix.objectalgo.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 ObjectMatrix3D view() {
+	return (ObjectMatrix3D) 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 ObjectMatrix2D 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 ObjectMatrix3D viewColumnFlip() {
+	return (ObjectMatrix3D) (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 ObjectMatrix3D viewDice(int axis0, int axis1, int axis2) {
+	return (ObjectMatrix3D) (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 ObjectMatrix3D viewPart(int slice, int row, int column, int depth, int height, int width) {
+	return (ObjectMatrix3D) (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 ObjectMatrix2D 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 ObjectMatrix3D viewRowFlip() {
+	return (ObjectMatrix3D) (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 ObjectMatrix2D#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 ObjectMatrix3D 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 ObjectMatrix2DProcedure() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public final boolean apply(ObjectMatrix2D 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 ObjectMatrix3D viewSelection(ObjectMatrix2DProcedure 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 ObjectMatrix3D 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 ObjectMatrix2D 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 ObjectMatrix3D viewSliceFlip() {
+	return (ObjectMatrix3D) (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.objectalgo.Sorting#sort(ObjectMatrix3D,int,int)}.
+For more advanced sorting functionality, see {@link org.apache.mahout.colt.matrix.objectalgo.Sorting}.
+@return a new sorted vector (matrix) view.
+@throws IndexOutOfBoundsException if <tt>row < 0 || row >= rows() || column < 0 || column >= columns()</tt>.
+*/
+public ObjectMatrix3D viewSorted(int row, int column) {
+	return org.apache.mahout.colt.matrix.objectalgo.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 ObjectMatrix3D viewStrides(int sliceStride, int rowStride, int columnStride) {
+	return (ObjectMatrix3D) (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.ObjectProcedure 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;
+}
+}

Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectMatrix3D.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectMatrix3DProcedure.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectMatrix3DProcedure.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectMatrix3DProcedure.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectMatrix3DProcedure.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,44 @@
+/*
+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 ObjectMatrix3DProcedure {
+/**
+ * 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);
+/**
+ * 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(ObjectMatrix3D element);
+}

Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/ObjectMatrix3DProcedure.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/BenchmarkKernel.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/BenchmarkKernel.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/BenchmarkKernel.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/BenchmarkKernel.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,101 @@
+/*
+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.bench;
+
+/**
+ * Not yet documented.
+ * 
+ * @author wolfgang.hoschek@cern.ch
+ * @version 1.0, 10-Nov-99
+ */
+class BenchmarkKernel {
+/**
+ * Benchmark constructor comment.
+ */
+protected BenchmarkKernel() {}
+/**
+ * Executes procedure repeatadly until more than minSeconds have elapsed.
+ */
+public static float run(double minSeconds, TimerProcedure procedure) {
+	long iter=0;
+	long minMillis = (long) (minSeconds * 1000);
+	long begin=System.currentTimeMillis();
+	long limit = begin + minMillis;
+	while (System.currentTimeMillis() < limit) {
+		procedure.init();
+		procedure.apply(null);
+		iter++;
+	}
+	long end = System.currentTimeMillis();
+	if (minSeconds/iter < 0.1) { 
+		// unreliable timing due to very fast iteration;
+		// reading, starting and stopping timer distorts measurement
+		// do it again with minimal timer overhead
+		//System.out.println("iter="+iter+", minSeconds/iter="+minSeconds/iter);
+		begin=System.currentTimeMillis();
+		for (long i=iter; --i >= 0; ) {
+			procedure.init();
+			procedure.apply(null);
+		}
+		end = System.currentTimeMillis();
+	}
+
+	long begin2 = System.currentTimeMillis();
+	int dummy=1; // prevent compiler from optimizing away the loop
+	for (long i=iter; --i >= 0; ) {
+		dummy *= i;
+		procedure.init();
+	}
+	long end2 = System.currentTimeMillis();
+	long elapsed = (end-begin) - (end2-begin2);
+	//if (dummy != 0) throw new RuntimeException("dummy != 0");
+	
+	return (float) elapsed/1000.0f / iter;
+}
+/**
+ * Returns a String with the system's properties (vendor, version, operating system, etc.)
+ */
+public static String systemInfo() {
+	String[] properties = {
+		"java.vm.vendor",
+		"java.vm.version",
+		"java.vm.name",
+		"os.name",
+		"os.version",
+		"os.arch",
+		"java.version",
+		"java.vendor",
+		"java.vendor.url"
+		/*
+		"java.vm.specification.version",
+		"java.vm.specification.vendor",
+		"java.vm.specification.name",
+		"java.specification.version",
+		"java.specification.vendor",
+		"java.specification.name"
+		*/
+	};
+
+	// build string matrix
+	org.apache.mahout.colt.matrix.ObjectMatrix2D matrix = new org.apache.mahout.colt.matrix.impl.DenseObjectMatrix2D(properties.length,2);
+	matrix.viewColumn(0).assign(properties);
+
+	// retrieve property values
+	for (int i=0; i<properties.length; i++) {
+		String value = System.getProperty(properties[i]);
+		if (value==null) value = "?"; // prop not available
+		matrix.set(i,1,value);
+	}
+
+	// format matrix
+	org.apache.mahout.colt.matrix.objectalgo.Formatter formatter = new org.apache.mahout.colt.matrix.objectalgo.Formatter();
+	formatter.setPrintShape(false);
+	return formatter.toString(matrix);
+}
+}

Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/BenchmarkKernel.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/BenchmarkMatrix.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/BenchmarkMatrix.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/BenchmarkMatrix.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/BenchmarkMatrix.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,945 @@
+/*
+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.bench;
+
+import org.apache.mahout.colt.matrix.DoubleFactory2D;
+import org.apache.mahout.colt.matrix.DoubleFactory3D;
+import org.apache.mahout.colt.matrix.DoubleMatrix2D;
+import org.apache.mahout.colt.matrix.DoubleMatrix3D;
+/**
+Configurable matrix benchmark.
+Runs the operations defined in main(args) or in the file specified by args.
+To get <a href="doc-files/usage.txt">this overall help</a> on usage type <tt>java org.apache.mahout.colt.matrix.bench.BenchmarkMatrix -help</tt>.
+To get help on usage of a given command, type <tt>java org.apache.mahout.colt.matrix.bench.BenchmarkMatrix -help &lt;command&gt;</tt>.
+Here is the <a href="doc-files/usage_dgemm.txt">help ouput for the dgemm</a> command.
+<a href="../doc-files/dgemmColt1.0.1ibm1.3LxPIII_2.txt">Here</a> is a sample result.
+For more results see the <a href="../doc-files/performanceLog.html">performance log</a>.
+ 
+@author wolfgang.hoschek@cern.ch
+@version 0.5, 10-May-2000
+*/
+/** 
+ * @deprecated until unit tests are in place.  Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public class BenchmarkMatrix {
+/**
+ * Benchmark constructor comment.
+ */
+protected BenchmarkMatrix() {}
+/**
+ * Not yet documented.
+ */
+protected static void bench_dgemm(String[] args) {
+	String[] types;
+	int cpus;
+	double minSecs;
+	boolean transposeA;
+	boolean transposeB;
+	double[] densities;
+	int[] sizes;
+	
+	try { // parse
+		int k = 1;
+		types = new String[] {args[k++]};
+		cpus = Integer.parseInt(args[k++]);
+		minSecs = new Double(args[k++]).doubleValue();
+		densities = new double[] {new Double(args[k++]).doubleValue()};
+		transposeA = new Boolean(args[k++]).booleanValue();
+		transposeB = new Boolean(args[k++]).booleanValue();
+		
+		sizes = new int[args.length - k];
+		for (int i=0; k<args.length; k++, i++) sizes[i] = Integer.parseInt(args[k]);
+	}
+	catch (Exception exc) {
+		System.out.println(usage(args[0]));
+		System.out.println("Ignoring command...\n");
+		return;
+	}
+
+	org.apache.mahout.colt.matrix.linalg.SmpBlas.allocateBlas(cpus, org.apache.mahout.colt.matrix.linalg.SeqBlas.seqBlas);
+	Double2DProcedure fun = fun_dgemm(transposeA,transposeB);
+	String title = fun.toString();
+	String params = transposeA +", "+transposeB+", 1, A, B, 0, C";
+	title = title + " dgemm("+params+")";
+	run(minSecs,title,fun,types,sizes,densities);
+}
+/**
+ * Not yet documented.
+ */
+protected static void bench_dgemv(String[] args) {
+	String[] types;
+	int cpus;
+	double minSecs;
+	boolean transposeA;
+	double[] densities;
+	int[] sizes;
+	
+	try { // parse
+		int k = 1;
+		types = new String[] {args[k++]};
+		cpus = Integer.parseInt(args[k++]);
+		minSecs = new Double(args[k++]).doubleValue();
+		densities = new double[] {new Double(args[k++]).doubleValue()};
+		transposeA = new Boolean(args[k++]).booleanValue();
+		
+		sizes = new int[args.length - k];
+		for (int i=0; k<args.length; k++, i++) sizes[i] = Integer.parseInt(args[k]);
+	}
+	catch (Exception exc) {
+		System.out.println(usage(args[0]));
+		System.out.println("Ignoring command...\n");
+		return;
+	}
+
+	org.apache.mahout.colt.matrix.linalg.SmpBlas.allocateBlas(cpus, org.apache.mahout.colt.matrix.linalg.SeqBlas.seqBlas);
+	Double2DProcedure fun = fun_dgemv(transposeA);
+	String title = fun.toString();
+	String params = transposeA +", 1, A, B, 0, C";
+	title = title + " dgemv("+params+")";
+	run(minSecs,title,fun,types,sizes,densities);
+}
+/**
+ * Not yet documented.
+ */
+protected static void bench_pow(String[] args) {
+	String[] types;
+	int cpus;
+	double minSecs;
+	double[] densities;
+	int exponent;
+	int[] sizes;
+	
+	try { // parse
+		int k = 1;
+		types = new String[] {args[k++]};
+		cpus = Integer.parseInt(args[k++]);
+		minSecs = new Double(args[k++]).doubleValue();
+		densities = new double[] {new Double(args[k++]).doubleValue()};
+		exponent = Integer.parseInt(args[k++]);
+		
+		sizes = new int[args.length - k];
+		for (int i=0; k<args.length; k++, i++) sizes[i] = Integer.parseInt(args[k]);
+	}
+	catch (Exception exc) {
+		System.out.println(usage(args[0]));
+		System.out.println("Ignoring command...\n");
+		return;
+	}
+
+	org.apache.mahout.colt.matrix.linalg.SmpBlas.allocateBlas(cpus, org.apache.mahout.colt.matrix.linalg.SeqBlas.seqBlas);
+	Double2DProcedure fun = fun_pow(exponent);
+	String title = fun.toString();
+	String params = "A,"+exponent;
+	title = title +" pow("+params+")";
+	run(minSecs,title,fun,types,sizes,densities);
+}
+/**
+ * Not yet documented.
+ */
+protected static void benchGeneric(Double2DProcedure fun, String[] args) {
+	String[] types;
+	int cpus;
+	double minSecs;
+	double[] densities;
+	int[] sizes;
+	
+	try { // parse
+		int k = 1;
+		types = new String[] {args[k++]};
+		cpus = Integer.parseInt(args[k++]);
+		minSecs = new Double(args[k++]).doubleValue();
+		densities = new double[] {new Double(args[k++]).doubleValue()};
+		
+		sizes = new int[args.length - k];
+		for (int i=0; k<args.length; k++, i++) sizes[i] = Integer.parseInt(args[k]);
+	}
+	catch (Exception exc) {
+		System.out.println(usage(args[0]));
+		System.out.println("Ignoring command...\n");
+		return;
+	}
+
+	org.apache.mahout.colt.matrix.linalg.SmpBlas.allocateBlas(cpus, org.apache.mahout.colt.matrix.linalg.SeqBlas.seqBlas);
+	String title = fun.toString();
+	run(minSecs,title,fun,types,sizes,densities);
+}
+/**
+ * 
+ */
+protected static String commands() {
+	return "dgemm, dgemv, pow, assign, assignGetSet, assignGetSetQuick, assignLog, assignPlusMult, elementwiseMult, elementwiseMultB, SOR5, SOR8, LUDecompose, LUSolve";
+}
+/**
+ * Linear algebrax matrix-matrix multiply.
+ */
+protected static Double2DProcedure fun_dgemm(final boolean transposeA, final boolean transposeB) {
+	return new Double2DProcedure() {
+		public String toString() { return "Blas matrix-matrix mult";	}
+		public void setParameters(DoubleMatrix2D G, DoubleMatrix2D H) {
+			super.setParameters(G,H);
+			D = new org.apache.mahout.colt.matrix.impl.DenseDoubleMatrix2D(A.rows(),A.columns()).assign(0.5);
+			C = D.copy();
+			B = D.copy();
+		}
+		public void init() { C.assign(D); }
+		public void apply(org.apache.mahout.colt.Timer timer) {
+			org.apache.mahout.colt.matrix.linalg.SmpBlas.smpBlas.dgemm(transposeA,transposeB,1,A,B,0,C);
+		}
+		public double operations() { // Mflops
+			double m = A.rows();
+			double n = A.columns();
+			double p = B.columns();
+			return 2.0*m*n*p / 1.0E6; 
+		}
+	};
+}
+/**
+ * Linear algebrax matrix-matrix multiply.
+ */
+protected static Double2DProcedure fun_dgemv(final boolean transposeA) {
+	return new Double2DProcedure() { 
+		public String toString() { return "Blas matrix-vector mult";	}
+		public void setParameters(DoubleMatrix2D G, DoubleMatrix2D H) {
+			super.setParameters(G,H);
+			D = new org.apache.mahout.colt.matrix.impl.DenseDoubleMatrix2D(A.rows(),A.columns()).assign(0.5);
+			C = D.copy();
+			B = D.copy();
+		}
+		public void init() { C.viewRow(0).assign(D.viewRow(0)); }
+		public void apply(org.apache.mahout.colt.Timer timer) {
+			org.apache.mahout.colt.matrix.linalg.SmpBlas.smpBlas.dgemv(transposeA,1,A,B.viewRow(0),0,C.viewRow(0));
+		}
+		public double operations() { // Mflops
+			double m = A.rows();
+			double n = A.columns();
+			//double p = B.columns();
+			return 2.0*m*n / 1.0E6; 
+		}
+	};
+}
+/**
+ * 2D assign with get,set
+ */
+protected static Double2DProcedure fun_pow(final int k) {
+	return new Double2DProcedure() {
+		public double dummy;
+		public String toString() { return "matrix to the power of an exponent";	}
+		public void setParameters(DoubleMatrix2D A, DoubleMatrix2D B) {
+			if (k<0) { // must be nonsingular for inversion
+				if (!org.apache.mahout.colt.matrix.linalg.Property.ZERO.isDiagonallyDominantByRow(A) ||
+					!org.apache.mahout.colt.matrix.linalg.Property.ZERO.isDiagonallyDominantByColumn(A)) {
+						org.apache.mahout.colt.matrix.linalg.Property.ZERO.generateNonSingular(A);
+					}
+				super.setParameters(A,B);
+			}
+		}
+
+		public void init() {}		
+		public void apply(org.apache.mahout.colt.Timer timer) {
+			org.apache.mahout.colt.matrix.linalg.Algebra.DEFAULT.pow(A,k);
+		}
+		public double operations() { // Mflops
+			double m = A.rows();
+			if (k==0) return m; // identity
+			double mflops = 0;
+			if (k<0) {
+				// LU.decompose
+				double N = Math.min(A.rows(),A.columns());
+				mflops += (2.0 * N*N*N / 3.0 / 1.0E6);
+
+				// LU.solve
+				double n = A.columns();
+				double nx = B.columns();
+				mflops += (2.0 * nx*(n*n + n) / 1.0E6); 
+			}
+			// mult
+			mflops += 2.0*(Math.abs(k)-1)*m*m*m / 1.0E6;
+			return mflops; 
+		}
+	};
+}
+/**
+ * 2D assign with A.assign(B)
+ */
+protected static Double2DProcedure funAssign() {
+	return new Double2DProcedure() {
+		public String toString() { return "A.assign(B) [Mops/sec]";	}
+		public void init() { A.assign(0); }		
+		public void apply(org.apache.mahout.colt.Timer timer) {
+			A.assign(B);
+		}
+	};
+}
+/**
+ * 2D assign with get,set
+ */
+protected static Double2DProcedure funAssignGetSet() {
+	return new Double2DProcedure() { 
+		public String toString() { return "A.assign(B) via get and set [Mops/sec]";	}
+		public void init() { A.assign(0); }		
+		public void apply(org.apache.mahout.colt.Timer timer) {
+			int rows=B.rows();
+			int columns=B.columns();
+			/*
+			for (int row=rows; --row >= 0; ) {
+				for (int column=columns; --column >= 0; ) {
+					A.set(row,column, B.get(row,column));
+				}
+			}
+			*/
+			for (int row=0; row < rows; row++) {
+				for (int column=0; column < columns; column++) {
+					A.set(row,column, B.get(row,column));
+				}
+			}
+		}
+	};
+}
+/**
+ * 2D assign with getQuick,setQuick
+ */
+protected static Double2DProcedure funAssignGetSetQuick() {
+	return new Double2DProcedure() { 
+		public String toString() { return "A.assign(B) via getQuick and setQuick [Mops/sec]";	}
+		public void init() { A.assign(0); }		
+		public void apply(org.apache.mahout.colt.Timer timer) {
+			int rows=B.rows();
+			int columns=B.columns();
+			//for (int row=rows; --row >= 0; ) {
+			//	for (int column=columns; --column >= 0; ) {
+			for (int row=0; row < rows; row++) {
+				for (int column=0; column < columns; column++) {
+					A.setQuick(row,column, B.getQuick(row,column));
+				}
+			}
+		}
+	};
+}
+/**
+ * 2D assign with A.assign(B)
+ */
+protected static Double2DProcedure funAssignLog() {
+	return new Double2DProcedure() { 
+		public String toString() { return "A[i,j] = log(A[i,j]) via Blas.assign(fun) [Mflops/sec]";	}
+		public void init() { A.assign(C); }		
+		public void apply(org.apache.mahout.colt.Timer timer) {
+			org.apache.mahout.colt.matrix.linalg.SmpBlas.smpBlas.assign(A, org.apache.mahout.jet.math.Functions.log);
+		}
+	};
+}
+/**
+ * 2D assign with A.assign(B)
+ */
+protected static Double2DProcedure funAssignPlusMult() {
+	return new Double2DProcedure() { 
+		public String toString() { return "A[i,j] = A[i,j] + s*B[i,j] via Blas.assign(fun) [Mflops/sec]";	}
+		public void init() { A.assign(C); }		
+		public void apply(org.apache.mahout.colt.Timer timer) {
+			org.apache.mahout.colt.matrix.linalg.SmpBlas.smpBlas.assign(A,B, org.apache.mahout.jet.math.Functions.plusMult(0.5));
+		}
+		public double operations() { // Mflops
+			double m = A.rows();
+			double n = A.columns();
+			return 2*m*n / 1.0E6; 
+		}
+	};
+}
+/**
+ * Linear algebrax matrix-matrix multiply.
+ */
+protected static Double2DProcedure funCorrelation() {
+	return new Double2DProcedure() { 
+		public String toString() { return "xxxxxxx";	}
+		public void init() {  }		
+		public void setParameters(DoubleMatrix2D A, DoubleMatrix2D B) {
+			super.setParameters(A.viewDice(),B); // transposed --> faster (memory aware) iteration in correlation algo
+		}
+		public void apply(org.apache.mahout.colt.Timer timer) {
+			org.apache.mahout.colt.matrix.doublealgo.Statistic.correlation(
+				org.apache.mahout.colt.matrix.doublealgo.Statistic.covariance(A));
+		}
+		public double operations() { // Mflops
+			double m = A.rows();
+			double n = A.columns();
+			return m*(n*n + n) / 1.0E6; 
+		}
+	};
+}
+/**
+ * Element-by-element matrix-matrix multiply.
+ */
+protected static Double2DProcedure funElementwiseMult() {
+	return new Double2DProcedure() { 
+		public String toString() { return "A.assign(F.mult(0.5)) via Blas [Mflops/sec]";	}
+		public void init() { A.assign(C); }		
+		public void apply(org.apache.mahout.colt.Timer timer) {
+			org.apache.mahout.colt.matrix.linalg.SmpBlas.smpBlas.assign(A, org.apache.mahout.jet.math.Functions.mult(0.5));
+		}
+	};
+}
+/**
+ * Element-by-element matrix-matrix multiply.
+ */
+protected static Double2DProcedure funElementwiseMultB() {
+	return new Double2DProcedure() { 
+		public String toString() { return "A.assign(B,F.mult) via Blas [Mflops/sec]";	}
+		public void init() { A.assign(C); }		
+		public void apply(org.apache.mahout.colt.Timer timer) {
+			org.apache.mahout.colt.matrix.linalg.SmpBlas.smpBlas.assign(A,B, org.apache.mahout.jet.math.Functions.mult);
+		}
+	};
+}
+/**
+ * 2D assign with get,set
+ */
+protected static Double2DProcedure funGetQuick() {
+	return new Double2DProcedure() {
+		public double dummy;
+		public String toString() { return "xxxxxxx";	}
+		public void init() {}		
+		public void apply(org.apache.mahout.colt.Timer timer) {
+			int rows=B.rows();
+			int columns=B.columns();
+			double sum =0;
+			//for (int row=rows; --row >= 0; ) {
+			//	for (int column=columns; --column >= 0; ) {
+			for (int row=0; row < rows; row++) {
+				for (int column=0; column < columns; column++) {
+					sum += A.getQuick(row,column);
+				}
+			}
+			dummy = sum;
+		}
+	};
+}
+/**
+ * 2D assign with getQuick,setQuick
+ */
+protected static Double2DProcedure funLUDecompose() {
+	return new Double2DProcedure() {
+		org.apache.mahout.colt.matrix.linalg.LUDecompositionQuick lu = new org.apache.mahout.colt.matrix.linalg.LUDecompositionQuick(0);
+		public String toString() { return "LU.decompose(A) [Mflops/sec]";	}
+		public void init() { A.assign(C); }
+		public void apply(org.apache.mahout.colt.Timer timer) {
+			lu.decompose(A);	
+		}
+		public double operations() { // Mflops
+			double N = Math.min(A.rows(),A.columns());
+			return (2.0 * N*N*N / 3.0 / 1.0E6); 
+		}
+	};
+}
+/**
+ * 2D assign with getQuick,setQuick
+ */
+protected static Double2DProcedure funLUSolve() {
+	return new Double2DProcedure() {
+		org.apache.mahout.colt.matrix.linalg.LUDecompositionQuick lu;
+		public String toString() { return "LU.solve(A) [Mflops/sec]";	}
+		public void setParameters(DoubleMatrix2D A, DoubleMatrix2D B) {
+			lu = null;
+			if (!org.apache.mahout.colt.matrix.linalg.Property.ZERO.isDiagonallyDominantByRow(A) ||
+				!org.apache.mahout.colt.matrix.linalg.Property.ZERO.isDiagonallyDominantByColumn(A)) {
+					org.apache.mahout.colt.matrix.linalg.Property.ZERO.generateNonSingular(A);
+				}
+			super.setParameters(A,B);
+			lu = new org.apache.mahout.colt.matrix.linalg.LUDecompositionQuick(0);
+			lu.decompose(A);
+		}
+		public void init() { B.assign(D); }
+		public void apply(org.apache.mahout.colt.Timer timer) {
+			lu.solve(B);	
+		}
+		public double operations() { // Mflops
+			double n = A.columns();
+			double nx = B.columns();
+			return (2.0 * nx*(n*n + n) / 1.0E6); 
+		}
+	};
+}
+/**
+ * Linear algebrax matrix-matrix multiply.
+ */
+protected static Double2DProcedure funMatMultLarge() {
+	return new Double2DProcedure() {
+		public String toString() { return "xxxxxxx";	}
+		public void setParameters(DoubleMatrix2D A, DoubleMatrix2D B) {
+			// do not allocate mem for "D" --> safe some mem
+			this.A = A;
+			this.B = B;
+			this.C = A.copy();
+		}
+		public void init() { C.assign(0); }
+		public void apply(org.apache.mahout.colt.Timer timer) { A.zMult(B,C); }
+		public double operations() { // Mflops
+			double m = A.rows();
+			double n = A.columns();
+			double p = B.columns();
+			return 2.0*m*n*p / 1.0E6; 
+		}
+	};
+}
+/**
+ * Linear algebrax matrix-vector multiply.
+ */
+protected static Double2DProcedure funMatVectorMult() {
+	return new Double2DProcedure() { 
+		public String toString() { return "xxxxxxx";	}
+		public void setParameters(DoubleMatrix2D G, DoubleMatrix2D H) {
+			super.setParameters(G,H);
+			D = new org.apache.mahout.colt.matrix.impl.DenseDoubleMatrix2D(A.rows(),A.columns()).assign(0.5);
+			C = D.copy();
+			B = D.copy();
+		}
+		public void init() { C.viewRow(0).assign(D.viewRow(0)); }
+		public void apply(org.apache.mahout.colt.Timer timer) { A.zMult(B.viewRow(0),C.viewRow(0)); }
+		public double operations() { // Mflops
+			double m = A.rows();
+			double n = A.columns();
+			//double p = B.columns();
+			return 2.0*m*n / 1.0E6; 
+		}
+	};
+}
+/**
+ * 2D assign with get,set
+ */
+protected static Double2DProcedure funSetQuick() {
+	return new Double2DProcedure() {
+		private int current;
+		private double density;
+		public String toString() { return "xxxxxxx";	}
+		public void init() { 
+			A.assign(0);
+			int seed = 123456;
+			current = 4*seed+1;
+			density = A.cardinality() / (double) A.size();
+		}		
+		public void apply(org.apache.mahout.colt.Timer timer) {
+			int rows=B.rows();
+			int columns=B.columns();
+			//for (int row=rows; --row >= 0; ) {
+			//	for (int column=columns; --column >= 0; ) {
+			for (int row=0; row < rows; row++) {
+				for (int column=0; column < columns; column++) {
+					// a very fast random number generator (this is an inline version of class org.apache.mahout.jet.random.engine.DRand)
+					current *= 0x278DDE6D;
+					double random = (double) (current & 0xFFFFFFFFL) * 2.3283064365386963E-10;
+					// random uniform in (0.0,1.0)
+					if (random < density) 
+						A.setQuick(row,column,random);
+					else
+						A.setQuick(row,column,0);
+				}
+			}
+		}
+	};
+}
+/**
+ * 
+ */
+protected static Double2DProcedure funSOR5() {
+	return new Double2DProcedure() {
+		double value = 2; 
+		double omega = 1.25;
+		final double alpha = omega * 0.25;
+		final double beta = 1-omega;
+		org.apache.mahout.colt.function.Double9Function function = new org.apache.mahout.colt.function.Double9Function() {
+			public final double apply(	
+				double a00, double a01, double a02,
+				double a10, double a11, double a12,
+				double a20, double a21, double a22) {
+				return alpha*a11 + beta*(a01+a10+a12+a21);
+			}
+		};
+		public String toString() { return "A.zAssign8Neighbors(5 point function) [Mflops/sec]";	}
+		public void init() { B.assign(D); }
+		public void apply(org.apache.mahout.colt.Timer timer) { A.zAssign8Neighbors(B,function); }
+		public double operations() { // Mflops
+			double n = A.columns();
+			double m = A.rows();
+			return 6.0 * m*n / 1.0E6; 
+		}
+	};
+}
+/**
+ * 
+ */
+protected static Double2DProcedure funSOR8() {
+	return new Double2DProcedure() {
+		double value = 2;
+		double omega = 1.25;
+		final double alpha = omega * 0.25;
+		final double beta = 1-omega;
+		org.apache.mahout.colt.function.Double9Function function = new org.apache.mahout.colt.function.Double9Function() {
+			public final double apply(	
+				double a00, double a01, double a02,
+				double a10, double a11, double a12,
+				double a20, double a21, double a22) {
+				return alpha*a11 + beta*(a00+a10+a20+a01+a21+a02+a12+a22);
+			}
+		};
+		public String toString() { return "A.zAssign8Neighbors(9 point function) [Mflops/sec]";	}
+		public void init() { B.assign(D); }
+		public void apply(org.apache.mahout.colt.Timer timer) { A.zAssign8Neighbors(B,function); }
+		public double operations() { // Mflops
+			double n = A.columns();
+			double m = A.rows();
+			return 10.0 * m*n / 1.0E6; 
+		}
+	};
+}
+/**
+ * 
+ */
+protected static Double2DProcedure funSort() {
+	return new Double2DProcedure() { 
+		public String toString() { return "xxxxxxx";	}
+		public void init() { A.assign(C); }
+		public void apply(org.apache.mahout.colt.Timer timer) { A.viewSorted(0); }
+	};
+}
+/**
+ * Not yet documented.
+ */
+protected static DoubleFactory2D getFactory(String type) {
+	DoubleFactory2D factory;
+	if (type.equals("dense")) return DoubleFactory2D.dense;
+	if (type.equals("sparse")) return DoubleFactory2D.sparse;
+	if (type.equals("rowCompressed")) return DoubleFactory2D.rowCompressed;
+	String s = "type="+type+" is unknown. Use one of {dense,sparse,rowCompressed}";
+	throw new IllegalArgumentException(s);
+}
+/**
+ * Not yet documented.
+ */
+protected static Double2DProcedure getGenericFunction(String cmd) {
+	if (cmd.equals("dgemm")) return fun_dgemm(false,false);
+	else if (cmd.equals("dgemv")) return fun_dgemv(false);
+	else if (cmd.equals("pow")) return fun_pow(2);
+	else if (cmd.equals("assign")) return funAssign();
+	else if (cmd.equals("assignGetSet")) return funAssignGetSet();
+	else if (cmd.equals("assignGetSetQuick")) return funAssignGetSetQuick();
+	else if (cmd.equals("elementwiseMult")) return funElementwiseMult();
+	else if (cmd.equals("elementwiseMultB")) return funElementwiseMultB();
+	else if (cmd.equals("SOR5")) return funSOR5();
+	else if (cmd.equals("SOR8")) return funSOR8();
+	else if (cmd.equals("LUDecompose")) return funLUDecompose();
+	else if (cmd.equals("LUSolve")) return funLUSolve();
+	else if (cmd.equals("assignLog")) return funAssignLog();
+	else if (cmd.equals("assignPlusMult")) return funAssignPlusMult();
+	/*
+	else if (cmd.equals("xxxxxxxxxxxxxxxxx")) return xxxxx();
+	}
+	*/
+	return null;
+}
+/**
+ * Executes a command
+ */
+protected static boolean handle(String[] params) {
+	boolean success = true;
+	String cmd = params[0];
+	if (cmd.equals("dgemm")) bench_dgemm(params);
+	else if (cmd.equals("dgemv")) bench_dgemv(params);
+	else if (cmd.equals("pow")) bench_pow(params);
+	else {
+		Double2DProcedure fun = getGenericFunction(cmd);
+		if (fun!=null) {
+			benchGeneric(fun,params);
+		}
+		else {
+			success = false;
+			String s = "Command="+params[0]+" is illegal or unknown. Should be one of "+commands()+"followed by appropriate parameters.\n"+usage()+"\nIgnoring this line.\n";
+			System.out.println(s);
+		}
+	}				
+	return success;
+}
+/**
+ * Runs the matrix benchmark operations defined in args or in the file specified by args0.
+ * To get detailed help on usage type java org.apache.mahout.colt.matrix.bench.BenchmarkMatrix -help
+ */
+public static void main(String[] args) {
+	int n = args.length;
+	if (n==0 || (n<=1 && args[0].equals("-help"))) { // overall help
+		System.out.println(usage());
+		return;
+	}
+	if (args[0].equals("-help")) { // help on specific command
+		if (commands().indexOf(args[1]) < 0) {
+			System.out.println(args[1]+": no such command available.\n"+usage());
+		}
+		else {
+			System.out.println(usage(args[1]));
+		}
+		return;
+	}
+		
+	System.out.println("Colt Matrix benchmark running on\n");
+	System.out.println(BenchmarkKernel.systemInfo()+"\n");
+    // TODO print out real version info?
+	System.out.println("Colt Version is [unknown - now in Mahout]" + "\n");
+
+	org.apache.mahout.colt.Timer timer = new org.apache.mahout.colt.Timer().start();
+	if (!args[0].equals("-file")) { // interactive mode, commands supplied via java class args
+		System.out.println("\n\nExecuting command = "+new org.apache.mahout.colt.list.ObjectArrayList(args)+" ...");
+		handle(args);
+	}
+	else { // batch mode, read commands from file
+		/* 
+		parse command file in args[0]
+		one command per line (including parameters)
+		for example:
+		// dgemm dense 2 2.0 false true 0.999 10 30 50 100 250 500 1000
+		dgemm dense 2 2.5 false true 0.999 10 50 
+		dgemm sparse 2 2.5 false true 0.001 500 1000  
+		*/
+		java.io.BufferedReader reader=null;
+		try {
+			reader = new java.io.BufferedReader(new java.io.FileReader(args[1]));
+		} catch (java.io.IOException exc) { throw new RuntimeException(exc.getMessage()); }
+		
+		java.io.StreamTokenizer stream = new java.io.StreamTokenizer(reader);
+		stream.eolIsSignificant(true);
+		stream.slashSlashComments(true); // allow // comments
+		stream.slashStarComments(true);  // allow /* comments */
+		try {
+			org.apache.mahout.colt.list.ObjectArrayList words = new org.apache.mahout.colt.list.ObjectArrayList();
+			int token;
+			while ((token = stream.nextToken()) != stream.TT_EOF) { // while not end of file
+				if (token == stream.TT_EOL) { // execute a command line at a time
+					//System.out.println(words);
+					if (words.size() > 0) { // ignore emty lines
+						String[] params = new String[words.size()];
+						for (int i=0; i<words.size(); i++) params[i] = (String) words.get(i);
+
+						// execute command
+						System.out.println("\n\nExecuting command = "+words+" ...");
+						handle(params);
+					}
+					words.clear();
+				}
+				else {
+					String word;
+					org.apache.mahout.colt.matrix.impl.Former formatter = new org.apache.mahout.colt.matrix.impl.FormerFactory().create("%G");
+					// ok: 2.0 -> 2   wrong: 2.0 -> 2.0 (kills Integer.parseInt())
+					if (token == stream.TT_NUMBER) 
+						word = formatter.form(stream.nval);
+					else 
+						word = stream.sval;
+					if (word != null) words.add(word);
+				}
+			}
+			reader.close();
+
+			System.out.println("\nCommand file name used: "+args[1]+ "\nTo reproduce and compare results, here it's contents:");
+			try {
+				reader = new java.io.BufferedReader(new java.io.FileReader(args[1]));
+			} catch (java.io.IOException exc) { throw new RuntimeException(exc.getMessage()); }
+
+			/*java.io.InputStream input = new java.io.DataInputStream(new java.io.BufferedInputStream(new java.io.FileInputStream(args[1])));
+			BufferedReader d
+						   = new BufferedReader(new InputStreamReader(in));
+						   */
+			String line;
+			while ((line = reader.readLine()) != null) { // while not end of file
+				System.out.println(line);
+			}
+			reader.close();
+			
+		} catch (java.io.IOException exc) { throw new RuntimeException(exc.getMessage()); }
+	}
+	
+	System.out.println("\nProgram execution took a total of "+timer.minutes() +" minutes.");
+	System.out.println("Good bye.");
+}
+/**
+ * Executes procedure repeatadly until more than minSeconds have elapsed.
+ */
+protected static void run(double minSeconds, String title, Double2DProcedure function, String[] types, int[] sizes, double[] densities) {
+	//int[] sizes = {33,500,1000};
+	//double[] densities = {0.001,0.01,0.99};
+	
+	//int[] sizes = {3,5,7,9,30,45,60,61,100,200,300,500,800,1000};
+	//double[] densities = {0.001,0.01,0.1,0.999};
+	
+	//int[] sizes = {3};
+	//double[] densities = {0.1};
+
+	DoubleMatrix3D timings = DoubleFactory3D.dense.make(types.length,sizes.length,densities.length);
+	org.apache.mahout.colt.Timer runTime = new org.apache.mahout.colt.Timer().start();
+	for (int k=0; k<types.length; k++) {
+		//DoubleFactory2D factory = (k==0 ? DoubleFactory2D.dense : k==1 ? DoubleFactory2D.sparse : DoubleFactory2D.rowCompressed);
+		//DoubleFactory2D factory = (k==0 ? DoubleFactory2D.dense : k==1 ? DoubleFactory2D.sparse : k==2 ? DoubleFactory2D.rowCompressed : DoubleFactory2D.rowCompressedModified);
+		DoubleFactory2D factory = getFactory(types[k]);
+		System.out.print("\n@"); 
+
+		for (int i=0; i<sizes.length; i++) {
+			int size = sizes[i];
+			System.out.print("x");
+			//System.out.println("doing size="+size+"...");
+
+			for (int j=0; j<densities.length; j++) {
+				final double density = densities[j];
+				System.out.print(".");
+				//System.out.println("   doing density="+density+"...");
+				float opsPerSec;
+
+				//if (true) {
+				//if (!((k==1 && density >= 0.1 && size >=100) || (size>5000 && (k==0 || density>1.0E-4) ))) {
+				if (!((k>0 && density >= 0.1 && size >=500) )) {
+					double val = 0.5;
+					function.A=null; function.B=null; function.C=null; function.D=null; // --> help gc before allocating new mem
+					DoubleMatrix2D A = factory.sample(size,size,val,density);
+					DoubleMatrix2D B = factory.sample(size,size,val,density);
+					function.setParameters(A,B);
+					A = null; B = null; // help gc
+					double ops = function.operations();
+					double secs = BenchmarkKernel.run(minSeconds,function);
+					opsPerSec = (float) (ops / secs);
+				}
+				else { // skip this parameter combination (not used in practice & would take a lot of memory and time)
+					opsPerSec = Float.NaN;
+				}
+				timings.set(k,i,j,opsPerSec);
+				//System.out.println(secs);
+				//System.out.println(opsPerSec+" Mops/sec\n");
+			}
+		}
+	}
+	runTime.stop();
+	
+	String sliceAxisName = "type";
+	String rowAxisName = "size"; 
+	String colAxisName = "d"; //"density";
+	//String[] sliceNames = {"dense", "sparse"};
+	//String[] sliceNames = {"dense", "sparse", "rowCompressed"};
+	String[] sliceNames = types;
+	//hep.aida.bin.BinFunctions1D F = hep.aida.bin.BinFunctions1D.functions;
+	//hep.aida.bin.BinFunction1D[] aggr = null; //{F.mean, F.median, F.sum};
+	String[] rowNames = new String[sizes.length];
+	String[] colNames = new String[densities.length];
+	for (int i=sizes.length; --i >= 0; ) rowNames[i]=Integer.toString(sizes[i]);
+	for (int j=densities.length; --j >= 0; ) colNames[j]=Double.toString(densities[j]);
+	System.out.println("*");
+	// show transposed
+	String tmp = rowAxisName; rowAxisName = colAxisName; colAxisName = tmp;
+	String[] tmp2 = rowNames; rowNames = colNames; colNames = tmp2;
+	timings = timings.viewDice(0,2,1);
+	//System.out.println(new org.apache.mahout.colt.matrix.doublealgo.Formatter("%1.3G").toTitleString(timings,sliceNames,rowNames,colNames,sliceAxisName,rowAxisName,colAxisName,"Performance of "+title,aggr));
+	/*
+	title = "Speedup of dense over sparse";
+	DoubleMatrix2D speedup = org.apache.mahout.colt.matrix.doublealgo.Transform.div(timings.viewSlice(0).copy(),timings.viewSlice(1));
+	System.out.println("\n"+new org.apache.mahout.colt.matrix.doublealgo.Formatter("%1.3G").toTitleString(speedup,rowNames,colNames,rowAxisName,colAxisName,title,aggr));
+	*/
+	System.out.println("Run took a total of "+runTime+". End of run.");
+}
+/**
+ * Executes procedure repeatadly until more than minSeconds have elapsed.
+ */
+protected static void runSpecial(double minSeconds, String title, Double2DProcedure function) {
+	int[] sizes =        {10000};
+	double[] densities = {0.00001};
+	boolean[] sparses  = {true};
+	
+	DoubleMatrix2D timings = DoubleFactory2D.dense.make(sizes.length,4);
+	org.apache.mahout.colt.Timer runTime = new org.apache.mahout.colt.Timer().start();
+	for (int i=0; i<sizes.length; i++) {
+		int size = sizes[i];
+		double density = densities[i];
+		boolean sparse = sparses[i];
+		final DoubleFactory2D factory = (sparse ? DoubleFactory2D.sparse : DoubleFactory2D.dense);
+		System.out.print("\n@"); 
+
+		System.out.print("x");
+		double val = 0.5;
+		function.A=null; function.B=null; function.C=null; function.D=null; // --> help gc before allocating new mem
+		DoubleMatrix2D A = factory.sample(size,size,val,density);
+		DoubleMatrix2D B = factory.sample(size,size,val,density);
+		function.setParameters(A,B);
+		A = null; B = null; // help gc
+		float secs = BenchmarkKernel.run(minSeconds,function);
+		double ops = function.operations();
+		float opsPerSec = (float) (ops / secs);
+		timings.viewRow(i).set(0,sparse ? 0: 1);
+		timings.viewRow(i).set(1,size);
+		timings.viewRow(i).set(2,density);
+		timings.viewRow(i).set(3,opsPerSec);
+		//System.out.println(secs);
+		//System.out.println(opsPerSec+" Mops/sec\n");
+	}
+	runTime.stop();
+	
+	//hep.aida.bin.BinFunctions1D F = hep.aida.bin.BinFunctions1D.functions;
+	//hep.aida.bin.BinFunction1D[] aggr = null; //{F.mean, F.median, F.sum};
+	String[] rowNames = null;
+	String[] colNames = {"dense (y=1,n=0)", "size", "density", "flops/sec"};
+	String rowAxisName = null;
+	String colAxisName = null;
+	System.out.println("*");
+	//System.out.println(new org.apache.mahout.colt.matrix.doublealgo.Formatter("%1.3G").toTitleString(timings,rowNames,colNames,rowAxisName,colAxisName,title,aggr));
+
+	System.out.println("Run took a total of "+runTime+". End of run.");
+}
+/**
+ * Overall usage.
+ */
+protected static String usage() {
+	String usage = 
+"\nUsage (help): To get this help, type java org.apache.mahout.colt.matrix.bench.BenchmarkMatrix -help\n"+
+"To get help on a command's args, omit args and type java org.apache.mahout.colt.matrix.bench.BenchmarkMatrix -help <command>\n" +
+"Available commands: "+commands()+"\n\n"+
+
+"Usage (direct): java org.apache.mahout.colt.matrix.bench.BenchmarkMatrix command {args}\n"+
+"Example: dgemm dense 2 2.0 0.999 false true 5 10 25 50 100 250 500\n\n"+
+
+"Usage (batch mode): java org.apache.mahout.colt.matrix.bench.BenchmarkMatrix -file <file>\nwhere <file> is a text file with each line holding a command followed by appropriate args (comments and empty lines ignored).\n\n"+
+"Example file's content:\n" +
+"dgemm dense 1 2.0 0.999 false true 5 10 25 50 100 250 500\n"+
+"dgemm dense 2 2.0 0.999 false true 5 10 25 50 100 250 500\n\n"+
+"/*\n"+
+"Java like comments in file are ignored\n"+
+"dgemv dense 1 2.0 0.001 false 5 10 25 50 100 250 500 1000\n"+
+"dgemv sparse 1 2.0 0.001 false 5 10 25 50 100 250 500 1000\n"+
+"dgemv rowCompressed 1 2.0 0.001 false 5 10 25 50 100 250 500 1000\n"+
+"*/\n"+
+"// more comments ignored\n";
+	return usage;
+}
+/**
+ * Usage of a specific command.
+ */
+protected static String usage(String cmd) {
+	String usage = cmd + " description: " + getGenericFunction(cmd).toString() +
+	"\nArguments to be supplied:\n" +
+	//String usage = "Illegal arguments! Arguments to be supplied:\n" +
+		//"\te.g. "+cmd+" dense 2 2.0 false 0.999 10 30 50 100 250 500 1000\n"+
+		"\t<operation> <type> <cpus> <minSecs> <density>";
+	if (cmd.equals("dgemv")) usage = usage +	" <transposeA>";
+	if (cmd.equals("dgemm")) usage = usage +	" <transposeA> <transposeB>";
+	if (cmd.equals("pow")) usage = usage +	" <exponent>";
+	usage = usage +
+		" {sizes}\n" +
+		"where\n" +
+		"\toperation = the operation to benchmark; in this case: "+cmd+"\n"+
+		"\ttype = matrix type to be used; e.g. dense, sparse or rowCompressed\n"+
+		"\tcpus = #cpus available; e.g. 1 or 2 or ...\n"+
+		"\tminSecs = #seconds each operation shall at least run; e.g. 2.0 is a good number giving realistic timings\n"+
+		"\tdensity = the density of the matrices to be benchmarked; e.g. 0.999 is very dense, 0.001 is very sparse\n";
+		
+	if (cmd.equals("dgemv")) usage = usage +	"\ttransposeA = false or true\n";
+	if (cmd.equals("dgemm")) usage = usage +	"\ttransposeA = false or true\n\ttransposeB = false or true\n";
+	if (cmd.equals("pow")) usage = usage +	"\texponent = the number of times to multiply; e.g. 1000\n";
+	usage = usage +
+		"\tsizes = a list of problem sizes; e.g. 100 200 benchmarks squared 100x100 and 200x200 matrices";
+	return usage;
+}
+}

Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/BenchmarkMatrix.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/Double2DProcedure.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/Double2DProcedure.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/Double2DProcedure.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/Double2DProcedure.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,33 @@
+/*
+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.bench;
+
+import org.apache.mahout.colt.matrix.DoubleMatrix2D;
+
+abstract class Double2DProcedure implements TimerProcedure {
+	public DoubleMatrix2D A;
+	public DoubleMatrix2D B;
+	public DoubleMatrix2D C;
+	public DoubleMatrix2D D;
+/**
+ * The number of operations a single call to "apply" involves.
+ */
+public double operations() {
+	return A.rows()*A.columns() / 1.0E6;
+}
+/**
+ * Sets the matrices to operate upon.
+ */
+public void setParameters(DoubleMatrix2D A, DoubleMatrix2D B) {
+	this.A=A;
+	this.B=B;
+	this.C=A.copy();
+	this.D=B.copy();
+}
+}

Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/Double2DProcedure.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/TimerProcedure.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/TimerProcedure.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/TimerProcedure.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/TimerProcedure.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.bench;
+
+/**
+ * Interface that represents a procedure object: a procedure that takes 
+ * a single argument and does not return a value.
+ */
+interface TimerProcedure {
+/**
+ * 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.
+ */
+public void apply(org.apache.mahout.colt.Timer element);
+/**
+ * Prepare parameters before calling apply()
+ */
+public void init();
+}

Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/TimerProcedure.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/doc-files/usage.txt
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/doc-files/usage.txt?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/doc-files/usage.txt (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/doc-files/usage.txt Mon Nov 23 15:14:26 2009
@@ -0,0 +1,23 @@
+
+Usage (help): To get this help, type java org.apache.mahout.colt.matrix.bench.BenchmarkMatrix -help
+To get help on a command's args, omit args and type java org.apache.mahout.colt.matrix.bench.BenchmarkMatrix -help <command>
+Available commands: dgemm, dgemv, pow, assign, assignGetSet, assignGetSetQuick, assignLog, assignPlusMult, elementwiseMult, elementwiseMultB, SOR5, SOR8, LUDecompose, LUSolve
+
+Usage (direct): java org.apache.mahout.colt.matrix.bench.BenchmarkMatrix command {args}
+Example: dgemm dense 2 2.0 0.999 false true 5 10 25 50 100 250 500
+
+Usage (batch mode): java org.apache.mahout.colt.matrix.bench.BenchmarkMatrix -file <file>
+where <file> is a text file with each line holding a command followed by appropriate args (comments and empty lines ignored).
+
+Example file's content:
+dgemm dense 1 2.0 0.999 false true 5 10 25 50 100 250 500
+dgemm dense 2 2.0 0.999 false true 5 10 25 50 100 250 500
+
+/*
+Java like comments in file are ignored
+dgemv dense 1 2.0 0.001 false 5 10 25 50 100 250 500 1000
+dgemv sparse 1 2.0 0.001 false 5 10 25 50 100 250 500 1000
+dgemv rowCompressed 1 2.0 0.001 false 5 10 25 50 100 250 500 1000
+*/
+// more comments ignored
+

Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/bench/doc-files/usage.txt
------------------------------------------------------------------------------
    svn:eol-style = native