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 [36/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/BenchmarkMatrix2D.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/BenchmarkMatrix2D.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/BenchmarkMatrix2D.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/BenchmarkMatrix2D.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,1039 @@
+/*
+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;
+/**
+Benchmarks the performance of matrices. Here are the results of some encouraging
+measurements. Note that all benchmarks only measure the time spent in accessing
+a matrix element; they exclude the loop itself.
+<p>
+<center>
+ <table border cellpadding="3" cellspacing="0" align="center">
+ <tr valign="middle" bgcolor="#33CC66" nowrap align="center">
+ <td nowrap colspan="7"> <font size="+2">Iteration Performance [million method
+ calls per second]</font><br>
+ <font size="-1">Pentium Pro 200 Mhz, SunJDK 1.2.2, NT, java -classic,<br>
+ 60 times repeating the same iteration </font></td>
+ </tr>
+ <tr valign="middle" bgcolor="#33CC66" nowrap align="center">
+ <td nowrap>
+ <div align="left"> Element type</div>
+ </td>
+ <td nowrap colspan="6"> Matrix2D type </td>
+ </tr>
+ <tr valign="middle" bgcolor="#66CCFF" nowrap align="center">
+ <td nowrap bgcolor="#FF9966" rowspan="2">
+ <div align="left"> .</div>
+ </td>
+ <td bgcolor="#FF9966" colspan="2">
+ <p><tt>DenseDoubleMatrix2D</tt><br>
+ 1000 x 1000 </p>
+ </td>
+ <td bgcolor="#FF9966" colspan="2"> </td>
+ <td bgcolor="#FF9966" colspan="2">
+ <p><tt>SparseDoubleMatrix2D</tt><br>
+ 100 x 1000,<br>
+ <font size="-1"> minLoadFactor=0.2, maxLoadFactor=0.5, initialCapacity
+ = 0</font></p>
+ </td>
+ </tr>
+ <tr valign="middle" bgcolor="#66CCFF" nowrap align="center">
+ <td bgcolor="#FF9966"> getQuick</td>
+ <td bgcolor="#FF9966"> setQuick</td>
+ <td bgcolor="#FF9966"> </td>
+ <td bgcolor="#FF9966"> </td>
+ <td bgcolor="#FF9966"> getQuick</td>
+ <td bgcolor="#FF9966">setQuick</td>
+ </tr>
+ <tr valign="middle" bgcolor="#66CCFF" nowrap align="center">
+ <td nowrap bgcolor="#FF9966">double</td>
+ <td nowrap>5</td>
+ <td nowrap>5</td>
+ <td nowrap> </td>
+ <td nowrap> </td>
+ <td nowrap>1</td>
+ <td nowrap>0.27</td>
+ </tr>
+ <tr valign="middle" bgcolor="#66CCFF" nowrap align="center">
+ <td nowrap bgcolor="#FF9966"> int</td>
+ <td nowrap>5 </td>
+ <td nowrap>5.5 </td>
+ <td nowrap> </td>
+ <td nowrap> </td>
+ <td nowrap>1 </td>
+ <td nowrap>0.3</td>
+ </tr>
+ </table>
+</center>
+<p align="left"> As can be seen, sparse matrices are certainly not quite as quick
+ as dense ones, but not really slow either. Considering their minimal footprint
+ they can be a real alternative.
+<p> Comparing the OO abstractions to zero-abstraction primitive Java arrays may
+ or may not be useful. Still, the table below provides some interesting information.
+ For example, access to <tt>Type_T_Matrix2D</tt> is quicker than naive usage
+ of <tt>Type_T_[]</tt>. Primitive arrays should only be considered if the optimized
+ form can be applied. Note again that all benchmarks only measure the time spent
+ in accessing a matrix element; they exclude the loop itself.
+<p>
+<center>
+ <table border cellpadding="3" cellspacing="0" align="center" width="617">
+ <tr valign="middle" bgcolor="#33CC66" nowrap align="center">
+ <td height="30" nowrap colspan="7"> <font size="+2">Iteration Performance
+ [million element accesses per second]</font><br>
+ <font size="-1">Pentium Pro 200 Mhz, SunJDK 1.2.2, NT, java -classic,<br>
+ 200 times repeating the same iteration </font></td>
+ </tr>
+ <tr valign="middle" bgcolor="#33CC66" nowrap align="center">
+ <td width="78" height="30" nowrap>
+ <div align="left"> Element type</div>
+ </td>
+ <td height="30" nowrap colspan="6">
+ <div align="center">Matrix2D type = Java array <tt>double[][]</tt></div>
+ </td>
+ </tr>
+ <tr valign="middle" bgcolor="#66CCFF" nowrap align="center">
+ <td width="78" height="60" nowrap bgcolor="#FF9966" rowspan="2">
+ <div align="left"> .</div>
+ </td>
+ <td height="132" bgcolor="#FF9966" colspan="2">
+ <p>Unoptimized Form<br>
+ 1000 x 1000<br>
+ <div align="left"> <font size="-1">
+ <pre>
+for (int row=0; row < rows; row++) {
+ for (int col=0; col < columns; ) {
+ value = m[row][col++];
+ ...
+ }
+}
+</pre>
+ </font> </div>
+ </td>
+ <td height="132" bgcolor="#FF9966" colspan="4"> Optimized Form<br>
+ 1000 x 1000
+ <div align="left"> <font size="-1">
+ <pre>
+for (int row=0; row < rows; row++) {
+ int[] r = matrix[row];
+ for (int col=0; col < columns; ) {
+ value = r[col++];
+ ...
+ }
+}
+</pre>
+ </font> </div>
+ </td>
+ </tr>
+ <tr valign="middle" bgcolor="#66CCFF" nowrap align="center">
+ <td width="152" height="30" bgcolor="#FF9966"> getting</td>
+ <td width="144" height="30" bgcolor="#FF9966"> setting</td>
+ <td width="150" height="30" bgcolor="#FF9966"> getting</td>
+ <td width="138" height="30" bgcolor="#FF9966" colspan="3"> setting</td>
+ </tr>
+ <tr valign="middle" bgcolor="#66CCFF" nowrap align="center">
+ <td width="78" height="30" nowrap bgcolor="#FF9966">double</td>
+ <td width="152" height="30" nowrap>1.6</td>
+ <td width="144" height="30" nowrap>1.8</td>
+ <td width="150" height="30" nowrap>18</td>
+ <td width="138" height="30" nowrap colspan="3">11</td>
+ </tr>
+ <tr valign="middle" bgcolor="#66CCFF" nowrap align="center">
+ <td width="78" height="30" nowrap bgcolor="#FF9966"> int</td>
+ <td width="152" height="30" nowrap>1.5 </td>
+ <td width="144" height="30" nowrap>1.8</td>
+ <td width="150" height="30" nowrap>28</td>
+ <td width="138" height="30" nowrap colspan="3">26</td>
+ </tr>
+ </table>
+</center>
+<left>
+
+@author wolfgang.hoschek@cern.ch
+@version 1.0, 09/24/99
+*/
+class BenchmarkMatrix2D {
+/**
+ * Makes this class non instantiable, but still let's others inherit from it.
+ */
+protected BenchmarkMatrix2D() {
+ throw new RuntimeException("Non instantiable");
+}
+/**
+ * Runs a bench on matrices holding double elements.
+ */
+public static void doubleBenchmark(int runs, int rows, int columns, String kind, boolean print, int initialCapacity, double minLoadFactor, double maxLoadFactor) {
+ System.out.println("benchmarking double matrix");
+ // certain loops need to be constructed so that the jitter can't optimize them away and we get fantastic numbers.
+ // this involves primarly read-loops
+
+ org.apache.mahout.colt.Timer timer1 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer timer2 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer timer3 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer timer4 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer emptyLoop = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer emptyLoop2 = new org.apache.mahout.colt.Timer();
+
+ emptyLoop.start();
+ int dummy = 0;
+ for (int i=0; i<runs; i++) {
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ dummy++;
+ }
+ }
+ }
+ emptyLoop.stop();
+ System.out.println(dummy); // !!! so that the jitter can't optimize away the whole loop
+
+ emptyLoop2.start();
+ dummy = 3;
+ double dummy2 = 0;
+ for (int i=0; i<runs; i++) {
+ for (int value = 0, column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ dummy2 += dummy;
+ }
+ }
+ }
+ emptyLoop2.stop();
+ System.out.println(dummy2); // !!! so that the jitter can't optimize away the whole loop
+
+
+ long before = Runtime.getRuntime().freeMemory();
+ long size = (((long)rows)*columns)*runs;
+
+ DoubleMatrix2D matrix = null;
+ if (kind.equals("sparse")) matrix = new SparseDoubleMatrix2D(rows,columns,initialCapacity,minLoadFactor,maxLoadFactor);
+ else if (kind.equals("dense")) matrix = new DenseDoubleMatrix2D(rows,columns);
+ //else if (kind.equals("denseArray")) matrix = new DoubleArrayMatrix2D(rows,columns);
+ else throw new RuntimeException("unknown kind");
+
+ System.out.println("\nNow filling...");
+ //if (kind.equals("sparse")) ((SparseDoubleMatrix2D)matrix).elements.hashCollisions = 0;
+ for (int i=0; i<runs; i++) {
+ matrix.assign(0);
+ matrix.ensureCapacity(initialCapacity);
+ if (kind.equals("sparse")) ((SparseDoubleMatrix2D)matrix).ensureCapacity(initialCapacity);
+ timer1.start();
+ int value = 0;
+ for (int row=0; row < rows; row++) {
+ for (int column=0; column < columns; column++) {
+ matrix.setQuick(row,column,value++);
+ }
+ }
+ timer1.stop();
+ }
+ timer1.display();
+ timer1.minus(emptyLoop).display();
+ System.out.println(size / timer1.minus(emptyLoop).seconds() +" elements / sec");
+
+ Runtime.getRuntime().gc(); // invite gc
+ try { Thread.currentThread().sleep(1000); } catch (InterruptedException exc) {};
+ long after = Runtime.getRuntime().freeMemory();
+ System.out.println("KB needed="+(before-after) / 1024);
+ System.out.println("bytes needed per non-zero="+(before-after) / (double)matrix.cardinality());
+ if (print) {
+ System.out.println(matrix);
+ if (kind.equals("sparse")) System.out.println("map="+((SparseDoubleMatrix2D)matrix).elements);
+ }
+ /*
+ if (kind.equals("sparse")) {
+ int hashCollisions = ((SparseDoubleMatrix2D)matrix).elements.hashCollisions;
+ System.out.println("hashCollisions="+hashCollisions);
+ System.out.println("--> "+ ((double)hashCollisions / (rows*columns)) +" hashCollisions/element on average.");
+ }
+ */
+
+ System.out.println("\nNow reading...");
+ //if (kind.equals("sparse")) ((SparseDoubleMatrix2D)matrix).elements.hashCollisions = 0;
+ timer2.start();
+ double element=0;
+ for (int i=0; i<runs; i++) {
+ for (int row=0; row < rows; row++) {
+ for (int column=0; column < columns; column++) {
+ element += matrix.getQuick(row,column);
+ }
+ }
+ }
+ timer2.stop().display();
+ timer2.minus(emptyLoop2).display();
+ System.out.println(size / timer2.minus(emptyLoop2).seconds() +" elements / sec");
+ if (print) System.out.println(matrix);
+ //if (kind.equals("sparse")) System.out.println("hashCollisions="+((SparseDoubleMatrix2D)matrix).elements.hashCollisions);
+ System.out.println(element); // !!! so that the jitter can't optimize away the whole loop
+
+ System.out.println("\nNow reading view...");
+ DoubleMatrix2D view = matrix.viewPart(0,0,rows,columns);
+ timer4.start();
+ element=0;
+ for (int i=0; i<runs; i++) {
+ for (int row=0; row < rows; row++) {
+ for (int column=0; column < columns; column++) {
+ element += view.getQuick(row,column);
+ }
+ }
+ }
+ timer4.stop().display();
+ timer4.minus(emptyLoop2).display();
+ System.out.println(size / timer4.minus(emptyLoop2).seconds() +" elements / sec");
+ if (print) System.out.println(view);
+ //if (kind.equals("sparse")) System.out.println("hashCollisions="+((SparseDoubleMatrix2D)view).elements.hashCollisions);
+ System.out.println(element); // !!! so that the jitter can't optimize away the whole loop
+
+ System.out.println("\nNow removing...");
+ before = Runtime.getRuntime().freeMemory();
+ //if (kind.equals("sparse")) ((SparseDoubleMatrix2D)matrix).elements.hashCollisions = 0;
+ for (int i=0; i<runs; i++) {
+ // initializing
+ for (int row=0; row < rows; row++) {
+ for (int column=0; column < columns; column++) {
+ matrix.setQuick(row,column,1);
+ }
+ }
+ timer3.start();
+ for (int row=0; row < rows; row++) {
+ for (int column=0; column < columns; column++) {
+ matrix.setQuick(row,column,0);
+ }
+ }
+ timer3.stop();
+ }
+ timer3.display();
+ timer3.minus(emptyLoop).display();
+ System.out.println(size / timer3.minus(emptyLoop).seconds() +" elements / sec");
+ Runtime.getRuntime().gc(); // invite gc
+ try { Thread.currentThread().sleep(1000); } catch (InterruptedException exc) {};
+ after = Runtime.getRuntime().freeMemory();
+ System.out.println("KB needed="+(before-after)/1024);
+ System.out.println("KB free="+(after/1024));
+
+ if (print) System.out.println(matrix);
+ //if (kind.equals("sparse")) System.out.println("hashCollisions"+((SparseDoubleMatrix2D)matrix).elements.hashCollisions);
+
+
+ System.out.println("bye bye.");
+}
+/**
+ * Runs a bench on matrices holding double elements.
+ */
+public static void doubleBenchmarkMult(int runs, int rows, int columns, String kind, boolean print, int initialCapacity, double minLoadFactor, double maxLoadFactor) {
+ System.out.println("benchmarking double matrix");
+ // certain loops need to be constructed so that the jitter can't optimize them away and we get fantastic numbers.
+ // this involves primarly read-loops
+
+ org.apache.mahout.colt.Timer timer1 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer timer2 = new org.apache.mahout.colt.Timer();
+
+ long size = (((long)rows)*columns)*runs;
+
+ DoubleMatrix2D matrix = null;
+ if (kind.equals("sparse")) matrix = new SparseDoubleMatrix2D(rows,columns,initialCapacity,minLoadFactor,maxLoadFactor);
+ else if (kind.equals("dense")) matrix = new DenseDoubleMatrix2D(rows,columns);
+ //else if (kind.equals("denseArray")) matrix = new DoubleArrayMatrix2D(rows,columns);
+ else throw new RuntimeException("unknown kind");
+
+ System.out.println("\nNow multiplying...");
+ matrix.assign(1);
+ //if (kind.equals("sparse")) ((SparseDoubleMatrix2D)matrix).elements.hashCollisions = 0;
+ for (int i=0; i<runs; i++) {
+ timer1.start();
+ org.apache.mahout.colt.matrix.doublealgo.Transform.mult(matrix, 3);
+ timer1.stop();
+ }
+ timer1.display();
+ System.out.println(size / timer1.seconds() +" elements / sec");
+
+ if (print) {
+ System.out.println(matrix);
+ }
+ /*
+ if (kind.equals("sparse")) {
+ int hashCollisions = ((SparseDoubleMatrix2D)matrix).elements.hashCollisions;
+ System.out.println("hashCollisions="+hashCollisions);
+ System.out.println("--> "+ ((double)hashCollisions / (rows*columns)) +" hashCollisions/element on average.");
+ }
+ */
+
+ System.out.println("\nNow multiplying2...");
+ matrix.assign(1);
+ //if (kind.equals("sparse")) ((SparseDoubleMatrix2D)matrix).elements.hashCollisions = 0;
+ for (int i=0; i<runs; i++) {
+ timer2.start();
+ org.apache.mahout.colt.matrix.doublealgo.Transform.mult(matrix,3);
+ timer2.stop();
+ }
+ timer2.display();
+ System.out.println(size / timer2.seconds() +" elements / sec");
+
+ if (print) {
+ System.out.println(matrix);
+ }
+ /*
+ if (kind.equals("sparse")) {
+ int hashCollisions = ((SparseDoubleMatrix2D)matrix).elements.hashCollisions;
+ System.out.println("hashCollisions="+hashCollisions);
+ System.out.println("--> "+ ((double)hashCollisions / (rows*columns)) +" hashCollisions/element on average.");
+ }
+ */
+ System.out.println("bye bye.");
+}
+/**
+ * Runs a bench on matrices holding double elements.
+ */
+public static void doubleBenchmarkPrimitive(int runs, int rows, int columns, boolean print) {
+ // certain loops need to be constructed so that the jitter can't optimize them away and we get fantastic numbers.
+ // this involves primarly read-loops
+ org.apache.mahout.colt.Timer timer1 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer timer2 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer timer3 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer emptyLoop = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer emptyLoop2 = new org.apache.mahout.colt.Timer();
+
+ emptyLoop.start();
+ int dummy = 0;
+ for (int i=0; i<runs; i++) {
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ dummy++;
+ }
+ }
+ }
+ emptyLoop.stop();
+ System.out.println(dummy); // !!! so that the jitter can't optimize away the whole loop
+
+ emptyLoop2.start();
+ dummy = 3;
+ double dummy2 = 0;
+ for (int i=0; i<runs; i++) {
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ dummy2 += dummy;
+ }
+ }
+ }
+ emptyLoop2.stop();
+ System.out.println(dummy2); // !!! so that the jitter can't optimize away the whole loop
+
+ long before = Runtime.getRuntime().freeMemory();
+ long size = (((long)rows)*columns)*runs;
+
+ double[][] matrix = new double[rows][columns];
+
+ System.out.println("\nNow filling...");
+ for (int i=0; i<runs; i++) {
+ timer1.start();
+ int value = 0;
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ matrix[row][column] = value++;
+ }
+ }
+ timer1.stop();
+ }
+ timer1.display();
+ timer1.minus(emptyLoop).display();
+ System.out.println(size / timer1.minus(emptyLoop).seconds() +" elements / sec");
+
+ Runtime.getRuntime().gc(); // invite gc
+ try { Thread.currentThread().sleep(1000); } catch (InterruptedException exc) {};
+ long after = Runtime.getRuntime().freeMemory();
+ System.out.println("KB needed="+(before-after) / 1024);
+ if (print) {
+ DenseDoubleMatrix2D m = new DenseDoubleMatrix2D(rows,columns);
+ m.assign(matrix);
+ System.out.println(m);
+ }
+
+ System.out.println("\nNow reading...");
+ timer2.start();
+ double element=0;
+ for (int i=0; i<runs; i++) {
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ element += matrix[row][column];
+ }
+ }
+ }
+ timer2.stop().display();
+ timer2.minus(emptyLoop2).display();
+ System.out.println(size / timer2.minus(emptyLoop2).seconds() +" elements / sec");
+ if (print) {
+ DenseDoubleMatrix2D m = new DenseDoubleMatrix2D(rows,columns);
+ m.assign(matrix);
+ System.out.println(m);
+ }
+ System.out.println(element); // !!! so that the jitter can't optimize away the whole loop
+
+ System.out.println("\nNow removing...");
+ before = Runtime.getRuntime().freeMemory();
+ for (int i=0; i<runs; i++) {
+ /*
+ // initializing
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ matrix.setQuick(row,column,1);
+ }
+ }
+ */
+ timer3.start();
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ matrix[row][column] = 0;
+ }
+ }
+ timer3.stop();
+ }
+ timer3.display();
+ timer3.minus(emptyLoop).display();
+ System.out.println(size / timer3.minus(emptyLoop).seconds() +" elements / sec");
+ Runtime.getRuntime().gc(); // invite gc
+ try { Thread.currentThread().sleep(1000); } catch (InterruptedException exc) {};
+ after = Runtime.getRuntime().freeMemory();
+ System.out.println("KB needed="+(before-after)/1024);
+ System.out.println("KB free="+(after/1024));
+
+ if (print) {
+ DenseDoubleMatrix2D m = new DenseDoubleMatrix2D(rows,columns);
+ m.assign(matrix);
+ System.out.println(m);
+ }
+
+ System.out.println("bye bye.");
+}
+/**
+ * Runs a bench on matrices holding double elements.
+ */
+public static void doubleBenchmarkPrimitiveOptimized(int runs, int rows, int columns, boolean print) {
+ // certain loops need to be constructed so that the jitter can't optimize them away and we get fantastic numbers.
+ // this involves primarly read-loops
+ org.apache.mahout.colt.Timer timer1 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer timer2 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer timer3 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer emptyLoop = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer emptyLoop2 = new org.apache.mahout.colt.Timer();
+
+ emptyLoop.start();
+ int dummy = 0;
+ for (int i=0; i<runs; i++) {
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ dummy++;
+ }
+ }
+ }
+ emptyLoop.stop();
+ System.out.println(dummy); // !!! so that the jitter can't optimize away the whole loop
+
+ emptyLoop2.start();
+ dummy = 3;
+ double dummy2 = 0;
+ for (int i=0; i<runs; i++) {
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ dummy2 += dummy;
+ }
+ }
+ }
+ emptyLoop2.stop();
+ System.out.println(dummy2); // !!! so that the jitter can't optimize away the whole loop
+
+ long before = Runtime.getRuntime().freeMemory();
+ long size = (((long)rows)*columns)*runs;
+
+ double[][] matrix = new double[rows][columns];
+
+ System.out.println("\nNow filling...");
+ for (int i=0; i<runs; i++) {
+ timer1.start();
+ int value = 0;
+ for (int row=0; row < rows; row++) {
+ double[] r = matrix[row];
+ for (int column=0; column < columns; column++) {
+ r[column] = value++;
+ //matrix[row][column] = value++;
+ }
+ }
+ timer1.stop();
+ }
+ timer1.display();
+ timer1.minus(emptyLoop).display();
+ System.out.println(size / timer1.minus(emptyLoop).seconds() +" elements / sec");
+
+ Runtime.getRuntime().gc(); // invite gc
+ try { Thread.currentThread().sleep(1000); } catch (InterruptedException exc) {};
+ long after = Runtime.getRuntime().freeMemory();
+ System.out.println("KB needed="+(before-after) / 1024);
+ if (print) {
+ DenseDoubleMatrix2D m = new DenseDoubleMatrix2D(rows,columns);
+ m.assign(matrix);
+ System.out.println(m);
+ }
+
+ System.out.println("\nNow reading...");
+ timer2.start();
+ double element=0;
+ for (int i=0; i<runs; i++) {
+ for (int row=0; row < rows; row++) {
+ double[] r = matrix[row];
+ for (int column=0; column < columns; column++) {
+ element += r[column];
+ //element += matrix[row][column];
+ }
+ }
+ }
+ timer2.stop().display();
+ timer2.minus(emptyLoop2).display();
+ System.out.println(size / timer2.minus(emptyLoop2).seconds() +" elements / sec");
+ if (print) {
+ DenseDoubleMatrix2D m = new DenseDoubleMatrix2D(rows,columns);
+ m.assign(matrix);
+ System.out.println(m);
+ }
+ System.out.println(element); // !!! so that the jitter can't optimize away the whole loop
+
+ System.out.println("\nNow removing...");
+ before = Runtime.getRuntime().freeMemory();
+ for (int i=0; i<runs; i++) {
+ timer3.start();
+ for (int row=0; row < rows; row++) {
+ double[] r = matrix[row];
+ for (int column=0; column < columns; column++) {
+ r[column] = 0;
+ //matrix[row][column] = 0;
+ }
+ }
+ timer3.stop();
+ }
+ timer3.display();
+ timer3.minus(emptyLoop).display();
+ System.out.println(size / timer3.minus(emptyLoop).seconds() +" elements / sec");
+ Runtime.getRuntime().gc(); // invite gc
+ try { Thread.currentThread().sleep(1000); } catch (InterruptedException exc) {};
+ after = Runtime.getRuntime().freeMemory();
+ System.out.println("KB needed="+(before-after)/1024);
+ System.out.println("KB free="+(after/1024));
+
+ if (print) {
+ DenseDoubleMatrix2D m = new DenseDoubleMatrix2D(rows,columns);
+ m.assign(matrix);
+ System.out.println(m);
+ }
+
+ System.out.println("bye bye.");
+}
+/**
+ * Runs a bench on matrices holding int elements.
+ */
+public static void intBenchmark(int runs, int rows, int columns, String kind, boolean print, int initialCapacity, double minLoadFactor, double maxLoadFactor) {
+ throw new InternalError();
+ /*
+ // certain loops need to be constructed so that the jitter can't optimize them away and we get fantastic numbers.
+ // this involves primarly read-loops
+
+ org.apache.mahout.colt.Timer timer1 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer timer2 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer timer3 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer emptyLoop = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer emptyLoop2 = new org.apache.mahout.colt.Timer();
+
+ emptyLoop.start();
+ int dummy = 0;
+ for (int i=0; i<runs; i++) {
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ dummy++;
+ }
+ }
+ }
+ emptyLoop.stop();
+ System.out.println(dummy); // !!! so that the jitter can't optimize away the whole loop
+
+ emptyLoop2.start();
+ dummy = 3;
+ int dummy2 = 0;
+ for (int i=0; i<runs; i++) {
+ for (int value = 0, column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ dummy2 += dummy;
+ }
+ }
+ }
+ emptyLoop2.stop();
+ System.out.println(dummy2); // !!! so that the jitter can't optimize away the whole loop
+
+ long before = Runtime.getRuntime().freeMemory();
+ long size = (((long)rows)*columns)*runs;
+
+ AbstractIntMatrix2D matrix = null;
+ if (kind.equals("sparse")) matrix = new SparseIntMatrix2D(rows,columns,initialCapacity,minLoadFactor,maxLoadFactor);
+ else if (kind.equals("dense")) matrix = new DenseIntMatrix2D(rows,columns);
+ //else if (kind.equals("denseArray")) matrix = new DoubleArrayMatrix2D(rows,columns);
+ else throw new RuntimeException("unknown kind");
+
+ System.out.println("\nNow filling...");
+ if (kind.equals("sparse")) ((SparseIntMatrix2D)matrix).elements.hashCollisions = 0;
+ for (int i=0; i<runs; i++) {
+ matrix.assign(0);
+ matrix.ensureCapacity(initialCapacity);
+ if (kind.equals("sparse")) ((SparseIntMatrix2D)matrix).ensureCapacity(initialCapacity);
+ timer1.start();
+ int value = 0;
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ matrix.setQuick(row,column,value++);
+ }
+ }
+ timer1.stop();
+ }
+ timer1.display();
+ timer1.minus(emptyLoop).display();
+ System.out.println(size / timer1.minus(emptyLoop).seconds() +" elements / sec");
+
+ Runtime.getRuntime().gc(); // invite gc
+ try { Thread.currentThread().sleep(1000); } catch (InterruptedException exc) {};
+ long after = Runtime.getRuntime().freeMemory();
+ System.out.println("KB needed="+(before-after) / 1024);
+ System.out.println("bytes needed per non-zero="+(before-after) / (double)matrix.cardinality());
+ if (print) {
+ System.out.println(matrix);
+ if (kind.equals("sparse")) System.out.println("map="+((SparseIntMatrix2D)matrix).elements);
+ }
+ if (kind.equals("sparse")) {
+ int hashCollisions = ((SparseIntMatrix2D)matrix).elements.hashCollisions;
+ System.out.println("hashCollisions="+hashCollisions);
+ System.out.println("--> "+ ((double)hashCollisions / (rows*columns)) +" probes/element on average.");
+ }
+
+ System.out.println("\nNow reading...");
+ if (kind.equals("sparse")) ((SparseIntMatrix2D)matrix).elements.hashCollisions = 0;
+ timer2.start();
+ int element=0;
+ for (int i=0; i<runs; i++) {
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ element += matrix.getQuick(row,column);
+ }
+ }
+ }
+ timer2.stop().display();
+ timer2.minus(emptyLoop2).display();
+ System.out.println(size / timer2.minus(emptyLoop2).seconds() +" elements / sec");
+ if (print) System.out.println(matrix);
+ if (kind.equals("sparse")) System.out.println("hashCollisions="+((SparseIntMatrix2D)matrix).elements.hashCollisions);
+ System.out.println(element); // !!! so that the jitter can't optimize away the whole loop
+
+ System.out.println("\nNow removing...");
+ before = Runtime.getRuntime().freeMemory();
+ if (kind.equals("sparse")) ((SparseIntMatrix2D)matrix).elements.hashCollisions = 0;
+ for (int i=0; i<runs; i++) {
+ // initializing
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ matrix.setQuick(row,column,1);
+ }
+ }
+ timer3.start();
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ matrix.setQuick(row,column,0);
+ }
+ }
+ timer3.stop();
+ }
+ timer3.display();
+ timer3.minus(emptyLoop).display();
+ System.out.println(size / timer3.minus(emptyLoop).seconds() +" elements / sec");
+ Runtime.getRuntime().gc(); // invite gc
+ try { Thread.currentThread().sleep(1000); } catch (InterruptedException exc) {};
+ after = Runtime.getRuntime().freeMemory();
+ System.out.println("KB needed="+(before-after)/1024);
+ System.out.println("KB free="+(after/1024));
+
+ if (print) System.out.println(matrix);
+ if (kind.equals("sparse")) System.out.println("hashCollisions="+((SparseIntMatrix2D)matrix).elements.hashCollisions);
+
+
+ System.out.println("bye bye.");
+ */
+}
+/**
+ * Runs a bench on matrices holding int elements.
+ */
+public static void intBenchmarkPrimitive(int runs, int rows, int columns, boolean print) {
+ throw new InternalError();
+ /*
+ // certain loops need to be constructed so that the jitter can't optimize them away and we get fantastic numbers.
+ // this involves primarly read-loops
+ org.apache.mahout.colt.Timer timer1 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer timer2 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer timer3 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer emptyLoop = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer emptyLoop2 = new org.apache.mahout.colt.Timer();
+
+ emptyLoop.start();
+ int dummy = 0;
+ for (int i=0; i<runs; i++) {
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ dummy++;
+ }
+ }
+ }
+ emptyLoop.stop();
+ System.out.println(dummy); // !!! so that the jitter can't optimize away the whole loop
+
+ emptyLoop2.start();
+ dummy = 3;
+ int dummy2 = 0;
+ for (int i=0; i<runs; i++) {
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ dummy2 += dummy;
+ }
+ }
+ }
+ emptyLoop2.stop();
+ System.out.println(dummy2); // !!! so that the jitter can't optimize away the whole loop
+
+ long before = Runtime.getRuntime().freeMemory();
+ long size = (((long)rows)*columns)*runs;
+
+ int[][] matrix = new int[rows][columns];
+
+ System.out.println("\nNow filling...");
+ for (int i=0; i<runs; i++) {
+ timer1.start();
+ int value = 0;
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ matrix[row][column] = value++;
+ }
+ }
+ timer1.stop();
+ }
+ timer1.display();
+ timer1.minus(emptyLoop).display();
+ System.out.println(size / timer1.minus(emptyLoop).seconds() +" elements / sec");
+
+ Runtime.getRuntime().gc(); // invite gc
+ try { Thread.currentThread().sleep(1000); } catch (InterruptedException exc) {};
+ long after = Runtime.getRuntime().freeMemory();
+ System.out.println("KB needed="+(before-after) / 1024);
+ if (print) {
+ DenseIntMatrix2D m = new DenseIntMatrix2D(rows,columns);
+ m.assign(matrix);
+ System.out.println(m);
+ }
+
+ System.out.println("\nNow reading...");
+ timer2.start();
+ int element=0;
+ for (int i=0; i<runs; i++) {
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ element += matrix[row][column];
+ }
+ }
+ }
+ timer2.stop().display();
+ timer2.minus(emptyLoop2).display();
+ System.out.println(size / timer2.minus(emptyLoop2).seconds() +" elements / sec");
+ if (print) {
+ DenseIntMatrix2D m = new DenseIntMatrix2D(rows,columns);
+ m.assign(matrix);
+ System.out.println(m);
+ }
+ System.out.println(element); // !!! so that the jitter can't optimize away the whole loop
+
+ System.out.println("\nNow removing...");
+ before = Runtime.getRuntime().freeMemory();
+ for (int i=0; i<runs; i++) {
+ timer3.start();
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ matrix[row][column] = 0;
+ }
+ }
+ timer3.stop();
+ }
+ timer3.display();
+ timer3.minus(emptyLoop).display();
+ System.out.println(size / timer3.minus(emptyLoop).seconds() +" elements / sec");
+ Runtime.getRuntime().gc(); // invite gc
+ try { Thread.currentThread().sleep(1000); } catch (InterruptedException exc) {};
+ after = Runtime.getRuntime().freeMemory();
+ System.out.println("KB needed="+(before-after)/1024);
+ System.out.println("KB free="+(after/1024));
+
+ if (print) {
+ DenseIntMatrix2D m = new DenseIntMatrix2D(rows,columns);
+ m.assign(matrix);
+ System.out.println(m);
+ }
+
+ System.out.println("bye bye.");
+ */
+}
+/**
+ * Runs a bench on matrices holding int elements.
+ */
+public static void intBenchmarkPrimitiveOptimized(int runs, int rows, int columns, boolean print) {
+ throw new InternalError();
+ /*
+ // certain loops need to be constructed so that the jitter can't optimize them away and we get fantastic numbers.
+ // this involves primarly read-loops
+ org.apache.mahout.colt.Timer timer1 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer timer2 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer timer3 = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer emptyLoop = new org.apache.mahout.colt.Timer();
+ org.apache.mahout.colt.Timer emptyLoop2 = new org.apache.mahout.colt.Timer();
+
+ emptyLoop.start();
+ int dummy = 0;
+ for (int i=0; i<runs; i++) {
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ dummy++;
+ }
+ }
+ }
+ emptyLoop.stop();
+ System.out.println(dummy); // !!! so that the jitter can't optimize away the whole loop
+
+ int[][] matrix = new int[rows][columns];
+ emptyLoop2.start();
+ dummy = 3;
+ int dummy2 = 7;
+ System.out.println(dummy2); // !!! so that the jitter can't optimize away the whole loop
+ for (int i=0; i<runs; i++) {
+ for (int column=0; column < columns; column++) {
+ for (int row=0; row < rows; row++) {
+ dummy2 += dummy; //matrix[row][column];
+ }
+ }
+ }
+ emptyLoop2.stop();
+ System.out.println(dummy2); // !!! so that the jitter can't optimize away the whole loop
+
+ long before = Runtime.getRuntime().freeMemory();
+ long size = (((long)rows)*columns)*runs;
+
+
+ System.out.println("\nNow filling...");
+ for (int i=0; i<runs; i++) {
+ timer1.start();
+ int value = 0;
+ for (int row=0; row < rows; row++) {
+ int[] r = matrix[row];
+ for (int column=0; column < columns; column++) {
+ r[column] = value++;
+ //matrix[row][column] = value++;
+ }
+ }
+ timer1.stop();
+ }
+ timer1.display();
+ timer1.minus(emptyLoop).display();
+ System.out.println(size / timer1.minus(emptyLoop).seconds() +" elements / sec");
+
+ Runtime.getRuntime().gc(); // invite gc
+ try { Thread.currentThread().sleep(1000); } catch (InterruptedException exc) {};
+ long after = Runtime.getRuntime().freeMemory();
+ System.out.println("KB needed="+(before-after) / 1024);
+ if (print) {
+ DenseIntMatrix2D m = new DenseIntMatrix2D(rows,columns);
+ m.assign(matrix);
+ System.out.println(m);
+ }
+
+ System.out.println("\nNow reading...");
+ timer2.start();
+ int element=0;
+ for (int i=0; i<runs; i++) {
+ for (int row=0; row < rows; row++) {
+ int[] r = matrix[row];
+ for (int column=0; column < columns; column++) {
+ element += r[column];
+ //element += matrix[row][column];
+ }
+ }
+ }
+ timer2.stop().display();
+ timer2.minus(emptyLoop2).display();
+ System.out.println(size / timer2.minus(emptyLoop2).seconds() +" elements / sec");
+ if (print) {
+ DenseIntMatrix2D m = new DenseIntMatrix2D(rows,columns);
+ m.assign(matrix);
+ System.out.println(m);
+ }
+ System.out.println(element); // !!! so that the jitter can't optimize away the whole loop
+
+ System.out.println("\nNow removing...");
+ before = Runtime.getRuntime().freeMemory();
+ for (int i=0; i<runs; i++) {
+ timer3.start();
+ for (int row=0; row < rows; row++) {
+ int[] r = matrix[row];
+ for (int column=0; column < columns; column++) {
+ r[column] = 0;
+ //matrix[row][column] = 0;
+ }
+ }
+ timer3.stop();
+ }
+ timer3.display();
+ timer3.minus(emptyLoop).display();
+ System.out.println(size / timer3.minus(emptyLoop).seconds() +" elements / sec");
+ Runtime.getRuntime().gc(); // invite gc
+ try { Thread.currentThread().sleep(1000); } catch (InterruptedException exc) {};
+ after = Runtime.getRuntime().freeMemory();
+ System.out.println("KB needed="+(before-after)/1024);
+ System.out.println("KB free="+(after/1024));
+
+ if (print) {
+ DenseIntMatrix2D m = new DenseIntMatrix2D(rows,columns);
+ m.assign(matrix);
+ System.out.println(m);
+ }
+
+ System.out.println("bye bye.");
+ */
+}
+/**
+ * Benchmarks various methods of this class.
+ */
+public static void main(String args[]) {
+ int runs = Integer.parseInt(args[0]);
+ int rows = Integer.parseInt(args[1]);
+ int columns = Integer.parseInt(args[2]);
+ //int size = Integer.parseInt(args[3]);
+ //boolean isSparse = args[4].equals("sparse");
+ String kind = args[3];
+ int initialCapacity = Integer.parseInt(args[4]);
+ double minLoadFactor = new Double(args[5]).doubleValue();
+ double maxLoadFactor = new Double(args[6]).doubleValue();
+ boolean print = args[7].equals("print");
+ String type = args[8];
+ String command = args[9];
+
+ if (type.equals("int")) {
+ if (kind.equals("primitive")) intBenchmarkPrimitive(runs,rows,columns,print);
+ else if (kind.equals("primitiveOpt")) intBenchmarkPrimitiveOptimized(runs,rows,columns,print);
+ else intBenchmark(runs,rows,columns,kind,print,initialCapacity,minLoadFactor,maxLoadFactor);
+ }
+ else if (type.equals("double")) {
+ if (kind.equals("primitive")) doubleBenchmarkPrimitive(runs,rows,columns,print);
+ else if (kind.equals("primitiveOpt")) doubleBenchmarkPrimitiveOptimized(runs,rows,columns,print);
+ else if (command.equals("mult")) doubleBenchmarkMult(runs,rows,columns,kind,print,initialCapacity,minLoadFactor,maxLoadFactor);
+ else doubleBenchmark(runs,rows,columns,kind,print,initialCapacity,minLoadFactor,maxLoadFactor);
+ }
+
+}
+}
Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/BenchmarkMatrix2D.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DelegateDoubleMatrix1D.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DelegateDoubleMatrix1D.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DelegateDoubleMatrix1D.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DelegateDoubleMatrix1D.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,85 @@
+/*
+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;
+/**
+1-d matrix holding <tt>double</tt> elements; either a view wrapping another 2-d matrix and therefore delegating calls to it.
+
+@author wolfgang.hoschek@cern.ch
+@version 1.0, 09/24/99
+*/
+class DelegateDoubleMatrix1D extends WrapperDoubleMatrix1D {
+ /*
+ * The elements of the matrix.
+ */
+ protected DoubleMatrix2D content;
+ /*
+ * The row this view is bound to.
+ */
+ protected int row;
+public DelegateDoubleMatrix1D(DoubleMatrix2D newContent, int row) {
+ super(null);
+ if (row < 0 || row >= newContent.rows()) throw new IllegalArgumentException();
+ setUp(newContent.columns());
+ this.row=row;
+ this.content = newContent;
+}
+/**
+ * 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<0 || index>=size()</tt>.
+ *
+ * @param index the index of the cell.
+ * @return the value of the specified cell.
+ */
+public double getQuick(int index) {
+ return content.getQuick(row,index);
+}
+/**
+ * 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>DenseDoubleMatrix1D</tt> the new matrix must also be of type <tt>DenseDoubleMatrix1D</tt>,
+ * if the receiver is an instance of type <tt>SparseDoubleMatrix1D</tt> the new matrix must also be of type <tt>SparseDoubleMatrix1D</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 DoubleMatrix1D like(int size) {
+ return content.like1D(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>DenseDoubleMatrix1D</tt> the new matrix must be of type <tt>DenseDoubleMatrix2D</tt>,
+ * if the receiver is an instance of type <tt>SparseDoubleMatrix1D</tt> the new matrix must 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.
+ * @return a new matrix of the corresponding dynamic type.
+ */
+public DoubleMatrix2D like2D(int rows, int columns) {
+ return content.like(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<0 || index>=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, double value) {
+ content.setQuick(row,index, value);
+}
+}
Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DelegateDoubleMatrix1D.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseDoubleMatrix1D.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseDoubleMatrix1D.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseDoubleMatrix1D.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseDoubleMatrix1D.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,512 @@
+/*
+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 1-d matrix (aka <i>vector</i>) 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.
+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 DenseDoubleMatrix1D extends DoubleMatrix1D {
+ /**
+ * The elements of this matrix.
+ */
+ protected double[] 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 DenseDoubleMatrix1D(double[] 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 DenseDoubleMatrix1D(int size) {
+ setUp(size);
+ this.elements = new double[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 DenseDoubleMatrix1D(int size, double[] 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 DoubleMatrix1D assign(double[] 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;
+}
+/**
+ * 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 DoubleMatrix1D assign(double value) {
+ int index = index(0);
+ int s = this.stride;
+ double[] elems = this.elements;
+ for (int i=size; --i >= 0; ) {
+ elems[index] = value;
+ index += s;
+ }
+ 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 DoubleMatrix1D assign(org.apache.mahout.colt.function.DoubleFunction function) {
+ int s=stride;
+ int i=index(0);
+ double[] elems = this.elements;
+ if (elems==null) throw new InternalError();
+
+ // 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;
+ for (int k=size; --k >= 0; ) {
+ elems[i] *= multiplicator;
+ i += s;
+ }
+ }
+ else { // 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 DoubleMatrix1D assign(DoubleMatrix1D source) {
+ // overriden for performance only
+ if (! (source instanceof DenseDoubleMatrix1D)) {
+ return super.assign(source);
+ }
+ DenseDoubleMatrix1D other = (DenseDoubleMatrix1D) 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)) {
+ DoubleMatrix1D c = other.copy();
+ if (! (c instanceof DenseDoubleMatrix1D)) { // should not happen
+ return super.assign(source);
+ }
+ other = (DenseDoubleMatrix1D) c;
+ }
+
+ final double[] elems = this.elements;
+ final double[] 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,
+ new DoubleDoubleFunction() {
+ public double apply(double x, double y) { return Math.pow(x,y); }
+ }
+);
+</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 DoubleMatrix1D assign(DoubleMatrix1D y, org.apache.mahout.colt.function.DoubleDoubleFunction function) {
+ // overriden for performance only
+ if (! (y instanceof DenseDoubleMatrix1D)) {
+ return super.assign(y,function);
+ }
+ DenseDoubleMatrix1D other = (DenseDoubleMatrix1D) y;
+ checkSize(y);
+ final double[] elems = this.elements;
+ final double[] otherElems = other.elements;
+ if (elems==null || otherElems==null) throw new InternalError();
+ int s = this.stride;
+ int ys = other.stride;
+
+ int index = index(0);
+ int otherIndex = other.index(0);
+
+ // specialized for speed
+ if (function== org.apache.mahout.jet.math.Functions.mult) { // x[i] = x[i] * y[i]
+ for (int k=size; --k >= 0; ) {
+ elems[index] *= otherElems[otherIndex];
+ index += s;
+ otherIndex += ys;
+ }
+ }
+ else if (function== org.apache.mahout.jet.math.Functions.div) { // x[i] = x[i] / y[i]
+ for (int k=size; --k >= 0; ) {
+ elems[index] /= otherElems[otherIndex];
+ index += s;
+ otherIndex += ys;
+ }
+ }
+ 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 k=size; --k >= 0; ) {
+ elems[index] += otherElems[otherIndex];
+ index += s;
+ otherIndex += ys;
+ }
+ }
+ else if (multiplicator == -1) { // x[i] = x[i] - y[i]
+ for (int k=size; --k >= 0; ) {
+ elems[index] -= otherElems[otherIndex];
+ index += s;
+ otherIndex += ys;
+ }
+ }
+ else { // the general case x[i] = x[i] + mult*y[i]
+ for (int k=size; --k >= 0; ) {
+ elems[index] += multiplicator*otherElems[otherIndex];
+ index += s;
+ otherIndex += ys;
+ }
+ }
+ }
+ else { // 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 number of cells having non-zero values, but at most maxCardinality; ignores tolerance.
+ */
+protected int cardinality(int maxCardinality) {
+ int cardinality = 0;
+ int index = index(0);
+ int s = this.stride;
+ double[] elems = this.elements;
+ int i=size;
+ while (--i >= 0 && cardinality < maxCardinality) {
+ if (elems[index] != 0) cardinality++;
+ index += s;
+ }
+ return cardinality;
+}
+/**
+ * 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<0 || index>=size()</tt>.
+ *
+ * @param index the index of the cell.
+ * @return the value of the specified cell.
+ */
+public double 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(DoubleMatrix1D other) {
+ if (other instanceof SelectedDenseDoubleMatrix1D) {
+ SelectedDenseDoubleMatrix1D otherMatrix = (SelectedDenseDoubleMatrix1D) other;
+ return this.elements==otherMatrix.elements;
+ }
+ else if (other instanceof DenseDoubleMatrix1D) {
+ DenseDoubleMatrix1D otherMatrix = (DenseDoubleMatrix1D) 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>DenseDoubleMatrix1D</tt> the new matrix must also be of type <tt>DenseDoubleMatrix1D</tt>,
+ * if the receiver is an instance of type <tt>SparseDoubleMatrix1D</tt> the new matrix must also be of type <tt>SparseDoubleMatrix1D</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 DoubleMatrix1D like(int size) {
+ return new DenseDoubleMatrix1D(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>DenseDoubleMatrix1D</tt> the new matrix must be of type <tt>DenseDoubleMatrix2D</tt>,
+ * if the receiver is an instance of type <tt>SparseDoubleMatrix1D</tt> the new matrix must 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.
+ * @return a new matrix of the corresponding dynamic type.
+ */
+public DoubleMatrix2D like2D(int rows, int columns) {
+ return new DenseDoubleMatrix2D(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<0 || index>=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, double 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(DoubleMatrix1D other) {
+ // overriden for performance only
+ if (! (other instanceof DenseDoubleMatrix1D)) {
+ super.swap(other);
+ }
+ DenseDoubleMatrix1D y = (DenseDoubleMatrix1D) other;
+ if (y==this) return;
+ checkSize(y);
+
+ final double[] elems = this.elements;
+ final double[] 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; ) {
+ double 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(double[] 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 DoubleMatrix1D viewSelectionLike(int[] offsets) {
+ return new SelectedDenseDoubleMatrix1D(this.elements,offsets);
+}
+/**
+ * Returns the dot product of two vectors x and y, which is <tt>Sum(x[i]*y[i])</tt>.
+ * Where <tt>x == this</tt>.
+ * Operates on cells at indexes <tt>from .. Min(size(),y.size(),from+length)-1</tt>.
+ * @param y the second vector.
+ * @param from the first index to be considered.
+ * @param length the number of cells to be considered.
+ * @return the sum of products; zero if <tt>from<0 || length<0</tt>.
+ */
+public double zDotProduct(DoubleMatrix1D y, int from, int length) {
+ if (!(y instanceof DenseDoubleMatrix1D)) {
+ return super.zDotProduct(y, from, length);
+ }
+ DenseDoubleMatrix1D yy = (DenseDoubleMatrix1D) y;
+
+ int tail = from + length;
+ if (from < 0 || length < 0) return 0;
+ if (size < tail) tail = size;
+ if (y.size < tail) tail = y.size;
+ int min = tail-from;
+
+ int i = index(from);
+ int j = yy.index(from);
+ int s = stride;
+ int ys = yy.stride;
+ final double[] elems = this.elements;
+ final double[] yElems = yy.elements;
+ if (elems==null || yElems==null) throw new InternalError();
+
+ double sum = 0;
+ /*
+ // unoptimized
+ for (int k = min; --k >= 0;) {
+ sum += elems[i] * yElems[j];
+ i += s;
+ j += ys;
+ }
+ */
+
+ // optimized
+ // loop unrolling
+ i -= s;
+ j -= ys;
+ for (int k=min/4; --k >= 0; ) {
+ sum += elems[i += s] * yElems[j += ys] +
+ elems[i += s] * yElems[j += ys] +
+ elems[i += s] * yElems[j += ys] +
+ elems[i += s] * yElems[j += ys];
+ }
+ for (int k=min%4; --k >= 0; ) {
+ sum += elems[i += s] * yElems[j += ys];
+ }
+ return sum;
+}
+/**
+ * Returns the sum of all cells; <tt>Sum( x[i] )</tt>.
+ * @return the sum.
+ */
+public double zSum() {
+ double sum = 0;
+ int s=stride;
+ int i=index(0);
+ final double[] elems = this.elements;
+ if (elems==null) throw new InternalError();
+ for (int k=size; --k >= 0; ) {
+ sum += elems[i];
+ i += s;
+ }
+ return sum;
+}
+}
Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/impl/DenseDoubleMatrix1D.java
------------------------------------------------------------------------------
svn:eol-style = native