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 [37/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/impl/DenseDoubleMatrix2D.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseDoubleMatrix2D.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseDoubleMatrix2D.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseDoubleMatrix2D.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,817 @@
+/*
+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.impl;
+
+import org.apache.mahout.colt.matrix.DoubleMatrix1D;
+import org.apache.mahout.colt.matrix.DoubleMatrix2D;
+/**
+Dense 2-d matrix 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>
+<b>Implementation:</b>
+<p>
+Internally holds one single contigous one-dimensional array, addressed in row major. 
+Note that this implementation is not synchronized.
+<p>
+<b>Memory requirements:</b>
+<p>
+<tt>memory [bytes] = 8*rows()*columns()</tt>.
+Thus, a 1000*1000 matrix uses 8 MB.
+<p>
+<b>Time complexity:</b>
+<p>
+<tt>O(1)</tt> (i.e. constant time) for the basic operations
+<tt>get</tt>, <tt>getQuick</tt>, <tt>set</tt>, <tt>setQuick</tt> and <tt>size</tt>,
+<p>
+Cells are internally addressed in row-major.
+Applications demanding utmost speed can exploit this fact.
+Setting/getting values in a loop row-by-row is quicker than column-by-column.
+Thus
+<pre>
+   for (int row=0; row < rows; row++) {
+	  for (int column=0; column < columns; column++) {
+		 matrix.setQuick(row,column,someValue);
+	  }
+   }
+</pre>
+is quicker than
+<pre>
+   for (int column=0; column < columns; column++) {
+	  for (int row=0; row < rows; row++) {
+		 matrix.setQuick(row,column,someValue);
+	  }
+   }
+</pre>
+@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 DenseDoubleMatrix2D extends DoubleMatrix2D {
+	static final long serialVersionUID = 1020177651L;
+	/**
+	  * The elements of this matrix.
+	  * elements are stored in row major, i.e.
+	  * index==row*columns + column
+	  * columnOf(index)==index%columns
+	  * rowOf(index)==index/columns
+	  * i.e. {row0 column0..m}, {row1 column0..m}, ..., {rown column0..m}
+	  */
+	protected double[] elements;
+/**
+ * Constructs a matrix with a copy of the given 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 DenseDoubleMatrix2D(double[][] values) {
+	this(values.length, values.length==0 ? 0: values[0].length);
+	assign(values);
+}
+/**
+ * Constructs a matrix with a given number of rows and columns.
+ * All entries are initially <tt>0</tt>.
+ * @param rows the number of rows the matrix shall have.
+ * @param columns the number of columns the matrix shall have.
+ * @throws	IllegalArgumentException if <tt>rows<0 || columns<0 || (double)columns*rows > Integer.MAX_VALUE</tt>.
+ */
+public DenseDoubleMatrix2D(int rows, int columns) {
+	setUp(rows, columns);
+	this.elements = new double[rows*columns];
+}
+/**
+ * Constructs a view with the given parameters.
+ * @param rows the number of rows the matrix shall have.
+ * @param columns the number of columns the matrix shall have.
+ * @param elements the cells.
+ * @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>.
+ * @throws	IllegalArgumentException if <tt>rows<0 || columns<0 || (double)columns*rows > Integer.MAX_VALUE</tt> or flip's are illegal.
+ */
+protected DenseDoubleMatrix2D(int rows, int columns, double[] elements, int rowZero, int columnZero, int rowStride, int columnStride) {
+	setUp(rows,columns,rowZero,columnZero,rowStride,columnStride);
+	this.elements = elements;
+	this.isNoView = false;
+}
+/**
+ * Sets all cells to the state specified by <tt>values</tt>.
+ * <tt>values</tt> is required to have the form <tt>values[row][column]</tt>
+ * and have exactly the same number of 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 != rows() || for any 0 &lt;= row &lt; rows(): values[row].length != columns()</tt>.
+ */
+public DoubleMatrix2D assign(double[][] values) {
+	if (this.isNoView) {
+		if (values.length != rows) throw new IllegalArgumentException("Must have same number of rows: rows="+values.length+"rows()="+rows());
+		int i = columns*(rows-1);
+		for (int row=rows; --row >= 0;) {
+			double[] currentRow = values[row];
+			if (currentRow.length != columns) throw new IllegalArgumentException("Must have same number of columns in every row: columns="+currentRow.length+"columns()="+columns());			
+			System.arraycopy(currentRow, 0, this.elements, i, columns);
+			i -= columns;
+		}
+	}
+	else {
+		super.assign(values);
+	}
+	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 DoubleMatrix2D assign(double value) {
+	final double[] elems = this.elements;
+	int index = index(0,0);
+	int cs = this.columnStride;
+	int rs = this.rowStride;
+	for (int row=rows; --row >= 0; ) {
+		for (int i=index, column=columns; --column >= 0; ) {
+			elems[i] = value;
+			i += cs;
+		}
+		index += rs;
+	}
+	return this;
+}
+/**
+Assigns the result of a function to each cell; <tt>x[row,col] = function(x[row,col])</tt>.
+<p>
+<b>Example:</b>
+<pre>
+matrix = 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);
+-->
+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 DoubleMatrix2D assign(org.apache.mahout.colt.function.DoubleFunction function) {
+	final double[] elems = this.elements;
+	if (elems==null) throw new InternalError();
+	int index = index(0,0);
+	int cs = this.columnStride;
+	int rs = this.rowStride;
+	
+	// specialization for speed
+	if (function instanceof org.apache.mahout.jet.math.Mult) { // x[i] = mult*x[i]
+		double multiplicator = ((org.apache.mahout.jet.math.Mult)function).multiplicator;
+		if (multiplicator==1) return this;
+		if (multiplicator==0) return assign(0);
+		for (int row=rows; --row >= 0; ) { // the general case
+			for (int i=index, column=columns; --column >= 0; ) {
+				elems[i] *= multiplicator;
+				i += cs;
+			}
+			index += rs;
+		}
+	}
+	else { // the general case x[i] = f(x[i])
+		for (int row=rows; --row >= 0; ) { 
+			for (int i=index, column=columns; --column >= 0; ) {
+				elems[i] = function.apply(elems[i]);
+				i += cs;
+			}
+			index += rs;
+		}
+	}
+	return this;
+}
+/**
+ * Replaces all cell values of the receiver with the values of another matrix.
+ * Both matrices must have the same number of 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     source   the source matrix to copy from (may be identical to the receiver).
+ * @return <tt>this</tt> (for convenience only).
+ * @throws	IllegalArgumentException if <tt>columns() != source.columns() || rows() != source.rows()</tt>
+ */
+public DoubleMatrix2D assign(DoubleMatrix2D source) {
+	// overriden for performance only
+	if (! (source instanceof DenseDoubleMatrix2D)) {
+		return super.assign(source);
+	}
+	DenseDoubleMatrix2D other = (DenseDoubleMatrix2D) source;
+	if (other==this) return this; // nothing to do
+	checkShape(other);
+	
+	if (this.isNoView && other.isNoView) { // quickest
+		System.arraycopy(other.elements, 0, this.elements, 0, this.elements.length);
+		return this;
+	}
+	
+	if (haveSharedCells(other)) {
+		DoubleMatrix2D c = other.copy();
+		if (! (c instanceof DenseDoubleMatrix2D)) { // should not happen
+			return super.assign(other);
+		}
+		other = (DenseDoubleMatrix2D) c;
+	}
+	
+	final double[] elems = this.elements;
+	final double[] otherElems = other.elements;
+	if (elems==null || otherElems==null) throw new InternalError();
+	int cs = this.columnStride;
+	int ocs = other.columnStride;
+	int rs = this.rowStride;
+	int ors = other.rowStride;
+
+	int otherIndex = other.index(0,0);
+	int index = index(0,0);
+	for (int row=rows; --row >= 0; ) {
+		for (int i=index, j=otherIndex, column=columns; --column >= 0; ) {
+			elems[i] = otherElems[j];
+			i += cs;
+			j += ocs;
+		}
+		index += rs;
+		otherIndex += ors;
+	}
+	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 = 2 x 2 matrix 
+0 1 
+2 3
+
+m2 = 2 x 2 matrix 
+0 2 
+4 6
+
+m1.assign(m2, org.apache.mahout.jet.math.Functions.pow);
+-->
+m1 == 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>columns() != other.columns() || rows() != other.rows()</tt>
+@see org.apache.mahout.jet.math.Functions
+*/
+public DoubleMatrix2D assign(DoubleMatrix2D y, org.apache.mahout.colt.function.DoubleDoubleFunction function) {
+	// overriden for performance only
+	if (! (y instanceof DenseDoubleMatrix2D)) {
+		return super.assign(y, function);
+	}
+	DenseDoubleMatrix2D other = (DenseDoubleMatrix2D) y;
+	checkShape(y);
+	
+	final double[] elems = this.elements;
+	final double[] otherElems = other.elements;
+	if (elems==null || otherElems==null) throw new InternalError();
+	int cs = this.columnStride;
+	int ocs = other.columnStride;
+	int rs = this.rowStride;
+	int ors = other.rowStride;
+
+	int otherIndex = other.index(0,0);
+	int index = index(0,0);
+
+	// specialized for speed
+	if (function== org.apache.mahout.jet.math.Functions.mult) { // x[i] = x[i] * y[i]
+		for (int row=rows; --row >= 0; ) {
+			for (int i=index, j=otherIndex, column=columns; --column >= 0; ) {
+				elems[i] *= otherElems[j];
+				i += cs;
+				j += ocs;
+			}
+			index += rs;
+			otherIndex += ors;
+		}
+	}
+	else if (function== org.apache.mahout.jet.math.Functions.div) { // x[i] = x[i] / y[i]
+		for (int row=rows; --row >= 0; ) {
+			for (int i=index, j=otherIndex, column=columns; --column >= 0; ) {
+				elems[i] /= otherElems[j];
+				i += cs;
+				j += ocs;
+			}
+			index += rs;
+			otherIndex += ors;
+		}
+	}
+	else if (function instanceof org.apache.mahout.jet.math.PlusMult) {
+		double multiplicator = ((org.apache.mahout.jet.math.PlusMult) function).multiplicator;
+		if (multiplicator == 0) { // x[i] = x[i] + 0*y[i]
+			return this;
+		}
+		else if (multiplicator == 1) { // x[i] = x[i] + y[i]
+			for (int row=rows; --row >= 0; ) {
+				for (int i=index, j=otherIndex, column=columns; --column >= 0; ) {
+					elems[i] += otherElems[j];
+					i += cs;
+					j += ocs;
+				}
+				index += rs;
+				otherIndex += ors;
+			}
+		}
+		else if (multiplicator == -1) { // x[i] = x[i] - y[i]
+			for (int row=rows; --row >= 0; ) {
+				for (int i=index, j=otherIndex, column=columns; --column >= 0; ) {
+					elems[i] -= otherElems[j];
+					i += cs;
+					j += ocs;
+				}
+				index += rs;
+				otherIndex += ors;
+			}
+		}
+		else { // the general case
+			for (int row=rows; --row >= 0; ) { // x[i] = x[i] + mult*y[i]
+				for (int i=index, j=otherIndex, column=columns; --column >= 0; ) {
+					elems[i] += multiplicator*otherElems[j];
+					i += cs;
+					j += ocs;
+				}
+				index += rs;
+				otherIndex += ors;
+			}
+		}
+	}
+	else { // the general case x[i] = f(x[i],y[i])
+		for (int row=rows; --row >= 0; ) {
+			for (int i=index, j=otherIndex, column=columns; --column >= 0; ) {
+				elems[i] = function.apply(elems[i], otherElems[j]);
+				i += cs;
+				j += ocs;
+			}
+			index += rs;
+			otherIndex += ors;
+		}
+	}
+	return this;
+}
+/**
+ * Returns the matrix cell value at coordinate <tt>[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>0 &lt;= column &lt; columns() && 0 &lt;= row &lt; rows()</tt>.
+ *
+ * @param     row   the index of the row-coordinate.
+ * @param     column   the index of the column-coordinate.
+ * @return    the value at the specified coordinate.
+ */
+public double getQuick(int row, int column) {
+	//if (debug) if (column<0 || column>=columns || row<0 || row>=rows) throw new IndexOutOfBoundsException("row:"+row+", column:"+column);
+	//return elements[index(row,column)];
+	//manually inlined:
+	return elements[rowZero + row*rowStride + columnZero + column*columnStride];
+}
+/**
+ * Returns <tt>true</tt> if both matrices share common cells.
+ * More formally, returns <tt>true</tt> if <tt>other != null</tt> and at least one of the following conditions is met
+ * <ul>
+ * <li>the receiver is a view of the other matrix
+ * <li>the other matrix is a view of the receiver
+ * <li><tt>this == other</tt>
+ * </ul>
+ */
+protected boolean haveSharedCellsRaw(DoubleMatrix2D other) {
+	if (other instanceof SelectedDenseDoubleMatrix2D) {
+		SelectedDenseDoubleMatrix2D otherMatrix = (SelectedDenseDoubleMatrix2D) other;
+		return this.elements==otherMatrix.elements;
+	}
+	else if (other instanceof DenseDoubleMatrix2D) {
+		DenseDoubleMatrix2D otherMatrix = (DenseDoubleMatrix2D) other;
+		return this.elements==otherMatrix.elements;
+	}
+	return false;
+}
+/**
+ * Returns the position of the given coordinate within the (virtual or non-virtual) internal 1-dimensional array. 
+ *
+ * @param     row   the index of the row-coordinate.
+ * @param     column   the index of the column-coordinate.
+ */
+protected int index(int row, int column) {
+	// return super.index(row,column);
+	// manually inlined for speed:
+	return rowZero + row*rowStride + columnZero + column*columnStride;
+}
+/**
+ * Construct and returns a new empty matrix <i>of the same dynamic type</i> as the receiver, having the specified number of rows and columns.
+ * For example, if the receiver is an instance of type <tt>DenseDoubleMatrix2D</tt> the new matrix must also be of type <tt>DenseDoubleMatrix2D</tt>,
+ * if the receiver is an instance of type <tt>SparseDoubleMatrix2D</tt> the new matrix must also be of type <tt>SparseDoubleMatrix2D</tt>, etc.
+ * In general, the new matrix should have internal parametrization as similar as possible.
+ *
+ * @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 DoubleMatrix2D like(int rows, int columns) {
+	return new DenseDoubleMatrix2D(rows, columns);
+}
+/**
+ * Construct and returns a new 1-d matrix <i>of the corresponding dynamic type</i>, entirelly independent of the receiver.
+ * For example, if the receiver is an instance of type <tt>DenseDoubleMatrix2D</tt> the new matrix must be of type <tt>DenseDoubleMatrix1D</tt>,
+ * if the receiver is an instance of type <tt>SparseDoubleMatrix2D</tt> the new matrix must be of type <tt>SparseDoubleMatrix1D</tt>, etc.
+ *
+ * @param size the number of cells the matrix shall have.
+ * @return  a new matrix of the corresponding dynamic type.
+ */
+public DoubleMatrix1D like1D(int size) {
+	return new DenseDoubleMatrix1D(size);
+}
+/**
+ * Construct and returns a new 1-d matrix <i>of the corresponding dynamic type</i>, sharing the same cells.
+ * For example, if the receiver is an instance of type <tt>DenseDoubleMatrix2D</tt> the new matrix must be of type <tt>DenseDoubleMatrix1D</tt>,
+ * if the receiver is an instance of type <tt>SparseDoubleMatrix2D</tt> the new matrix must be of type <tt>SparseDoubleMatrix1D</tt>, etc.
+ *
+ * @param size the number of cells the matrix shall have.
+ * @param zero the index of the first element.
+ * @param stride the number of indexes between any two elements, i.e. <tt>index(i+1)-index(i)</tt>.
+ * @return  a new matrix of the corresponding dynamic type.
+ */
+protected DoubleMatrix1D like1D(int size, int zero, int stride) {
+	return new DenseDoubleMatrix1D(size,this.elements,zero,stride);
+}
+/**
+ * Sets the matrix cell at coordinate <tt>[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>0 &lt;= column &lt; columns() && 0 &lt;= row &lt; rows()</tt>.
+ *
+ * @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 void setQuick(int row, int column, double value) {
+	//if (debug) if (column<0 || column>=columns || row<0 || row>=rows) throw new IndexOutOfBoundsException("row:"+row+", column:"+column);
+	//elements[index(row,column)] = value;
+	//manually inlined:
+	elements[rowZero + row*rowStride + columnZero + column*columnStride] = value;
+}
+/**
+ * Construct and returns a new selection view.
+ *
+ * @param rowOffsets the offsets of the visible elements.
+ * @param columnOffsets the offsets of the visible elements.
+ * @return  a new view.
+ */
+protected DoubleMatrix2D viewSelectionLike(int[] rowOffsets, int[] columnOffsets) {
+	return new SelectedDenseDoubleMatrix2D(this.elements,rowOffsets,columnOffsets,0);
+}
+/**
+8 neighbor stencil transformation. For efficient finite difference operations.
+Applies a function to a moving <tt>3 x 3</tt> window.
+Does nothing if <tt>rows() < 3 || columns() < 3</tt>.
+<pre>
+B[i,j] = function.apply(
+&nbsp;&nbsp;&nbsp;A[i-1,j-1], A[i-1,j], A[i-1,j+1],
+&nbsp;&nbsp;&nbsp;A[i,  j-1], A[i,  j], A[i,  j+1],
+&nbsp;&nbsp;&nbsp;A[i+1,j-1], A[i+1,j], A[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;
+
+// 8 neighbors
+org.apache.mahout.colt.function.Double9Function f = new org.apache.mahout.colt.function.Double9Function() {
+&nbsp;&nbsp;&nbsp;public final double apply(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double a00, double a01, double a02,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double a10, double a11, double a12,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double a20, double a21, double a22) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return beta*a11 + alpha*(a00+a01+a02 + a10+a12 + a20+a21+a22);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
+};
+A.zAssign8Neighbors(B,f);
+
+// 4 neighbors
+org.apache.mahout.colt.function.Double9Function g = new org.apache.mahout.colt.function.Double9Function() {
+&nbsp;&nbsp;&nbsp;public final double apply(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double a00, double a01, double a02,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double a10, double a11, double a12,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double a20, double a21, double a22) {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return beta*a11 + alpha*(a01+a10+a12+a21);
+&nbsp;&nbsp;&nbsp;}
+C.zAssign8Neighbors(B,g); // fast, even though it doesn't look like it
+};
+</pre>
+	
+@param B the matrix to hold the results.
+@param function the function to be applied to the 9 cells.
+@throws NullPointerException if <tt>function==null</tt>.
+@throws IllegalArgumentException if <tt>rows() != B.rows() || columns() != B.columns()</tt>.
+*/
+public void zAssign8Neighbors(DoubleMatrix2D B, org.apache.mahout.colt.function.Double9Function function) {
+	// 1. using only 4-5 out of the 9 cells in "function" is *not* the limiting factor for performance.
+
+	// 2. if the "function" would be hardwired into the innermost loop, a speedup of 1.5-2.0 would be seen
+	// but then the multi-purpose interface is gone...
+
+	if (!(B instanceof DenseDoubleMatrix2D)) {
+		super.zAssign8Neighbors(B, function);
+		return;
+	}
+	if (function==null) throw new NullPointerException("function must not be null.");
+	checkShape(B);
+	int r = rows-1;
+	int c = columns-1;
+	if (rows<3 || columns<3) return; // nothing to do
+
+	DenseDoubleMatrix2D BB = (DenseDoubleMatrix2D) B;
+	int A_rs = rowStride;
+	int B_rs = BB.rowStride;
+	int A_cs = columnStride;
+	int B_cs = BB.columnStride;
+	double[] elems = this.elements;
+	double[] B_elems = BB.elements;
+	if (elems == null || B_elems==null) throw new InternalError();
+
+	int A_index = index(1,1);
+	int B_index = BB.index(1,1);
+	for (int i=1; i<r; i++) {
+		double a00, a01, a02;
+		double a10, a11, a12;
+		double a20, a21, a22;
+		
+		int B11 = B_index;
+
+		int A02 = A_index - A_rs - A_cs;
+		int A12 = A02 + A_rs;
+		int A22 = A12 + A_rs;
+
+		// in each step six cells can be remembered in registers - they don't need to be reread from slow memory
+		a00=elems[A02]; A02+=A_cs;   a01=elems[A02]; //A02+=A_cs;
+		a10=elems[A12]; A12+=A_cs;   a11=elems[A12]; //A12+=A_cs;
+		a20=elems[A22]; A22+=A_cs;   a21=elems[A22]; //A22+=A_cs; 
+		
+		for (int j=1; j<c; j++) {
+			//in each step 3 instead of 9 cells need to be read from memory.
+			a02=elems[A02+=A_cs]; 
+			a12=elems[A12+=A_cs]; 
+			a22=elems[A22+=A_cs]; 
+			
+			B_elems[B11] = function.apply(
+				a00, a01, a02,
+				a10, a11, a12,
+				a20, a21, a22);
+			B11 += B_cs;
+			
+			// move remembered cells
+			a00=a01; a01=a02;
+			a10=a11; a11=a12;
+			a20=a21; a21=a22;
+		}
+		A_index += A_rs;
+		B_index += B_rs;
+	}
+
+}
+public DoubleMatrix1D zMult(DoubleMatrix1D y, DoubleMatrix1D z, double alpha, double beta, boolean transposeA) {
+	if (transposeA) return viewDice().zMult(y,z,alpha,beta,false);
+	if (z==null) z = new DenseDoubleMatrix1D(this.rows);
+	if (!(y instanceof DenseDoubleMatrix1D && z instanceof DenseDoubleMatrix1D)) return super.zMult(y,z,alpha,beta,transposeA);
+	
+	if (columns != y.size || rows > z.size)	
+		throw new IllegalArgumentException("Incompatible args: "+toStringShort()+", "+y.toStringShort()+", "+z.toStringShort());
+
+	DenseDoubleMatrix1D yy = (DenseDoubleMatrix1D) y;
+	DenseDoubleMatrix1D zz = (DenseDoubleMatrix1D) z;
+	final double[] AElems = this.elements;
+	final double[] yElems = yy.elements;
+	final double[] zElems = zz.elements;
+	if (AElems==null || yElems==null || zElems==null) throw new InternalError();
+	int As = this.columnStride;
+	int ys = yy.stride;
+	int zs = zz.stride;
+
+	int indexA = index(0,0);
+	int indexY = yy.index(0);
+	int indexZ = zz.index(0);
+
+	int cols = columns;
+	for (int row=rows; --row >= 0; ) {
+		double sum = 0;
+
+		/*
+		// not loop unrolled
+		for (int i=indexA, j=indexY, column=columns; --column >= 0; ) {
+			sum += AElems[i] * yElems[j];
+			i += As;
+			j += ys;
+		}
+		*/
+
+		// loop unrolled
+		int i = indexA - As;
+		int j = indexY - ys;	
+		for (int k=cols%4; --k >= 0; ) {
+			sum += AElems[i += As] * yElems[j += ys];
+		}
+		for (int k=cols/4; --k >= 0; ) { 
+			sum += AElems[i += As] * yElems[j += ys] + 
+				AElems[i += As] * yElems[j += ys] +
+				AElems[i += As] * yElems[j += ys] +
+				AElems[i += As] * yElems[j += ys];
+		}		
+
+		zElems[indexZ] = alpha*sum + beta*zElems[indexZ];
+		indexA += this.rowStride;
+		indexZ += zs;
+	}
+
+	return z;
+}
+public DoubleMatrix2D zMult(DoubleMatrix2D B, DoubleMatrix2D C, double alpha, double beta, boolean transposeA, boolean transposeB) {
+	// overriden for performance only
+	if (transposeA) return viewDice().zMult(B,C,alpha,beta,false,transposeB);
+	if (B instanceof SparseDoubleMatrix2D || B instanceof RCDoubleMatrix2D) {
+		// exploit quick sparse mult
+		// A*B = (B' * A')'
+		if (C==null) {
+			return B.zMult(this, null, alpha,beta,!transposeB,true).viewDice();
+		}
+		else {
+			B.zMult(this, C.viewDice(), alpha,beta,!transposeB,true);
+			return C;
+		}
+		/*
+		final RCDoubleMatrix2D transB = new RCDoubleMatrix2D(B.columns,B.rows);
+		B.forEachNonZero(
+			new org.apache.mahout.colt.function.IntIntDoubleFunction() {
+				public double apply(int i, int j, double value) {
+					transB.setQuick(j,i,value);
+					return value;
+				}
+			}
+		);
+
+		return transB.zMult(this.viewDice(),C.viewDice()).viewDice();
+		*/
+	}
+	if (transposeB) return this.zMult(B.viewDice(),C,alpha,beta,transposeA,false);
+	
+	int m = rows;
+	int n = columns;
+	int p = B.columns;
+	if (C==null) C = new DenseDoubleMatrix2D(m,p);
+	if (!(C instanceof DenseDoubleMatrix2D)) return super.zMult(B,C,alpha,beta,transposeA,transposeB);
+	if (B.rows != n)
+		throw new IllegalArgumentException("Matrix2D inner dimensions must agree:"+toStringShort()+", "+B.toStringShort());
+	if (C.rows != m || C.columns != p)
+		throw new IllegalArgumentException("Incompatibel result matrix: "+toStringShort()+", "+B.toStringShort()+", "+C.toStringShort());
+	if (this == C || B == C)
+		throw new IllegalArgumentException("Matrices must not be identical");
+
+	DenseDoubleMatrix2D BB = (DenseDoubleMatrix2D) B;
+	DenseDoubleMatrix2D CC = (DenseDoubleMatrix2D) C;
+	final double[] AElems = this.elements;
+	final double[] BElems = BB.elements;
+	final double[] CElems = CC.elements;
+	if (AElems==null || BElems==null || CElems==null) throw new InternalError();
+
+	int cA = this.columnStride;
+	int cB = BB.columnStride;
+	int cC = CC.columnStride;
+
+	int rA = this.rowStride;
+	int rB = BB.rowStride;
+	int rC = CC.rowStride;
+
+	/*
+	A is blocked to hide memory latency
+			xxxxxxx B
+			xxxxxxx
+			xxxxxxx
+	A
+	xxx     xxxxxxx C
+	xxx     xxxxxxx
+	---     -------
+	xxx     xxxxxxx
+	xxx     xxxxxxx
+	---     -------
+	xxx     xxxxxxx
+	*/
+	final int BLOCK_SIZE = 30000; // * 8 == Level 2 cache in bytes
+	//if (n+p == 0) return C;
+	//int m_optimal = (BLOCK_SIZE - n*p) / (n+p);
+	int m_optimal = (BLOCK_SIZE - n) / (n+1);
+	if (m_optimal <= 0) m_optimal = 1;
+	int blocks = m/m_optimal;
+	int rr = 0;
+	if (m%m_optimal != 0) blocks++;
+	for (; --blocks >= 0; ) {
+		int jB = BB.index(0,0);
+		int indexA = index(rr,0);
+		int jC =  CC.index(rr,0);
+		rr += m_optimal;
+		if (blocks==0) m_optimal += m - rr;
+		
+		for (int j = p; --j >= 0; ) {
+			int iA = indexA;
+			int iC = jC;
+			for (int i = m_optimal; --i >= 0; ) {
+				int kA = iA;
+				int kB = jB;
+				double s = 0;
+
+				/*
+				// not unrolled:
+				for (int k = n; --k >= 0; ) {
+					//s += getQuick(i,k) * B.getQuick(k,j);
+					s += AElems[kA] * BElems[kB];
+					kB += rB;
+					kA += cA;
+				}
+				*/
+				
+				// loop unrolled				
+				kA -= cA;
+				kB -= rB;
+				
+				for (int k=n%4; --k >= 0; ) {
+					s += AElems[kA += cA] * BElems[kB += rB];
+				}
+				for (int k=n/4; --k >= 0; ) { 
+					s += AElems[kA += cA] * BElems[kB += rB] + 
+						AElems[kA += cA] * BElems[kB += rB] +
+						AElems[kA += cA] * BElems[kB += rB] +
+						AElems[kA += cA] * BElems[kB += rB];
+				}		
+
+				CElems[iC] = alpha*s + beta*CElems[iC];
+				iA += rA;
+				iC += rC;
+			}
+			jB += cB;
+			jC += cC;
+		}
+	}
+	return C;
+}
+/**
+ * Returns the sum of all cells; <tt>Sum( x[i,j] )</tt>.
+ * @return the sum.
+ */
+public double zSum() {
+	double sum = 0;
+	final double[] elems = this.elements;
+	if (elems==null) throw new InternalError();
+	int index = index(0,0);
+	int cs = this.columnStride;
+	int rs = this.rowStride;
+	for (int row=rows; --row >= 0; ) {
+		for (int i=index, column=columns; --column >= 0; ) {
+			sum += elems[i];
+			i += cs;
+		}
+		index += rs;
+	}
+	return sum;
+}
+}

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

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseDoubleMatrix3D.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseDoubleMatrix3D.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseDoubleMatrix3D.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseDoubleMatrix3D.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,460 @@
+/*
+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.impl;
+
+import org.apache.mahout.colt.matrix.DoubleMatrix2D;
+import org.apache.mahout.colt.matrix.DoubleMatrix3D;
+/**
+Dense 3-d matrix 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>
+<b>Implementation:</b>
+<p>
+Internally holds one single contigous one-dimensional array, addressed in (in decreasing order of significance): slice major, row major, column major.
+Note that this implementation is not synchronized.
+<p>
+<b>Memory requirements:</b>
+<p>
+<tt>memory [bytes] = 8*slices()*rows()*columns()</tt>.
+Thus, a 100*100*100 matrix uses 8 MB.
+<p>
+<b>Time complexity:</b>
+<p>
+<tt>O(1)</tt> (i.e. constant time) for the basic operations
+<tt>get</tt>, <tt>getQuick</tt>, <tt>set</tt>, <tt>setQuick</tt> and <tt>size</tt>,
+<p>
+Applications demanding utmost speed can exploit knowledge about the internal addressing.
+Setting/getting values in a loop slice-by-slice, row-by-row, column-by-column is quicker than, for example, column-by-column, row-by-row, slice-by-slice.
+Thus
+<pre>
+   for (int slice=0; slice < slices; slice++) {
+	  for (int row=0; row < rows; row++) {
+	     for (int column=0; column < columns; column++) {
+			matrix.setQuick(slice,row,column,someValue);
+		 }		    
+	  }
+   }
+</pre>
+is quicker than
+<pre>
+   for (int column=0; column < columns; column++) {
+	  for (int row=0; row < rows; row++) {
+	     for (int slice=0; slice < slices; slice++) {
+			matrix.setQuick(slice,row,column,someValue);
+		 }
+	  }
+   }
+</pre>
+@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 DenseDoubleMatrix3D extends DoubleMatrix3D {
+	/**
+	  * The elements of this matrix.
+	  * elements are stored in slice major, then row major, then column major, in order of significance, i.e.
+	  * index==slice*sliceStride+ row*rowStride + column*columnStride
+	  * i.e. {slice0 row0..m}, {slice1 row0..m}, ..., {sliceN row0..m}
+	  * with each row storead as 
+	  * {row0 column0..m}, {row1 column0..m}, ..., {rown column0..m}
+	  */
+	protected double[] elements;
+/**
+ * Constructs a matrix with a copy of the given values.
+ * <tt>values</tt> is required to have the form <tt>values[slice][row][column]</tt>
+ * and have exactly the same number of rows in in every slice and exactly the same number of columns in 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;= slice &lt; values.length: values[slice].length != values[slice-1].length</tt>.
+ * @throws IllegalArgumentException if <tt>for any 1 &lt;= row &lt; values[0].length: values[slice][row].length != values[slice][row-1].length</tt>.
+ */
+public DenseDoubleMatrix3D(double[][][] values) {
+	this(values.length, (values.length==0 ? 0: values[0].length), (values.length==0 ? 0: values[0].length==0 ? 0 : values[0][0].length));
+	assign(values);
+}
+/**
+ * Constructs a matrix with a given number of slices, rows and columns.
+ * All entries are initially <tt>0</tt>.
+ * @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.
+ * @throws	IllegalArgumentException if <tt>(double)slices*columns*rows > Integer.MAX_VALUE</tt>.
+ * @throws	IllegalArgumentException if <tt>slices<0 || rows<0 || columns<0</tt>.
+ */
+public DenseDoubleMatrix3D(int slices, int rows, int columns) {
+	setUp(slices,rows, columns);
+	this.elements = new double[slices*rows*columns];
+}
+/**
+ * Constructs a view with the given parameters.
+ * @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.
+ * @param elements the cells.
+ * @param sliceZero the position of the first element.
+ * @param rowZero the position of the first element.
+ * @param columnZero the position of the first element.
+ * @param sliceStride the number of elements between two slices, i.e. <tt>index(k+1,i,j)-index(k,i,j)</tt>.
+ * @param rowStride the number of elements between two rows, i.e. <tt>index(k,i+1,j)-index(k,i,j)</tt>.
+ * @param columnnStride the number of elements between two columns, i.e. <tt>index(k,i,j+1)-index(k,i,j)</tt>.
+ * @throws	IllegalArgumentException if <tt>(double)slices*columns*rows > Integer.MAX_VALUE</tt>.
+ * @throws	IllegalArgumentException if <tt>slices<0 || rows<0 || columns<0</tt>.
+ */
+protected DenseDoubleMatrix3D(int slices, int rows, int columns, double[] elements, int sliceZero, int rowZero, int columnZero, int sliceStride, int rowStride, int columnStride) {
+	setUp(slices,rows,columns,sliceZero,rowZero,columnZero,sliceStride,rowStride,columnStride);
+	this.elements = elements;
+	this.isNoView = false;
+}
+/**
+ * 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 (this.isNoView) {
+		if (values.length != slices) throw new IllegalArgumentException("Must have same number of slices: slices="+values.length+"slices()="+slices());
+		int i=slices*rows*columns - columns;
+		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());			
+				System.arraycopy(currentRow, 0, this.elements, i, columns);
+				i -= columns;
+			}
+		}
+	}
+	else {
+		super.assign(values);
+	}
+	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     source   the source matrix to copy from (may be identical to the receiver).
+ * @return <tt>this</tt> (for convenience only).
+ * @throws	IllegalArgumentException if <tt>slices() != source.slices() || rows() != source.rows() || columns() != source.columns()</tt>
+ */
+public DoubleMatrix3D assign(DoubleMatrix3D source) {
+	// overriden for performance only
+	if (! (source instanceof DenseDoubleMatrix3D)) {
+		return super.assign(source);
+	}
+	DenseDoubleMatrix3D other = (DenseDoubleMatrix3D) source;
+	if (other==this) return this;
+	checkShape(other);
+	if (haveSharedCells(other)) {
+		DoubleMatrix3D c = other.copy();
+		if (! (c instanceof DenseDoubleMatrix3D)) { // should not happen
+			return super.assign(source);
+		}
+		other = (DenseDoubleMatrix3D) c;
+	}
+
+	if (this.isNoView && other.isNoView) { // quickest
+		System.arraycopy(other.elements, 0, this.elements, 0, this.elements.length);
+		return this;
+	}
+	return super.assign(other);
+}
+/**
+ * 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 double getQuick(int slice, int row, int column) {
+	//if (debug) if (slice<0 || slice>=slices || row<0 || row>=rows || column<0 || column>=columns) throw new IndexOutOfBoundsException("slice:"+slice+", row:"+row+", column:"+column);
+	//return elements[index(slice,row,column)];
+	//manually inlined:
+	return elements[sliceZero + slice*sliceStride + rowZero + row*rowStride + columnZero + column*columnStride];
+}
+/**
+ * Returns <tt>true</tt> if both matrices share common cells.
+ * More formally, returns <tt>true</tt> if <tt>other != null</tt> and at least one of the following conditions is met
+ * <ul>
+ * <li>the receiver is a view of the other matrix
+ * <li>the other matrix is a view of the receiver
+ * <li><tt>this == other</tt>
+ * </ul>
+ */
+protected boolean haveSharedCellsRaw(DoubleMatrix3D other) {
+	if (other instanceof SelectedDenseDoubleMatrix3D) {
+		SelectedDenseDoubleMatrix3D otherMatrix = (SelectedDenseDoubleMatrix3D) other;
+		return this.elements==otherMatrix.elements;
+	}
+	else if (other instanceof DenseDoubleMatrix3D) {
+		DenseDoubleMatrix3D otherMatrix = (DenseDoubleMatrix3D) other;
+		return this.elements==otherMatrix.elements;
+	}
+	return false;
+}
+/**
+ * Returns the position of the given coordinate within the (virtual or non-virtual) internal 1-dimensional array. 
+ *
+ * @param     slice   the index of the slice-coordinate.
+ * @param     row   the index of the row-coordinate.
+ * @param     column   the index of the third-coordinate.
+ */
+protected int index(int slice, int row, int column) {
+	//return _sliceOffset(_sliceRank(slice)) + _rowOffset(_rowRank(row)) + _columnOffset(_columnRank(column));
+	//manually inlined:
+	return sliceZero + slice*sliceStride + rowZero + row*rowStride + columnZero + column*columnStride;	
+}
+/**
+ * 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 DoubleMatrix3D like(int slices, int rows, int columns) {
+	return new DenseDoubleMatrix3D(slices,rows,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 DoubleMatrix2D like2D(int rows, int columns, int rowZero, int columnZero, int rowStride, int columnStride) {
+	return new DenseDoubleMatrix2D(rows,columns,this.elements,rowZero,columnZero,rowStride,columnStride);
+}
+/**
+ * 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 void setQuick(int slice, int row, int column, double value) {
+	//if (debug) if (slice<0 || slice>=slices || row<0 || row>=rows || column<0 || column>=columns) throw new IndexOutOfBoundsException("slice:"+slice+", row:"+row+", column:"+column);
+	//elements[index(slice,row,column)] = value;
+	//manually inlined:
+	elements[sliceZero + slice*sliceStride + rowZero + row*rowStride + columnZero + column*columnStride] = value;
+}
+/**
+ * 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 DoubleMatrix3D viewSelectionLike(int[] sliceOffsets, int[] rowOffsets, int[] columnOffsets) {
+	return new SelectedDenseDoubleMatrix3D(this.elements,sliceOffsets,rowOffsets,columnOffsets,0);
+}
+/**
+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) {
+	// overridden for performance only
+	if (!(B instanceof DenseDoubleMatrix3D)) {
+		super.zAssign27Neighbors(B, function);
+		return;
+	}
+	if (function==null) throw new NullPointerException("function must not be null.");
+	checkShape(B);
+	int r = rows-1;
+	int c = columns-1;
+	if (rows<3 || columns<3 || slices<3) return; // nothing to do
+
+	DenseDoubleMatrix3D BB = (DenseDoubleMatrix3D) B;
+	int A_ss = sliceStride;
+	int A_rs = rowStride;
+	int B_rs = BB.rowStride;
+	int A_cs = columnStride;
+	int B_cs = BB.columnStride;
+	double[] elems = this.elements;
+	double[] B_elems = BB.elements;
+	if (elems == null || B_elems==null) throw new InternalError();
+
+	for (int k=1; k<slices-1; k++) {
+		int A_index = index(k,1,1);
+		int B_index = BB.index(k,1,1);
+
+		for (int i=1; i<r; i++) {
+			int A002 = A_index - A_ss - A_rs - A_cs;
+			int A012 = A002 + A_rs;
+			int A022 = A012 + A_rs;
+
+			int A102 = A002 + A_ss;
+			int A112 = A102 + A_rs;
+			int A122 = A112 + A_rs;
+
+			int A202 = A102 + A_ss;
+			int A212 = A202 + A_rs;
+			int A222 = A212 + A_rs;
+
+			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;
+	
+			a000=elems[A002]; A002+=A_cs;   a001=elems[A002];
+			a010=elems[A012]; A012+=A_cs;   a011=elems[A012]; 
+			a020=elems[A022]; A022+=A_cs;   a021=elems[A022]; 
+
+			a100=elems[A102]; A102+=A_cs;   a101=elems[A102]; 
+			a110=elems[A112]; A112+=A_cs;   a111=elems[A112]; 
+			a120=elems[A122]; A122+=A_cs;   a121=elems[A122]; 
+
+			a200=elems[A202]; A202+=A_cs;   a201=elems[A202];
+			a210=elems[A212]; A212+=A_cs;   a211=elems[A212]; 
+			a220=elems[A222]; A222+=A_cs;   a221=elems[A222]; 
+
+			int B11 = B_index;
+			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=elems[A002+=A_cs]; 
+				a012=elems[A012+=A_cs]; 
+				a022=elems[A022+=A_cs]; 
+
+				a102=elems[A102+=A_cs]; 
+				a112=elems[A112+=A_cs]; 
+				a122=elems[A122+=A_cs]; 
+
+				a202=elems[A202+=A_cs]; 
+				a212=elems[A212+=A_cs]; 
+				a222=elems[A222+=A_cs]; 
+
+				B_elems[B11] = 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);
+				B11 += B_cs;
+				
+				// move remembered cells
+				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;			
+			}
+		A_index += A_rs;
+		B_index += B_rs;
+		}
+	}
+}
+}

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

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseObjectMatrix1D.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseObjectMatrix1D.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseObjectMatrix1D.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseObjectMatrix1D.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,359 @@
+/*
+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.impl;
+
+import org.apache.mahout.colt.matrix.ObjectMatrix1D;
+import org.apache.mahout.colt.matrix.ObjectMatrix2D;
+/**
+Dense 1-d matrix (aka <i>vector</i>) 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>
+<b>Implementation:</b>
+<p>
+Internally holds one single contigous one-dimensional array. 
+Note that this implementation is not synchronized.
+<p>
+<b>Memory requirements:</b>
+<p>
+<tt>memory [bytes] = 8*size()</tt>.
+Thus, a 1000000 matrix uses 8 MB.
+<p>
+<b>Time complexity:</b>
+<p>
+<tt>O(1)</tt> (i.e. constant time) for the basic operations
+<tt>get</tt>, <tt>getQuick</tt>, <tt>set</tt>, <tt>setQuick</tt> and <tt>size</tt>,
+<p>
+@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 DenseObjectMatrix1D extends ObjectMatrix1D {
+	/**
+	  * The elements of this matrix.
+	  */
+	protected Object[] elements;
+/**
+ * Constructs a matrix with a copy of the given 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 DenseObjectMatrix1D(Object[] values) {
+	this(values.length);
+	assign(values);
+}
+/**
+ * Constructs a matrix with a given number of cells.
+ * All entries are initially <tt>0</tt>.
+ * @param size the number of cells the matrix shall have.
+ * @throws IllegalArgumentException if <tt>size<0</tt>.
+ */
+public DenseObjectMatrix1D(int size) {
+	setUp(size);
+	this.elements = new Object[size];
+}
+/**
+ * Constructs a matrix view with the given parameters.
+ * @param size the number of cells the matrix shall have.
+ * @param elements the cells.
+ * @param zero the index of the first element.
+ * @param stride the number of indexes between any two elements, i.e. <tt>index(i+1)-index(i)</tt>.
+ * @throws IllegalArgumentException if <tt>size<0</tt>.
+ */
+protected DenseObjectMatrix1D(int size, Object[] elements, int zero, int stride) {
+	setUp(size,zero,stride);
+	this.elements = elements;
+	this.isNoView = false;
+}
+/**
+ * Sets all cells to the state specified by <tt>values</tt>.
+ * <tt>values</tt> is required to have the same number of cells 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 != size()</tt>.
+ */
+public ObjectMatrix1D assign(Object[] values) {
+	if (isNoView) {
+		if (values.length != size) throw new IllegalArgumentException("Must have same number of cells: length="+values.length+"size()="+size());
+		System.arraycopy(values, 0, this.elements, 0, values.length);
+	}
+	else {
+		super.assign(values);
+	}
+	return this;
+}
+/**
+Assigns the result of a function to each cell; <tt>x[i] = function(x[i])</tt>.
+(Iterates downwards from <tt>[size()-1]</tt> to <tt>[0]</tt>).
+<p>
+<b>Example:</b>
+<pre>
+// change each cell to its sine
+matrix =   0.5      1.5      2.5       3.5 
+matrix.assign(org.apache.mahout.jet.math.Functions.sin);
+-->
+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 ObjectMatrix1D assign(org.apache.mahout.colt.function.ObjectFunction function) {
+	int s=stride;
+	int i=index(0);
+	Object[] elems = this.elements;
+	if (elements==null) throw new InternalError();
+
+	// the general case x[i] = f(x[i])
+	for (int k=size; --k >= 0; ) {
+		elems[i] = function.apply(elems[i]);
+		i += s;
+	}
+	return this;
+}
+/**
+ * Replaces all cell values of the receiver with the values of another matrix.
+ * Both matrices must have the same size.
+ * 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     source   the source matrix to copy from (may be identical to the receiver).
+ * @return <tt>this</tt> (for convenience only).
+ * @throws	IllegalArgumentException if <tt>size() != other.size()</tt>.
+ */
+public ObjectMatrix1D assign(ObjectMatrix1D source) {
+	// overriden for performance only
+	if (! (source instanceof DenseObjectMatrix1D)) {
+		return super.assign(source);
+	}
+	DenseObjectMatrix1D other = (DenseObjectMatrix1D) source;
+	if (other==this) return this;
+	checkSize(other);
+	if (isNoView && other.isNoView) { // quickest
+		System.arraycopy(other.elements, 0, this.elements, 0, this.elements.length);
+		return this;
+	}
+	if (haveSharedCells(other)) {
+		ObjectMatrix1D c = other.copy();
+		if (! (c instanceof DenseObjectMatrix1D)) { // should not happen
+			return super.assign(source);
+		}
+		other = (DenseObjectMatrix1D) c;
+	}
+
+	final Object[] elems = this.elements;
+	final Object[] otherElems = other.elements;
+	if (elements==null || otherElems==null) throw new InternalError();
+	int s = this.stride;
+	int ys = other.stride;
+
+	int index = index(0);
+	int otherIndex = other.index(0);
+	for (int k=size; --k >= 0; ) {
+		elems[index] = otherElems[otherIndex];
+		index += s;
+		otherIndex += ys;
+	}
+	return this;
+}
+/**
+Assigns the result of a function to each cell; <tt>x[i] = function(x[i],y[i])</tt>.
+(Iterates downwards from <tt>[size()-1]</tt> to <tt>[0]</tt>).
+<p>
+<b>Example:</b>
+<pre>
+// assign x[i] = x[i]<sup>y[i]</sup>
+m1 = 0 1 2 3;
+m2 = 0 2 4 6;
+m1.assign(m2, org.apache.mahout.jet.math.Functions.pow);
+-->
+m1 == 1 1 16 729
+
+// for non-standard functions there is no shortcut: 
+m1.assign(m2,
+&nbsp;&nbsp;&nbsp;new ObjectObjectFunction() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public Object apply(Object x, Object y) { return Math.pow(x,y); }
+&nbsp;&nbsp;&nbsp;}
+);
+</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>size() != y.size()</tt>.
+@see org.apache.mahout.jet.math.Functions
+*/
+public ObjectMatrix1D assign(ObjectMatrix1D y, org.apache.mahout.colt.function.ObjectObjectFunction function) {
+	// overriden for performance only
+	if (! (y instanceof DenseObjectMatrix1D)) {
+		return super.assign(y,function);
+	}
+	DenseObjectMatrix1D other = (DenseObjectMatrix1D) y;
+	checkSize(y);
+	final Object[] elems = this.elements;
+	final Object[] otherElems = other.elements;
+	if (elements==null || otherElems==null) throw new InternalError();
+	int s = this.stride;
+	int ys = other.stride;
+
+	int index = index(0);
+	int otherIndex = other.index(0);
+
+	// the general case x[i] = f(x[i],y[i])		
+	for (int k=size; --k >= 0; ) {
+		elems[index] = function.apply(elems[index], otherElems[otherIndex]);
+		index += s;
+		otherIndex += ys;
+	}
+	return this;
+}
+/**
+ * Returns the matrix cell value at coordinate <tt>index</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>index&lt;0 || index&gt;=size()</tt>.
+ *
+ * @param     index   the index of the cell.
+ * @return    the value of the specified cell.
+ */
+public Object getQuick(int index) {
+	//if (debug) if (index<0 || index>=size) checkIndex(index);
+	//return elements[index(index)];
+	// manually inlined:
+	return elements[zero + index*stride];
+}
+/**
+ * Returns <tt>true</tt> if both matrices share at least one identical cell.
+ */
+protected boolean haveSharedCellsRaw(ObjectMatrix1D other) {
+	if (other instanceof SelectedDenseObjectMatrix1D) {
+		SelectedDenseObjectMatrix1D otherMatrix = (SelectedDenseObjectMatrix1D) other;
+		return this.elements==otherMatrix.elements;
+	}
+	else if (other instanceof DenseObjectMatrix1D) {
+		DenseObjectMatrix1D otherMatrix = (DenseObjectMatrix1D) other;
+		return this.elements==otherMatrix.elements;
+	}
+	return false;
+}
+/**
+ * Returns the position of the element with the given relative rank within the (virtual or non-virtual) internal 1-dimensional array.
+ * You may want to override this method for performance.
+ *
+ * @param     rank   the rank of the element.
+ */
+protected int index(int rank) {
+	// overriden for manual inlining only
+	//return _offset(_rank(rank));
+	return zero + rank*stride;
+}
+/**
+ * Construct and returns a new empty matrix <i>of the same dynamic type</i> as the receiver, having the specified size.
+ * For example, if the receiver is an instance of type <tt>DenseObjectMatrix1D</tt> the new matrix must also be of type <tt>DenseObjectMatrix1D</tt>,
+ * if the receiver is an instance of type <tt>SparseObjectMatrix1D</tt> the new matrix must also be of type <tt>SparseObjectMatrix1D</tt>, etc.
+ * In general, the new matrix should have internal parametrization as similar as possible.
+ *
+ * @param size the number of cell the matrix shall have.
+ * @return  a new empty matrix of the same dynamic type.
+ */
+public ObjectMatrix1D like(int size) {
+	return new DenseObjectMatrix1D(size);
+}
+/**
+ * Construct and returns a new 2-d matrix <i>of the corresponding dynamic type</i>, entirelly independent of the receiver.
+ * For example, if the receiver is an instance of type <tt>DenseObjectMatrix1D</tt> the new matrix must be of type <tt>DenseObjectMatrix2D</tt>,
+ * if the receiver is an instance of type <tt>SparseObjectMatrix1D</tt> the new matrix must 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.
+ * @return  a new matrix of the corresponding dynamic type.
+ */
+public ObjectMatrix2D like2D(int rows, int columns) {
+	return new DenseObjectMatrix2D(rows,columns);
+}
+/**
+ * Sets the matrix cell at coordinate <tt>index</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>index&lt;0 || index&gt;=size()</tt>.
+ *
+ * @param     index   the index of the cell.
+ * @param    value the value to be filled into the specified cell.
+ */
+public void setQuick(int index, Object value) {
+	//if (debug) if (index<0 || index>=size) checkIndex(index);
+	//elements[index(index)] = value;
+	// manually inlined:
+	elements[zero + index*stride] = value;
+}
+/**
+Swaps each element <tt>this[i]</tt> with <tt>other[i]</tt>.
+@throws IllegalArgumentException if <tt>size() != other.size()</tt>.
+*/
+public void swap(ObjectMatrix1D other) {
+	// overriden for performance only
+	if (! (other instanceof DenseObjectMatrix1D)) {
+		super.swap(other);
+	}
+	DenseObjectMatrix1D y = (DenseObjectMatrix1D) other;
+	if (y==this) return;
+	checkSize(y);
+	
+	final Object[] elems = this.elements;
+	final Object[] otherElems = y.elements;
+	if (elements==null || otherElems==null) throw new InternalError();
+	int s = this.stride;
+	int ys = y.stride;
+
+	int index = index(0);
+	int otherIndex = y.index(0);
+	for (int k=size; --k >= 0; ) {
+		Object tmp = elems[index];
+		elems[index] = otherElems[otherIndex];
+		otherElems[otherIndex] = tmp;
+		index += s;
+		otherIndex += ys;
+	}
+	return;
+}
+/**
+Fills the cell values into the specified 1-dimensional array.
+The values are copied. So subsequent changes in <tt>values</tt> are not reflected in the matrix, and vice-versa.
+After this call returns the array <tt>values</tt> has the form 
+<br>
+<tt>for (int i=0; i < size(); i++) values[i] = get(i);</tt>
+
+@throws IllegalArgumentException if <tt>values.length < size()</tt>.
+*/
+public void toArray(Object[] values) {
+	if (values.length < size) throw new IllegalArgumentException("values too small");
+	if (this.isNoView) System.arraycopy(this.elements,0,values,0,this.elements.length);
+	else super.toArray(values);
+}
+/**
+ * Construct and returns a new selection view.
+ *
+ * @param offsets the offsets of the visible elements.
+ * @return  a new view.
+ */
+protected ObjectMatrix1D viewSelectionLike(int[] offsets) {
+	return new SelectedDenseObjectMatrix1D(this.elements,offsets);
+}
+}

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

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseObjectMatrix2D.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseObjectMatrix2D.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseObjectMatrix2D.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseObjectMatrix2D.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,399 @@
+/*
+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.impl;
+
+import org.apache.mahout.colt.matrix.ObjectMatrix1D;
+import org.apache.mahout.colt.matrix.ObjectMatrix2D;
+/**
+Dense 2-d matrix 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>
+<b>Implementation:</b>
+<p>
+Internally holds one single contigous one-dimensional array, addressed in row major. 
+Note that this implementation is not synchronized.
+<p>
+<b>Memory requirements:</b>
+<p>
+<tt>memory [bytes] = 8*rows()*columns()</tt>.
+Thus, a 1000*1000 matrix uses 8 MB.
+<p>
+<b>Time complexity:</b>
+<p>
+<tt>O(1)</tt> (i.e. constant time) for the basic operations
+<tt>get</tt>, <tt>getQuick</tt>, <tt>set</tt>, <tt>setQuick</tt> and <tt>size</tt>,
+<p>
+Cells are internally addressed in row-major.
+Applications demanding utmost speed can exploit this fact.
+Setting/getting values in a loop row-by-row is quicker than column-by-column.
+Thus
+<pre>
+   for (int row=0; row < rows; row++) {
+	  for (int column=0; column < columns; column++) {
+		 matrix.setQuick(row,column,someValue);
+	  }
+   }
+</pre>
+is quicker than
+<pre>
+   for (int column=0; column < columns; column++) {
+	  for (int row=0; row < rows; row++) {
+		 matrix.setQuick(row,column,someValue);
+	  }
+   }
+</pre>
+@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 DenseObjectMatrix2D extends ObjectMatrix2D {
+	/**
+	  * The elements of this matrix.
+	  * elements are stored in row major, i.e.
+	  * index==row*columns + column
+	  * columnOf(index)==index%columns
+	  * rowOf(index)==index/columns
+	  * i.e. {row0 column0..m}, {row1 column0..m}, ..., {rown column0..m}
+	  */
+	protected Object[] elements;
+/**
+ * Constructs a matrix with a copy of the given 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 DenseObjectMatrix2D(Object[][] values) {
+	this(values.length, values.length==0 ? 0: values[0].length);
+	assign(values);
+}
+/**
+ * Constructs a matrix with a given number of rows and columns.
+ * All entries are initially <tt>0</tt>.
+ * @param rows the number of rows the matrix shall have.
+ * @param columns the number of columns the matrix shall have.
+ * @throws	IllegalArgumentException if <tt>rows<0 || columns<0 || (Object)columns*rows > Integer.MAX_VALUE</tt>.
+ */
+public DenseObjectMatrix2D(int rows, int columns) {
+	setUp(rows, columns);
+	this.elements = new Object[rows*columns];
+}
+/**
+ * Constructs a view with the given parameters.
+ * @param rows the number of rows the matrix shall have.
+ * @param columns the number of columns the matrix shall have.
+ * @param elements the cells.
+ * @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>.
+ * @throws	IllegalArgumentException if <tt>rows<0 || columns<0 || (Object)columns*rows > Integer.MAX_VALUE</tt> or flip's are illegal.
+ */
+protected DenseObjectMatrix2D(int rows, int columns, Object[] elements, int rowZero, int columnZero, int rowStride, int columnStride) {
+	setUp(rows,columns,rowZero,columnZero,rowStride,columnStride);
+	this.elements = elements;
+	this.isNoView = false;
+}
+/**
+ * Sets all cells to the state specified by <tt>values</tt>.
+ * <tt>values</tt> is required to have the form <tt>values[row][column]</tt>
+ * and have exactly the same number of 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 != rows() || for any 0 &lt;= row &lt; rows(): values[row].length != columns()</tt>.
+ */
+public ObjectMatrix2D assign(Object[][] values) {
+	if (this.isNoView) {
+		if (values.length != rows) throw new IllegalArgumentException("Must have same number of rows: rows="+values.length+"rows()="+rows());
+		int i = columns*(rows-1);
+		for (int row=rows; --row >= 0;) {
+			Object[] currentRow = values[row];
+			if (currentRow.length != columns) throw new IllegalArgumentException("Must have same number of columns in every row: columns="+currentRow.length+"columns()="+columns());			
+			System.arraycopy(currentRow, 0, this.elements, i, columns);
+			i -= columns;
+		}
+	}
+	else {
+		super.assign(values);
+	}
+	return this;
+}
+/**
+Assigns the result of a function to each cell; <tt>x[row,col] = function(x[row,col])</tt>.
+<p>
+<b>Example:</b>
+<pre>
+matrix = 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);
+-->
+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 ObjectMatrix2D assign(org.apache.mahout.colt.function.ObjectFunction function) {
+	final Object[] elems = this.elements;
+	if (elems==null) throw new InternalError();
+	int index = index(0,0);
+	int cs = this.columnStride;
+	int rs = this.rowStride;
+	
+	// the general case x[i] = f(x[i])
+	for (int row=rows; --row >= 0; ) { 
+		for (int i=index, column=columns; --column >= 0; ) {
+			elems[i] = function.apply(elems[i]);
+			i += cs;
+		}
+		index += rs;
+	}
+	return this;
+}
+/**
+ * Replaces all cell values of the receiver with the values of another matrix.
+ * Both matrices must have the same number of 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     source   the source matrix to copy from (may be identical to the receiver).
+ * @return <tt>this</tt> (for convenience only).
+ * @throws	IllegalArgumentException if <tt>columns() != source.columns() || rows() != source.rows()</tt>
+ */
+public ObjectMatrix2D assign(ObjectMatrix2D source) {
+	// overriden for performance only
+	if (! (source instanceof DenseObjectMatrix2D)) {
+		return super.assign(source);
+	}
+	DenseObjectMatrix2D other = (DenseObjectMatrix2D) source;
+	if (other==this) return this; // nothing to do
+	checkShape(other);
+	
+	if (this.isNoView && other.isNoView) { // quickest
+		System.arraycopy(other.elements, 0, this.elements, 0, this.elements.length);
+		return this;
+	}
+	
+	if (haveSharedCells(other)) {
+		ObjectMatrix2D c = other.copy();
+		if (! (c instanceof DenseObjectMatrix2D)) { // should not happen
+			return super.assign(other);
+		}
+		other = (DenseObjectMatrix2D) c;
+	}
+	
+	final Object[] elems = this.elements;
+	final Object[] otherElems = other.elements;
+	if (elements==null || otherElems==null) throw new InternalError();
+	int cs = this.columnStride;
+	int ocs = other.columnStride;
+	int rs = this.rowStride;
+	int ors = other.rowStride;
+
+	int otherIndex = other.index(0,0);
+	int index = index(0,0);
+	for (int row=rows; --row >= 0; ) {
+		for (int i=index, j=otherIndex, column=columns; --column >= 0; ) {
+			elems[i] = otherElems[j];
+			i += cs;
+			j += ocs;
+		}
+		index += rs;
+		otherIndex += ors;
+	}
+	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 = 2 x 2 matrix 
+0 1 
+2 3
+
+m2 = 2 x 2 matrix 
+0 2 
+4 6
+
+m1.assign(m2, org.apache.mahout.jet.math.Functions.pow);
+-->
+m1 == 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>columns() != other.columns() || rows() != other.rows()</tt>
+@see org.apache.mahout.jet.math.Functions
+*/
+public ObjectMatrix2D assign(ObjectMatrix2D y, org.apache.mahout.colt.function.ObjectObjectFunction function) {
+	// overriden for performance only
+	if (! (y instanceof DenseObjectMatrix2D)) {
+		return super.assign(y, function);
+	}
+	DenseObjectMatrix2D other = (DenseObjectMatrix2D) y;
+	checkShape(y);
+	
+	final Object[] elems = this.elements;
+	final Object[] otherElems = other.elements;
+	if (elems==null || otherElems==null) throw new InternalError();
+	int cs = this.columnStride;
+	int ocs = other.columnStride;
+	int rs = this.rowStride;
+	int ors = other.rowStride;
+
+	int otherIndex = other.index(0,0);
+	int index = index(0,0);
+
+	// the general case x[i] = f(x[i],y[i])
+	for (int row=rows; --row >= 0; ) {
+		for (int i=index, j=otherIndex, column=columns; --column >= 0; ) {
+			elems[i] = function.apply(elems[i], otherElems[j]);
+			i += cs;
+			j += ocs;
+		}
+		index += rs;
+		otherIndex += ors;
+	}
+	return this;
+}
+/**
+ * Returns the matrix cell value at coordinate <tt>[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>0 &lt;= column &lt; columns() && 0 &lt;= row &lt; rows()</tt>.
+ *
+ * @param     row   the index of the row-coordinate.
+ * @param     column   the index of the column-coordinate.
+ * @return    the value at the specified coordinate.
+ */
+public Object getQuick(int row, int column) {
+	//if (debug) if (column<0 || column>=columns || row<0 || row>=rows) throw new IndexOutOfBoundsException("row:"+row+", column:"+column);
+	//return elements[index(row,column)];
+	//manually inlined:
+	return elements[rowZero + row*rowStride + columnZero + column*columnStride];
+}
+/**
+ * Returns <tt>true</tt> if both matrices share common cells.
+ * More formally, returns <tt>true</tt> if <tt>other != null</tt> and at least one of the following conditions is met
+ * <ul>
+ * <li>the receiver is a view of the other matrix
+ * <li>the other matrix is a view of the receiver
+ * <li><tt>this == other</tt>
+ * </ul>
+ */
+protected boolean haveSharedCellsRaw(ObjectMatrix2D other) {
+	if (other instanceof SelectedDenseObjectMatrix2D) {
+		SelectedDenseObjectMatrix2D otherMatrix = (SelectedDenseObjectMatrix2D) other;
+		return this.elements==otherMatrix.elements;
+	}
+	else if (other instanceof DenseObjectMatrix2D) {
+		DenseObjectMatrix2D otherMatrix = (DenseObjectMatrix2D) other;
+		return this.elements==otherMatrix.elements;
+	}
+	return false;
+}
+/**
+ * Returns the position of the given coordinate within the (virtual or non-virtual) internal 1-dimensional array. 
+ *
+ * @param     row   the index of the row-coordinate.
+ * @param     column   the index of the column-coordinate.
+ */
+protected int index(int row, int column) {
+	// return super.index(row,column);
+	// manually inlined for speed:
+	return rowZero + row*rowStride + columnZero + column*columnStride;
+}
+/**
+ * Construct and returns a new empty matrix <i>of the same dynamic type</i> as the receiver, having the specified number of rows and columns.
+ * For example, if the receiver is an instance of type <tt>DenseObjectMatrix2D</tt> the new matrix must also be of type <tt>DenseObjectMatrix2D</tt>,
+ * if the receiver is an instance of type <tt>SparseObjectMatrix2D</tt> the new matrix must also be of type <tt>SparseObjectMatrix2D</tt>, etc.
+ * In general, the new matrix should have internal parametrization as similar as possible.
+ *
+ * @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 ObjectMatrix2D like(int rows, int columns) {
+	return new DenseObjectMatrix2D(rows, columns);
+}
+/**
+ * Construct and returns a new 1-d matrix <i>of the corresponding dynamic type</i>, entirelly independent of the receiver.
+ * For example, if the receiver is an instance of type <tt>DenseObjectMatrix2D</tt> the new matrix must be of type <tt>DenseObjectMatrix1D</tt>,
+ * if the receiver is an instance of type <tt>SparseObjectMatrix2D</tt> the new matrix must be of type <tt>SparseObjectMatrix1D</tt>, etc.
+ *
+ * @param size the number of cells the matrix shall have.
+ * @return  a new matrix of the corresponding dynamic type.
+ */
+public ObjectMatrix1D like1D(int size) {
+	return new DenseObjectMatrix1D(size);
+}
+/**
+ * Construct and returns a new 1-d matrix <i>of the corresponding dynamic type</i>, sharing the same cells.
+ * For example, if the receiver is an instance of type <tt>DenseObjectMatrix2D</tt> the new matrix must be of type <tt>DenseObjectMatrix1D</tt>,
+ * if the receiver is an instance of type <tt>SparseObjectMatrix2D</tt> the new matrix must be of type <tt>SparseObjectMatrix1D</tt>, etc.
+ *
+ * @param size the number of cells the matrix shall have.
+ * @param zero the index of the first element.
+ * @param stride the number of indexes between any two elements, i.e. <tt>index(i+1)-index(i)</tt>.
+ * @return  a new matrix of the corresponding dynamic type.
+ */
+protected ObjectMatrix1D like1D(int size, int zero, int stride) {
+	return new DenseObjectMatrix1D(size,this.elements,zero,stride);
+}
+/**
+ * Sets the matrix cell at coordinate <tt>[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>0 &lt;= column &lt; columns() && 0 &lt;= row &lt; rows()</tt>.
+ *
+ * @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 void setQuick(int row, int column, Object value) {
+	//if (debug) if (column<0 || column>=columns || row<0 || row>=rows) throw new IndexOutOfBoundsException("row:"+row+", column:"+column);
+	//elements[index(row,column)] = value;
+	//manually inlined:
+	elements[rowZero + row*rowStride + columnZero + column*columnStride] = value;
+}
+/**
+ * Construct and returns a new selection view.
+ *
+ * @param rowOffsets the offsets of the visible elements.
+ * @param columnOffsets the offsets of the visible elements.
+ * @return  a new view.
+ */
+protected ObjectMatrix2D viewSelectionLike(int[] rowOffsets, int[] columnOffsets) {
+	return new SelectedDenseObjectMatrix2D(this.elements,rowOffsets,columnOffsets,0);
+}
+}

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