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 [23/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/list/adapter/LongListAdapter.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/list/adapter/LongListAdapter.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/list/adapter/LongListAdapter.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/list/adapter/LongListAdapter.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,124 @@
+/*
+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.list.adapter;
+
+import org.apache.mahout.colt.list.AbstractLongList;
+/**
+ * Adapter that permits an {@link org.apache.mahout.colt.list.AbstractLongList} to be viewed and treated as a JDK 1.2 {@link java.util.AbstractList}.
+ * Makes the contained list compatible with the JDK 1.2 Collections Framework.
+ * <p>
+ * Any attempt to pass elements other than <tt>java.lang.Number</tt> to setter methods will throw a <tt>java.lang.ClassCastException</tt>.
+ * <tt>java.lang.Number.longValue()</tt> is used to convert objects into primitive values which are then stored in the backing templated list.
+ * Getter methods return <tt>java.lang.Long</tt> objects.
+ */
+/** 
+ * @deprecated until unit tests are in place.  Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public class LongListAdapter extends java.util.AbstractList implements java.util.List {
+	protected AbstractLongList content;
+/**
+ * Constructs a list backed by the specified content list.
+ */
+public LongListAdapter(AbstractLongList content) {
+	this.content = content;
+}
+/**
+ * Inserts the specified element at the specified position in this list
+ * (optional operation).  Shifts the element currently at that position
+ * (if any) and any subsequent elements to the right (adds one to their
+ * indices).<p>
+ *
+ * @param index index at which the specified element is to be inserted.
+ * @param element element to be inserted.
+ * 
+ * @throws ClassCastException if the class of the specified element
+ * 		  prevents it from being added to this list.
+ * @throws IllegalArgumentException if some aspect of the specified
+ *		  element prevents it from being added to this list.
+ * @throws IndexOutOfBoundsException index is out of range (<tt>index &lt;
+ *		  0 || index &gt; size()</tt>).
+ */
+public void add(int index, Object element) {
+	content.beforeInsert(index,value(element));
+	modCount++;
+}
+/**
+ * Returns the element at the specified position in this list.
+ *
+ * @param index index of element to return.
+ * 
+ * @return the element at the specified position in this list.
+ * @throws IndexOutOfBoundsException if the given index is out of range
+ * 		  (<tt>index &lt; 0 || index &gt;= size()</tt>).
+ */
+public Object get(int index) {
+	return object(content.get(index));
+}
+/**
+ * Transforms an element of a primitive data type to an object. 
+ */
+protected static Object object(long element) {
+	return new Long(element);
+}
+/**
+ * Removes the element at the specified position in this list (optional
+ * operation).  Shifts any subsequent elements to the left (subtracts one
+ * from their indices).  Returns the element that was removed from the
+ * list.<p>
+ *
+ * @param index the index of the element to remove.
+ * @return the element previously at the specified position.
+ * 
+ * @throws IndexOutOfBoundsException if the specified index is out of
+ * 		  range (<tt>index &lt; 0 || index &gt;= size()</tt>).
+ */
+public Object remove(int index) {
+	Object old = get(index);
+	content.remove(index);
+	modCount++;
+	return old;
+}
+/**
+ * Replaces the element at the specified position in this list with the
+ * specified element (optional operation). <p>
+ *
+ * @param index index of element to replace.
+ * @param element element to be stored at the specified position.
+ * @return the element previously at the specified position.
+ * 
+ * @throws ClassCastException if the class of the specified element
+ * 		  prevents it from being added to this list.
+ * @throws IllegalArgumentException if some aspect of the specified
+ *		  element prevents it from being added to this list.
+ * 
+ * @throws IndexOutOfBoundsException if the specified index is out of
+ *            range (<tt>index &lt; 0 || index &gt;= size()</tt>).
+ */
+
+public Object set(int index, Object element) {
+	Object old = get(index);
+	content.set(index,value(element));
+	return old;
+}
+/**
+ * Returns the number of elements in this list.
+ *
+ * @return  the number of elements in this list.
+ */
+public int size() {
+	return content.size();
+}
+/**
+ * Transforms an object element to a primitive data type. 
+ */
+protected static long value(Object element) {
+	return ((Number)element).longValue();
+}
+}

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

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/list/adapter/ObjectListAdapter.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/list/adapter/ObjectListAdapter.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/list/adapter/ObjectListAdapter.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/list/adapter/ObjectListAdapter.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,108 @@
+/*
+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.list.adapter;
+
+import org.apache.mahout.colt.list.ObjectArrayList;
+/**
+ * Adapter that permits an {@link org.apache.mahout.colt.list.ObjectArrayList} to be viewed and treated as a JDK 1.2 {@link java.util.AbstractList}.
+ * Makes the contained list compatible with the JDK 1.2 Collections Framework.
+ */
+/** 
+ * @deprecated until unit tests are in place.  Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public class ObjectListAdapter extends java.util.AbstractList implements java.util.List {
+	protected ObjectArrayList content;
+/**
+ * Constructs a list backed by the specified content list.
+ */
+public ObjectListAdapter(ObjectArrayList content) {
+	this.content = content;
+}
+/**
+ * Inserts the specified element at the specified position in this list
+ * (optional operation).  Shifts the element currently at that position
+ * (if any) and any subsequent elements to the right (adds one to their
+ * indices).<p>
+ *
+ * @param index index at which the specified element is to be inserted.
+ * @param element element to be inserted.
+ * 
+ * @throws ClassCastException if the class of the specified element
+ * 		  prevents it from being added to this list.
+ * @throws IllegalArgumentException if some aspect of the specified
+ *		  element prevents it from being added to this list.
+ * @throws IndexOutOfBoundsException index is out of range (<tt>index &lt;
+ *		  0 || index &gt; size()</tt>).
+ */
+public void add(int index, Object element) {
+	content.beforeInsert(index,element);
+	modCount++;
+}
+/**
+ * Returns the element at the specified position in this list.
+ *
+ * @param index index of element to return.
+ * 
+ * @return the element at the specified position in this list.
+ * @throws IndexOutOfBoundsException if the given index is out of range
+ * 		  (<tt>index &lt; 0 || index &gt;= size()</tt>).
+ */
+public Object get(int index) {
+	return content.get(index);
+}
+/**
+ * Removes the element at the specified position in this list (optional
+ * operation).  Shifts any subsequent elements to the left (subtracts one
+ * from their indices).  Returns the element that was removed from the
+ * list.<p>
+ *
+ * @param index the index of the element to remove.
+ * @return the element previously at the specified position.
+ * 
+ * @throws IndexOutOfBoundsException if the specified index is out of
+ * 		  range (<tt>index &lt; 0 || index &gt;= size()</tt>).
+ */
+public Object remove(int index) {
+	Object old = get(index);
+	content.remove(index);
+	modCount++;
+	return old;
+}
+/**
+ * Replaces the element at the specified position in this list with the
+ * specified element (optional operation). <p>
+ *
+ * @param index index of element to replace.
+ * @param element element to be stored at the specified position.
+ * @return the element previously at the specified position.
+ * 
+ * @throws ClassCastException if the class of the specified element
+ * 		  prevents it from being added to this list.
+ * @throws IllegalArgumentException if some aspect of the specified
+ *		  element prevents it from being added to this list.
+ * 
+ * @throws IndexOutOfBoundsException if the specified index is out of
+ *            range (<tt>index &lt; 0 || index &gt;= size()</tt>).
+ */
+
+public Object set(int index, Object element) {
+	Object old = get(index);
+	content.set(index,element);
+	return old;
+}
+/**
+ * Returns the number of elements in this list.
+ *
+ * @return  the number of elements in this list.
+ */
+public int size() {
+	return content.size();
+}
+}

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

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/list/adapter/package.html
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/list/adapter/package.html?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/list/adapter/package.html (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/list/adapter/package.html Mon Nov 23 15:14:26 2009
@@ -0,0 +1,5 @@
+<HTML>
+<BODY>
+List adapters that make Colt lists compatible with the JDK 1.2 Collections Framework.
+</BODY>
+</HTML>

Propchange: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/list/adapter/package.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/list/package.html
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/list/package.html?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/list/package.html (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/list/package.html Mon Nov 23 15:14:26 2009
@@ -0,0 +1,162 @@
+<HTML>
+<BODY>
+Resizable lists holding objects or primitive data types such as <tt>int</tt>,
+<tt>double</tt>, etc. For non-resizable lists (1-dimensional matrices) see
+package {@link cern.colt.matrix}.<p></p>
+
+<h1><a name="Overview"></a>Getting Started</h1>
+
+<h2>1. Overview</h2>
+
+<p>The list package offers flexible object oriented abstractions modelling dynamically
+  resizing lists holding objects or primitive data types such as <tt>int</tt>,
+  <tt>double</tt>, etc. It is designed to be scalable in terms of performance
+  and memory requirements.</p>
+
+<p>Features include: </p>
+
+<p></p>
+<ul>
+  <li>Lists operating on objects as well as all primitive data types such as <tt>int</tt>,
+    <tt>double</tt>, etc.
+  </li>
+  <li>Compact representations</li>
+  <li>A number of general purpose list operations including: adding, inserting,
+    removing, iterating, searching, sorting, extracting ranges and copying. All
+    operations are designed to perform well on mass data.
+  </li>
+  <li>Support for quick access to list elements. This is achieved by bounds-checking
+    and non-bounds-checking accessor methods as well as zero-copy transformations
+    to primitive arrays such as <tt>int[]</tt>, <tt>double[]</tt>, etc.
+  </li>
+  <li>Allows to use high level algorithms on primitive data types without any
+    space and time overhead. Operations on primitive arrays, Colt lists and JAL
+    algorithms can freely be mixed at zero copy overhead.
+  </li>
+</ul>
+<p>File-based I/O can be achieved through the standard Java built-in serialization
+  mechanism. All classes implement the {@link java.io.Serializable} interface.
+  However, the toolkit is entirely decoupled from advanced I/O. It provides data
+  structures and algorithms only.
+
+<p> This toolkit borrows concepts and terminology from the Javasoft <a
+        href="http://www.javasoft.com/products/jdk/1.2/docs/guide/collections/index.html">
+  Collections framework</a> written by Josh Bloch and introduced in JDK 1.2.
+
+<h2>2. Introduction</h2>
+
+<p>Lists are fundamental to virtually any application. Large scale resizable lists
+  are, for example, used in scientific computations, simulations database management
+  systems, to name just a few.</p>
+
+<h2></h2>
+
+<p>A list is a container holding elements that can be accessed via zero-based
+  indexes. Lists may be implemented in different ways (most commonly with arrays).
+  A resizable list automatically grows as elements are added. The lists of this
+  package do not automatically shrink. Shrinking needs to be triggered by explicitly
+  calling <tt>trimToSize()</tt> methods.</p>
+
+<p><i>Growing policy</i>: A list implemented with arrays initially has a certain
+  <tt>initialCapacity</tt> - per default 10 elements, but customizable upon instance
+  construction. As elements are added, this capacity may nomore be sufficient.
+  When a list is automatically grown, its capacity is expanded to <tt>1.5*currentCapacity</tt>.
+  Thus, excessive resizing (involving copying) is avoided.</p>
+<h4>Copying</h4>
+
+<p>
+
+<p>Any list can be copied. A copy is <i>equal</i> to the original but entirely
+  independent of the original. So changes in the copy are not reflected in the
+  original, and vice-versa.
+
+<h2>3. Organization of this package</h2>
+
+<p>Class naming follows the schema <tt>&lt;ElementType&gt;&lt;ImplementationTechnique&gt;List</tt>.
+  For example, we have a {@link cern.colt.list.DoubleArrayList}, which is a list
+  holding <tt>double</tt> elements implemented with <tt>double</tt>[] arrays.
+</p>
+
+<p>The classes for lists of a given value type are derived from a common abstract
+  base class tagged <tt>Abstract&lt;ElementType&gt;</tt><tt>List</tt>. For example,
+  all lists operating on <tt>double</tt> elements are derived from {@link cern.colt.list.AbstractDoubleList},
+  which in turn is derived from an abstract base class tying together all lists
+  regardless of value type, {@link cern.colt.list.AbstractList}, which finally
+  is rooted in grandmother {@link cern.colt.list.AbstractCollection}. The abstract
+  base classes provide skeleton implementations for all but few methods. Experimental
+  data layouts (such as compressed, sparse, linked, etc.) can easily be implemented
+  and inherit a rich set of functionality. Have a look at the javadoc <a href="package-tree.html">tree
+    view</a> to get the broad picture.</p>
+
+<h2>4. Example usage</h2>
+
+<p>The following snippet fills a list, randomizes it, extracts the first half
+  of the elements, sums them up and prints the result. It is implemented entirely
+  with accessor methods.</p>
+<table>
+  <td class="PRE">
+      <pre>
+int s = 1000000;<br>AbstractDoubleList list = new DoubleArrayList();
+for (int i=0; i&lt;s; i++) { list.add((double)i); }
+list.shuffle();
+AbstractDoubleList part = list.partFromTo(0,list.size()/2 - 1);
+double sum = 0.0;
+for (int i=0; i&lt;part.size(); i++) { sum += part.get(i); }
+System.out.println(sum);
+</pre>
+  </td>
+</table>
+<p> For efficiency, all classes provide back doors to enable getting/setting the
+  backing array directly. In this way, the high level operations of these classes
+  can be used where appropriate, and one can switch to <tt>[]</tt>-array index
+  notations where necessary. The key methods for this are <tt>public &lt;ElementType&gt;[]
+    elements()</tt> and <tt>public void elements(&lt;ElementType&gt;[])</tt>. The
+  former trustingly returns the array it internally keeps to store the elements.
+  Holding this array in hand, we can use the <tt>[]</tt>-array operator to
+  perform iteration over large lists without needing to copy the array or paying
+  the performance penalty introduced by accessor methods. Alternatively any JAL
+  algorithm (or other algorithm) can operate on the returned primitive array.
+  The latter method forces a list to internally hold a user provided array. Using
+  this approach one can avoid needing to copy the elements into the list.
+
+<p>As a consequence, operations on primitive arrays, Colt lists and JAL algorithms
+  can freely be mixed at zero-copy overhead.
+
+<p> Note that such special treatment certainly breaks encapsulation. This functionality
+  is provided for performance reasons only and should only be used when absolutely
+  necessary. Here is the above example in mixed notation:
+<table>
+  <td class="PRE">
+      <pre>
+int s = 1000000;<br>DoubleArrayList list = new DoubleArrayList(s); // list.size()==0, capacity==s
+list.setSize(s); // list.size()==s<br>double[] values = list.elements(); // zero copy, values.length==s<br>for (int i=0; i&lt;s; i++) { values[i]=(double)i; }
+list.shuffle();
+double sum = 0.0;
+int limit = values.length/2;
+for (int i=0; i&lt;limit; i++) { sum += values[i]; }
+System.out.println(sum);
+</pre>
+  </td>
+</table>
+<p> Or even more compact using lists as algorithm objects:
+<table>
+  <td class="PRE">
+      <pre>
+int s = 1000000;<br>double[] values = new double[s];
+for (int i=0; i&lt;s; i++) { values[i]=(double)i; }
+new DoubleArrayList(values).shuffle(); // zero-copy, shuffle via back door
+double sum = 0.0;
+int limit = values.length/2;
+for (int i=0; i&lt;limit; i++) { sum += values[i]; }
+System.out.println(sum);
+</pre>
+  </td>
+</table>
+<p>
+
+<h2>5. Notes </h2>
+
+<p>The quicksorts and mergesorts are the JDK 1.2 V1.26 algorithms, modified as
+  necessary to operate on the given data types.
+</BODY>
+</HTML>

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

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/map/AbstractDoubleIntMap.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/map/AbstractDoubleIntMap.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/map/AbstractDoubleIntMap.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/map/AbstractDoubleIntMap.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,455 @@
+/*
+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.map;
+
+import org.apache.mahout.colt.function.DoubleIntProcedure;
+import org.apache.mahout.colt.function.DoubleProcedure;
+import org.apache.mahout.colt.list.DoubleArrayList;
+import org.apache.mahout.colt.list.IntArrayList;
+/**
+Abstract base class for hash maps holding (key,value) associations of type <tt>(double-->int)</tt>.
+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>
+Almost all methods are expressed in terms of {@link #forEachKey(DoubleProcedure)}. 
+As such they are fully functional, but inefficient. Override them in subclasses if necessary.
+
+@author wolfgang.hoschek@cern.ch
+@version 1.0, 09/24/99
+@see	    java.util.HashMap
+*/
+/** 
+ * @deprecated until unit tests are in place.  Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public abstract class AbstractDoubleIntMap extends AbstractMap {
+	//public static int hashCollisions = 0; // for debug only
+/**
+ * Makes this class non instantiable, but still let's others inherit from it.
+ */
+protected AbstractDoubleIntMap() {}
+/**
+ * Returns <tt>true</tt> if the receiver contains the specified key.
+ *
+ * @return <tt>true</tt> if the receiver contains the specified key.
+ */
+public boolean containsKey(final double key) {
+	return ! forEachKey(
+		new DoubleProcedure() {
+			public boolean apply(double iterKey) {
+				return (key != iterKey);
+			}
+		}
+	);
+}
+/**
+ * Returns <tt>true</tt> if the receiver contains the specified value.
+ *
+ * @return <tt>true</tt> if the receiver contains the specified value.
+ */
+public boolean containsValue(final int value) {
+	return ! forEachPair( 
+		new DoubleIntProcedure() {
+			public boolean apply(double iterKey, int iterValue) {
+				return (value != iterValue);
+			}
+		}
+	);
+}
+/**
+ * Returns a deep copy of the receiver; uses <code>clone()</code> and casts the result.
+ *
+ * @return  a deep copy of the receiver.
+ */
+public AbstractDoubleIntMap copy() {
+	return (AbstractDoubleIntMap) clone();
+}
+/**
+ * Compares the specified object with this map for equality.  Returns
+ * <tt>true</tt> if the given object is also a map and the two maps
+ * represent the same mappings.  More formally, two maps <tt>m1</tt> and
+ * <tt>m2</tt> represent the same mappings iff
+ * <pre>
+ * m1.forEachPair(
+ *		new DoubleIntProcedure() {
+ *			public boolean apply(double key, int value) {
+ *				return m2.containsKey(key) && m2.get(key) == value;
+ *			}
+ *		}
+ *	)
+ * &&
+ * m2.forEachPair(
+ *		new DoubleIntProcedure() {
+ *			public boolean apply(double key, int value) {
+ *				return m1.containsKey(key) && m1.get(key) == value;
+ *			}
+ *		}
+ *	);
+ * </pre>
+ *
+ * This implementation first checks if the specified object is this map;
+ * if so it returns <tt>true</tt>.  Then, it checks if the specified
+ * object is a map whose size is identical to the size of this set; if
+ * not, it it returns <tt>false</tt>.  If so, it applies the iteration as described above.
+ *
+ * @param obj object to be compared for equality with this map.
+ * @return <tt>true</tt> if the specified object is equal to this map.
+ */
+public boolean equals(Object obj) {
+	if (obj == this) return true;
+
+	if (!(obj instanceof AbstractDoubleIntMap)) return false;
+	final AbstractDoubleIntMap other = (AbstractDoubleIntMap) obj;
+	if (other.size() != size()) return false;
+
+	return 
+		forEachPair(
+			new DoubleIntProcedure() {
+				public boolean apply(double key, int value) {
+					return other.containsKey(key) && other.get(key) == value;
+				}
+			}
+		)
+		&&
+		other.forEachPair(
+			new DoubleIntProcedure() {
+				public boolean apply(double key, int value) {
+					return containsKey(key) && get(key) == value;
+				}
+			}
+		);
+}
+/**
+ * Applies a procedure to each key of the receiver, if any.
+ * Note: Iterates over the keys in no particular order.
+ * Subclasses can define a particular order, for example, "sorted by key".
+ * All methods which <i>can</i> be expressed in terms of this method (most methods can) <i>must guarantee</i> to use the <i>same</i> order defined by this method, even if it is no particular order.
+ * This is necessary so that, for example, methods <tt>keys</tt> and <tt>values</tt> will yield association pairs, not two uncorrelated lists.
+ *
+ * @param procedure    the procedure to be applied. Stops iteration if the procedure returns <tt>false</tt>, otherwise continues. 
+ * @return <tt>false</tt> if the procedure stopped before all keys where iterated over, <tt>true</tt> otherwise. 
+ */
+public abstract boolean forEachKey(DoubleProcedure procedure);
+/**
+ * Applies a procedure to each (key,value) pair of the receiver, if any.
+ * Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(DoubleProcedure)}.
+ *
+ * @param procedure    the procedure to be applied. Stops iteration if the procedure returns <tt>false</tt>, otherwise continues. 
+ * @return <tt>false</tt> if the procedure stopped before all keys where iterated over, <tt>true</tt> otherwise. 
+ */
+public boolean forEachPair(final DoubleIntProcedure procedure) {
+	return forEachKey(
+		new DoubleProcedure() {
+			public boolean apply(double key) {
+				return procedure.apply(key,get(key));
+			}
+		}
+	);
+}
+/**
+ * Returns the value associated with the specified key.
+ * It is often a good idea to first check with {@link #containsKey(double)} whether the given key has a value associated or not, i.e. whether there exists an association for the given key or not.
+ *
+ * @param key the key to be searched for.
+ * @return the value associated with the specified key; <tt>0</tt> if no such key is present.
+ */
+public abstract int get(double key);
+/**
+ * Returns the first key the given value is associated with.
+ * It is often a good idea to first check with {@link #containsValue(int)} whether there exists an association from a key to this value.
+ * Search order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(DoubleProcedure)}.
+ *
+ * @param value the value to search for.
+ * @return the first key for which holds <tt>get(key) == value</tt>; 
+ *		   returns <tt>Double.NaN</tt> if no such key exists.
+ */
+public double keyOf(final int value) {
+	final double[] foundKey = new double[1];
+	boolean notFound = forEachPair(
+		new DoubleIntProcedure() {
+			public boolean apply(double iterKey, int iterValue) {
+				boolean found = value == iterValue;
+				if (found) foundKey[0] = iterKey;
+				return !found;
+			}
+		}
+	);
+	if (notFound) return Double.NaN;
+	return foundKey[0];
+}
+/**
+ * Returns a list filled with all keys contained in the receiver.
+ * The returned list has a size that equals <tt>this.size()</tt>.
+ * Note: Keys are filled into the list in no particular order.
+ * However, the order is <i>identical</i> to the order used by method {@link #forEachKey(DoubleProcedure)}.
+ * <p>
+ * This method can be used to iterate over the keys of the receiver.
+ *
+ * @return the keys.
+ */
+public DoubleArrayList keys() {
+	DoubleArrayList list = new DoubleArrayList(size());
+	keys(list);
+	return list;
+}
+/**
+ * Fills all keys contained in the receiver into the specified list.
+ * Fills the list, starting at index 0.
+ * After this call returns the specified list has a new size that equals <tt>this.size()</tt>.
+ * Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(DoubleProcedure)}.
+ * <p>
+ * This method can be used to iterate over the keys of the receiver.
+ *
+ * @param list the list to be filled, can have any size.
+ */
+public void keys(final DoubleArrayList list) {
+	list.clear();
+	forEachKey(
+		new DoubleProcedure() {
+			public boolean apply(double key) {
+				list.add(key);
+				return true;
+			}
+		}
+	);
+}
+/**
+ * Fills all keys <i>sorted ascending by their associated value</i> into the specified list.
+ * Fills into the list, starting at index 0.
+ * After this call returns the specified list has a new size that equals <tt>this.size()</tt>.
+ * Primary sort criterium is "value", secondary sort criterium is "key". 
+ * This means that if any two values are equal, the smaller key comes first.
+ * <p>
+ * <b>Example:</b>
+ * <br>
+ * <tt>keys = (8,7,6), values = (1,2,2) --> keyList = (8,6,7)</tt>
+ *
+ * @param keyList the list to be filled, can have any size.
+ */
+public void keysSortedByValue(final DoubleArrayList keyList) {
+	pairsSortedByValue(keyList, new IntArrayList(size()));
+}
+/**
+Fills all pairs satisfying a given condition into the specified lists.
+Fills into the lists, starting at index 0.
+After this call returns the specified lists both have a new size, the number of pairs satisfying the condition.
+Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(DoubleProcedure)}.
+<p>
+<b>Example:</b>
+<br>
+<pre>
+DoubleIntProcedure condition = new DoubleIntProcedure() { // match even values only
+	public boolean apply(double key, int value) { return value%2==0; }
+}
+keys = (8,7,6), values = (1,2,2) --> keyList = (6,8), valueList = (2,1)</tt>
+</pre>
+
+@param condition    the condition to be matched. Takes the current key as first and the current value as second argument.
+@param keyList the list to be filled with keys, can have any size.
+@param valueList the list to be filled with values, can have any size.
+*/
+public void pairsMatching(final DoubleIntProcedure condition, final DoubleArrayList keyList, final IntArrayList valueList) {
+	keyList.clear();
+	valueList.clear();
+	
+	forEachPair(
+		new DoubleIntProcedure() {
+			public boolean apply(double key, int value) {
+				if (condition.apply(key,value)) {
+					keyList.add(key);
+					valueList.add(value);
+				}
+				return true;
+			}
+		}
+	);
+}
+/**
+ * Fills all keys and values <i>sorted ascending by key</i> into the specified lists.
+ * Fills into the lists, starting at index 0.
+ * After this call returns the specified lists both have a new size that equals <tt>this.size()</tt>.
+ * <p>
+ * <b>Example:</b>
+ * <br>
+ * <tt>keys = (8,7,6), values = (1,2,2) --> keyList = (6,7,8), valueList = (2,2,1)</tt>
+ *
+ * @param keyList the list to be filled with keys, can have any size.
+ * @param valueList the list to be filled with values, can have any size.
+ */
+public void pairsSortedByKey(final DoubleArrayList keyList, final IntArrayList valueList) {
+	/*
+	keys(keyList); 
+	values(valueList);
+	
+	final double[] k = keyList.elements();
+	final int[] v = valueList.elements();
+	org.apache.mahout.colt.Swapper swapper = new org.apache.mahout.colt.Swapper() {
+		public void swap(int a, int b) {
+			int t1;	double t2;
+			t1 = v[a]; v[a] = v[b]; v[b] = t1;
+			t2 = k[a]; k[a] = k[b];	k[b] = t2;
+		}
+	}; 
+
+	org.apache.mahout.colt.function.IntComparator comp = new org.apache.mahout.colt.function.IntComparator() {
+		public int compare(int a, int b) {
+			return k[a]<k[b] ? -1 : k[a]==k[b] ? 0 : 1;
+		}
+	};
+	org.apache.mahout.colt.MultiSorting.sort(0,keyList.size(),comp,swapper);
+	*/	
+	
+
+	
+	// this variant may be quicker
+	//org.apache.mahout.colt.map.OpenDoubleIntHashMap.hashCollisions = 0;
+	//System.out.println("collisions="+org.apache.mahout.colt.map.OpenDoubleIntHashMap.hashCollisions);
+	keys(keyList);
+	keyList.sort();
+	valueList.setSize(keyList.size());
+	for (int i=keyList.size(); --i >= 0; ) {
+		valueList.setQuick(i,get(keyList.getQuick(i)));
+	}
+	//System.out.println("collisions="+org.apache.mahout.colt.map.OpenDoubleIntHashMap.hashCollisions);
+	
+}
+/**
+ * Fills all keys and values <i>sorted ascending by value</i> into the specified lists.
+ * Fills into the lists, starting at index 0.
+ * After this call returns the specified lists both have a new size that equals <tt>this.size()</tt>.
+ * Primary sort criterium is "value", secondary sort criterium is "key". 
+ * This means that if any two values are equal, the smaller key comes first.
+ * <p>
+ * <b>Example:</b>
+ * <br>
+ * <tt>keys = (8,7,6), values = (1,2,2) --> keyList = (8,6,7), valueList = (1,2,2)</tt>
+ *
+ * @param keyList the list to be filled with keys, can have any size.
+ * @param valueList the list to be filled with values, can have any size.
+ */
+public void pairsSortedByValue(final DoubleArrayList keyList, final IntArrayList valueList) {
+	keys(keyList);
+	values(valueList);
+	
+	final double[] k = keyList.elements();
+	final int[] v = valueList.elements();
+	org.apache.mahout.colt.Swapper swapper = new org.apache.mahout.colt.Swapper() {
+		public void swap(int a, int b) {
+			int t1;	double t2;
+			t1 = v[a]; v[a] = v[b]; v[b] = t1;
+			t2 = k[a]; k[a] = k[b];	k[b] = t2;
+		}
+	}; 
+
+	org.apache.mahout.colt.function.IntComparator comp = new org.apache.mahout.colt.function.IntComparator() {
+		public int compare(int a, int b) {
+			return v[a]<v[b] ? -1 : v[a]>v[b] ? 1 : (k[a]<k[b] ? -1 : (k[a]==k[b] ? 0 : 1));
+		}
+	};
+
+	//org.apache.mahout.colt.map.OpenDoubleIntHashMap.hashCollisions = 0;
+	org.apache.mahout.colt.GenericSorting.quickSort(0,keyList.size(),comp,swapper);
+	//System.out.println("collisions="+org.apache.mahout.colt.map.OpenDoubleIntHashMap.hashCollisions);
+}
+/**
+ * Associates the given key with the given value.
+ * Replaces any old <tt>(key,someOtherValue)</tt> association, if existing.
+ *
+ * @param key the key the value shall be associated with.
+ * @param value the value to be associated.
+ * @return <tt>true</tt> if the receiver did not already contain such a key;
+ *         <tt>false</tt> if the receiver did already contain such a key - the new value has now replaced the formerly associated value.
+ */
+public abstract boolean put(double key, int value);
+/**
+ * Removes the given key with its associated element from the receiver, if present.
+ *
+ * @param key the key to be removed from the receiver.
+ * @return <tt>true</tt> if the receiver contained the specified key, <tt>false</tt> otherwise.
+ */
+public abstract boolean removeKey(double key);
+/**
+ * Returns a string representation of the receiver, containing
+ * the String representation of each key-value pair, sorted ascending by key.
+ */
+public String toString() {
+	DoubleArrayList theKeys = keys();
+	theKeys.sort();
+
+	StringBuffer buf = new StringBuffer();
+	buf.append("[");
+	int maxIndex = theKeys.size() - 1;
+	for (int i = 0; i <= maxIndex; i++) {
+		double key = theKeys.get(i);
+	    buf.append(String.valueOf(key));
+		buf.append("->");
+	    buf.append(String.valueOf(get(key)));
+		if (i < maxIndex) buf.append(", ");
+	}
+	buf.append("]");
+	return buf.toString();
+}
+/**
+ * Returns a string representation of the receiver, containing
+ * the String representation of each key-value pair, sorted ascending by value.
+ */
+public String toStringByValue() {
+	DoubleArrayList theKeys = new DoubleArrayList();
+	keysSortedByValue(theKeys);
+
+	StringBuffer buf = new StringBuffer();
+	buf.append("[");
+	int maxIndex = theKeys.size() - 1;
+	for (int i = 0; i <= maxIndex; i++) {
+		double key = theKeys.get(i);
+	    buf.append(String.valueOf(key));
+		buf.append("->");
+	    buf.append(String.valueOf(get(key)));
+		if (i < maxIndex) buf.append(", ");
+	}
+	buf.append("]");
+	return buf.toString();
+}
+/**
+ * Returns a list filled with all values contained in the receiver.
+ * The returned list has a size that equals <tt>this.size()</tt>.
+ * Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(DoubleProcedure)}.
+ * <p>
+ * This method can be used to iterate over the values of the receiver.
+ *
+ * @return the values.
+ */
+public IntArrayList values() {
+	IntArrayList list = new IntArrayList(size());
+	values(list);
+	return list;
+}
+/**
+ * Fills all values contained in the receiver into the specified list.
+ * Fills the list, starting at index 0.
+ * After this call returns the specified list has a new size that equals <tt>this.size()</tt>.
+ * Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(DoubleProcedure)}.
+ * <p>
+ * This method can be used to iterate over the values of the receiver.
+ *
+ * @param list the list to be filled, can have any size.
+ */
+public void values(final IntArrayList list) {
+	list.clear();
+	forEachKey(
+		new DoubleProcedure() {
+			public boolean apply(double key) {
+				list.add(get(key));
+				return true;
+			}
+		}
+	);
+}
+}

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

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/map/AbstractIntDoubleMap.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/map/AbstractIntDoubleMap.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/map/AbstractIntDoubleMap.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/map/AbstractIntDoubleMap.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,456 @@
+/*
+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.map;
+
+import org.apache.mahout.colt.function.IntDoubleProcedure;
+import org.apache.mahout.colt.function.IntProcedure;
+import org.apache.mahout.colt.list.DoubleArrayList;
+import org.apache.mahout.colt.list.IntArrayList;
+/**
+Abstract base class for hash maps holding (key,value) associations of type <tt>(int-->double)</tt>.
+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>
+Almost all methods are expressed in terms of {@link #forEachKey(IntProcedure)}. 
+As such they are fully functional, but inefficient. Override them in subclasses if necessary.
+
+@author wolfgang.hoschek@cern.ch
+@version 1.0, 09/24/99
+@see	    java.util.HashMap
+*/
+/** 
+ * @deprecated until unit tests are in place.  Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public abstract class AbstractIntDoubleMap extends AbstractMap {
+	//public static int hashCollisions = 0; // for debug only
+/**
+ * Makes this class non instantiable, but still let's others inherit from it.
+ */
+protected AbstractIntDoubleMap() {}
+/**
+Assigns the result of a function to each value; <tt>v[i] = function(v[i])</tt>.
+
+@param function a function object taking as argument the current association's value.
+*/
+public void assign(final org.apache.mahout.colt.function.DoubleFunction function) {
+	copy().forEachPair(
+		new org.apache.mahout.colt.function.IntDoubleProcedure() {
+			public boolean apply(int key, double value) {
+				put(key,function.apply(value));
+				return true;
+			}
+		}
+	);
+}
+/**
+ * Clears the receiver, then adds all (key,value) pairs of <tt>other</tt>values to it.
+ *
+ * @param other the other map to be copied into the receiver.
+ */
+public void assign(AbstractIntDoubleMap other) {
+	clear();
+	other.forEachPair(
+		new IntDoubleProcedure() {
+			public boolean apply(int key, double value) {
+				put(key,value);
+				return true;
+			}
+		}
+	);
+}
+/**
+ * Returns <tt>true</tt> if the receiver contains the specified key.
+ *
+ * @return <tt>true</tt> if the receiver contains the specified key.
+ */
+public boolean containsKey(final int key) {
+	return ! forEachKey(
+		new IntProcedure() {
+			public boolean apply(int iterKey) {
+				return (key != iterKey);
+			}
+		}
+	);
+}
+/**
+ * Returns <tt>true</tt> if the receiver contains the specified value.
+ *
+ * @return <tt>true</tt> if the receiver contains the specified value.
+ */
+public boolean containsValue(final double value) {
+	return ! forEachPair( 
+		new IntDoubleProcedure() {
+			public boolean apply(int iterKey, double iterValue) {
+				return (value != iterValue);
+			}
+		}
+	);
+}
+/**
+ * Returns a deep copy of the receiver; uses <code>clone()</code> and casts the result.
+ *
+ * @return  a deep copy of the receiver.
+ */
+public AbstractIntDoubleMap copy() {
+	return (AbstractIntDoubleMap) clone();
+}
+/**
+ * Compares the specified object with this map for equality.  Returns
+ * <tt>true</tt> if the given object is also a map and the two maps
+ * represent the same mappings.  More formally, two maps <tt>m1</tt> and
+ * <tt>m2</tt> represent the same mappings iff
+ * <pre>
+ * m1.forEachPair(
+ *		new IntDoubleProcedure() {
+ *			public boolean apply(int key, double value) {
+ *				return m2.containsKey(key) && m2.get(key) == value;
+ *			}
+ *		}
+ *	)
+ * &&
+ * m2.forEachPair(
+ *		new IntDoubleProcedure() {
+ *			public boolean apply(int key, double value) {
+ *				return m1.containsKey(key) && m1.get(key) == value;
+ *			}
+ *		}
+ *	);
+ * </pre>
+ *
+ * This implementation first checks if the specified object is this map;
+ * if so it returns <tt>true</tt>.  Then, it checks if the specified
+ * object is a map whose size is identical to the size of this set; if
+ * not, it it returns <tt>false</tt>.  If so, it applies the iteration as described above.
+ *
+ * @param obj object to be compared for equality with this map.
+ * @return <tt>true</tt> if the specified object is equal to this map.
+ */
+public boolean equals(Object obj) {
+	if (obj == this) return true;
+
+	if (!(obj instanceof AbstractIntDoubleMap)) return false;
+	final AbstractIntDoubleMap other = (AbstractIntDoubleMap) obj;
+	if (other.size() != size()) return false;
+
+	return 
+		forEachPair(
+			new IntDoubleProcedure() {
+				public boolean apply(int key, double value) {
+					return other.containsKey(key) && other.get(key) == value;
+				}
+			}
+		)
+		&&
+		other.forEachPair(
+			new IntDoubleProcedure() {
+				public boolean apply(int key, double value) {
+					return containsKey(key) && get(key) == value;
+				}
+			}
+		);
+}
+/**
+ * Applies a procedure to each key of the receiver, if any.
+ * Note: Iterates over the keys in no particular order.
+ * Subclasses can define a particular order, for example, "sorted by key".
+ * All methods which <i>can</i> be expressed in terms of this method (most methods can) <i>must guarantee</i> to use the <i>same</i> order defined by this method, even if it is no particular order.
+ * This is necessary so that, for example, methods <tt>keys</tt> and <tt>values</tt> will yield association pairs, not two uncorrelated lists.
+ *
+ * @param procedure    the procedure to be applied. Stops iteration if the procedure returns <tt>false</tt>, otherwise continues. 
+ * @return <tt>false</tt> if the procedure stopped before all keys where iterated over, <tt>true</tt> otherwise. 
+ */
+public abstract boolean forEachKey(IntProcedure procedure);
+/**
+ * Applies a procedure to each (key,value) pair of the receiver, if any.
+ * Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+ *
+ * @param procedure    the procedure to be applied. Stops iteration if the procedure returns <tt>false</tt>, otherwise continues. 
+ * @return <tt>false</tt> if the procedure stopped before all keys where iterated over, <tt>true</tt> otherwise. 
+ */
+public boolean forEachPair(final IntDoubleProcedure procedure) {
+	return forEachKey(
+		new IntProcedure() {
+			public boolean apply(int key) {
+				return procedure.apply(key,get(key));
+			}
+		}
+	);
+}
+/**
+ * Returns the value associated with the specified key.
+ * It is often a good idea to first check with {@link #containsKey(int)} whether the given key has a value associated or not, i.e. whether there exists an association for the given key or not.
+ *
+ * @param key the key to be searched for.
+ * @return the value associated with the specified key; <tt>0</tt> if no such key is present.
+ */
+public abstract double get(int key);
+/**
+ * Returns the first key the given value is associated with.
+ * It is often a good idea to first check with {@link #containsValue(double)} whether there exists an association from a key to this value.
+ * Search order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+ *
+ * @param value the value to search for.
+ * @return the first key for which holds <tt>get(key) == value</tt>; 
+ *		   returns <tt>Integer.MIN_VALUE</tt> if no such key exists.
+ */
+public int keyOf(final double value) {
+	final int[] foundKey = new int[1];
+	boolean notFound = forEachPair(
+		new IntDoubleProcedure() {
+			public boolean apply(int iterKey, double iterValue) {
+				boolean found = value == iterValue;
+				if (found) foundKey[0] = iterKey;
+				return !found;
+			}
+		}
+	);
+	if (notFound) return Integer.MIN_VALUE;
+	return foundKey[0];
+}
+/**
+ * Returns a list filled with all keys contained in the receiver.
+ * The returned list has a size that equals <tt>this.size()</tt>.
+ * Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+ * <p>
+ * This method can be used to iterate over the keys of the receiver.
+ *
+ * @return the keys.
+ */
+public IntArrayList keys() {
+	IntArrayList list = new IntArrayList(size());
+	keys(list);
+	return list;
+}
+/**
+ * Fills all keys contained in the receiver into the specified list.
+ * Fills the list, starting at index 0.
+ * After this call returns the specified list has a new size that equals <tt>this.size()</tt>.
+ * Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+ * <p>
+ * This method can be used to iterate over the keys of the receiver.
+ *
+ * @param list the list to be filled, can have any size.
+ */
+public void keys(final IntArrayList list) {
+	list.clear();
+	forEachKey(
+		new IntProcedure() {
+			public boolean apply(int key) {
+				list.add(key);
+				return true;
+			}
+		}
+	);
+}
+/**
+ * Fills all keys <i>sorted ascending by their associated value</i> into the specified list.
+ * Fills into the list, starting at index 0.
+ * After this call returns the specified list has a new size that equals <tt>this.size()</tt>.
+ * Primary sort criterium is "value", secondary sort criterium is "key". 
+ * This means that if any two values are equal, the smaller key comes first.
+ * <p>
+ * <b>Example:</b>
+ * <br>
+ * <tt>keys = (8,7,6), values = (1,2,2) --> keyList = (8,6,7)</tt>
+ *
+ * @param keyList the list to be filled, can have any size.
+ */
+public void keysSortedByValue(final IntArrayList keyList) {
+	pairsSortedByValue(keyList, new DoubleArrayList(size()));
+}
+/**
+Fills all pairs satisfying a given condition into the specified lists.
+Fills into the lists, starting at index 0.
+After this call returns the specified lists both have a new size, the number of pairs satisfying the condition.
+Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+<p>
+<b>Example:</b>
+<br>
+<pre>
+IntDoubleProcedure condition = new IntDoubleProcedure() { // match even keys only
+	public boolean apply(int key, double value) { return key%2==0; }
+}
+keys = (8,7,6), values = (1,2,2) --> keyList = (6,8), valueList = (2,1)</tt>
+</pre>
+
+@param condition    the condition to be matched. Takes the current key as first and the current value as second argument.
+@param keyList the list to be filled with keys, can have any size.
+@param valueList the list to be filled with values, can have any size.
+*/
+public void pairsMatching(final IntDoubleProcedure condition, final IntArrayList keyList, final DoubleArrayList valueList) {
+	keyList.clear();
+	valueList.clear();
+	
+	forEachPair(
+		new IntDoubleProcedure() {
+			public boolean apply(int key, double value) {
+				if (condition.apply(key,value)) {
+					keyList.add(key);
+					valueList.add(value);
+				}
+				return true;
+			}
+		}
+	);
+}
+/**
+ * Fills all keys and values <i>sorted ascending by key</i> into the specified lists.
+ * Fills into the lists, starting at index 0.
+ * After this call returns the specified lists both have a new size that equals <tt>this.size()</tt>.
+ * <p>
+ * <b>Example:</b>
+ * <br>
+ * <tt>keys = (8,7,6), values = (1,2,2) --> keyList = (6,7,8), valueList = (2,2,1)</tt>
+ *
+ * @param keyList the list to be filled with keys, can have any size.
+ * @param valueList the list to be filled with values, can have any size.
+ */
+public void pairsSortedByKey(final IntArrayList keyList, final DoubleArrayList valueList) {
+	keys(keyList);
+	keyList.sort();
+	valueList.setSize(keyList.size());
+	for (int i=keyList.size(); --i >= 0; ) {
+		valueList.setQuick(i,get(keyList.getQuick(i)));
+	}
+}
+/**
+ * Fills all keys and values <i>sorted ascending by value</i> into the specified lists.
+ * Fills into the lists, starting at index 0.
+ * After this call returns the specified lists both have a new size that equals <tt>this.size()</tt>.
+ * Primary sort criterium is "value", secondary sort criterium is "key". 
+ * This means that if any two values are equal, the smaller key comes first.
+ * <p>
+ * <b>Example:</b>
+ * <br>
+ * <tt>keys = (8,7,6), values = (1,2,2) --> keyList = (8,6,7), valueList = (1,2,2)</tt>
+ *
+ * @param keyList the list to be filled with keys, can have any size.
+ * @param valueList the list to be filled with values, can have any size.
+ */
+public void pairsSortedByValue(final IntArrayList keyList, final DoubleArrayList valueList) {
+	keys(keyList);
+	values(valueList);
+	
+	final int[] k = keyList.elements();
+	final double[] v = valueList.elements();
+	org.apache.mahout.colt.Swapper swapper = new org.apache.mahout.colt.Swapper() {
+		public void swap(int a, int b) {
+			int t2;	double t1;
+			t1 = v[a]; v[a] = v[b]; v[b] = t1;
+			t2 = k[a]; k[a] = k[b];	k[b] = t2;
+		}
+	}; 
+
+	org.apache.mahout.colt.function.IntComparator comp = new org.apache.mahout.colt.function.IntComparator() {
+		public int compare(int a, int b) {
+			return v[a]<v[b] ? -1 : v[a]>v[b] ? 1 : (k[a]<k[b] ? -1 : (k[a]==k[b] ? 0 : 1));
+		}
+	};
+
+	org.apache.mahout.colt.GenericSorting.quickSort(0,keyList.size(),comp,swapper);
+}
+/**
+ * Associates the given key with the given value.
+ * Replaces any old <tt>(key,someOtherValue)</tt> association, if existing.
+ *
+ * @param key the key the value shall be associated with.
+ * @param value the value to be associated.
+ * @return <tt>true</tt> if the receiver did not already contain such a key;
+ *         <tt>false</tt> if the receiver did already contain such a key - the new value has now replaced the formerly associated value.
+ */
+public abstract boolean put(int key, double value);
+/**
+ * Removes the given key with its associated element from the receiver, if present.
+ *
+ * @param key the key to be removed from the receiver.
+ * @return <tt>true</tt> if the receiver contained the specified key, <tt>false</tt> otherwise.
+ */
+public abstract boolean removeKey(int key);
+/**
+ * Returns a string representation of the receiver, containing
+ * the String representation of each key-value pair, sorted ascending by key.
+ */
+public String toString() {
+	IntArrayList theKeys = keys();
+	String tmp = theKeys.toString() + "\n";
+	theKeys.sort();
+
+	StringBuffer buf = new StringBuffer(tmp);
+	//StringBuffer buf = new StringBuffer();
+	buf.append("[");
+	int maxIndex = theKeys.size() - 1;
+	for (int i = 0; i <= maxIndex; i++) {
+		int key = theKeys.get(i);
+	    buf.append(String.valueOf(key));
+		buf.append("->");
+	    buf.append(String.valueOf(get(key)));
+		if (i < maxIndex) buf.append(", ");
+	}
+	buf.append("]");
+	return buf.toString();
+}
+/**
+ * Returns a string representation of the receiver, containing
+ * the String representation of each key-value pair, sorted ascending by value.
+ */
+public String toStringByValue() {
+	IntArrayList theKeys = new IntArrayList();
+	keysSortedByValue(theKeys);
+
+	StringBuffer buf = new StringBuffer();
+	buf.append("[");
+	int maxIndex = theKeys.size() - 1;
+	for (int i = 0; i <= maxIndex; i++) {
+		int key = theKeys.get(i);
+	    buf.append(String.valueOf(key));
+		buf.append("->");
+	    buf.append(String.valueOf(get(key)));
+		if (i < maxIndex) buf.append(", ");
+	}
+	buf.append("]");
+	return buf.toString();
+}
+/**
+ * Returns a list filled with all values contained in the receiver.
+ * The returned list has a size that equals <tt>this.size()</tt>.
+ * Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+ * <p>
+ * This method can be used to iterate over the values of the receiver.
+ *
+ * @return the values.
+ */
+public DoubleArrayList values() {
+	DoubleArrayList list = new DoubleArrayList(size());
+	values(list);
+	return list;
+}
+/**
+ * Fills all values contained in the receiver into the specified list.
+ * Fills the list, starting at index 0.
+ * After this call returns the specified list has a new size that equals <tt>this.size()</tt>.
+ * Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+ * <p>
+ * This method can be used to iterate over the values of the receiver.
+ *
+ * @param list the list to be filled, can have any size.
+ */
+public void values(final DoubleArrayList list) {
+	list.clear();
+	forEachKey(
+		new IntProcedure() {
+			public boolean apply(int key) {
+				list.add(get(key));
+				return true;
+			}
+		}
+	);
+}
+}

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

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/map/AbstractIntIntMap.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/map/AbstractIntIntMap.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/map/AbstractIntIntMap.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/map/AbstractIntIntMap.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,422 @@
+/*
+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.map;
+
+import org.apache.mahout.colt.function.IntIntProcedure;
+import org.apache.mahout.colt.function.IntProcedure;
+import org.apache.mahout.colt.list.IntArrayList;
+/**
+Abstract base class for hash maps holding (key,value) associations of type <tt>(int-->int)</tt>.
+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>
+Almost all methods are expressed in terms of {@link #forEachKey(IntProcedure)}. 
+As such they are fully functional, but inefficient. Override them in subclasses if necessary.
+
+@author wolfgang.hoschek@cern.ch
+@version 1.0, 09/24/99
+@see	    java.util.HashMap
+*/
+/** 
+ * @deprecated until unit tests are in place.  Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public abstract class AbstractIntIntMap extends AbstractMap {
+	//public static int hashCollisions = 0; // for debug only
+/**
+ * Makes this class non instantiable, but still let's others inherit from it.
+ */
+protected AbstractIntIntMap() {}
+/**
+ * Returns <tt>true</tt> if the receiver contains the specified key.
+ *
+ * @return <tt>true</tt> if the receiver contains the specified key.
+ */
+public boolean containsKey(final int key) {
+	return ! forEachKey(
+		new IntProcedure() {
+			public boolean apply(int iterKey) {
+				return (key != iterKey);
+			}
+		}
+	);
+}
+/**
+ * Returns <tt>true</tt> if the receiver contains the specified value.
+ *
+ * @return <tt>true</tt> if the receiver contains the specified value.
+ */
+public boolean containsValue(final int value) {
+	return ! forEachPair(
+		new IntIntProcedure() {
+			public boolean apply(int iterKey, int iterValue) {
+				return (value != iterValue);
+			}
+		}
+	);
+}
+/**
+ * Returns a deep copy of the receiver; uses <code>clone()</code> and casts the result.
+ *
+ * @return  a deep copy of the receiver.
+ */
+public AbstractIntIntMap copy() {
+	return (AbstractIntIntMap) clone();
+}
+/**
+ * Compares the specified object with this map for equality.  Returns
+ * <tt>true</tt> if the given object is also a map and the two maps
+ * represent the same mappings.  More formally, two maps <tt>m1</tt> and
+ * <tt>m2</tt> represent the same mappings iff
+ * <pre>
+ * m1.forEachPair(
+ *		new IntIntProcedure() {
+ *			public boolean apply(int key, int value) {
+ *				return m2.containsKey(key) && m2.get(key) == value;
+ *			}
+ *		}
+ *	)
+ * &&
+ * m2.forEachPair(
+ *		new IntIntProcedure() {
+ *			public boolean apply(int key, int value) {
+ *				return m1.containsKey(key) && m1.get(key) == value;
+ *			}
+ *		}
+ *	);
+ * </pre>
+ *
+ * This implementation first checks if the specified object is this map;
+ * if so it returns <tt>true</tt>.  Then, it checks if the specified
+ * object is a map whose size is identical to the size of this set; if
+ * not, it it returns <tt>false</tt>.  If so, it applies the iteration as described above.
+ *
+ * @param obj object to be compared for equality with this map.
+ * @return <tt>true</tt> if the specified object is equal to this map.
+ */
+public boolean equals(Object obj) {
+	if (obj == this) return true;
+
+	if (!(obj instanceof AbstractIntIntMap)) return false;
+	final AbstractIntIntMap other = (AbstractIntIntMap) obj;
+	if (other.size() != size()) return false;
+
+	return 
+		forEachPair(
+			new IntIntProcedure() {
+				public boolean apply(int key, int value) {
+					return other.containsKey(key) && other.get(key) == value;
+				}
+			}
+		)
+		&&
+		other.forEachPair(
+			new IntIntProcedure() {
+				public boolean apply(int key, int value) {
+					return containsKey(key) && get(key) == value;
+				}
+			}
+		);
+}
+/**
+ * Applies a procedure to each key of the receiver, if any.
+ * Note: Iterates over the keys in no particular order.
+ * Subclasses can define a particular order, for example, "sorted by key".
+ * All methods which <i>can</i> be expressed in terms of this method (most methods can) <i>must guarantee</i> to use the <i>same</i> order defined by this method, even if it is no particular order.
+ * This is necessary so that, for example, methods <tt>keys</tt> and <tt>values</tt> will yield association pairs, not two uncorrelated lists.
+ *
+ * @param procedure    the procedure to be applied. Stops iteration if the procedure returns <tt>false</tt>, otherwise continues. 
+ * @return <tt>false</tt> if the procedure stopped before all keys where iterated over, <tt>true</tt> otherwise. 
+ */
+public abstract boolean forEachKey(IntProcedure procedure);
+/**
+ * Applies a procedure to each (key,value) pair of the receiver, if any.
+ * Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+ *
+ * @param procedure    the procedure to be applied. Stops iteration if the procedure returns <tt>false</tt>, otherwise continues. 
+ * @return <tt>false</tt> if the procedure stopped before all keys where iterated over, <tt>true</tt> otherwise. 
+ */
+public boolean forEachPair(final IntIntProcedure procedure) {
+	return forEachKey(
+		new IntProcedure() {
+			public boolean apply(int key) {
+				return procedure.apply(key,get(key));
+			}
+		}
+	);
+}
+/**
+ * Returns the value associated with the specified key.
+ * It is often a good idea to first check with {@link #containsKey(int)} whether the given key has a value associated or not, i.e. whether there exists an association for the given key or not.
+ *
+ * @param key the key to be searched for.
+ * @return the value associated with the specified key; <tt>0</tt> if no such key is present.
+ */
+public abstract int get(int key);
+/**
+ * Returns the first key the given value is associated with.
+ * It is often a good idea to first check with {@link #containsValue(int)} whether there exists an association from a key to this value.
+ * Search order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+ *
+ * @param value the value to search for.
+ * @return the first key for which holds <tt>get(key) == value</tt>; 
+ *		   returns <tt>Integer.MIN_VALUE</tt> if no such key exists.
+ */
+public int keyOf(final int value) {
+	final int[] foundKey = new int[1];
+	boolean notFound = forEachPair(
+		new IntIntProcedure() {
+			public boolean apply(int iterKey, int iterValue) {
+				boolean found = value == iterValue;
+				if (found) foundKey[0] = iterKey;
+				return !found;
+			}
+		}
+	);
+	if (notFound) return Integer.MIN_VALUE;
+	return foundKey[0];
+}
+/**
+ * Returns a list filled with all keys contained in the receiver.
+ * The returned list has a size that equals <tt>this.size()</tt>.
+ * Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+ * <p>
+ * This method can be used to iterate over the keys of the receiver.
+ *
+ * @return the keys.
+ */
+public IntArrayList keys() {
+	IntArrayList list = new IntArrayList(size());
+	keys(list);
+	return list;
+}
+/**
+ * Fills all keys contained in the receiver into the specified list.
+ * Fills the list, starting at index 0.
+ * After this call returns the specified list has a new size that equals <tt>this.size()</tt>.
+ * Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+ * <p>
+ * This method can be used to iterate over the keys of the receiver.
+ *
+ * @param list the list to be filled, can have any size.
+ */
+public void keys(final IntArrayList list) {
+	list.clear();
+	forEachKey(
+		new IntProcedure() {
+			public boolean apply(int key) {
+				list.add(key);
+				return true;
+			}
+		}
+	);
+}
+/**
+ * Fills all keys <i>sorted ascending by their associated value</i> into the specified list.
+ * Fills into the list, starting at index 0.
+ * After this call returns the specified list has a new size that equals <tt>this.size()</tt>.
+ * Primary sort criterium is "value", secondary sort criterium is "key". 
+ * This means that if any two values are equal, the smaller key comes first.
+ * <p>
+ * <b>Example:</b>
+ * <br>
+ * <tt>keys = (8,7,6), values = (1,2,2) --> keyList = (8,6,7)</tt>
+ *
+ * @param keyList the list to be filled, can have any size.
+ */
+public void keysSortedByValue(final IntArrayList keyList) {
+	pairsSortedByValue(keyList, new IntArrayList(size()));
+}
+/**
+Fills all pairs satisfying a given condition into the specified lists.
+Fills into the lists, starting at index 0.
+After this call returns the specified lists both have a new size, the number of pairs satisfying the condition.
+Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+<p>
+<b>Example:</b>
+<br>
+<pre>
+IntIntProcedure condition = new IntIntProcedure() { // match even keys only
+	public boolean apply(int key, int value) { return key%2==0; }
+}
+keys = (8,7,6), values = (1,2,2) --> keyList = (6,8), valueList = (2,1)</tt>
+</pre>
+
+@param condition    the condition to be matched. Takes the current key as first and the current value as second argument.
+@param keyList the list to be filled with keys, can have any size.
+@param valueList the list to be filled with values, can have any size.
+*/
+public void pairsMatching(final IntIntProcedure condition, final IntArrayList keyList, final IntArrayList valueList) {
+	keyList.clear();
+	valueList.clear();
+	
+	forEachPair(
+		new IntIntProcedure() {
+			public boolean apply(int key, int value) {
+				if (condition.apply(key,value)) {
+					keyList.add(key);
+					valueList.add(value);
+				}
+				return true;
+			}
+		}
+	);
+}
+/**
+ * Fills all keys and values <i>sorted ascending by key</i> into the specified lists.
+ * Fills into the lists, starting at index 0.
+ * After this call returns the specified lists both have a new size that equals <tt>this.size()</tt>.
+ * <p>
+ * <b>Example:</b>
+ * <br>
+ * <tt>keys = (8,7,6), values = (1,2,2) --> keyList = (6,7,8), valueList = (2,2,1)</tt>
+ *
+ * @param keyList the list to be filled with keys, can have any size.
+ * @param valueList the list to be filled with values, can have any size.
+ */
+public void pairsSortedByKey(final IntArrayList keyList, final IntArrayList valueList) {
+	keys(keyList);
+	keyList.sort();
+	valueList.setSize(keyList.size());
+	for (int i=keyList.size(); --i >= 0; ) {
+		valueList.setQuick(i,get(keyList.getQuick(i)));
+	}
+}
+/**
+ * Fills all keys and values <i>sorted ascending by value</i> into the specified lists.
+ * Fills into the lists, starting at index 0.
+ * After this call returns the specified lists both have a new size that equals <tt>this.size()</tt>.
+ * Primary sort criterium is "value", secondary sort criterium is "key". 
+ * This means that if any two values are equal, the smaller key comes first.
+ * <p>
+ * <b>Example:</b>
+ * <br>
+ * <tt>keys = (8,7,6), values = (1,2,2) --> keyList = (8,6,7), valueList = (1,2,2)</tt>
+ *
+ * @param keyList the list to be filled with keys, can have any size.
+ * @param valueList the list to be filled with values, can have any size.
+ */
+public void pairsSortedByValue(final IntArrayList keyList, final IntArrayList valueList) {
+	keys(keyList);
+	values(valueList);
+	
+	final int[] k = keyList.elements();
+	final int[] v = valueList.elements();
+	org.apache.mahout.colt.Swapper swapper = new org.apache.mahout.colt.Swapper() {
+		public void swap(int a, int b) {
+			int t2;	int t1;
+			t1 = v[a]; v[a] = v[b]; v[b] = t1;
+			t2 = k[a]; k[a] = k[b];	k[b] = t2;
+		}
+	}; 
+
+	org.apache.mahout.colt.function.IntComparator comp = new org.apache.mahout.colt.function.IntComparator() {
+		public int compare(int a, int b) {
+			return v[a]<v[b] ? -1 : v[a]>v[b] ? 1 : (k[a]<k[b] ? -1 : (k[a]==k[b] ? 0 : 1));
+		}
+	};
+
+	org.apache.mahout.colt.GenericSorting.quickSort(0,keyList.size(),comp,swapper);
+}
+/**
+ * Associates the given key with the given value.
+ * Replaces any old <tt>(key,someOtherValue)</tt> association, if existing.
+ *
+ * @param key the key the value shall be associated with.
+ * @param value the value to be associated.
+ * @return <tt>true</tt> if the receiver did not already contain such a key;
+ *         <tt>false</tt> if the receiver did already contain such a key - the new value has now replaced the formerly associated value.
+ */
+public abstract boolean put(int key, int value);
+/**
+ * Removes the given key with its associated element from the receiver, if present.
+ *
+ * @param key the key to be removed from the receiver.
+ * @return <tt>true</tt> if the receiver contained the specified key, <tt>false</tt> otherwise.
+ */
+public abstract boolean removeKey(int key);
+/**
+ * Returns a string representation of the receiver, containing
+ * the String representation of each key-value pair, sorted ascending by key.
+ */
+public String toString() {
+	IntArrayList theKeys = keys();
+	//theKeys.sort(); 
+
+	StringBuffer buf = new StringBuffer();
+	buf.append("[");
+	int maxIndex = theKeys.size() - 1;
+	for (int i = 0; i <= maxIndex; i++) {
+		int key = theKeys.get(i);
+	    buf.append(String.valueOf(key));
+		buf.append("->");
+	    buf.append(String.valueOf(get(key)));
+		if (i < maxIndex) buf.append(", ");
+	}
+	buf.append("]");
+	return buf.toString();
+}
+/**
+ * Returns a string representation of the receiver, containing
+ * the String representation of each key-value pair, sorted ascending by value.
+ */
+public String toStringByValue() {
+	IntArrayList theKeys = new IntArrayList();
+	keysSortedByValue(theKeys);
+
+	StringBuffer buf = new StringBuffer();
+	buf.append("[");
+	int maxIndex = theKeys.size() - 1;
+	for (int i = 0; i <= maxIndex; i++) {
+		int key = theKeys.get(i);
+	    buf.append(String.valueOf(key));
+		buf.append("->");
+	    buf.append(String.valueOf(get(key)));
+		if (i < maxIndex) buf.append(", ");
+	}
+	buf.append("]");
+	return buf.toString();
+}
+/**
+ * Returns a list filled with all values contained in the receiver.
+ * The returned list has a size that equals <tt>this.size()</tt>.
+ * Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+ * <p>
+ * This method can be used to iterate over the values of the receiver.
+ *
+ * @return the values.
+ */
+public IntArrayList values() {
+	IntArrayList list = new IntArrayList(size());
+	values(list);
+	return list;
+}
+/**
+ * Fills all values contained in the receiver into the specified list.
+ * Fills the list, starting at index 0.
+ * After this call returns the specified list has a new size that equals <tt>this.size()</tt>.
+ * Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+ * <p>
+ * This method can be used to iterate over the values of the receiver.
+ *
+ * @param list the list to be filled, can have any size.
+ */
+public void values(final IntArrayList list) {
+	list.clear();
+	forEachKey(
+		new IntProcedure() {
+			public boolean apply(int key) {
+				list.add(get(key));
+				return true;
+			}
+		}
+	);
+}
+}

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

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/map/AbstractIntObjectMap.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/map/AbstractIntObjectMap.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/map/AbstractIntObjectMap.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/map/AbstractIntObjectMap.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,426 @@
+/*
+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.map;
+
+import org.apache.mahout.colt.function.IntObjectProcedure;
+import org.apache.mahout.colt.function.IntProcedure;
+import org.apache.mahout.colt.list.IntArrayList;
+import org.apache.mahout.colt.list.ObjectArrayList;
+/**
+Abstract base class for hash maps holding (key,value) associations of type <tt>(int-->Object)</tt>.
+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>
+Almost all methods are expressed in terms of {@link #forEachKey(IntProcedure)}. 
+As such they are fully functional, but inefficient. Override them in subclasses if necessary.
+
+@author wolfgang.hoschek@cern.ch
+@version 1.0, 09/24/99
+@see	    java.util.HashMap
+*/
+/** 
+ * @deprecated until unit tests are in place.  Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public abstract class AbstractIntObjectMap extends AbstractMap {
+	//public static int hashCollisions = 0; // for debug only
+/**
+ * Makes this class non instantiable, but still let's others inherit from it.
+ */
+protected AbstractIntObjectMap() {}
+/**
+ * Returns <tt>true</tt> if the receiver contains the specified key.
+ *
+ * @return <tt>true</tt> if the receiver contains the specified key.
+ */
+public boolean containsKey(final int key) {
+	return ! forEachKey(
+		new IntProcedure() {
+			public boolean apply(int iterKey) {
+				return (key != iterKey);
+			}
+		}
+	);
+}
+/**
+ * Returns <tt>true</tt> if the receiver contains the specified value.
+ * Tests for identity.
+ *
+ * @return <tt>true</tt> if the receiver contains the specified value.
+ */
+public boolean containsValue(final Object value) {
+	return ! forEachPair( 
+		new IntObjectProcedure() {
+			public boolean apply(int iterKey, Object iterValue) {
+				return (value != iterValue);
+			}
+		}
+	);
+}
+/**
+ * Returns a deep copy of the receiver; uses <code>clone()</code> and casts the result.
+ *
+ * @return  a deep copy of the receiver.
+ */
+public AbstractIntObjectMap copy() {
+	return (AbstractIntObjectMap) clone();
+}
+/**
+ * Compares the specified object with this map for equality.  Returns
+ * <tt>true</tt> if the given object is also a map and the two maps
+ * represent the same mappings.  More formally, two maps <tt>m1</tt> and
+ * <tt>m2</tt> represent the same mappings iff
+ * <pre>
+ * m1.forEachPair(
+ *		new IntObjectProcedure() {
+ *			public boolean apply(int key, Object value) {
+ *				return m2.containsKey(key) && m2.get(key) == value;
+ *			}
+ *		}
+ *	)
+ * &&
+ * m2.forEachPair(
+ *		new IntObjectProcedure() {
+ *			public boolean apply(int key, Object value) {
+ *				return m1.containsKey(key) && m1.get(key) == value;
+ *			}
+ *		}
+ *	);
+ * </pre>
+ *
+ * This implementation first checks if the specified object is this map;
+ * if so it returns <tt>true</tt>.  Then, it checks if the specified
+ * object is a map whose size is identical to the size of this set; if
+ * not, it it returns <tt>false</tt>.  If so, it applies the iteration as described above.
+ *
+ * @param obj object to be compared for equality with this map.
+ * @return <tt>true</tt> if the specified object is equal to this map.
+ */
+public boolean equals(Object obj) {
+	if (obj == this) return true;
+
+	if (!(obj instanceof AbstractIntObjectMap)) return false;
+	final AbstractIntObjectMap other = (AbstractIntObjectMap) obj;
+	if (other.size() != size()) return false;
+
+	return 
+		forEachPair(
+			new IntObjectProcedure() {
+				public boolean apply(int key, Object value) {
+					return other.containsKey(key) && other.get(key) == value;
+				}
+			}
+		)
+		&&
+		other.forEachPair(
+			new IntObjectProcedure() {
+				public boolean apply(int key, Object value) {
+					return containsKey(key) && get(key) == value;
+				}
+			}
+		);
+}
+/**
+ * Applies a procedure to each key of the receiver, if any.
+ * Note: Iterates over the keys in no particular order.
+ * Subclasses can define a particular order, for example, "sorted by key".
+ * All methods which <i>can</i> be expressed in terms of this method (most methods can) <i>must guarantee</i> to use the <i>same</i> order defined by this method, even if it is no particular order.
+ * This is necessary so that, for example, methods <tt>keys</tt> and <tt>values</tt> will yield association pairs, not two uncorrelated lists.
+ *
+ * @param procedure    the procedure to be applied. Stops iteration if the procedure returns <tt>false</tt>, otherwise continues. 
+ * @return <tt>false</tt> if the procedure stopped before all keys where iterated over, <tt>true</tt> otherwise. 
+ */
+public abstract boolean forEachKey(IntProcedure procedure);
+/**
+ * Applies a procedure to each (key,value) pair of the receiver, if any.
+ * Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+ *
+ * @param procedure    the procedure to be applied. Stops iteration if the procedure returns <tt>false</tt>, otherwise continues. 
+ * @return <tt>false</tt> if the procedure stopped before all keys where iterated over, <tt>true</tt> otherwise. 
+ */
+public boolean forEachPair(final IntObjectProcedure procedure) {
+	return forEachKey(
+		new IntProcedure() {
+			public boolean apply(int key) {
+				return procedure.apply(key,get(key));
+			}
+		}
+	);
+}
+/**
+ * Returns the value associated with the specified key.
+ * It is often a good idea to first check with {@link #containsKey(int)} whether the given key has a value associated or not, i.e. whether there exists an association for the given key or not.
+ *
+ * @param key the key to be searched for.
+ * @return the value associated with the specified key; <tt>null</tt> if no such key is present.
+ */
+public abstract Object get(int key);
+/**
+ * Returns the first key the given value is associated with.
+ * It is often a good idea to first check with {@link #containsValue(Object)} whether there exists an association from a key to this value.
+ * Search order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+ *
+ * @param value the value to search for.
+ * @return the first key for which holds <tt>get(key) == value</tt>; 
+ *		   returns <tt>Integer.MIN_VALUE</tt> if no such key exists.
+ */
+public int keyOf(final Object value) {
+	final int[] foundKey = new int[1];
+	boolean notFound = forEachPair(
+		new IntObjectProcedure() {
+			public boolean apply(int iterKey, Object iterValue) {
+				boolean found = value == iterValue;
+				if (found) foundKey[0] = iterKey;
+				return !found;
+			}
+		}
+	);
+	if (notFound) return Integer.MIN_VALUE;
+	return foundKey[0];
+}
+/**
+ * Returns a list filled with all keys contained in the receiver.
+ * The returned list has a size that equals <tt>this.size()</tt>.
+ * Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+ * <p>
+ * This method can be used to iterate over the keys of the receiver.
+ *
+ * @return the keys.
+ */
+public IntArrayList keys() {
+	IntArrayList list = new IntArrayList(size());
+	keys(list);
+	return list;
+}
+/**
+ * Fills all keys contained in the receiver into the specified list.
+ * Fills the list, starting at index 0.
+ * After this call returns the specified list has a new size that equals <tt>this.size()</tt>.
+ * Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+ * <p>
+ * This method can be used to iterate over the keys of the receiver.
+ *
+ * @param list the list to be filled, can have any size.
+ */
+public void keys(final IntArrayList list) {
+	list.clear();
+	forEachKey(
+		new IntProcedure() {
+			public boolean apply(int key) {
+				list.add(key);
+				return true;
+			}
+		}
+	);
+}
+/**
+ * Fills all keys <i>sorted ascending by their associated value</i> into the specified list.
+ * Fills into the list, starting at index 0.
+ * After this call returns the specified list has a new size that equals <tt>this.size()</tt>.
+ * Primary sort criterium is "value", secondary sort criterium is "key". 
+ * This means that if any two values are equal, the smaller key comes first.
+ * <p>
+ * <b>Example:</b>
+ * <br>
+ * <tt>keys = (8,7,6), values = (1,2,2) --> keyList = (8,6,7)</tt>
+ *
+ * @param keyList the list to be filled, can have any size.
+ */
+public void keysSortedByValue(final IntArrayList keyList) {
+	pairsSortedByValue(keyList, new ObjectArrayList(size()));
+}
+/**
+Fills all pairs satisfying a given condition into the specified lists.
+Fills into the lists, starting at index 0.
+After this call returns the specified lists both have a new size, the number of pairs satisfying the condition.
+Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+<p>
+<b>Example:</b>
+<br>
+<pre>
+IntObjectProcedure condition = new IntObjectProcedure() { // match even keys only
+	public boolean apply(int key, Object value) { return key%2==0; }
+}
+keys = (8,7,6), values = (1,2,2) --> keyList = (6,8), valueList = (2,1)</tt>
+</pre>
+
+@param condition    the condition to be matched. Takes the current key as first and the current value as second argument.
+@param keyList the list to be filled with keys, can have any size.
+@param valueList the list to be filled with values, can have any size.
+*/
+public void pairsMatching(final IntObjectProcedure condition, final IntArrayList keyList, final ObjectArrayList valueList) {
+	keyList.clear();
+	valueList.clear();
+	
+	forEachPair(
+		new IntObjectProcedure() {
+			public boolean apply(int key, Object value) {
+				if (condition.apply(key,value)) {
+					keyList.add(key);
+					valueList.add(value);
+				}
+				return true;
+			}
+		}
+	);
+}
+/**
+ * Fills all keys and values <i>sorted ascending by key</i> into the specified lists.
+ * Fills into the lists, starting at index 0.
+ * After this call returns the specified lists both have a new size that equals <tt>this.size()</tt>.
+ * <p>
+ * <b>Example:</b>
+ * <br>
+ * <tt>keys = (8,7,6), values = (1,2,2) --> keyList = (6,7,8), valueList = (2,2,1)</tt>
+ *
+ * @param keyList the list to be filled with keys, can have any size.
+ * @param valueList the list to be filled with values, can have any size.
+ */
+public void pairsSortedByKey(final IntArrayList keyList, final ObjectArrayList valueList) {
+	keys(keyList);
+	keyList.sort();
+	valueList.setSize(keyList.size());
+	for (int i=keyList.size(); --i >= 0; ) {
+		valueList.setQuick(i,get(keyList.getQuick(i)));
+	}
+}
+/**
+ * Fills all keys and values <i>sorted ascending by value according to natural ordering</i> into the specified lists.
+ * Fills into the lists, starting at index 0.
+ * After this call returns the specified lists both have a new size that equals <tt>this.size()</tt>.
+ * Primary sort criterium is "value", secondary sort criterium is "key". 
+ * This means that if any two values are equal, the smaller key comes first.
+ * <p>
+ * <b>Example:</b>
+ * <br>
+ * <tt>keys = (8,7,6), values = (1,2,2) --> keyList = (8,6,7), valueList = (1,2,2)</tt>
+ *
+ * @param keyList the list to be filled with keys, can have any size.
+ * @param valueList the list to be filled with values, can have any size.
+ */
+public void pairsSortedByValue(final IntArrayList keyList, final ObjectArrayList valueList) {
+	keys(keyList);
+	values(valueList);
+	
+	final int[] k = keyList.elements();
+	final Object[] v = valueList.elements();
+	org.apache.mahout.colt.Swapper swapper = new org.apache.mahout.colt.Swapper() {
+		public void swap(int a, int b) {
+			int t2;	Object t1;
+			t1 = v[a]; v[a] = v[b]; v[b] = t1;
+			t2 = k[a]; k[a] = k[b];	k[b] = t2;
+		}
+	}; 
+
+	org.apache.mahout.colt.function.IntComparator comp = new org.apache.mahout.colt.function.IntComparator() {
+		public int compare(int a, int b) {
+			int ab = ((Comparable)v[a]).compareTo((Comparable)v[b]);
+			return ab<0 ? -1 : ab>0 ? 1 : (k[a]<k[b] ? -1 : (k[a]==k[b] ? 0 : 1));
+			//return v[a]<v[b] ? -1 : v[a]>v[b] ? 1 : (k[a]<k[b] ? -1 : (k[a]==k[b] ? 0 : 1));
+		}
+	};
+
+	org.apache.mahout.colt.GenericSorting.quickSort(0,keyList.size(),comp,swapper);
+}
+/**
+ * Associates the given key with the given value.
+ * Replaces any old <tt>(key,someOtherValue)</tt> association, if existing.
+ *
+ * @param key the key the value shall be associated with.
+ * @param value the value to be associated.
+ * @return <tt>true</tt> if the receiver did not already contain such a key;
+ *         <tt>false</tt> if the receiver did already contain such a key - the new value has now replaced the formerly associated value.
+ */
+public abstract boolean put(int key, Object value);
+/**
+ * Removes the given key with its associated element from the receiver, if present.
+ *
+ * @param key the key to be removed from the receiver.
+ * @return <tt>true</tt> if the receiver contained the specified key, <tt>false</tt> otherwise.
+ */
+public abstract boolean removeKey(int key);
+/**
+ * Returns a string representation of the receiver, containing
+ * the String representation of each key-value pair, sorted ascending by key.
+ */
+public String toString() {
+	IntArrayList theKeys = keys();
+	theKeys.sort();
+
+	StringBuffer buf = new StringBuffer();
+	buf.append("[");
+	int maxIndex = theKeys.size() - 1;
+	for (int i = 0; i <= maxIndex; i++) {
+		int key = theKeys.get(i);
+	    buf.append(String.valueOf(key));
+		buf.append("->");
+	    buf.append(String.valueOf(get(key)));
+		if (i < maxIndex) buf.append(", ");
+	}
+	buf.append("]");
+	return buf.toString();
+}
+/**
+ * Returns a string representation of the receiver, containing
+ * the String representation of each key-value pair, sorted ascending by value, according to natural ordering.
+ */
+public String toStringByValue() {
+	IntArrayList theKeys = new IntArrayList();
+	keysSortedByValue(theKeys);
+
+	StringBuffer buf = new StringBuffer();
+	buf.append("[");
+	int maxIndex = theKeys.size() - 1;
+	for (int i = 0; i <= maxIndex; i++) {
+		int key = theKeys.get(i);
+	    buf.append(String.valueOf(key));
+		buf.append("->");
+	    buf.append(String.valueOf(get(key)));
+		if (i < maxIndex) buf.append(", ");
+	}
+	buf.append("]");
+	return buf.toString();
+}
+/**
+ * Returns a list filled with all values contained in the receiver.
+ * The returned list has a size that equals <tt>this.size()</tt>.
+ * Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+ * <p>
+ * This method can be used to iterate over the values of the receiver.
+ *
+ * @return the values.
+ */
+public ObjectArrayList values() {
+	ObjectArrayList list = new ObjectArrayList(size());
+	values(list);
+	return list;
+}
+/**
+ * Fills all values contained in the receiver into the specified list.
+ * Fills the list, starting at index 0.
+ * After this call returns the specified list has a new size that equals <tt>this.size()</tt>.
+ * Iteration order is guaranteed to be <i>identical</i> to the order used by method {@link #forEachKey(IntProcedure)}.
+ * <p>
+ * This method can be used to iterate over the values of the receiver.
+ *
+ * @param list the list to be filled, can have any size.
+ */
+public void values(final ObjectArrayList list) {
+	list.clear();
+	forEachKey(
+		new IntProcedure() {
+			public boolean apply(int key) {
+				list.add(get(key));
+				return true;
+			}
+		}
+	);
+}
+}

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