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 [34/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/doublealgo/Sorting.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/doublealgo/Sorting.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/doublealgo/Sorting.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/doublealgo/Sorting.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,767 @@
+/*
+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.doublealgo;
+
+import org.apache.mahout.colt.function.IntComparator;
+import org.apache.mahout.colt.matrix.DoubleFactory2D;
+import org.apache.mahout.colt.matrix.DoubleFactory3D;
+import org.apache.mahout.colt.matrix.DoubleMatrix1D;
+import org.apache.mahout.colt.matrix.DoubleMatrix2D;
+import org.apache.mahout.colt.matrix.DoubleMatrix3D;
+import org.apache.mahout.colt.matrix.impl.DenseDoubleMatrix1D;
+/**
+Matrix quicksorts and mergesorts.
+Use idioms like <tt>Sorting.quickSort.sort(...)</tt> and <tt>Sorting.mergeSort.sort(...)</tt>.
+<p>
+This is another case demonstrating one primary goal of this library: Delivering easy to use, yet very efficient APIs.
+The sorts return convenient <i>sort views</i>.
+This enables the usage of algorithms which scale well with the problem size:
+For example, sorting a 1000000 x 10000 or a 1000000 x 100 x 100 matrix performs just as fast as sorting a 1000000 x 1 matrix.
+This is so, because internally the algorithms only move around integer indexes, they do not physically move around entire rows or slices.
+The original matrix is left unaffected.
+<p>
+The quicksort is a derivative of the JDK 1.2 V1.26 algorithms (which are, in turn, based on Bentley's and McIlroy's fine work).
+The mergesort is a derivative of the JAL algorithms, with optimisations taken from the JDK algorithms.
+Mergesort is <i>stable</i> (by definition), while quicksort is not.
+A stable sort is, for example, helpful, if matrices are sorted successively
+by multiple columns. It preserves the relative position of equal elements.
+
+@see org.apache.mahout.colt.GenericSorting
+@see org.apache.mahout.colt.Sorting
+@see java.util.Arrays
+
+@author wolfgang.hoschek@cern.ch
+@version 1.1, 25/May/2000
+*/
+/**
+ * @deprecated until unit tests are in place. Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public class Sorting extends org.apache.mahout.colt.PersistentObject {
+ /**
+ * A prefabricated quicksort.
+ */
+ public static final Sorting quickSort = new Sorting(); // already has quicksort implemented
+
+ /**
+ * A prefabricated mergesort.
+ */
+ public static final Sorting mergeSort = new Sorting() { // override quicksort with mergesort
+ protected void runSort(int[] a, int fromIndex, int toIndex, IntComparator c) {
+ org.apache.mahout.colt.Sorting.mergeSort(a,fromIndex,toIndex,c);
+ }
+ protected void runSort(int fromIndex, int toIndex, IntComparator c, org.apache.mahout.colt.Swapper swapper) {
+ org.apache.mahout.colt.GenericSorting.mergeSort(fromIndex, toIndex, c, swapper);
+ }
+ };
+/**
+ * Makes this class non instantiable, but still let's others inherit from it.
+ */
+protected Sorting() {}
+/**
+ * Compare two values, one of which is assumed to be Double.NaN
+ */
+private static final int compareNaN(double a, double b) {
+ if (a!=a) {
+ if (b!=b) return 0; // NaN equals NaN
+ else return 1; // e.g. NaN > 5
+ }
+ return -1; // e.g. 5 < NaN
+}
+protected void runSort(int[] a, int fromIndex, int toIndex, IntComparator c) {
+ org.apache.mahout.colt.Sorting.quickSort(a,fromIndex,toIndex,c);
+}
+protected void runSort(int fromIndex, int toIndex, IntComparator c, org.apache.mahout.colt.Swapper swapper) {
+ org.apache.mahout.colt.GenericSorting.quickSort(fromIndex, toIndex, c, swapper);
+}
+/**
+Sorts the vector into ascending order, according to the <i>natural ordering</i>.
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa.
+To sort ranges use sub-ranging views. To sort descending, use flip views ...
+<p>
+<b>Example:</b>
+<table border="1" cellspacing="0">
+ <tr nowrap>
+ <td valign="top"><tt> 7, 1, 3, 1<br>
+ </tt></td>
+ <td valign="top">
+ <p><tt> ==> 1, 1, 3, 7<br>
+ The vector IS NOT SORTED.<br>
+ The new VIEW IS SORTED.</tt></p>
+ </td>
+ </tr>
+</table>
+
+@param vector the vector to be sorted.
+@return a new sorted vector (matrix) view.
+ <b>Note that the original matrix is left unaffected.</b>
+*/
+public DoubleMatrix1D sort(final DoubleMatrix1D vector) {
+ int[] indexes = new int[vector.size()]; // row indexes to reorder instead of matrix itself
+ for (int i=indexes.length; --i >= 0; ) indexes[i] = i;
+
+ IntComparator comp = new IntComparator() {
+ public int compare(int a, int b) {
+ double av = vector.getQuick(a);
+ double bv = vector.getQuick(b);
+ if (av!=av || bv!=bv) return compareNaN(av,bv); // swap NaNs to the end
+ return av<bv ? -1 : (av==bv ? 0 : 1);
+ }
+ };
+
+ runSort(indexes,0,indexes.length,comp);
+
+ return vector.viewSelection(indexes);
+}
+/**
+Sorts the vector into ascending order, according to the order induced by the specified comparator.
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa.
+The algorithm compares two cells at a time, determinining whether one is smaller, equal or larger than the other.
+To sort ranges use sub-ranging views. To sort descending, use flip views ...
+<p>
+<b>Example:</b>
+<pre>
+// sort by sinus of cells
+DoubleComparator comp = new DoubleComparator() {
+ public int compare(double a, double b) {
+ double as = Math.sin(a); double bs = Math.sin(b);
+ return as < bs ? -1 : as == bs ? 0 : 1;
+ }
+};
+sorted = quickSort(vector,comp);
+</pre>
+
+@param vector the vector to be sorted.
+@param c the comparator to determine the order.
+@return a new matrix view sorted as specified.
+ <b>Note that the original vector (matrix) is left unaffected.</b>
+*/
+public DoubleMatrix1D sort(final DoubleMatrix1D vector, final org.apache.mahout.colt.function.DoubleComparator c) {
+ int[] indexes = new int[vector.size()]; // row indexes to reorder instead of matrix itself
+ for (int i=indexes.length; --i >= 0; ) indexes[i] = i;
+
+ IntComparator comp = new IntComparator() {
+ public int compare(int a, int b) {
+ return c.compare(vector.getQuick(a), vector.getQuick(b));
+ }
+ };
+
+ runSort(indexes,0,indexes.length,comp);
+
+ return vector.viewSelection(indexes);
+}
+/**
+Sorts the matrix rows into ascending order, according to the <i>natural ordering</i> of the matrix values in the virtual column <tt>aggregates</tt>;
+Particularly efficient when comparing expensive aggregates, because aggregates need not be recomputed time and again, as is the case for comparator based sorts.
+Essentially, this algorithm makes expensive comparisons cheap.
+Normally each element of <tt>aggregates</tt> is a summary measure of a row.
+Speedup over comparator based sorting = <tt>2*log(rows)</tt>, on average.
+For this operation, quicksort is usually faster.
+<p>
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa.
+To sort ranges use sub-ranging views. To sort columns by rows, use dice views. To sort descending, use flip views ...
+<p>
+<b>Example:</b>
+Each aggregate is the sum of a row
+<table border="1" cellspacing="0">
+ <tr nowrap>
+ <td valign="top"><tt>4 x 2 matrix: <br>
+ 1, 1<br>
+ 5, 4<br>
+ 3, 0<br>
+ 4, 4 <br>
+ </tt></td>
+ <td align="left" valign="top">
+ <tt>aggregates=<br>
+ 2<br>
+ 9<br>
+ 3<br>
+ 8<br>
+ ==></tt></td>
+ <td valign="top">
+ <p><tt>4 x 2 matrix:<br>
+ 1, 1<br>
+ 3, 0<br>
+ 4, 4<br>
+ 5, 4</tt><br>
+ The matrix IS NOT SORTED.<br>
+ The new VIEW IS SORTED.</p>
+ </td>
+ </tr>
+</table>
+
+<table>
+<td class="PRE">
+<pre>
+// sort 10000 x 1000 matrix by sum of logarithms in a row (i.e. by geometric mean)
+DoubleMatrix2D matrix = new DenseDoubleMatrix2D(10000,1000);
+matrix.assign(new org.apache.mahout.jet.random.engine.MersenneTwister()); // initialized randomly
+org.apache.mahout.jet.math.Functions F = org.apache.mahout.jet.math.Functions.functions; // alias for convenience
+
+// THE QUICK VERSION (takes some 3 secs)
+// aggregates[i] = Sum(log(row));
+double[] aggregates = new double[matrix.rows()];
+for (int i = matrix.rows(); --i >= 0; ) aggregates[i] = matrix.viewRow(i).aggregate(F.plus, F.log);
+DoubleMatrix2D sorted = quickSort(matrix,aggregates);
+
+// THE SLOW VERSION (takes some 90 secs)
+DoubleMatrix1DComparator comparator = new DoubleMatrix1DComparator() {
+ public int compare(DoubleMatrix1D x, DoubleMatrix1D y) {
+ double a = x.aggregate(F.plus,F.log);
+ double b = y.aggregate(F.plus,F.log);
+ return a < b ? -1 : a==b ? 0 : 1;
+ }
+};
+DoubleMatrix2D sorted = quickSort(matrix,comparator);
+</pre>
+</td>
+</table>
+
+@param matrix the matrix to be sorted.
+@param aggregates the values to sort on. (As a side effect, this array will also get sorted).
+@return a new matrix view having rows sorted.
+ <b>Note that the original matrix is left unaffected.</b>
+@throws IndexOutOfBoundsException if <tt>aggregates.length != matrix.rows()</tt>.
+*/
+public DoubleMatrix2D sort(DoubleMatrix2D matrix, final double[] aggregates) {
+ int rows = matrix.rows();
+ if (aggregates.length != rows) throw new IndexOutOfBoundsException("aggregates.length != matrix.rows()");
+
+ // set up index reordering
+ final int[] indexes = new int[rows];
+ for (int i=rows; --i >= 0; ) indexes[i] = i;
+
+ // compares two aggregates at a time
+ org.apache.mahout.colt.function.IntComparator comp = new org.apache.mahout.colt.function.IntComparator() {
+ public int compare(int x, int y) {
+ double a = aggregates[x];
+ double b = aggregates[y];
+ if (a!=a || b!=b) return compareNaN(a,b); // swap NaNs to the end
+ return a < b ? -1 : (a==b) ? 0 : 1;
+ }
+ };
+ // swaps aggregates and reorders indexes
+ org.apache.mahout.colt.Swapper swapper = new org.apache.mahout.colt.Swapper() {
+ public void swap(int x, int y) {
+ int t1; double t2;
+ t1 = indexes[x]; indexes[x] = indexes[y]; indexes[y] = t1;
+ t2 = aggregates[x]; aggregates[x] = aggregates[y]; aggregates[y] = t2;
+ }
+ };
+
+ // sort indexes and aggregates
+ runSort(0,rows,comp,swapper);
+
+ // view the matrix according to the reordered row indexes
+ // take all columns in the original order
+ return matrix.viewSelection(indexes,null);
+}
+/**
+Sorts the matrix rows into ascending order, according to the <i>natural ordering</i> of the matrix values in 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.
+To sort ranges use sub-ranging views. To sort columns by rows, use dice views. To sort descending, use flip views ...
+<p>
+<b>Example:</b>
+<table border="1" cellspacing="0">
+ <tr nowrap>
+ <td valign="top"><tt>4 x 2 matrix: <br>
+ 7, 6<br>
+ 5, 4<br>
+ 3, 2<br>
+ 1, 0 <br>
+ </tt></td>
+ <td align="left" valign="top">
+ <p><tt>column = 0;<br>
+ view = quickSort(matrix,column);<br>
+ System.out.println(view); </tt><tt><br>
+ ==> </tt></p>
+ </td>
+ <td valign="top">
+ <p><tt>4 x 2 matrix:<br>
+ 1, 0<br>
+ 3, 2<br>
+ 5, 4<br>
+ 7, 6</tt><br>
+ The matrix IS NOT SORTED.<br>
+ The new VIEW IS SORTED.</p>
+ </td>
+ </tr>
+</table>
+
+@param matrix the matrix to be sorted.
+@param column the index of the column inducing the order.
+@return a new matrix view having rows sorted by the given column.
+ <b>Note that the original matrix is left unaffected.</b>
+@throws IndexOutOfBoundsException if <tt>column < 0 || column >= matrix.columns()</tt>.
+*/
+public DoubleMatrix2D sort(DoubleMatrix2D matrix, int column) {
+ if (column < 0 || column >= matrix.columns()) throw new IndexOutOfBoundsException("column="+column+", matrix="+Formatter.shape(matrix));
+
+ int[] rowIndexes = new int[matrix.rows()]; // row indexes to reorder instead of matrix itself
+ for (int i=rowIndexes.length; --i >= 0; ) rowIndexes[i] = i;
+
+ final DoubleMatrix1D col = matrix.viewColumn(column);
+ IntComparator comp = new IntComparator() {
+ public int compare(int a, int b) {
+ double av = col.getQuick(a);
+ double bv = col.getQuick(b);
+ if (av!=av || bv!=bv) return compareNaN(av,bv); // swap NaNs to the end
+ return av<bv ? -1 : (av==bv ? 0 : 1);
+ }
+ };
+
+ runSort(rowIndexes,0,rowIndexes.length,comp);
+
+ // view the matrix according to the reordered row indexes
+ // take all columns in the original order
+ return matrix.viewSelection(rowIndexes,null);
+}
+/**
+Sorts the matrix rows according to the order induced by the specified comparator.
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa.
+The algorithm compares two rows (1-d matrices) at a time, determinining whether one is smaller, equal or larger than the other.
+To sort ranges use sub-ranging views. To sort columns by rows, use dice views. To sort descending, use flip views ...
+<p>
+<b>Example:</b>
+<pre>
+// sort by sum of values in a row
+DoubleMatrix1DComparator comp = new DoubleMatrix1DComparator() {
+ public int compare(DoubleMatrix1D a, DoubleMatrix1D b) {
+ double as = a.zSum(); double bs = b.zSum();
+ return as < bs ? -1 : as == bs ? 0 : 1;
+ }
+};
+sorted = quickSort(matrix,comp);
+</pre>
+
+@param matrix the matrix to be sorted.
+@param c the comparator to determine the order.
+@return a new matrix view having rows sorted as specified.
+ <b>Note that the original matrix is left unaffected.</b>
+*/
+public DoubleMatrix2D sort(final DoubleMatrix2D matrix, final DoubleMatrix1DComparator c) {
+ int[] rowIndexes = new int[matrix.rows()]; // row indexes to reorder instead of matrix itself
+ for (int i=rowIndexes.length; --i >= 0; ) rowIndexes[i] = i;
+
+ final DoubleMatrix1D[] views = new DoubleMatrix1D[matrix.rows()]; // precompute views for speed
+ for (int i=views.length; --i >= 0; ) views[i] = matrix.viewRow(i);
+
+ IntComparator comp = new IntComparator() {
+ public int compare(int a, int b) {
+ //return c.compare(matrix.viewRow(a), matrix.viewRow(b));
+ return c.compare(views[a], views[b]);
+ }
+ };
+
+ runSort(rowIndexes,0,rowIndexes.length,comp);
+
+ // view the matrix according to the reordered row indexes
+ // take all columns in the original order
+ return matrix.viewSelection(rowIndexes,null);
+}
+/**
+Sorts the matrix rows into ascending order, according to the <i>natural ordering</i> of the values computed by applying the given aggregation function to each row;
+Particularly efficient when comparing expensive aggregates, because aggregates need not be recomputed time and again, as is the case for comparator based sorts.
+Essentially, this algorithm makes expensive comparisons cheap.
+Normally <tt>aggregates</tt> defines a summary measure of a row.
+Speedup over comparator based sorting = <tt>2*log(rows)</tt>, on average.
+<p>
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa.
+To sort ranges use sub-ranging views. To sort columns by rows, use dice views. To sort descending, use flip views ...
+<p>
+<b>Example:</b>
+Each aggregate is the sum of a row
+<table border="1" cellspacing="0">
+ <tr nowrap>
+ <td valign="top"><tt>4 x 2 matrix: <br>
+ 1, 1<br>
+ 5, 4<br>
+ 3, 0<br>
+ 4, 4 <br>
+ </tt></td>
+ <td align="left" valign="top">
+ <tt>aggregates=<br>
+ hep.aida.bin.BinFunctions1D.sum<br>
+ ==></tt></td>
+ <td valign="top">
+ <p><tt>4 x 2 matrix:<br>
+ 1, 1<br>
+ 3, 0<br>
+ 4, 4<br>
+ 5, 4</tt><br>
+ The matrix IS NOT SORTED.<br>
+ The new VIEW IS SORTED.</p>
+ </td>
+ </tr>
+</table>
+
+<table>
+<td class="PRE">
+<pre>
+// sort 10000 x 1000 matrix by median or by sum of logarithms in a row (i.e. by geometric mean)
+DoubleMatrix2D matrix = new DenseDoubleMatrix2D(10000,1000);
+matrix.assign(new org.apache.mahout.jet.random.engine.MersenneTwister()); // initialized randomly
+org.apache.mahout.jet.math.Functions F = org.apache.mahout.jet.math.Functions.functions; // alias for convenience
+
+// THE QUICK VERSION (takes some 10 secs)
+DoubleMatrix2D sorted = quickSort(matrix,hep.aida.bin.BinFunctions1D.median);
+//DoubleMatrix2D sorted = quickSort(matrix,hep.aida.bin.BinFunctions1D.sumOfLogarithms);
+
+// THE SLOW VERSION (takes some 300 secs)
+DoubleMatrix1DComparator comparator = new DoubleMatrix1DComparator() {
+ public int compare(DoubleMatrix1D x, DoubleMatrix1D y) {
+ double a = org.apache.mahout.colt.matrix.doublealgo.Statistic.bin(x).median();
+ double b = org.apache.mahout.colt.matrix.doublealgo.Statistic.bin(y).median();
+ // double a = x.aggregate(F.plus,F.log);
+ // double b = y.aggregate(F.plus,F.log);
+ return a < b ? -1 : a==b ? 0 : 1;
+ }
+};
+DoubleMatrix2D sorted = quickSort(matrix,comparator);
+</pre>
+</td>
+</table>
+
+@param matrix the matrix to be sorted.
+@param aggregate the function to sort on; aggregates values in a row.
+@return a new matrix view having rows sorted.
+ <b>Note that the original matrix is left unaffected.</b>
+
+public DoubleMatrix2D sort(DoubleMatrix2D matrix, hep.aida.bin.BinFunction1D aggregate) {
+ // precompute aggregates over rows, as defined by "aggregate"
+
+ // a bit clumsy, because Statistic.aggregate(...) is defined on columns, so we need to transpose views
+ DoubleMatrix2D tmp = matrix.like(1,matrix.rows());
+ hep.aida.bin.BinFunction1D[] func = {aggregate};
+ Statistic.aggregate(matrix.viewDice(), func, tmp);
+ double[] aggr = tmp.viewRow(0).toArray();
+ return sort(matrix,aggr);
+}
+*/
+/**
+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.
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa.
+To sort ranges use sub-ranging views. To sort by other dimensions, use dice views. To sort descending, use flip views ...
+<p>
+The algorithm compares two 2-d slices at a time, determinining whether one is smaller, equal or larger than the other.
+Comparison is based on the cell <tt>[row,column]</tt> within a slice.
+Let <tt>A</tt> and <tt>B</tt> be two 2-d slices. Then we have the following rules
+<ul>
+<li><tt>A < B iff A.get(row,column) < B.get(row,column)</tt>
+<li><tt>A == B iff A.get(row,column) == B.get(row,column)</tt>
+<li><tt>A > B iff A.get(row,column) > B.get(row,column)</tt>
+</ul>
+
+@param matrix the matrix to be sorted.
+@param row the index of the row inducing the order.
+@param column the index of the column inducing the order.
+@return a new matrix view having slices sorted by the values of the slice view <tt>matrix.viewRow(row).viewColumn(column)</tt>.
+ <b>Note that the original matrix is left unaffected.</b>
+@throws IndexOutOfBoundsException if <tt>row < 0 || row >= matrix.rows() || column < 0 || column >= matrix.columns()</tt>.
+*/
+public DoubleMatrix3D sort(DoubleMatrix3D matrix, int row, int column) {
+ if (row < 0 || row >= matrix.rows()) throw new IndexOutOfBoundsException("row="+row+", matrix="+Formatter.shape(matrix));
+ if (column < 0 || column >= matrix.columns()) throw new IndexOutOfBoundsException("column="+column+", matrix="+Formatter.shape(matrix));
+
+ int[] sliceIndexes = new int[matrix.slices()]; // indexes to reorder instead of matrix itself
+ for (int i=sliceIndexes.length; --i >= 0; ) sliceIndexes[i] = i;
+
+ final DoubleMatrix1D sliceView = matrix.viewRow(row).viewColumn(column);
+ IntComparator comp = new IntComparator() {
+ public int compare(int a, int b) {
+ double av = sliceView.getQuick(a);
+ double bv = sliceView.getQuick(b);
+ if (av!=av || bv!=bv) return compareNaN(av,bv); // swap NaNs to the end
+ return av<bv ? -1 : (av==bv ? 0 : 1);
+ }
+ };
+
+ runSort(sliceIndexes,0,sliceIndexes.length,comp);
+
+ // view the matrix according to the reordered slice indexes
+ // take all rows and columns in the original order
+ return matrix.viewSelection(sliceIndexes,null,null);
+}
+/**
+Sorts the matrix slices according to the order induced by the specified comparator.
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa.
+The algorithm compares two slices (2-d matrices) at a time, determinining whether one is smaller, equal or larger than the other.
+To sort ranges use sub-ranging views. To sort by other dimensions, use dice views. To sort descending, use flip views ...
+<p>
+<b>Example:</b>
+<pre>
+// sort by sum of values in a slice
+DoubleMatrix2DComparator comp = new DoubleMatrix2DComparator() {
+ public int compare(DoubleMatrix2D a, DoubleMatrix2D b) {
+ double as = a.zSum(); double bs = b.zSum();
+ return as < bs ? -1 : as == bs ? 0 : 1;
+ }
+};
+sorted = quickSort(matrix,comp);
+</pre>
+
+@param matrix the matrix to be sorted.
+@param c the comparator to determine the order.
+@return a new matrix view having slices sorted as specified.
+ <b>Note that the original matrix is left unaffected.</b>
+*/
+public DoubleMatrix3D sort(final DoubleMatrix3D matrix, final DoubleMatrix2DComparator c) {
+ int[] sliceIndexes = new int[matrix.slices()]; // indexes to reorder instead of matrix itself
+ for (int i=sliceIndexes.length; --i >= 0; ) sliceIndexes[i] = i;
+
+ final DoubleMatrix2D[] views = new DoubleMatrix2D[matrix.slices()]; // precompute views for speed
+ for (int i=views.length; --i >= 0; ) views[i] = matrix.viewSlice(i);
+
+ IntComparator comp = new IntComparator() {
+ public int compare(int a, int b) {
+ //return c.compare(matrix.viewSlice(a), matrix.viewSlice(b));
+ return c.compare(views[a], views[b]);
+ }
+ };
+
+ runSort(sliceIndexes,0,sliceIndexes.length,comp);
+
+ // view the matrix according to the reordered slice indexes
+ // take all rows and columns in the original order
+ return matrix.viewSelection(sliceIndexes,null,null);
+}
+/**
+ * Demonstrates advanced sorting.
+ * Sorts by sum of row.
+ */
+public static void zdemo1() {
+ Sorting sort = quickSort;
+ DoubleMatrix2D matrix = DoubleFactory2D.dense.descending(4,3);
+ DoubleMatrix1DComparator comp = new DoubleMatrix1DComparator() {
+ public int compare(DoubleMatrix1D a, DoubleMatrix1D b) {
+ double as = a.zSum(); double bs = b.zSum();
+ return as < bs ? -1 : as == bs ? 0 : 1;
+ }
+ };
+ System.out.println("unsorted:"+matrix);
+ System.out.println("sorted :"+sort.sort(matrix,comp));
+}
+/**
+ * Demonstrates advanced sorting.
+ * Sorts by sum of slice.
+ */
+public static void zdemo2() {
+ Sorting sort = quickSort;
+ DoubleMatrix3D matrix = DoubleFactory3D.dense.descending(4,3,2);
+ DoubleMatrix2DComparator comp = new DoubleMatrix2DComparator() {
+ public int compare(DoubleMatrix2D a, DoubleMatrix2D b) {
+ double as = a.zSum();
+ double bs = b.zSum();
+ return as < bs ? -1 : as == bs ? 0 : 1;
+ }
+ };
+ System.out.println("unsorted:"+matrix);
+ System.out.println("sorted :"+sort.sort(matrix,comp));
+}
+/**
+ * Demonstrates advanced sorting.
+ * Sorts by sinus of cell values.
+ */
+public static void zdemo3() {
+ Sorting sort = quickSort;
+ double[] values = {0.5, 1.5, 2.5, 3.5};
+ DoubleMatrix1D matrix = new DenseDoubleMatrix1D(values);
+ org.apache.mahout.colt.function.DoubleComparator comp = new org.apache.mahout.colt.function.DoubleComparator() {
+ public int compare(double a, double b) {
+ double as = Math.sin(a); double bs = Math.sin(b);
+ return as < bs ? -1 : as == bs ? 0 : 1;
+ }
+ };
+ System.out.println("unsorted:"+matrix);
+
+ DoubleMatrix1D sorted = sort.sort(matrix,comp);
+ System.out.println("sorted :"+sorted);
+
+ // check whether it is really sorted
+ sorted.assign(org.apache.mahout.jet.math.Functions.sin);
+ /*
+ sorted.assign(
+ new org.apache.mahout.colt.function.DoubleFunction() {
+ public double apply(double arg) { return Math.sin(arg); }
+ }
+ );
+ */
+ System.out.println("sined :"+sorted);
+}
+/**
+ * Demonstrates applying functions.
+ */
+protected static void zdemo4() {
+ double[] values1 = {0, 1, 2, 3};
+ double[] values2 = {0, 2, 4, 6};
+ DoubleMatrix1D matrix1 = new DenseDoubleMatrix1D(values1);
+ DoubleMatrix1D matrix2 = new DenseDoubleMatrix1D(values2);
+ System.out.println("m1:"+matrix1);
+ System.out.println("m2:"+matrix2);
+
+ matrix1.assign(matrix2, org.apache.mahout.jet.math.Functions.pow);
+
+ /*
+ matrix1.assign(matrix2,
+ new org.apache.mahout.colt.function.DoubleDoubleFunction() {
+ public double apply(double x, double y) { return Math.pow(x,y); }
+ }
+ );
+ */
+
+ System.out.println("applied:"+matrix1);
+}
+/**
+ * Demonstrates sorting with precomputation of aggregates (median and sum of logarithms).
+ *
+public static void zdemo5(int rows, int columns, boolean print) {
+ Sorting sort = quickSort;
+ // for reliable benchmarks, call this method twice: once with small dummy parameters to "warm up" the jitter, then with your real work-load
+
+ System.out.println("\n\n");
+ System.out.print("now initializing... ");
+ org.apache.mahout.colt.Timer timer = new org.apache.mahout.colt.Timer().start();
+
+ final org.apache.mahout.jet.math.Functions F = org.apache.mahout.jet.math.Functions.functions;
+ DoubleMatrix2D A = org.apache.mahout.colt.matrix.DoubleFactory2D.dense.make(rows,columns);
+ A.assign(new org.apache.mahout.jet.random.engine.DRand()); // initialize randomly
+ timer.stop().display();
+
+ // also benchmark copying in its several implementation flavours
+ DoubleMatrix2D B = A.like();
+ timer.reset().start();
+ System.out.print("now copying... ");
+ B.assign(A);
+ timer.stop().display();
+
+ timer.reset().start();
+ System.out.print("now copying subrange... ");
+ B.viewPart(0,0,rows,columns).assign(A.viewPart(0,0,rows,columns));
+ timer.stop().display();
+ //System.out.println(A);
+
+ timer.reset().start();
+ System.out.print("now copying selected... ");
+ B.viewSelection(null,null).assign(A.viewSelection(null,null));
+ timer.stop().display();
+
+ System.out.print("now sorting - quick version with precomputation... ");
+ timer.reset().start();
+ // THE QUICK VERSION (takes some 10 secs)
+ A = sort.sort(A,hep.aida.bin.BinFunctions1D.median);
+ //A = sort.sort(A,hep.aida.bin.BinFunctions1D.sumLog);
+ timer.stop().display();
+
+ // check results for correctness
+ // WARNING: be sure NOT TO PRINT huge matrices unless you have tons of main memory and time!!
+ // so we just show the first 5 rows
+ if (print) {
+ int r = Math.min(rows,5);
+ hep.aida.bin.BinFunction1D[] funs = {hep.aida.bin.BinFunctions1D.median, hep.aida.bin.BinFunctions1D.sumLog, hep.aida.bin.BinFunctions1D.geometricMean};
+ String[] rowNames = new String[r];
+ String[] columnNames = new String[columns];
+ for (int i=columns; --i >= 0; ) columnNames[i] = Integer.toString(i);
+ for (int i=r; --i >= 0; ) rowNames[i] = Integer.toString(i);
+ System.out.println("first part of sorted result = \n"+new org.apache.mahout.colt.matrix.doublealgo.Formatter("%G").toTitleString(
+ A.viewPart(0,0,r,columns), rowNames, columnNames, null, null, null, funs
+ ));
+ }
+
+
+ System.out.print("now sorting - slow version... ");
+ A = B;
+ org.apache.mahout.colt.matrix.doublealgo.DoubleMatrix1DComparator fun = new org.apache.mahout.colt.matrix.doublealgo.DoubleMatrix1DComparator() {
+ public int compare(DoubleMatrix1D x, DoubleMatrix1D y) {
+ double a = org.apache.mahout.colt.matrix.doublealgo.Statistic.bin(x).median();
+ double b = org.apache.mahout.colt.matrix.doublealgo.Statistic.bin(y).median();
+ //double a = x.aggregate(F.plus,F.log);
+ //double b = y.aggregate(F.plus,F.log);
+ return a < b ? -1 : (a==b) ? 0 : 1;
+ }
+ };
+ timer.reset().start();
+ A = sort.sort(A,fun);
+ timer.stop().display();
+}
+*/
+/**
+ * Demonstrates advanced sorting.
+ * Sorts by sum of row.
+ */
+public static void zdemo6() {
+ Sorting sort = quickSort;
+ double[][] values = {
+ { 3,7,0 },
+ { 2,1,0 },
+ { 2,2,0 },
+ { 1,8,0 },
+ { 2,5,0 },
+ { 7,0,0 },
+ { 2,3,0 },
+ { 1,0,0 },
+ { 4,0,0 },
+ { 2,0,0 }
+ };
+ DoubleMatrix2D A = DoubleFactory2D.dense.make(values);
+ DoubleMatrix2D B,C;
+ /*
+ DoubleMatrix1DComparator comp = new DoubleMatrix1DComparator() {
+ public int compare(DoubleMatrix1D a, DoubleMatrix1D b) {
+ double as = a.zSum(); double bs = b.zSum();
+ return as < bs ? -1 : as == bs ? 0 : 1;
+ }
+ };
+ */
+ System.out.println("\n\nunsorted:"+A);
+ B = quickSort.sort(A,1);
+ C = quickSort.sort(B,0);
+ System.out.println("quick sorted :"+C);
+
+ B = mergeSort.sort(A,1);
+ C = mergeSort.sort(B,0);
+ System.out.println("merge sorted :"+C);
+
+}
+/**
+ * Demonstrates sorting with precomputation of aggregates, comparing mergesort with quicksort.
+ */
+public static void zdemo7(int rows, int columns, boolean print) {
+ // for reliable benchmarks, call this method twice: once with small dummy parameters to "warm up" the jitter, then with your real work-load
+
+ System.out.println("\n\n");
+ System.out.println("now initializing... ");
+
+ final org.apache.mahout.jet.math.Functions F = org.apache.mahout.jet.math.Functions.functions;
+ DoubleMatrix2D A = org.apache.mahout.colt.matrix.DoubleFactory2D.dense.make(rows,columns);
+ A.assign(new org.apache.mahout.jet.random.engine.DRand()); // initialize randomly
+ DoubleMatrix2D B = A.copy();
+
+ double[] v1 = A.viewColumn(0).toArray();
+ double[] v2 = A.viewColumn(0).toArray();
+ System.out.print("now quick sorting... ");
+ org.apache.mahout.colt.Timer timer = new org.apache.mahout.colt.Timer().start();
+ quickSort.sort(A,0);
+ timer.stop().display();
+
+ System.out.print("now merge sorting... ");
+ timer.reset().start();
+ mergeSort.sort(A,0);
+ timer.stop().display();
+
+ System.out.print("now quick sorting with simple aggregation... ");
+ timer.reset().start();
+ quickSort.sort(A,v1);
+ timer.stop().display();
+
+ System.out.print("now merge sorting with simple aggregation... ");
+ timer.reset().start();
+ mergeSort.sort(A,v2);
+ timer.stop().display();
+}
+}
Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/doublealgo/Sorting.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/doublealgo/Statistic.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/doublealgo/Statistic.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/doublealgo/Statistic.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/doublealgo/Statistic.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,856 @@
+/*
+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.doublealgo;
+
+import org.apache.mahout.colt.function.DoubleDoubleFunction;
+import org.apache.mahout.colt.matrix.DoubleFactory2D;
+import org.apache.mahout.colt.matrix.DoubleMatrix1D;
+import org.apache.mahout.colt.matrix.DoubleMatrix2D;
+import org.apache.mahout.colt.matrix.DoubleMatrix3D;
+import org.apache.mahout.jet.random.engine.RandomEngine;
+/**
+Basic statistics operations on matrices.
+Computation of covariance, correlation, distance matrix.
+Random sampling views.
+Conversion to histograms with and without OLAP cube operators.
+Conversion to bins with retrieval of statistical bin measures.
+Also see {@link org.apache.mahout.jet.stat} and {@link hep.aida.bin}, in particular {@link hep.aida.bin.DynamicBin1D}.
+<p>
+Examples:
+<table border="1" cellspacing="0" dwcopytype="CopyTableRow">
+ <tr valign="top" align="center">
+ <td><tt>A</tt></td>
+ <td><tt>covariance(A)</tt></td>
+ <td><tt>correlation(covariance(A))</tt></td>
+ <td><tt>distance(A,EUCLID)</tt></td>
+ </tr>
+ <tr valign="top">
+ <td><tt> 4 x 3 matrix<br>
+ 1 2 3<br>
+ 2 4 6<br>
+ 3 6 9<br>
+ 4 -8 -10 </tt> </td>
+ <td><tt> 3 x 3 matrix<br>
+ 1.25 -3.5 -4.5<br>
+ -3.5 29 39 <br>
+ -4.5 39 52.5 </tt></td>
+ <td><tt> 3 x 3 matrix<br>
+ 1 -0.581318 -0.555492<br>
+ -0.581318 1 0.999507<br>
+ -0.555492 0.999507 1
+ </tt></td>
+ <td><tt> 3 x 3 matrix<br>
+ 0 12.569805 15.874508<br>
+ 12.569805 0 4.242641<br>
+ 15.874508 4.242641 0
+ </tt> <tt> </tt></td>
+ </tr>
+</table>
+
+@author wolfgang.hoschek@cern.ch
+@version 1.0, 09/24/99
+*/
+/**
+ * @deprecated until unit tests are in place. Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public class Statistic extends Object {
+ private static final org.apache.mahout.jet.math.Functions F = org.apache.mahout.jet.math.Functions.functions;
+ /**
+ * Euclidean distance function; <tt>Sqrt(Sum( (x[i]-y[i])^2 ))</tt>.
+ */
+ public static final VectorVectorFunction EUCLID = new VectorVectorFunction() {
+ public final double apply(DoubleMatrix1D a, DoubleMatrix1D b) {
+ return Math.sqrt(a.aggregate(b, F.plus, F.chain(F.square,F.minus)));
+ }
+ };
+
+ /**
+ * Bray-Curtis distance function; <tt>Sum( abs(x[i]-y[i]) ) / Sum( x[i]+y[i] )</tt>.
+ */
+ public static final VectorVectorFunction BRAY_CURTIS = new VectorVectorFunction() {
+ public final double apply(DoubleMatrix1D a, DoubleMatrix1D b) {
+ return a.aggregate(b, F.plus, F.chain(F.abs,F.minus)) / a.aggregate(b, F.plus, F.plus);
+ }
+ };
+
+ /**
+ * Canberra distance function; <tt>Sum( abs(x[i]-y[i]) / abs(x[i]+y[i]) )</tt>.
+ */
+ public static final VectorVectorFunction CANBERRA = new VectorVectorFunction() {
+ DoubleDoubleFunction fun = new DoubleDoubleFunction() {
+ public final double apply(double a, double b) {
+ return Math.abs(a-b) / Math.abs(a+b);
+ }
+ };
+ public final double apply(DoubleMatrix1D a, DoubleMatrix1D b) {
+ return a.aggregate(b, F.plus, fun);
+ }
+ };
+
+ /**
+ * Maximum distance function; <tt>Max( abs(x[i]-y[i]) )</tt>.
+ */
+ public static final VectorVectorFunction MAXIMUM = new VectorVectorFunction() {
+ public final double apply(DoubleMatrix1D a, DoubleMatrix1D b) {
+ return a.aggregate(b, F.max, F.chain(F.abs,F.minus));
+ }
+ };
+
+ /**
+ * Manhattan distance function; <tt>Sum( abs(x[i]-y[i]) )</tt>.
+ */
+ public static final VectorVectorFunction MANHATTAN = new VectorVectorFunction() {
+ public final double apply(DoubleMatrix1D a, DoubleMatrix1D b) {
+ return a.aggregate(b, F.plus, F.chain(F.abs,F.minus));
+ }
+ };
+
+
+
+
+/**
+ * Interface that represents a function object: a function that takes
+ * two argument vectors and returns a single value.
+ */
+/**
+ * @deprecated until unit tests are in place. Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public interface VectorVectorFunction {
+/**
+ * Applies a function to two argument vectors.
+ *
+ * @param x the first argument vector passed to the function.
+ * @param y the second argument vector passed to the function.
+ * @return the result of the function.
+ */
+abstract public double apply(org.apache.mahout.colt.matrix.DoubleMatrix1D x, org.apache.mahout.colt.matrix.DoubleMatrix1D y);
+}
+
+/**
+ * Makes this class non instantiable, but still let's others inherit from it.
+ */
+protected Statistic() {}
+/**
+ * Applies the given aggregation functions to each column and stores the results in a the result matrix.
+ * If matrix has shape <tt>m x n</tt>, then result must have shape <tt>aggr.length x n</tt>.
+ * Tip: To do aggregations on rows use dice views (transpositions), as in <tt>aggregate(matrix.viewDice(),aggr,result.viewDice())</tt>.
+ *
+ * @param matrix any matrix; a column holds the values of a given variable.
+ * @param aggr the aggregation functions to be applied to each column.
+ * @param result the matrix to hold the aggregation results.
+ * @return <tt>result</tt> (for convenience only).
+ * @see Formatter
+ * @see hep.aida.bin.BinFunction1D
+ * @see hep.aida.bin.BinFunctions1D
+ *
+public static DoubleMatrix2D aggregate(DoubleMatrix2D matrix, hep.aida.bin.BinFunction1D[] aggr, DoubleMatrix2D result) {
+ DynamicBin1D bin = new DynamicBin1D();
+ double[] elements = new double[matrix.rows()];
+ org.apache.mahout.colt.list.DoubleArrayList values = new org.apache.mahout.colt.list.DoubleArrayList(elements);
+ for (int column=matrix.columns(); --column >= 0; ) {
+ matrix.viewColumn(column).toArray(elements); // copy column into values
+ bin.clear();
+ bin.addAllOf(values);
+ for (int i=aggr.length; --i >= 0; ) {
+ result.set(i, column, aggr[i].apply(bin));
+ }
+ }
+ return result;
+}
+*/
+/**
+Fills all cell values of the given vector into a bin from which statistics measures can be retrieved efficiently.
+Cells values are copied.
+<br>
+Tip: Use <tt>System.out.println(bin(vector))</tt> to print most measures computed by the bin. Example:
+<table>
+<td class="PRE">
+<pre>
+Size: 20000
+Sum: 299858.02350278624
+SumOfSquares: 5399184.154095971
+Min: 0.8639113139711261
+Max: 59.75331890541892
+Mean: 14.992901175139313
+RMS: 16.43043540825375
+Variance: 45.17438077634358
+Standard deviation: 6.721188940681818
+Standard error: 0.04752598277592142
+Geometric mean: 13.516615397064466
+Product: Infinity
+Harmonic mean: 11.995174297952191
+Sum of inversions: 1667.337172700724
+Skew: 0.8922838940067878
+Kurtosis: 1.1915828121825598
+Sum of powers(3): 1.1345828465808412E8
+Sum of powers(4): 2.7251055344494686E9
+Sum of powers(5): 7.367125643433887E10
+Sum of powers(6): 2.215370909100143E12
+Moment(0,0): 1.0
+Moment(1,0): 14.992901175139313
+Moment(2,0): 269.95920770479853
+Moment(3,0): 5672.914232904206
+Moment(4,0): 136255.27672247344
+Moment(5,0): 3683562.8217169433
+Moment(6,0): 1.1076854545500715E8
+Moment(0,mean()): 1.0
+Moment(1,mean()): -2.0806734113421045E-14
+Moment(2,mean()): 45.172122057305664
+Moment(3,mean()): 270.92018671421
+Moment(4,mean()): 8553.8664869067
+Moment(5,mean()): 153357.41712233616
+Moment(6,mean()): 4273757.570142922
+25%, 50% and 75% Quantiles: 10.030074811938091, 13.977982089912224,
+18.86124362967137
+quantileInverse(mean): 0.559163335012079
+Distinct elements & frequencies not printed (too many).
+</pre>
+</td>
+</table>
+
+@param vector the vector to analyze.
+@return a bin holding the statistics measures of the vector.
+*
+public static DynamicBin1D bin(DoubleMatrix1D vector) {
+ DynamicBin1D bin = new DynamicBin1D();
+ bin.addAllOf(DoubleFactory1D.dense.toList(vector));
+ return bin;
+}
+*/
+/**
+ * Modifies the given covariance matrix to be a correlation matrix (in-place).
+ * The correlation matrix is a square, symmetric matrix consisting of nothing but correlation coefficients.
+ * The rows and the columns represent the variables, the cells represent correlation coefficients.
+ * The diagonal cells (i.e. the correlation between a variable and itself) will equal 1, for the simple reason that the correlation coefficient of a variable with itself equals 1.
+ * The correlation of two column vectors x and y is given by <tt>corr(x,y) = cov(x,y) / (stdDev(x)*stdDev(y))</tt> (Pearson's correlation coefficient).
+ * A correlation coefficient varies between -1 (for a perfect negative relationship) to +1 (for a perfect positive relationship).
+ * See the <A HREF="http://www.cquest.utoronto.ca/geog/ggr270y/notes/not05efg.html"> math definition</A>
+ * and <A HREF="http://www.stat.berkeley.edu/users/stark/SticiGui/Text/gloss.htm#correlation_coef"> another def</A>.
+ * Compares two column vectors at a time. Use dice views to compare two row vectors at a time.
+ *
+ * @param covariance a covariance matrix, as, for example, returned by method {@link #covariance(DoubleMatrix2D)}.
+ * @return the modified covariance, now correlation matrix (for convenience only).
+ */
+public static DoubleMatrix2D correlation(DoubleMatrix2D covariance) {
+ for (int i=covariance.columns(); --i >= 0; ) {
+ for (int j=i; --j >= 0; ) {
+ double stdDev1 = Math.sqrt(covariance.getQuick(i,i));
+ double stdDev2 = Math.sqrt(covariance.getQuick(j,j));
+ double cov = covariance.getQuick(i,j);
+ double corr = cov / (stdDev1*stdDev2);
+
+ covariance.setQuick(i,j,corr);
+ covariance.setQuick(j,i,corr); // symmetric
+ }
+ }
+ for (int i=covariance.columns(); --i >= 0; ) covariance.setQuick(i,i,1);
+
+ return covariance;
+}
+/**
+ * Constructs and returns the covariance matrix of the given matrix.
+ * The covariance matrix is a square, symmetric matrix consisting of nothing but covariance coefficients.
+ * The rows and the columns represent the variables, the cells represent covariance coefficients.
+ * The diagonal cells (i.e. the covariance between a variable and itself) will equal the variances.
+ * The covariance of two column vectors x and y is given by <tt>cov(x,y) = (1/n) * Sum((x[i]-mean(x)) * (y[i]-mean(y)))</tt>.
+ * See the <A HREF="http://www.cquest.utoronto.ca/geog/ggr270y/notes/not05efg.html"> math definition</A>.
+ * Compares two column vectors at a time. Use dice views to compare two row vectors at a time.
+ *
+ * @param matrix any matrix; a column holds the values of a given variable.
+ * @return the covariance matrix (<tt>n x n, n=matrix.columns</tt>).
+ */
+public static DoubleMatrix2D covariance(DoubleMatrix2D matrix) {
+ int rows = matrix.rows();
+ int columns = matrix.columns();
+ DoubleMatrix2D covariance = new org.apache.mahout.colt.matrix.impl.DenseDoubleMatrix2D(columns,columns);
+
+ double[] sums = new double[columns];
+ DoubleMatrix1D[] cols = new DoubleMatrix1D[columns];
+ for (int i=columns; --i >= 0; ) {
+ cols[i] = matrix.viewColumn(i);
+ sums[i] = cols[i].zSum();
+ }
+
+ for (int i=columns; --i >= 0; ) {
+ for (int j=i+1; --j >= 0; ) {
+ double sumOfProducts = cols[i].zDotProduct(cols[j]);
+ double cov = (sumOfProducts - sums[i]*sums[j]/rows) / rows;
+ covariance.setQuick(i,j,cov);
+ covariance.setQuick(j,i,cov); // symmetric
+ }
+ }
+ return covariance;
+}
+/**
+2-d OLAP cube operator; Fills all cells of the given vectors into the given histogram.
+If you use hep.aida.ref.Converter.toString(histo) on the result, the OLAP cube of x-"column" vs. y-"column" , summing the weights "column" will be printed.
+For example, aggregate sales by product by region.
+<p>
+Computes the distinct values of x and y, yielding histogram axes that capture one distinct value per bin.
+Then fills the histogram.
+<p>
+Example output:
+<table>
+<td class="PRE">
+<pre>
+Cube:
+ Entries=5000, ExtraEntries=0
+ MeanX=4.9838, RmsX=NaN
+ MeanY=2.5304, RmsY=NaN
+ xAxis: Min=0, Max=10, Bins=11
+ yAxis: Min=0, Max=5, Bins=6
+Heights:
+ | X
+ | 0 1 2 3 4 5 6 7 8 9 10 | Sum
+----------------------------------------------------------
+Y 5 | 30 53 51 52 57 39 65 61 55 49 22 | 534
+ 4 | 43 106 112 96 92 94 107 98 98 110 47 | 1003
+ 3 | 39 134 87 93 102 103 110 90 114 98 51 | 1021
+ 2 | 44 81 113 96 101 86 109 83 111 93 42 | 959
+ 1 | 54 94 103 99 115 92 98 97 103 90 44 | 989
+ 0 | 24 54 52 44 42 56 46 47 56 53 20 | 494
+----------------------------------------------------------
+ Sum | 234 522 518 480 509 470 535 476 537 493 226 |
+</pre>
+</td>
+</table>
+@return the histogram containing the cube.
+@throws IllegalArgumentException if <tt>x.size() != y.size() || y.size() != weights.size()</tt>.
+*
+public static hep.aida.IHistogram2D cube(DoubleMatrix1D x, DoubleMatrix1D y, DoubleMatrix1D weights) {
+ if (x.size() != y.size() || y.size() != weights.size()) throw new IllegalArgumentException("vectors must have same size");
+
+ double epsilon = 1.0E-9;
+ org.apache.mahout.colt.list.DoubleArrayList distinct = new org.apache.mahout.colt.list.DoubleArrayList();
+ double[] vals = new double[x.size()];
+ org.apache.mahout.colt.list.DoubleArrayList sorted = new org.apache.mahout.colt.list.DoubleArrayList(vals);
+
+ // compute distinct values of x
+ x.toArray(vals); // copy x into vals
+ sorted.sort();
+ org.apache.mahout.jet.stat.Descriptive.frequencies(sorted, distinct, null);
+ // since bins are right-open [from,to) we need an additional dummy bin so that the last distinct value does not fall into the overflow bin
+ if (distinct.size()>0) distinct.add(distinct.get(distinct.size()-1) + epsilon);
+ distinct.trimToSize();
+ hep.aida.IAxis xaxis = new hep.aida.ref.VariableAxis(distinct.elements());
+
+ // compute distinct values of y
+ y.toArray(vals);
+ sorted.sort();
+ org.apache.mahout.jet.stat.Descriptive.frequencies(sorted, distinct, null);
+ // since bins are right-open [from,to) we need an additional dummy bin so that the last distinct value does not fall into the overflow bin
+ if (distinct.size()>0) distinct.add(distinct.get(distinct.size()-1) + epsilon);
+ distinct.trimToSize();
+ hep.aida.IAxis yaxis = new hep.aida.ref.VariableAxis(distinct.elements());
+
+ hep.aida.IHistogram2D histo = new hep.aida.ref.Histogram2D("Cube",xaxis,yaxis);
+ return histogram(histo,x,y,weights);
+}
+*/
+/**
+3-d OLAP cube operator; Fills all cells of the given vectors into the given histogram.
+If you use hep.aida.ref.Converter.toString(histo) on the result, the OLAP cube of x-"column" vs. y-"column" vs. z-"column", summing the weights "column" will be printed.
+For example, aggregate sales by product by region by time.
+<p>
+Computes the distinct values of x and y and z, yielding histogram axes that capture one distinct value per bin.
+Then fills the histogram.
+@return the histogram containing the cube.
+@throws IllegalArgumentException if <tt>x.size() != y.size() || x.size() != z.size() || x.size() != weights.size()</tt>.
+*
+public static hep.aida.IHistogram3D cube(DoubleMatrix1D x, DoubleMatrix1D y, DoubleMatrix1D z, DoubleMatrix1D weights) {
+ if (x.size() != y.size() || x.size() != z.size() || x.size() != weights.size()) throw new IllegalArgumentException("vectors must have same size");
+
+ double epsilon = 1.0E-9;
+ org.apache.mahout.colt.list.DoubleArrayList distinct = new org.apache.mahout.colt.list.DoubleArrayList();
+ double[] vals = new double[x.size()];
+ org.apache.mahout.colt.list.DoubleArrayList sorted = new org.apache.mahout.colt.list.DoubleArrayList(vals);
+
+ // compute distinct values of x
+ x.toArray(vals); // copy x into vals
+ sorted.sort();
+ org.apache.mahout.jet.stat.Descriptive.frequencies(sorted, distinct, null);
+ // since bins are right-open [from,to) we need an additional dummy bin so that the last distinct value does not fall into the overflow bin
+ if (distinct.size()>0) distinct.add(distinct.get(distinct.size()-1) + epsilon);
+ distinct.trimToSize();
+ hep.aida.IAxis xaxis = new hep.aida.ref.VariableAxis(distinct.elements());
+
+ // compute distinct values of y
+ y.toArray(vals);
+ sorted.sort();
+ org.apache.mahout.jet.stat.Descriptive.frequencies(sorted, distinct, null);
+ // since bins are right-open [from,to) we need an additional dummy bin so that the last distinct value does not fall into the overflow bin
+ if (distinct.size()>0) distinct.add(distinct.get(distinct.size()-1) + epsilon);
+ distinct.trimToSize();
+ hep.aida.IAxis yaxis = new hep.aida.ref.VariableAxis(distinct.elements());
+
+ // compute distinct values of z
+ z.toArray(vals);
+ sorted.sort();
+ org.apache.mahout.jet.stat.Descriptive.frequencies(sorted, distinct, null);
+ // since bins are right-open [from,to) we need an additional dummy bin so that the last distinct value does not fall into the overflow bin
+ if (distinct.size()>0) distinct.add(distinct.get(distinct.size()-1) + epsilon);
+ distinct.trimToSize();
+ hep.aida.IAxis zaxis = new hep.aida.ref.VariableAxis(distinct.elements());
+
+ hep.aida.IHistogram3D histo = new hep.aida.ref.Histogram3D("Cube",xaxis,yaxis,zaxis);
+ return histogram(histo,x,y,z,weights);
+}
+*/
+/**
+ * Demonstrates usage of this class.
+ */
+public static void demo1() {
+double[][] values = {
+ { 1, 2, 3 },
+ { 2, 4, 6 },
+ { 3, 6, 9 },
+ { 4, -8, -10 }
+};
+DoubleFactory2D factory = DoubleFactory2D.dense;
+DoubleMatrix2D A = factory.make(values);
+System.out.println("\n\nmatrix="+A);
+System.out.println("\ncovar1="+covariance(A));
+//System.out.println(correlation(covariance(A)));
+//System.out.println(distance(A,EUCLID));
+
+
+//System.out.println(org.apache.mahout.colt.matrixpattern.Converting.toHTML(A.toString()));
+//System.out.println(org.apache.mahout.colt.matrixpattern.Converting.toHTML(covariance(A).toString()));
+//System.out.println(org.apache.mahout.colt.matrixpattern.Converting.toHTML(correlation(covariance(A)).toString()));
+//System.out.println(org.apache.mahout.colt.matrixpattern.Converting.toHTML(distance(A,EUCLID).toString()));
+}
+/**
+ * Demonstrates usage of this class.
+ */
+public static void demo2(int rows, int columns, boolean print) {
+System.out.println("\n\ninitializing...");
+DoubleFactory2D factory = DoubleFactory2D.dense;
+DoubleMatrix2D A = factory.ascending(rows,columns);
+//double value = 1;
+//DoubleMatrix2D A = factory.make(rows,columns);
+//A.assign(value);
+
+System.out.println("benchmarking correlation...");
+
+org.apache.mahout.colt.Timer timer = new org.apache.mahout.colt.Timer().start();
+DoubleMatrix2D corr = correlation(covariance(A));
+timer.stop().display();
+
+if (print) {
+ System.out.println("printing result...");
+ System.out.println(corr);
+}
+System.out.println("done.");
+}
+/**
+ * Demonstrates usage of this class.
+ */
+public static void demo3(VectorVectorFunction norm) {
+double[][] values = {
+ { -0.9611052, -0.25421095 },
+ { 0.4308269, -0.69932648 },
+ { -1.2071029, 0.62030596 },
+ { 1.5345166, 0.02135884},
+ {-1.1341542, 0.20388430}
+};
+
+System.out.println("\n\ninitializing...");
+DoubleFactory2D factory = DoubleFactory2D.dense;
+DoubleMatrix2D A = factory.make(values).viewDice();
+
+System.out.println("\nA="+A.viewDice());
+System.out.println("\ndist="+distance(A,norm).viewDice());
+}
+/**
+ * Constructs and returns the distance matrix of the given matrix.
+ * The distance matrix is a square, symmetric matrix consisting of nothing but distance coefficients.
+ * The rows and the columns represent the variables, the cells represent distance coefficients.
+ * The diagonal cells (i.e. the distance between a variable and itself) will be zero.
+ * Compares two column vectors at a time. Use dice views to compare two row vectors at a time.
+ *
+ * @param matrix any matrix; a column holds the values of a given variable (vector).
+ * @param distanceFunction (EUCLID, CANBERRA, ..., or any user defined distance function operating on two vectors).
+ * @return the distance matrix (<tt>n x n, n=matrix.columns</tt>).
+ */
+public static DoubleMatrix2D distance(DoubleMatrix2D matrix, VectorVectorFunction distanceFunction) {
+ int columns = matrix.columns();
+ DoubleMatrix2D distance = new org.apache.mahout.colt.matrix.impl.DenseDoubleMatrix2D(columns,columns);
+
+ // cache views
+ DoubleMatrix1D[] cols = new DoubleMatrix1D[columns];
+ for (int i=columns; --i >= 0; ) {
+ cols[i] = matrix.viewColumn(i);
+ }
+
+ // work out all permutations
+ for (int i=columns; --i >= 0; ) {
+ for (int j=i; --j >= 0; ) {
+ double d = distanceFunction.apply(cols[i], cols[j]);
+ distance.setQuick(i,j,d);
+ distance.setQuick(j,i,d); // symmetric
+ }
+ }
+ return distance;
+}
+/**
+ * Fills all cells of the given vector into the given histogram.
+ * @return <tt>histo</tt> (for convenience only).
+ *
+public static hep.aida.IHistogram1D histogram(hep.aida.IHistogram1D histo, DoubleMatrix1D vector) {
+ for (int i=vector.size(); --i >= 0; ) {
+ histo.fill(vector.getQuick(i));
+ }
+ return histo;
+}
+**
+ * Fills all cells of the given vectors into the given histogram.
+ * @return <tt>histo</tt> (for convenience only).
+ * @throws IllegalArgumentException if <tt>x.size() != y.size()</tt>.
+ *
+public static hep.aida.IHistogram2D histogram(hep.aida.IHistogram2D histo, DoubleMatrix1D x, DoubleMatrix1D y) {
+ if (x.size() != y.size()) throw new IllegalArgumentException("vectors must have same size");
+ for (int i=x.size(); --i >= 0; ) {
+ histo.fill(x.getQuick(i), y.getQuick(i));
+ }
+ return histo;
+}
+**
+ * Fills all cells of the given vectors into the given histogram.
+ * @return <tt>histo</tt> (for convenience only).
+ * @throws IllegalArgumentException if <tt>x.size() != y.size() || y.size() != weights.size()</tt>.
+ *
+public static hep.aida.IHistogram2D histogram(hep.aida.IHistogram2D histo, DoubleMatrix1D x, DoubleMatrix1D y, DoubleMatrix1D weights) {
+ if (x.size() != y.size() || y.size() != weights.size()) throw new IllegalArgumentException("vectors must have same size");
+ for (int i=x.size(); --i >= 0; ) {
+ histo.fill(x.getQuick(i), y.getQuick(i), weights.getQuick(i));
+ }
+ return histo;
+}
+ *
+ * Fills all cells of the given vectors into the given histogram.
+ * @return <tt>histo</tt> (for convenience only).
+ * @throws IllegalArgumentException if <tt>x.size() != y.size() || x.size() != z.size() || x.size() != weights.size()</tt>.
+ *
+public static hep.aida.IHistogram3D histogram(hep.aida.IHistogram3D histo, DoubleMatrix1D x, DoubleMatrix1D y, DoubleMatrix1D z, DoubleMatrix1D weights) {
+ if (x.size() != y.size() || x.size() != z.size() || x.size() != weights.size()) throw new IllegalArgumentException("vectors must have same size");
+ for (int i=x.size(); --i >= 0; ) {
+ histo.fill(x.getQuick(i), y.getQuick(i), z.getQuick(i), weights.getQuick(i));
+ }
+ return histo;
+}
+**
+ * Benchmarks covariance computation.
+ */
+public static void main(String[] args) {
+ int rows = Integer.parseInt(args[0]);
+ int columns = Integer.parseInt(args[1]);
+ boolean print = args[2].equals("print");
+ demo2(rows,columns,print);
+}
+/**
+Constructs and returns a sampling view with a size of <tt>round(matrix.size() * fraction)</tt>.
+Samples "without replacement" from the uniform distribution.
+@param matrix any matrix.
+@param rowFraction the percentage of rows to be included in the view.
+@param columnFraction the percentage of columns to be included in the view.
+@param randomGenerator a uniform random number generator; set this parameter to <tt>null</tt> to use a default generator seeded with the current time.
+@return the sampling view.
+@throws IllegalArgumentException if <tt>! (0 <= rowFraction <= 1 && 0 <= columnFraction <= 1)</tt>.
+@see org.apache.mahout.jet.random.sampling.RandomSampler
+*/
+public static DoubleMatrix1D viewSample(DoubleMatrix1D matrix, double fraction, RandomEngine randomGenerator) {
+ // check preconditions and allow for a little tolerance
+ double epsilon = 1e-09;
+ if (fraction < 0 - epsilon || fraction > 1 + epsilon) throw new IllegalArgumentException();
+ if (fraction < 0) fraction = 0;
+ if (fraction > 1) fraction = 1;
+
+ // random generator seeded with current time
+ if (randomGenerator==null) randomGenerator = new org.apache.mahout.jet.random.engine.MersenneTwister((int) System.currentTimeMillis());
+
+ int ncols = (int) Math.round(matrix.size() * fraction);
+ int max = ncols;
+ long[] selected = new long[max]; // sampler works on long's, not int's
+
+ // sample
+ int n = ncols;
+ int N = matrix.size();
+ org.apache.mahout.jet.random.sampling.RandomSampler.sample(n,N,n,0,selected,0,randomGenerator);
+ int[] selectedCols = new int[n];
+ for (int i=0; i<n; i++) selectedCols[i] = (int) selected[i];
+
+ return matrix.viewSelection(selectedCols);
+}
+/**
+Constructs and returns a sampling view with <tt>round(matrix.rows() * rowFraction)</tt> rows and <tt>round(matrix.columns() * columnFraction)</tt> columns.
+Samples "without replacement".
+Rows and columns are randomly chosen from the uniform distribution.
+Examples:
+<table border="1" cellspacing="0">
+ <tr valign="top" align="center">
+ <td>
+ <div align="left"><tt>matrix</tt></div>
+ </td>
+ <td>
+ <div align="left"><tt>rowFraction=0.2<br>
+ columnFraction=0.2</tt></div>
+ </td>
+ <td>
+ <div align="left"><tt>rowFraction=0.2<br>
+ columnFraction=1.0 </tt></div>
+ </td>
+ <td>
+ <div align="left"><tt>rowFraction=1.0<br>
+ columnFraction=0.2 </tt></div>
+ </td>
+ </tr>
+ <tr valign="top">
+ <td><tt> 10 x 10 matrix<br>
+ 1 2 3 4 5 6 7 8 9 10<br>
+ 11 12 13 14 15 16 17 18 19 20<br>
+ 21 22 23 24 25 26 27 28 29 30<br>
+ 31 32 33 34 35 36 37 38 39 40<br>
+ 41 42 43 44 45 46 47 48 49 50<br>
+ 51 52 53 54 55 56 57 58 59 60<br>
+ 61 62 63 64 65 66 67 68 69 70<br>
+ 71 72 73 74 75 76 77 78 79 80<br>
+ 81 82 83 84 85 86 87 88 89 90<br>
+ 91 92 93 94 95 96 97 98 99 100
+ </tt> </td>
+ <td><tt> 2 x 2 matrix<br>
+ 43 50<br>
+ 53 60 </tt></td>
+ <td><tt> 2 x 10 matrix<br>
+ 41 42 43 44 45 46 47 48 49 50<br>
+ 91 92 93 94 95 96 97 98 99 100
+ </tt> </td>
+ <td><tt> 10 x 2 matrix<br>
+ 4 8<br>
+ 14 18<br>
+ 24 28<br>
+ 34 38<br>
+ 44 48<br>
+ 54 58<br>
+ 64 68<br>
+ 74 78<br>
+ 84 88<br>
+ 94 98 </tt> </td>
+ </tr>
+</table>
+@param matrix any matrix.
+@param rowFraction the percentage of rows to be included in the view.
+@param columnFraction the percentage of columns to be included in the view.
+@param randomGenerator a uniform random number generator; set this parameter to <tt>null</tt> to use a default generator seeded with the current time.
+@return the sampling view.
+@throws IllegalArgumentException if <tt>! (0 <= rowFraction <= 1 && 0 <= columnFraction <= 1)</tt>.
+@see org.apache.mahout.jet.random.sampling.RandomSampler
+*/
+public static DoubleMatrix2D viewSample(DoubleMatrix2D matrix, double rowFraction, double columnFraction, RandomEngine randomGenerator) {
+ // check preconditions and allow for a little tolerance
+ double epsilon = 1e-09;
+ if (rowFraction < 0 - epsilon || rowFraction > 1 + epsilon) throw new IllegalArgumentException();
+ if (rowFraction < 0) rowFraction = 0;
+ if (rowFraction > 1) rowFraction = 1;
+
+ if (columnFraction < 0 - epsilon || columnFraction > 1 + epsilon) throw new IllegalArgumentException();
+ if (columnFraction < 0) columnFraction = 0;
+ if (columnFraction > 1) columnFraction = 1;
+
+ // random generator seeded with current time
+ if (randomGenerator==null) randomGenerator = new org.apache.mahout.jet.random.engine.MersenneTwister((int) System.currentTimeMillis());
+
+ int nrows = (int) Math.round(matrix.rows() * rowFraction);
+ int ncols = (int) Math.round(matrix.columns() * columnFraction);
+ int max = Math.max(nrows,ncols);
+ long[] selected = new long[max]; // sampler works on long's, not int's
+
+ // sample rows
+ int n = nrows;
+ int N = matrix.rows();
+ org.apache.mahout.jet.random.sampling.RandomSampler.sample(n,N,n,0,selected,0,randomGenerator);
+ int[] selectedRows = new int[n];
+ for (int i=0; i<n; i++) selectedRows[i] = (int) selected[i];
+
+ // sample columns
+ n = ncols;
+ N = matrix.columns();
+ org.apache.mahout.jet.random.sampling.RandomSampler.sample(n,N,n,0,selected,0,randomGenerator);
+ int[] selectedCols = new int[n];
+ for (int i=0; i<n; i++) selectedCols[i] = (int) selected[i];
+
+ return matrix.viewSelection(selectedRows, selectedCols);
+}
+/**
+Constructs and returns a sampling view with <tt>round(matrix.slices() * sliceFraction)</tt> slices and <tt>round(matrix.rows() * rowFraction)</tt> rows and <tt>round(matrix.columns() * columnFraction)</tt> columns.
+Samples "without replacement".
+Slices, rows and columns are randomly chosen from the uniform distribution.
+@param matrix any matrix.
+@param sliceFraction the percentage of slices to be included in the view.
+@param rowFraction the percentage of rows to be included in the view.
+@param columnFraction the percentage of columns to be included in the view.
+@param randomGenerator a uniform random number generator; set this parameter to <tt>null</tt> to use a default generator seeded with the current time.
+@return the sampling view.
+@throws IllegalArgumentException if <tt>! (0 <= sliceFraction <= 1 && 0 <= rowFraction <= 1 && 0 <= columnFraction <= 1)</tt>.
+@see org.apache.mahout.jet.random.sampling.RandomSampler
+*/
+public static DoubleMatrix3D viewSample(DoubleMatrix3D matrix, double sliceFraction, double rowFraction, double columnFraction, RandomEngine randomGenerator) {
+ // check preconditions and allow for a little tolerance
+ double epsilon = 1e-09;
+ if (sliceFraction < 0 - epsilon || sliceFraction > 1 + epsilon) throw new IllegalArgumentException();
+ if (sliceFraction < 0) sliceFraction = 0;
+ if (sliceFraction > 1) sliceFraction = 1;
+
+ if (rowFraction < 0 - epsilon || rowFraction > 1 + epsilon) throw new IllegalArgumentException();
+ if (rowFraction < 0) rowFraction = 0;
+ if (rowFraction > 1) rowFraction = 1;
+
+ if (columnFraction < 0 - epsilon || columnFraction > 1 + epsilon) throw new IllegalArgumentException();
+ if (columnFraction < 0) columnFraction = 0;
+ if (columnFraction > 1) columnFraction = 1;
+
+ // random generator seeded with current time
+ if (randomGenerator==null) randomGenerator = new org.apache.mahout.jet.random.engine.MersenneTwister((int) System.currentTimeMillis());
+
+ int nslices = (int) Math.round(matrix.slices() * sliceFraction);
+ int nrows = (int) Math.round(matrix.rows() * rowFraction);
+ int ncols = (int) Math.round(matrix.columns() * columnFraction);
+ int max = Math.max(nslices,Math.max(nrows,ncols));
+ long[] selected = new long[max]; // sampler works on long's, not int's
+
+ // sample slices
+ int n = nslices;
+ int N = matrix.slices();
+ org.apache.mahout.jet.random.sampling.RandomSampler.sample(n,N,n,0,selected,0,randomGenerator);
+ int[] selectedSlices = new int[n];
+ for (int i=0; i<n; i++) selectedSlices[i] = (int) selected[i];
+
+ // sample rows
+ n = nrows;
+ N = matrix.rows();
+ org.apache.mahout.jet.random.sampling.RandomSampler.sample(n,N,n,0,selected,0,randomGenerator);
+ int[] selectedRows = new int[n];
+ for (int i=0; i<n; i++) selectedRows[i] = (int) selected[i];
+
+ // sample columns
+ n = ncols;
+ N = matrix.columns();
+ org.apache.mahout.jet.random.sampling.RandomSampler.sample(n,N,n,0,selected,0,randomGenerator);
+ int[] selectedCols = new int[n];
+ for (int i=0; i<n; i++) selectedCols[i] = (int) selected[i];
+
+ return matrix.viewSelection(selectedSlices,selectedRows, selectedCols);
+}
+/**
+ * Constructs and returns the distance matrix of the given matrix.
+ * The distance matrix is a square, symmetric matrix consisting of nothing but distance coefficients.
+ * The rows and the columns represent the variables, the cells represent distance coefficients.
+ * The diagonal cells (i.e. the distance between a variable and itself) will be zero.
+ * Compares two column vectors at a time. Use dice views to compare two row vectors at a time.
+ *
+ * @param matrix any matrix; a column holds the values of a given variable (vector).
+ * @param norm the kind of norm to be used (EUCLID, CANBERRA, ...).
+ * @return the distance matrix (<tt>n x n, n=matrix.columns</tt>).
+ */
+private static DoubleMatrix2D xdistanceOld(DoubleMatrix2D matrix, int norm) {
+ /*
+ int rows = matrix.rows();
+ int columns = matrix.columns();
+ DoubleMatrix2D distance = new org.apache.mahout.colt.matrix.impl.DenseDoubleMatrix2D(columns,columns);
+
+ // cache views
+ DoubleMatrix1D[] cols = new DoubleMatrix1D[columns];
+ for (int i=columns; --i >= 0; ) {
+ cols[i] = matrix.viewColumn(i);
+ }
+
+ // setup distance function
+ org.apache.mahout.jet.math.Functions F = org.apache.mahout.jet.math.Functions.functions;
+ DoubleDoubleFunction function = null;
+ //DoubleDoubleFunction function2 = null;
+ if (norm==EUCLID) function = F.chain(F.square,F.minus);
+ else if (norm==BRAY_CURTIS) function = F.chain(F.abs,F.minus);
+ else if (norm==CANBERRA) function = new DoubleDoubleFunction() {
+ public final double apply(double a, double b) { return Math.abs(a-b) / Math.abs(a+b);}
+ };
+ else if (norm==MAXIMUM) function = F.chain(F.abs,F.minus);
+ else if (norm==MANHATTAN) function = F.chain(F.abs,F.minus);
+ else throw new IllegalArgumentException("Unknown norm");
+
+ // work out all permutations
+ for (int i=columns; --i >= 0; ) {
+ for (int j=i; --j >= 0; ) {
+ double d = 0;
+ if (norm==EUCLID) d = Math.sqrt(cols[i].aggregate(cols[j], F.plus, function));
+ else if (norm==BRAY_CURTIS) d = cols[i].aggregate(cols[j], F.plus, function) / cols[i].aggregate(cols[j], F.plus, F.plus);
+ else if (norm==CANBERRA) d = cols[i].aggregate(cols[j], F.plus, function);
+ else if (norm==MAXIMUM) d = cols[i].aggregate(cols[j], F.max, function);
+ else if (norm==MANHATTAN) d = cols[i].aggregate(cols[j], F.plus, function);
+ distance.setQuick(i,j,d);
+ distance.setQuick(j,i,d); // symmetric
+ }
+ }
+ return distance;
+ */
+ return null;
+}
+/**
+ * Constructs and returns the distance matrix of the given matrix.
+ * The distance matrix is a square, symmetric matrix consisting of nothing but distance coefficients.
+ * The rows and the columns represent the variables, the cells represent distance coefficients.
+ * The diagonal cells (i.e. the distance between a variable and itself) will be zero.
+ * Compares two column vectors at a time. Use dice views to compare two row vectors at a time.
+ *
+ * @param matrix any matrix; a column holds the values of a given variable (vector).
+ * @param norm the kind of norm to be used (EUCLID, CANBERRA, ...).
+ * @return the distance matrix (<tt>n x n, n=matrix.columns</tt>).
+ */
+private static DoubleMatrix2D xdistanceOld2(DoubleMatrix2D matrix, int norm) {
+ /*
+ // setup distance function
+ final org.apache.mahout.jet.math.Functions F = org.apache.mahout.jet.math.Functions.functions;
+ VectorVectorFunction function;
+ if (norm==EUCLID) function = new VectorVectorFunction() {
+ public final double apply(DoubleMatrix1D a, DoubleMatrix1D b) {
+ return Math.sqrt(a.aggregate(b, F.plus, F.chain(F.square,F.minus)));
+ }
+ };
+ else if (norm==BRAY_CURTIS) function = new VectorVectorFunction() {
+ public final double apply(DoubleMatrix1D a, DoubleMatrix1D b) {
+ return a.aggregate(b, F.plus, F.chain(F.abs,F.minus)) / a.aggregate(b, F.plus, F.plus);
+ }
+ };
+ else if (norm==CANBERRA) function = new VectorVectorFunction() {
+ DoubleDoubleFunction fun = new DoubleDoubleFunction() {
+ public final double apply(double a, double b) {
+ return Math.abs(a-b) / Math.abs(a+b);
+ }
+ };
+ public final double apply(DoubleMatrix1D a, DoubleMatrix1D b) {
+ return a.aggregate(b, F.plus, fun);
+ }
+ };
+ else if (norm==MAXIMUM) function = new VectorVectorFunction() {
+ public final double apply(DoubleMatrix1D a, DoubleMatrix1D b) {
+ return a.aggregate(b, F.max, F.chain(F.abs,F.minus));
+ }
+ };
+ else if (norm==MANHATTAN) function = new VectorVectorFunction() {
+ public final double apply(DoubleMatrix1D a, DoubleMatrix1D b) {
+ return a.aggregate(b, F.plus, F.chain(F.abs,F.minus));
+ }
+ };
+ else throw new IllegalArgumentException("Unknown norm");
+
+ return distance(matrix,function);
+ */
+ return null;
+}
+}
Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/doublealgo/Statistic.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/doublealgo/Stencil.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/doublealgo/Stencil.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/doublealgo/Stencil.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/doublealgo/Stencil.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,93 @@
+/*
+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.doublealgo;
+
+import org.apache.mahout.colt.matrix.DoubleMatrix2D;
+import org.apache.mahout.colt.matrix.DoubleMatrix2DProcedure;
+import org.apache.mahout.colt.matrix.DoubleMatrix3D;
+import org.apache.mahout.colt.matrix.DoubleMatrix3DProcedure;
+/**
+Stencil operations. For efficient finite difference operations.
+Applies a function to a moving <tt>3 x 3</tt> or <tt>3 x 3 x 3</tt> window.
+Build on top of <tt>matrix.zAssignXXXNeighbors(...)</tt>.
+You can specify how many iterations shall at most be done, a convergence condition when iteration shall be terminated, and how many iterations shall pass between convergence checks.
+Always does two iterations at a time for efficiency.
+These class is for convencience and efficiency.
+
+@author wolfgang.hoschek@cern.ch
+@version 1.0, 01/02/2000
+*/
+/**
+ * @deprecated until unit tests are in place. Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public class Stencil extends Object {
+/**
+ * Makes this class non instantiable, but still let's others inherit from it.
+ */
+protected Stencil() {}
+/**
+27 point stencil operation.
+Applies a function to a moving <tt>3 x 3 x 3</tt> window.
+@param A the matrix to operate on.
+@param function the function to be applied to each window.
+@param maxIterations the maximum number of times the stencil shall be applied to the matrix.
+ Should be a multiple of 2 because two iterations are always done in one atomic step.
+@param hasConverged Convergence condition; will return before maxIterations are done when <tt>hasConverged.apply(A)==true</tt>.
+ Set this parameter to <tt>null</tt> to indicate that no convergence checks shall be made.
+@param convergenceIterations the number of iterations to pass between each convergence check.
+ (Since a convergence may be expensive, you may want to do it only every 2,4 or 8 iterations.)
+@return the number of iterations actually executed.
+*/
+public static int stencil27(DoubleMatrix3D A, org.apache.mahout.colt.function.Double27Function function, int maxIterations, DoubleMatrix3DProcedure hasConverged, int convergenceIterations) {
+ DoubleMatrix3D B = A.copy();
+ if (convergenceIterations <= 1) convergenceIterations=2;
+ if (convergenceIterations%2 != 0) convergenceIterations++; // odd -> make it even
+
+ int i=0;
+ while (i<maxIterations) { // do two steps at a time for efficiency
+ A.zAssign27Neighbors(B,function);
+ B.zAssign27Neighbors(A,function);
+ i=i+2;
+ if (i%convergenceIterations == 0 && hasConverged!=null) {
+ if (hasConverged.apply(A)) return i;
+ }
+ }
+ return i;
+}
+/**
+9 point stencil operation.
+Applies a function to a moving <tt>3 x 3</tt> window.
+@param A the matrix to operate on.
+@param function the function to be applied to each window.
+@param maxIterations the maximum number of times the stencil shall be applied to the matrix.
+ Should be a multiple of 2 because two iterations are always done in one atomic step.
+@param hasConverged Convergence condition; will return before maxIterations are done when <tt>hasConverged.apply(A)==true</tt>.
+ Set this parameter to <tt>null</tt> to indicate that no convergence checks shall be made.
+@param convergenceIterations the number of iterations to pass between each convergence check.
+ (Since a convergence may be expensive, you may want to do it only every 2,4 or 8 iterations.)
+@return the number of iterations actually executed.
+*/
+public static int stencil9(DoubleMatrix2D A, org.apache.mahout.colt.function.Double9Function function, int maxIterations, DoubleMatrix2DProcedure hasConverged, int convergenceIterations) {
+ DoubleMatrix2D B = A.copy();
+ if (convergenceIterations <= 1) convergenceIterations=2;
+ if (convergenceIterations%2 != 0) convergenceIterations++; // odd -> make it even
+
+ int i=0;
+ while (i<maxIterations) { // do two steps at a time for efficiency
+ A.zAssign8Neighbors(B,function);
+ B.zAssign8Neighbors(A,function);
+ i=i+2;
+ if (i%convergenceIterations == 0 && hasConverged!=null) {
+ if (hasConverged.apply(A)) return i;
+ }
+ }
+ return i;
+}
+}
Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/doublealgo/Stencil.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/doublealgo/Transform.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/doublealgo/Transform.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/doublealgo/Transform.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/doublealgo/Transform.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,376 @@
+/*
+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.doublealgo;
+
+import org.apache.mahout.colt.matrix.DoubleMatrix1D;
+import org.apache.mahout.colt.matrix.DoubleMatrix2D;
+/**
+Deprecated; Basic element-by-element transformations on {@link org.apache.mahout.colt.matrix.DoubleMatrix1D} and {@link org.apache.mahout.colt.matrix.DoubleMatrix2D}.
+All transformations modify the first argument matrix to hold the result of the transformation.
+Use idioms like <tt>result = mult(matrix.copy(),5)</tt> to leave source matrices unaffected.
+<p>
+If your favourite transformation is not provided by this class, consider using method <tt>assign</tt> in combination with prefabricated function objects of {@link org.apache.mahout.jet.math.Functions},
+using idioms like
+<table>
+<td class="PRE">
+<pre>
+org.apache.mahout.jet.math.Functions F = org.apache.mahout.jet.math.Functions.functions; // alias
+matrix.assign(F.square);
+matrix.assign(F.sqrt);
+matrix.assign(F.sin);
+matrix.assign(F.log);
+matrix.assign(F.log(b));
+matrix.assign(otherMatrix, F.min);
+matrix.assign(otherMatrix, F.max);
+</pre>
+</td>
+</table>
+Here are some <a href="../doc-files/functionObjects.html">other examples</a>.
+<p>
+Implementation: Performance optimized for medium to very large matrices.
+In fact, there is now nomore a performance advantage in using this class; The assign (transform) methods directly defined on matrices are now just as fast.
+Thus, this class will soon be removed altogether.
+
+@deprecated
+@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 Transform extends org.apache.mahout.colt.PersistentObject {
+ /**
+ * Little trick to allow for "aliasing", that is, renaming this class.
+ * Normally you would write
+ * <pre>
+ * Transform.mult(myMatrix,2);
+ * Transform.plus(myMatrix,5);
+ * </pre>
+ * Since this class has only static methods, but no instance methods
+ * you can also shorten the name "DoubleTransform" to a name that better suits you, for example "Trans".
+ * <pre>
+ * Transform T = Transform.transform; // kind of "alias"
+ * T.mult(myMatrix,2);
+ * T.plus(myMatrix,5);
+ * </pre>
+ */
+ public static final Transform transform = new Transform();
+
+ private static final org.apache.mahout.jet.math.Functions F = org.apache.mahout.jet.math.Functions.functions; // alias
+
+/**
+ * Makes this class non instantiable, but still let's others inherit from it.
+ */
+protected Transform() {}
+/**
+ * <tt>A[i] = Math.abs(A[i])</tt>.
+ * @param A the matrix to modify.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix1D abs(DoubleMatrix1D A) {
+ return A.assign(F.abs);
+}
+/**
+ * <tt>A[row,col] = Math.abs(A[row,col])</tt>.
+ * @param A the matrix to modify.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D abs(DoubleMatrix2D A) {
+ return A.assign(F.abs);
+}
+/**
+ * <tt>A = A / s <=> A[i] = A[i] / s</tt>.
+ * @param A the matrix to modify.
+ * @param s the scalar; can have any value.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix1D div(DoubleMatrix1D A, double s) {
+ return A.assign(F.div(s));
+}
+/**
+ * <tt>A = A / B <=> A[i] = A[i] / B[i]</tt>.
+ * @param A the matrix to modify.
+ * @param B the matrix to stay unaffected.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix1D div(DoubleMatrix1D A, DoubleMatrix1D B) {
+ return A.assign(B,F.div);
+}
+/**
+ * <tt>A = A / s <=> A[row,col] = A[row,col] / s</tt>.
+ * @param A the matrix to modify.
+ * @param s the scalar; can have any value.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D div(DoubleMatrix2D A, double s) {
+ return A.assign(F.div(s));
+}
+/**
+ * <tt>A = A / B <=> A[row,col] = A[row,col] / B[row,col]</tt>.
+ * @param A the matrix to modify.
+ * @param B the matrix to stay unaffected.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D div(DoubleMatrix2D A, DoubleMatrix2D B) {
+ return A.assign(B,F.div);
+}
+/**
+ * <tt>A[row,col] = A[row,col] == s ? 1 : 0</tt>; ignores tolerance.
+ * @param A the matrix to modify.
+ * @param s the scalar; can have any value.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D equals(DoubleMatrix2D A, double s) {
+ return A.assign(F.equals(s));
+}
+/**
+ * <tt>A[row,col] = A[row,col] == B[row,col] ? 1 : 0</tt>; ignores tolerance.
+ * @param A the matrix to modify.
+ * @param B the matrix to stay unaffected.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D equals(DoubleMatrix2D A, DoubleMatrix2D B) {
+ return A.assign(B,F.equals);
+}
+/**
+ * <tt>A[row,col] = A[row,col] > s ? 1 : 0</tt>.
+ * @param A the matrix to modify.
+ * @param s the scalar; can have any value.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D greater(DoubleMatrix2D A, double s) {
+ return A.assign(F.greater(s));
+}
+/**
+ * <tt>A[row,col] = A[row,col] > B[row,col] ? 1 : 0</tt>.
+ * @param A the matrix to modify.
+ * @param B the matrix to stay unaffected.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D greater(DoubleMatrix2D A, DoubleMatrix2D B) {
+ return A.assign(B,F.greater);
+}
+/**
+ * <tt>A[row,col] = A[row,col] < s ? 1 : 0</tt>.
+ * @param A the matrix to modify.
+ * @param s the scalar; can have any value.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D less(DoubleMatrix2D A, double s) {
+ return A.assign(F.less(s));
+}
+/**
+ * <tt>A[row,col] = A[row,col] < B[row,col] ? 1 : 0</tt>.
+ * @param A the matrix to modify.
+ * @param B the matrix to stay unaffected.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D less(DoubleMatrix2D A, DoubleMatrix2D B) {
+ return A.assign(B,F.less);
+}
+/**
+ * <tt>A = A - s <=> A[i] = A[i] - s</tt>.
+ * @param A the matrix to modify.
+ * @param s the scalar; can have any value.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix1D minus(DoubleMatrix1D A, double s) {
+ return A.assign(F.minus(s));
+}
+/**
+ * <tt>A = A - B <=> A[i] = A[i] - B[i]</tt>.
+ * @param A the matrix to modify.
+ * @param B the matrix to stay unaffected.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix1D minus(DoubleMatrix1D A, DoubleMatrix1D B) {
+ return A.assign(B,F.minus);
+}
+/**
+ * <tt>A = A - s <=> A[row,col] = A[row,col] - s</tt>.
+ * @param A the matrix to modify.
+ * @param s the scalar; can have any value.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D minus(DoubleMatrix2D A, double s) {
+ return A.assign(F.minus(s));
+}
+/**
+ * <tt>A = A - B <=> A[row,col] = A[row,col] - B[row,col]</tt>.
+ * @param A the matrix to modify.
+ * @param B the matrix to stay unaffected.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D minus(DoubleMatrix2D A, DoubleMatrix2D B) {
+ return A.assign(B,F.minus);
+}
+/**
+ * <tt>A = A - B*s <=> A[i] = A[i] - B[i]*s</tt>.
+ * @param A the matrix to modify.
+ * @param B the matrix to stay unaffected.
+ * @param s the scalar; can have any value.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix1D minusMult(DoubleMatrix1D A, DoubleMatrix1D B, double s) {
+ return A.assign(B,F.minusMult(s));
+}
+/**
+ * <tt>A = A - B*s <=> A[row,col] = A[row,col] - B[row,col]*s</tt>.
+ * @param A the matrix to modify.
+ * @param B the matrix to stay unaffected.
+ * @param s the scalar; can have any value.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D minusMult(DoubleMatrix2D A, DoubleMatrix2D B, double s) {
+ return A.assign(B,F.minusMult(s));
+}
+/**
+ * <tt>A = A * s <=> A[i] = A[i] * s</tt>.
+ * @param A the matrix to modify.
+ * @param s the scalar; can have any value.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix1D mult(DoubleMatrix1D A, double s) {
+ return A.assign(F.mult(s));
+}
+/**
+ * <tt>A = A * B <=> A[i] = A[i] * B[i]</tt>.
+ * @param A the matrix to modify.
+ * @param B the matrix to stay unaffected.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix1D mult(DoubleMatrix1D A, DoubleMatrix1D B) {
+ return A.assign(B,F.mult);
+}
+/**
+ * <tt>A = A * s <=> A[row,col] = A[row,col] * s</tt>.
+ * @param A the matrix to modify.
+ * @param s the scalar; can have any value.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D mult(DoubleMatrix2D A, double s) {
+ return A.assign(F.mult(s));
+}
+/**
+ * <tt>A = A * B <=> A[row,col] = A[row,col] * B[row,col]</tt>.
+ * @param A the matrix to modify.
+ * @param B the matrix to stay unaffected.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D mult(DoubleMatrix2D A, DoubleMatrix2D B) {
+ return A.assign(B,F.mult);
+}
+/**
+ * <tt>A = -A <=> A[i] = -A[i]</tt> for all cells.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix1D negate(DoubleMatrix1D A) {
+ return A.assign(F.mult(-1));
+}
+/**
+ * <tt>A = -A <=> A[row,col] = -A[row,col]</tt>.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D negate(DoubleMatrix2D A) {
+ return A.assign(F.mult(-1));
+}
+/**
+ * <tt>A = A + s <=> A[i] = A[i] + s</tt>.
+ * @param A the matrix to modify.
+ * @param s the scalar; can have any value.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix1D plus(DoubleMatrix1D A, double s) {
+ return A.assign(F.plus(s));
+}
+/**
+ * <tt>A = A + B <=> A[i] = A[i] + B[i]</tt>.
+ * @param A the matrix to modify.
+ * @param B the matrix to stay unaffected.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix1D plus(DoubleMatrix1D A, DoubleMatrix1D B) {
+ return A.assign(B,F.plus);
+}
+/**
+ * <tt>A = A + s <=> A[row,col] = A[row,col] + s</tt>.
+ * @param A the matrix to modify.
+ * @param s the scalar; can have any value.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D plus(DoubleMatrix2D A, double s) {
+ return A.assign(F.plus(s));
+}
+/**
+ * <tt>A = A + B <=> A[row,col] = A[row,col] + B[row,col]</tt>.
+ * @param A the matrix to modify.
+ * @param B the matrix to stay unaffected.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D plus(DoubleMatrix2D A, DoubleMatrix2D B) {
+ return A.assign(B,F.plus);
+}
+/**
+ * <tt>A = A + B*s<=> A[i] = A[i] + B[i]*s</tt>.
+ * @param A the matrix to modify.
+ * @param B the matrix to stay unaffected.
+ * @param s the scalar; can have any value.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix1D plusMult(DoubleMatrix1D A, DoubleMatrix1D B, double s) {
+ return A.assign(B,F.plusMult(s));
+}
+/**
+ * <tt>A = A + B*s <=> A[row,col] = A[row,col] + B[row,col]*s</tt>.
+ * @param A the matrix to modify.
+ * @param B the matrix to stay unaffected.
+ * @param s the scalar; can have any value.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D plusMult(DoubleMatrix2D A, DoubleMatrix2D B, double s) {
+ return A.assign(B,F.plusMult(s));
+}
+/**
+ * <tt>A = A<sup>s</sup> <=> A[i] = Math.pow(A[i], s)</tt>.
+ * @param A the matrix to modify.
+ * @param s the scalar; can have any value.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix1D pow(DoubleMatrix1D A, double s) {
+ return A.assign(F.pow(s));
+}
+/**
+ * <tt>A = A<sup>B</sup> <=> A[i] = Math.pow(A[i], B[i])</tt>.
+ * @param A the matrix to modify.
+ * @param B the matrix to stay unaffected.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix1D pow(DoubleMatrix1D A, DoubleMatrix1D B) {
+ return A.assign(B,F.pow);
+}
+/**
+ * <tt>A = A<sup>s</sup> <=> A[row,col] = Math.pow(A[row,col], s)</tt>.
+ * @param A the matrix to modify.
+ * @param s the scalar; can have any value.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D pow(DoubleMatrix2D A, double s) {
+ return A.assign(F.pow(s));
+}
+/**
+ * <tt>A = A<sup>B</sup> <=> A[row,col] = Math.pow(A[row,col], B[row,col])</tt>.
+ * @param A the matrix to modify.
+ * @param B the matrix to stay unaffected.
+ * @return <tt>A</tt> (for convenience only).
+ */
+public static DoubleMatrix2D pow(DoubleMatrix2D A, DoubleMatrix2D B) {
+ return A.assign(B,F.pow);
+}
+}
Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/doublealgo/Transform.java
------------------------------------------------------------------------------
svn:eol-style = native