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 [26/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/map/package.html
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/map/package.html?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/map/package.html (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/map/package.html Mon Nov 23 15:14:26 2009
@@ -0,0 +1,290 @@
+<HTML>
+<BODY>
+Automatically growing and shrinking maps holding objects or primitive
+data types such as <tt>int</tt>, <tt>double</tt>, etc. Currently all maps are
+based upon hashing.
+<h2><a name="Overview"></a>1. Overview</h2>
+
+<p>The map package offers flexible object oriented abstractions modelling automatically
+  resizing maps. It is designed to be scalable in terms of performance and memory
+  requirements.</p>
+
+<p>Features include: </p>
+
+<p></p>
+<ul>
+  <li>Maps operating on objects as well as all primitive data types such as <code>int</code>,
+    <code>double</code>, etc.
+  </li>
+  <li>Compact representations</li>
+  <li>Support for quick access to associations</li>
+  <li>A number of general purpose map operations</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 some 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>A map is an associative container that manages a set of (key,value) pairs.
+  It is useful for implementing a collection of one-to-one mappings. A (key,value)
+  pair is called an <i>association</i>. A value can be looked up up via its key.
+  Associations can quickly be set, removed and retrieved. They are stored in a
+  hashing structure based on the hash code of their keys, which is obtained by
+  using a hash function. </p>
+
+<p> A map can, for example, contain <tt>Name-->Location</tt> associations like
+  <tt>{("Pete", "Geneva"), ("Steve", "Paris"), ("Robert", "New York")}</tt> used
+  in address books or <tt>Index-->Value</tt> mappings like <tt>{(0, 100), (3,
+    1000), (100000, 70)}</tt> representing sparse lists or matrices. For example
+  this could mean at index 0 we have a value of 100, at index 3 we have a value
+  of 1000, at index 1000000 we have a value of 70, and at all other indexes we
+  have a value of, say, zero. Another example is a map of IP addresses to domain
+  names (DNS). Maps can also be useful to represent<i> multi sets</i>, that is,
+  sets where elements can occur more than once. For multi sets one would have
+  <tt>Value-->Frequency</tt> mappings like <tt>{(100, 1), (50, 1000), (101, 3))}</tt>
+  meaning element 100 occurs 1 time, element 50 occurs 1000 times, element 101
+  occurs 3 times. Further, maps can also manage <tt>ObjectIdentifier-->Object</tt>
+  mappings like <tt>{(12, obj1), (7, obj2), (10000, obj3), (9, obj4)}</tt> used
+  in Object Databases.
+
+<p> A map cannot contain two or more <i>equal</i> keys; a key can map to at most
+  one value. However, more than one key can map to identical values. For primitive
+  data types "equality" of keys is defined as identity (operator <tt>==</tt>).
+  For maps using <tt>Object</tt> keys, the meaning of "equality" can be specified
+  by the user upon instance construction. It can either be defined to be identity
+  (operator <tt>==</tt>) or to be given by the method {@link java.lang.Object#equals(Object)}.
+  Associations of kind <tt>(AnyType,Object)</tt> can be of the form <tt>(AnyKey,null)
+  </tt>, i.e. values can be <tt>null</tt>.
+
+<p> The classes of this package make no guarantees as to the order of the elements
+  returned by iterators; in particular, they do not guarantee that the order will
+  remain constant over time.
+
+<h2></h2>
+<h4>Copying</h4>
+
+<p>
+
+<p>Any map 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. Package organization</h2>
+
+<p>For most primitive data types and for objects there exists a separate map version.
+  All versions are just the same, except that they operate on different data types.
+  Colt includes two kinds of implementations for maps: The two different implementations
+  are tagged <b>Chained</b> and <b>Open</b>.
+  Note: Chained is no more included. Wherever it is mentioned it is of historic interest only.</p>
+<ul>
+  <li><b>Chained</b> uses extendible separate chaining with chains holding unsorted
+    dynamically linked collision lists.
+  <li><b>Open</b> uses extendible open addressing with double hashing.
+</ul>
+<p>Class naming follows the schema <tt>&lt;Implementation&gt;&lt;KeyType&gt;&lt;ValueType&gt;HashMap</tt>.
+  For example, a {@link cern.colt.map.OpenIntDoubleHashMap} holds <tt>(int-->double)</tt>
+  associations and is implemented with open addressing. A {@link cern.colt.map.OpenIntObjectHashMap}
+  holds <tt>(int-->Object)</tt> associations and is implemented with open addressing.
+</p>
+
+<p>The classes for maps of a given (key,value) type are derived from a common
+  abstract base class tagged <tt>Abstract&lt;KeyType&gt;&lt;ValueType&gt;</tt><tt>Map</tt>.
+  For example, all maps operating on <tt>(int-->double)</tt> associations are
+  derived from {@link cern.colt.map.AbstractIntDoubleMap}, which in turn is derived
+  from an abstract base class tying together all maps regardless of assocation
+  type, {@link cern.colt.map.AbstractMap}. The abstract base classes provide skeleton
+  implementations for all but few methods. Experimental layouts (such as chaining,
+  open addressing, extensible hashing, red-black-trees, 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>
+<TABLE>
+  <TD CLASS="PRE">
+      <PRE>
+int[]    keys   = {0    , 3     , 100000, 9   };
+double[] values = {100.0, 1000.0, 70.0  , 71.0};
+
+AbstractIntDoubleMap map = new OpenIntDoubleHashMap();
+
+// add several associations
+for (int i=0; i &lt; keys.length; i++) map.put(keys[i], values[i]);
+
+System.out.println("map="+map);
+System.out.println("size="+map.size());
+System.out.println(map.containsKey(3));
+System.out.println("get(3)="+map.get(3));
+System.out.println(map.containsKey(4));
+System.out.println("get(4)="+map.get(4));
+System.out.println(map.containsValue(71.0));
+System.out.println("keyOf(71.0)="+map.keyOf(71.0));
+
+// remove one association
+map.removeKey(3);
+System.out.println("\nmap="+map);
+System.out.println(map.containsKey(3));
+System.out.println("get(3)="+map.get(3));
+System.out.println(map.containsValue(1000.0));
+System.out.println("keyOf(1000.0)="+map.keyOf(1000.0));
+
+// clear
+map.clear();
+System.out.println("\nmap="+map);
+System.out.println("size="+map.size());
+</PRE>
+  </TD>
+</TABLE>
+
+yields the following output
+
+<TABLE>
+  <TD CLASS="PRE">
+<PRE>
+map=[0->100.0, 3->1000.0, 9->71.0, 100000->70.0]
+size=4
+true
+get(3)=1000.0
+false
+get(4)=0.0
+true
+keyOf(71.0)=9
+
+map=[0->100.0, 9->71.0, 100000->70.0]
+false
+get(3)=0.0
+false
+keyOf(1000.0)=-2147483648
+
+map=[]
+size=0
+</PRE>
+  </TD>
+</TABLE>
+<h2> 5. Notes </h2>
+
+<p>
+  Note that implementations are not synchronized.
+
+<p>
+  Choosing efficient parameters for hash maps is not always easy.
+  However, since parameters determine efficiency and memory requirements, here is a quick guide how to choose them.
+  If your use case does not heavily operate on hash maps but uses them just because they provide
+  convenient functionality, you can safely skip this section.
+  For those of you who care, read on.
+
+<p>
+
+  There are three parameters that can be customized upon map construction: <tt>initialCapacity</tt>,
+  <tt>minLoadFactor</tt> and <tt>maxLoadFactor</tt>.
+  The more memory one can afford, the faster a hash map.
+  The hash map's capacity is the maximum number of associations that can be added without needing to allocate new
+  internal memory.
+  A larger capacity means faster adding, searching and removing.
+  The <tt>initialCapacity</tt> corresponds to the capacity used upon instance construction.
+
+<p>
+  The <tt>loadFactor</tt> of a hash map measures the degree of "fullness".
+  It is given by the number of assocations (<tt>size()</tt>)
+  divided by the hash map capacity <tt>(0.0 &lt;= loadFactor &lt;= 1.0)</tt>.
+  The more associations are added, the larger the loadFactor and the more hash map performance degrades.
+  Therefore, when the loadFactor exceeds a customizable threshold (<tt>maxLoadFactor</tt>), the hash map is
+  automatically grown.
+  In such a way performance degradation can be avoided.
+  Similarly, when the loadFactor falls below a customizable threshold (<tt>minLoadFactor</tt>), the hash map is
+  automatically shrinked.
+  In such a way excessive memory consumption can be avoided.
+  Automatic resizing (both growing and shrinking) obeys the following invariant:
+
+<p>
+  <tt>capacity * minLoadFactor <= size() <= capacity * maxLoadFactor</tt>
+
+<p> The term <tt>capacity * minLoadFactor</tt> is called the <i>low water mark</i>,
+  <tt>capacity * maxLoadFactor</tt> is called the <i>high water mark</i>. In other
+  words, the number of associations may vary within the water mark constraints.
+  When it goes out of range, the map is automatically resized and memory consumption
+  changes proportionally.
+<ul>
+  <li>To tune for memory at the expense of performance, both increase <tt>minLoadFactor</tt> and <tt>maxLoadFactor</tt>.
+  <li>To tune for performance at the expense of memory, both decrease <tt>minLoadFactor</tt> and <tt>maxLoadFactor</tt>.
+    As as special case set <tt>minLoadFactor=0</tt> to avoid any automatic shrinking.
+</ul>
+Resizing large hash maps can be time consuming, <tt>O(size())</tt>, and should be avoided if possible (maintaining
+primes is not the reason).
+Unnecessary growing operations can be avoided if the number of associations is known before they are added, or can be
+estimated.<p>
+  In such a case good parameters are as follows:
+
+<p>
+  <i>For chaining:</i>
+  <br>Set the <tt>initialCapacity = 1.4*expectedSize</tt> or greater.
+  <br>Set the <tt>maxLoadFactor = 0.8</tt> or greater.
+
+<p>
+  <i>For open addressing:</i>
+  <br>Set the <tt>initialCapacity = 2*expectedSize</tt> or greater. Alternatively call <tt>ensureCapacity(...)</tt>.
+  <br>Set the <tt>maxLoadFactor = 0.5</tt>.
+  <br>Never set <tt>maxLoadFactor &gt; 0.55</tt>; open addressing exponentially slows down beyond that point.
+
+<p>
+  In this way the hash map will never need to grow and still stay fast.
+  It is never a good idea to set <tt>maxLoadFactor &lt; 0.1</tt>,
+  because the hash map would grow too often.
+  If it is entirelly unknown how many associations the application will use,
+  the default constructor should be used. The map will grow and shrink as needed.
+
+<p>
+
+  <b>Comparision of chaining and open addressing</b>
+
+<p> Chaining is faster than open addressing, when assuming unconstrained memory
+  consumption. Open addressing is more space efficient than chaining, because
+  it does not create entry objects but uses primitive arrays which are considerably
+  smaller. Entry objects consume significant amounts of memory compared to the
+  information they actually hold. Open addressing also poses no problems to the
+  garbage collector. In contrast, chaining can create millions of entry objects
+  which are linked; a nightmare for any garbage collector. In addition, entry
+  object creation is a bit slow. <br>
+  Therefore, with the same amount of memory, or even less memory, hash maps with
+  larger capacity can be maintained under open addressing, which yields smaller
+  loadFactors, which in turn keeps performance competitive with chaining. In our
+  benchmarks, using significantly less memory, open addressing usually is not
+  more than 1.2-1.5 times slower than chaining.
+
+<p><b>Further readings</b>:
+  <br>Knuth D., The Art of Computer Programming: Searching and Sorting, 3rd ed.
+  <br>Griswold W., Townsend G., The Design and Implementation of Dynamic Hashing for Sets and Tables in Icon, Software -
+  Practice and Experience, Vol. 23(4), 351-367 (April 1993).
+  <br>Larson P., Dynamic hash tables, Comm. of the ACM, 31, (4), 1988.
+
+<p>
+  <b>Performance:</b>
+
+<p>
+  Time complexity:
+  <br>The classes offer <i>expected</i> time complexity <tt>O(1)</tt> (i.e. constant time) for the basic operations
+  <tt>put</tt>, <tt>get</tt>, <tt>removeKey</tt>, <tt>containsKey</tt> and <tt>size</tt>,
+  assuming the hash function disperses the elements properly among the buckets.
+  Otherwise, pathological cases, although highly improbable, can occur, degrading performance to <tt>O(N)</tt> in the
+  worst case.
+  Operations <tt>containsValue</tt> and <tt>keyOf</tt> are <tt>O(N)</tt>.
+
+<p>
+  Memory requirements for <i>open addressing</i>:
+  <br>worst case: <tt>memory [bytes] = (1/minLoadFactor) * size() * (1 + sizeOf(key) + sizeOf(value))</tt>.
+  <br>best case: <tt>memory [bytes] = (1/maxLoadFactor) * size() * (1 + sizeOf(key) + sizeOf(value))</tt>.
+  Where <tt>sizeOf(int) = 4</tt>, <tt>sizeOf(double) = 8</tt>, <tt>sizeOf(Object) = 4</tt>, etc.
+  Thus, an <tt>OpenIntIntHashMap</tt> with minLoadFactor=0.25 and maxLoadFactor=0.5 and 1000000 associations uses
+  between 17 MB and 34 MB.
+  The same map with 1000 associations uses between 17 and 34 KB.
+
+<p>
+
+</BODY>
+</HTML>
+

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

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleFactory1D.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleFactory1D.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleFactory1D.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleFactory1D.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,205 @@
+/*
+Copyright � 1999 CERN - European Organization for Nuclear Research.
+Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose 
+is hereby granted without fee, provided that the above copyright notice appear in all copies and 
+that both that copyright notice and this permission notice appear in supporting documentation. 
+CERN makes no representations about the suitability of this software for any purpose. 
+It is provided "as is" without expressed or implied warranty.
+*/
+package org.apache.mahout.colt.matrix;
+
+import org.apache.mahout.colt.matrix.impl.DenseDoubleMatrix1D;
+import org.apache.mahout.colt.matrix.impl.SparseDoubleMatrix1D;
+/**
+Factory for convenient construction of 1-d matrices holding <tt>double</tt> cells.
+Use idioms like <tt>DoubleFactory1D.dense.make(1000)</tt> to construct dense matrices, 
+<tt>DoubleFactory1D.sparse.make(1000)</tt> to construct sparse matrices.
+
+If the factory is used frequently it might be useful to streamline the notation. 
+For example by aliasing:
+<table>
+<td class="PRE"> 
+<pre>
+DoubleFactory1D F = DoubleFactory1D.dense;
+F.make(1000);
+F.descending(10);
+F.random(3);
+...
+</pre>
+</td>
+</table>
+
+@author wolfgang.hoschek@cern.ch
+@version 1.0, 09/24/99
+*/
+/** 
+ * @deprecated until unit tests are in place.  Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public class DoubleFactory1D extends org.apache.mahout.colt.PersistentObject {
+	/**
+	 * A factory producing dense matrices.
+	 */
+	public static final DoubleFactory1D dense  = new DoubleFactory1D();
+
+	/**
+	 * A factory producing sparse matrices.
+	 */
+	public static final DoubleFactory1D sparse = new DoubleFactory1D();
+/**
+ * Makes this class non instantiable, but still let's others inherit from it.
+ */
+protected DoubleFactory1D() {}
+/**
+C = A||B; Constructs a new matrix which is the concatenation of two other matrices.
+Example: <tt>0 1</tt> append <tt>3 4</tt> --> <tt>0 1 3 4</tt>.
+*/
+public DoubleMatrix1D append(DoubleMatrix1D A, DoubleMatrix1D B) {
+	// concatenate
+	DoubleMatrix1D matrix = make(A.size()+B.size());
+	matrix.viewPart(0,A.size()).assign(A);
+	matrix.viewPart(A.size(),B.size()).assign(B);
+	return matrix;
+}
+/**
+Constructs a matrix with cells having ascending values.
+For debugging purposes.
+Example: <tt>0 1 2</tt>
+*/
+public DoubleMatrix1D ascending(int size) {
+	org.apache.mahout.jet.math.Functions F = org.apache.mahout.jet.math.Functions.functions;
+	return descending(size).assign(F.chain(F.neg,F.minus(size)));
+}
+/**
+Constructs a matrix with cells having descending values.
+For debugging purposes.
+Example: <tt>2 1 0</tt> 
+*/
+public DoubleMatrix1D descending(int size) {
+	DoubleMatrix1D matrix = make(size);
+	int v = 0;
+	for (int i=size; --i >= 0;) {
+		matrix.setQuick(i, v++);
+	}
+	return matrix;
+}
+/**
+ * Constructs a matrix with the given cell 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 DoubleMatrix1D make(double[] values) {
+	if (this==sparse) return new SparseDoubleMatrix1D(values);
+	else return new DenseDoubleMatrix1D(values);
+}
+/**
+Constructs a matrix which is the concatenation of all given parts.
+Cells are copied.
+*/
+public DoubleMatrix1D make(DoubleMatrix1D[] parts) {
+	if (parts.length==0) return make(0);
+	
+	int size = 0;
+	for (int i=0; i < parts.length; i++) size += parts[i].size();
+
+	DoubleMatrix1D vector = make(size);
+	size = 0;
+	for (int i=0; i < parts.length; i++) {
+		vector.viewPart(size,parts[i].size()).assign(parts[i]);
+		size += parts[i].size();
+	}
+
+	return vector;
+}
+/**
+ * Constructs a matrix with the given shape, each cell initialized with zero.
+ */
+public DoubleMatrix1D make(int size) {
+	if (this==sparse) return new SparseDoubleMatrix1D(size);
+	return new DenseDoubleMatrix1D(size);
+}
+/**
+ * Constructs a matrix with the given shape, each cell initialized with the given value.
+ */
+public DoubleMatrix1D make(int size, double initialValue) {
+	return make(size).assign(initialValue);
+}
+/**
+ * Constructs a matrix from the values of the given list.
+ * 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.
+ * @return a new matrix.
+ */
+public DoubleMatrix1D make(org.apache.mahout.colt.list.AbstractDoubleList values) {
+	int size = values.size();
+	DoubleMatrix1D vector = make(size);
+	for (int i=size; --i >= 0; ) vector.set(i, values.get(i));
+	return vector;
+}
+/**
+ * Constructs a matrix with uniformly distributed values in <tt>(0,1)</tt> (exclusive).
+ */
+public DoubleMatrix1D random(int size) {
+	return make(size).assign(org.apache.mahout.jet.math.Functions.random());
+}
+/**
+C = A||A||..||A; Constructs a new matrix which is concatenated <tt>repeat</tt> times.
+Example:
+<pre>
+0 1
+repeat(3) -->
+0 1 0 1 0 1
+</pre>
+*/
+public DoubleMatrix1D repeat(DoubleMatrix1D A, int repeat) {
+	int size = A.size();
+	DoubleMatrix1D matrix = make(repeat * size);
+	for (int i=repeat; --i >= 0; ) {
+		matrix.viewPart(size*i,size).assign(A);
+	}
+	return matrix;
+}
+/**
+ * Constructs a randomly sampled matrix with the given shape.
+ * Randomly picks exactly <tt>Math.round(size*nonZeroFraction)</tt> cells and initializes them to <tt>value</tt>, all the rest will be initialized to zero.
+ * Note that this is not the same as setting each cell with probability <tt>nonZeroFraction</tt> to <tt>value</tt>.
+ * @throws IllegalArgumentException if <tt>nonZeroFraction < 0 || nonZeroFraction > 1</tt>.
+ * @see org.apache.mahout.jet.random.sampling.RandomSampler
+ */
+public DoubleMatrix1D sample(int size, double value, double nonZeroFraction)  {
+	double epsilon = 1e-09;
+	if (nonZeroFraction < 0 - epsilon || nonZeroFraction > 1 + epsilon) throw new IllegalArgumentException();
+	if (nonZeroFraction < 0) nonZeroFraction = 0;
+	if (nonZeroFraction > 1) nonZeroFraction = 1;
+	
+	DoubleMatrix1D matrix = make(size);
+
+	int n = (int) Math.round(size*nonZeroFraction);
+	if (n==0) return matrix;
+
+	org.apache.mahout.jet.random.sampling.RandomSamplingAssistant sampler = new org.apache.mahout.jet.random.sampling.RandomSamplingAssistant(n,size,new org.apache.mahout.jet.random.engine.MersenneTwister());
+	for (int i=size; --i >=0; ) {
+		if (sampler.sampleNextElement()) {
+			matrix.set(i, value);
+		}
+	}
+	
+	return matrix;
+}
+/**
+ * Constructs a list from the given matrix.
+ * The values are copied. So subsequent changes in <tt>values</tt> are not reflected in the list, and vice-versa.
+ *
+ * @param values The values to be filled into the new list.
+ * @return a new list.
+ */
+public org.apache.mahout.colt.list.DoubleArrayList toList(DoubleMatrix1D values) {
+	int size = values.size();
+	org.apache.mahout.colt.list.DoubleArrayList list = new org.apache.mahout.colt.list.DoubleArrayList(size);
+	list.setSize(size);
+	for (int i=size; --i >= 0; ) list.set(i, values.get(i));
+	return list;
+}
+}

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

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleFactory2D.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleFactory2D.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleFactory2D.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleFactory2D.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,845 @@
+/*
+Copyright � 1999 CERN - European Organization for Nuclear Research.
+Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose 
+is hereby granted without fee, provided that the above copyright notice appear in all copies and 
+that both that copyright notice and this permission notice appear in supporting documentation. 
+CERN makes no representations about the suitability of this software for any purpose. 
+It is provided "as is" without expressed or implied warranty.
+*/
+package org.apache.mahout.colt.matrix;
+
+import org.apache.mahout.colt.matrix.impl.DenseDoubleMatrix2D;
+import org.apache.mahout.colt.matrix.impl.RCDoubleMatrix2D;
+import org.apache.mahout.colt.matrix.impl.SparseDoubleMatrix2D;
+/**
+Factory for convenient construction of 2-d matrices holding <tt>double</tt> 
+  cells. Also provides convenient methods to compose (concatenate) and decompose 
+  (split) matrices from/to constituent blocks. </p>
+<p>&nbsp; </p>
+<table border="0" cellspacing="0">
+  <tr align="left" valign="top"> 
+	<td><i>Construction</i></td>
+	<td>Use idioms like <tt>DoubleFactory2D.dense.make(4,4)</tt> to construct 
+	  dense matrices, <tt>DoubleFactory2D.sparse.make(4,4)</tt> to construct sparse 
+	  matrices.</td>
+  </tr>
+  <tr align="left" valign="top"> 
+	<td><i> Construction with initial values </i></td>
+	<td>Use other <tt>make</tt> methods to construct matrices with given initial 
+	  values. </td>
+  </tr>
+  <tr align="left" valign="top"> 
+	<td><i> Appending rows and columns </i></td>
+	<td>Use methods {@link #appendColumns(DoubleMatrix2D,DoubleMatrix2D) appendColumns}, 
+	  {@link #appendColumns(DoubleMatrix2D,DoubleMatrix2D) appendRows} and {@link 
+	  #repeat(DoubleMatrix2D,int,int) repeat} to append rows and columns. </td>
+  </tr>
+  <tr align="left" valign="top"> 
+	<td><i> General block matrices </i></td>
+	<td>Use methods {@link #compose(DoubleMatrix2D[][]) compose} and {@link #decompose(DoubleMatrix2D[][],DoubleMatrix2D) 
+	  decompose} to work with general block matrices. </td>
+  </tr>
+  <tr align="left" valign="top"> 
+	<td><i> Diagonal matrices </i></td>
+	<td>Use methods {@link #diagonal(DoubleMatrix1D) diagonal(vector)}, {@link 
+	  #diagonal(DoubleMatrix2D) diagonal(matrix)} and {@link #identity(int) identity} 
+	  to work with diagonal matrices. </td>
+  </tr>
+  <tr align="left" valign="top"> 
+	<td><i> Diagonal block matrices </i></td>
+	<td>Use method {@link #composeDiagonal(DoubleMatrix2D,DoubleMatrix2D,DoubleMatrix2D) 
+	  composeDiagonal} to work with diagonal block matrices. </td>
+  </tr>
+  <tr align="left" valign="top"> 
+	<td><i>Random</i></td>
+	<td>Use methods {@link #random(int,int) random} and {@link #sample(int,int,double,double) 
+	  sample} to construct random matrices. </td>
+  </tr>
+</table>
+<p>&nbsp;</p>
+<p>If the factory is used frequently it might be useful to streamline the notation. 
+  For example by aliasing: </p>
+<table>
+  <td class="PRE"> 
+	<pre>
+DoubleFactory2D F = DoubleFactory2D.dense;
+F.make(4,4);
+F.descending(10,20);
+F.random(4,4);
+...
+</pre>
+  </td>
+</table>
+
+@author wolfgang.hoschek@cern.ch
+@version 1.0, 09/24/99
+*/
+/** 
+ * @deprecated until unit tests are in place.  Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public class DoubleFactory2D extends org.apache.mahout.colt.PersistentObject {
+	/**
+	 * A factory producing dense matrices.
+	 */
+	public static final DoubleFactory2D dense  = new DoubleFactory2D();
+
+	/**
+	 * A factory producing sparse hash matrices.
+	 */
+	public static final DoubleFactory2D sparse = new DoubleFactory2D();
+
+	/**
+	 * A factory producing sparse row compressed matrices.
+	 */
+	public static final DoubleFactory2D rowCompressed = new DoubleFactory2D();
+	
+	/*
+	 * A factory producing sparse row compressed modified matrices.
+	 */
+	//public static final DoubleFactory2D rowCompressedModified = new DoubleFactory2D();
+/**
+ * Makes this class non instantiable, but still let's others inherit from it.
+ */
+protected DoubleFactory2D() {}
+/**
+C = A||B; Constructs a new matrix which is the column-wise concatenation of two other matrices.
+<pre>
+0 1 2
+3 4 5
+appendColumns
+6 7
+8 9
+-->
+0 1 2 6 7 
+3 4 5 8 9
+</pre>
+*/
+public DoubleMatrix2D appendColumns(DoubleMatrix2D A, DoubleMatrix2D B) {
+	// force both to have maximal shared number of rows.
+	if (B.rows() > A.rows()) B = B.viewPart(0,0,A.rows(),B.columns());
+	else if (B.rows() < A.rows()) A = A.viewPart(0,0,B.rows(),A.columns());
+
+	// concatenate
+	int ac = A.columns();
+	int bc = B.columns();
+	int r = A.rows();
+	DoubleMatrix2D matrix = make(r,ac+bc);
+	matrix.viewPart(0,0,r,ac).assign(A);
+	matrix.viewPart(0,ac,r,bc).assign(B);
+	return matrix;
+}
+/**
+C = A||B; Constructs a new matrix which is the row-wise concatenation of two other matrices.
+<pre>
+0 1 
+2 3 
+4 5
+appendRows
+6 7
+8 9
+-->
+0 1 
+2 3 
+4 5
+6 7
+8 9
+</pre>
+*/
+public DoubleMatrix2D appendRows(DoubleMatrix2D A, DoubleMatrix2D B) {
+	// force both to have maximal shared number of columns.
+	if (B.columns() > A.columns()) B = B.viewPart(0,0,B.rows(),A.columns());
+	else if (B.columns() < A.columns()) A = A.viewPart(0,0,A.rows(),B.columns());
+
+	// concatenate
+	int ar = A.rows();
+	int br = B.rows();
+	int c = A.columns();
+	DoubleMatrix2D matrix = make(ar+br, c);
+	matrix.viewPart(0,0,ar,c).assign(A);
+	matrix.viewPart(ar,0,br,c).assign(B);
+	return matrix;
+}
+/**
+Constructs a matrix with cells having ascending values.
+For debugging purposes.
+Example:
+<pre>
+0 1 2 
+3 4 5
+</pre>
+*/
+public DoubleMatrix2D ascending(int rows, int columns) {
+	org.apache.mahout.jet.math.Functions F = org.apache.mahout.jet.math.Functions.functions;
+	return descending(rows,columns).assign(F.chain(F.neg,F.minus(columns*rows)));
+}
+/**
+Checks whether the given array is rectangular, that is, whether all rows have the same number of columns.
+@throws IllegalArgumentException if the array is not rectangular.
+*/
+protected static void checkRectangularShape(double[][] array) {
+	int columns = -1;
+	for (int row=array.length; --row >= 0; ) {
+		if (array[row] != null) {
+			if (columns == -1) columns = array[row].length;
+			if (array[row].length != columns) throw new IllegalArgumentException("All rows of array must have same number of columns.");
+		}
+	}
+}
+/**
+Checks whether the given array is rectangular, that is, whether all rows have the same number of columns.
+@throws IllegalArgumentException if the array is not rectangular.
+*/
+protected static void checkRectangularShape(DoubleMatrix2D[][] array) {
+	int columns = -1;
+	for (int row=array.length; --row >= 0; ) {
+		if (array[row] != null) {
+			if (columns == -1) columns = array[row].length;
+			if (array[row].length != columns) throw new IllegalArgumentException("All rows of array must have same number of columns.");
+		}
+	}
+}
+/**
+Constructs a block matrix made from the given parts.
+The inverse to method {@link #decompose(DoubleMatrix2D[][], DoubleMatrix2D)}.
+<p>
+All matrices of a given column within <tt>parts</tt> must have the same number of columns.
+All matrices of a given row within <tt>parts</tt> must have the same number of rows.
+Otherwise an <tt>IllegalArgumentException</tt> is thrown. 
+Note that <tt>null</tt>s within <tt>parts[row,col]</tt> are an exception to this rule: they are ignored.
+Cells are copied.
+Example:
+<table border="1" cellspacing="0">
+  <tr align="left" valign="top"> 
+	<td><tt>Code</tt></td>
+	<td><tt>Result</tt></td>
+  </tr>
+  <tr align="left" valign="top"> 
+	<td> 
+	  <pre>
+DoubleMatrix2D[][] parts1 = 
+{
+&nbsp;&nbsp;&nbsp;{ null,        make(2,2,1), null        },
+&nbsp;&nbsp;&nbsp;{ make(4,4,2), null,        make(4,3,3) },
+&nbsp;&nbsp;&nbsp;{ null,        make(2,2,4), null        }
+};
+System.out.println(compose(parts1));
+</pre>
+	</td>
+	<td><tt>8&nbsp;x&nbsp;9&nbsp;matrix<br>
+	  0&nbsp;0&nbsp;0&nbsp;0&nbsp;1&nbsp;1&nbsp;0&nbsp;0&nbsp;0<br>
+	  0&nbsp;0&nbsp;0&nbsp;0&nbsp;1&nbsp;1&nbsp;0&nbsp;0&nbsp;0<br>
+	  2&nbsp;2&nbsp;2&nbsp;2&nbsp;0&nbsp;0&nbsp;3&nbsp;3&nbsp;3<br>
+	  2&nbsp;2&nbsp;2&nbsp;2&nbsp;0&nbsp;0&nbsp;3&nbsp;3&nbsp;3<br>
+	  2&nbsp;2&nbsp;2&nbsp;2&nbsp;0&nbsp;0&nbsp;3&nbsp;3&nbsp;3<br>
+	  2&nbsp;2&nbsp;2&nbsp;2&nbsp;0&nbsp;0&nbsp;3&nbsp;3&nbsp;3<br>
+	  0&nbsp;0&nbsp;0&nbsp;0&nbsp;4&nbsp;4&nbsp;0&nbsp;0&nbsp;0<br>
+	  0&nbsp;0&nbsp;0&nbsp;0&nbsp;4&nbsp;4&nbsp;0&nbsp;0&nbsp;0</tt></td>
+  </tr>
+  <tr align="left" valign="top"> 
+	<td> 
+	  <pre>
+DoubleMatrix2D[][] parts3 = 
+{
+&nbsp;&nbsp;&nbsp;{ identity(3),               null,                        },
+&nbsp;&nbsp;&nbsp;{ null,                      identity(3).viewColumnFlip() },
+&nbsp;&nbsp;&nbsp;{ identity(3).viewRowFlip(), null                         }
+};
+System.out.println("\n"+make(parts3));
+</pre>
+	</td>
+	<td><tt>9&nbsp;x&nbsp;6&nbsp;matrix<br>
+	  1&nbsp;0&nbsp;0&nbsp;0&nbsp;0&nbsp;0<br>
+	  0&nbsp;1&nbsp;0&nbsp;0&nbsp;0&nbsp;0<br>
+	  0&nbsp;0&nbsp;1&nbsp;0&nbsp;0&nbsp;0<br>
+	  0&nbsp;0&nbsp;0&nbsp;0&nbsp;0&nbsp;1<br>
+	  0&nbsp;0&nbsp;0&nbsp;0&nbsp;1&nbsp;0<br>
+	  0&nbsp;0&nbsp;0&nbsp;1&nbsp;0&nbsp;0<br>
+	  0&nbsp;0&nbsp;1&nbsp;0&nbsp;0&nbsp;0<br>
+	  0&nbsp;1&nbsp;0&nbsp;0&nbsp;0&nbsp;0<br>
+	  1&nbsp;0&nbsp;0&nbsp;0&nbsp;0&nbsp;0 </tt></td>
+  </tr>
+  <tr align="left" valign="top"> 
+	<td> 
+	  <pre>
+DoubleMatrix2D A = ascending(2,2);
+DoubleMatrix2D B = descending(2,2);
+DoubleMatrix2D _ = null;
+
+DoubleMatrix2D[][] parts4 = 
+{
+&nbsp;&nbsp;&nbsp;{ A, _, A, _ },
+&nbsp;&nbsp;&nbsp;{ _, A, _, B }
+};
+System.out.println("\n"+make(parts4));
+</pre>
+	</td>
+	<td><tt>4&nbsp;x&nbsp;8&nbsp;matrix<br>
+	  1&nbsp;2&nbsp;0&nbsp;0&nbsp;1&nbsp;2&nbsp;0&nbsp;0<br>
+	  3&nbsp;4&nbsp;0&nbsp;0&nbsp;3&nbsp;4&nbsp;0&nbsp;0<br>
+	  0&nbsp;0&nbsp;1&nbsp;2&nbsp;0&nbsp;0&nbsp;3&nbsp;2<br>
+	  0&nbsp;0&nbsp;3&nbsp;4&nbsp;0&nbsp;0&nbsp;1&nbsp;0 </tt></td>
+  </tr>
+  <tr align="left" valign="top"> 
+	<td> 
+	  <pre>
+DoubleMatrix2D[][] parts2 = 
+{
+&nbsp;&nbsp;&nbsp;{ null,        make(2,2,1), null        },
+&nbsp;&nbsp;&nbsp;{ make(4,4,2), null,        make(4,3,3) },
+&nbsp;&nbsp;&nbsp;{ null,        make(2,3,4), null        }
+};
+System.out.println("\n"+Factory2D.make(parts2));
+</pre>
+	</td>
+	<td><tt>IllegalArgumentException<br>
+	  A[0,1].cols != A[2,1].cols<br>
+	  (2 != 3)</tt></td>
+  </tr>
+</table>
+@throws IllegalArgumentException subject to the conditions outlined above.
+*/
+public DoubleMatrix2D compose(DoubleMatrix2D[][] parts) {
+	checkRectangularShape(parts);
+	int rows = parts.length;
+	int columns = 0;
+	if (parts.length > 0) columns = parts[0].length;
+	DoubleMatrix2D empty = make(0,0);
+	
+	if (rows==0 || columns==0) return empty;
+
+	// determine maximum column width of each column
+	int[] maxWidths = new int[columns];
+	for (int column=columns; --column >= 0; ) {
+		int maxWidth = 0;
+		for (int row=rows; --row >= 0; ) {
+			DoubleMatrix2D part = parts[row][column];
+			if (part != null) {
+				int width = part.columns();
+				if (maxWidth>0 && width>0 && width!=maxWidth) throw new IllegalArgumentException("Different number of columns.");
+				maxWidth = Math.max(maxWidth,width);
+			}
+		}
+		maxWidths[column] = maxWidth;
+	}
+
+	// determine row height of each row
+	int[] maxHeights = new int[rows];
+	for (int row=rows; --row >= 0; ) {
+		int maxHeight = 0;
+		for (int column=columns; --column >= 0; ) {
+			DoubleMatrix2D part = parts[row][column];
+			if (part != null) {
+				int height = part.rows();
+				if (maxHeight>0  && height>0 && height!=maxHeight) throw new IllegalArgumentException("Different number of rows.");
+				maxHeight = Math.max(maxHeight,height);
+			}
+		}
+		maxHeights[row] = maxHeight;
+	}
+
+
+	// shape of result 
+	int resultRows = 0;
+	for (int row=rows; --row >= 0; ) resultRows += maxHeights[row];
+	int resultCols = 0;
+	for (int column=columns; --column >= 0; ) resultCols += maxWidths[column];
+	
+	DoubleMatrix2D matrix = make(resultRows,resultCols);
+
+	// copy
+	int r=0;
+	for (int row=0; row < rows; row++) {
+		int c=0;
+		for (int column=0; column < columns; column++) {
+			DoubleMatrix2D part = parts[row][column];
+			if (part != null) {
+				matrix.viewPart(r,c,part.rows(),part.columns()).assign(part);
+			}
+			c += maxWidths[column];
+		}
+		r += maxHeights[row];
+	}
+	
+	return matrix;
+}
+/**
+Constructs a diagonal block matrix from the given parts (the <i>direct sum</i> of two matrices).
+That is the concatenation
+<pre>
+A 0
+0 B
+</pre>
+(The direct sum has <tt>A.rows()+B.rows()</tt> rows and <tt>A.columns()+B.columns()</tt> columns).
+Cells are copied.
+@return a new matrix which is the direct sum.
+*/
+public DoubleMatrix2D composeDiagonal(DoubleMatrix2D A, DoubleMatrix2D B) {
+	int ar = A.rows(); int ac = A.columns();
+	int br = B.rows(); int bc = B.columns();
+	DoubleMatrix2D sum = make(ar+br, ac+bc);
+	sum.viewPart(0,0,ar,ac).assign(A);
+	sum.viewPart(ar,ac,br,bc).assign(B);
+	return sum;
+}
+/**
+Constructs a diagonal block matrix from the given parts.
+The concatenation has the form
+<pre>
+A 0 0
+0 B 0
+0 0 C
+</pre>
+from the given parts.
+Cells are copied.
+*/
+public DoubleMatrix2D composeDiagonal(DoubleMatrix2D A, DoubleMatrix2D B, DoubleMatrix2D C) {
+	DoubleMatrix2D diag = make(A.rows()+B.rows()+C.rows(), A.columns()+B.columns()+C.columns());
+	diag.viewPart(0,0,A.rows(),A.columns()).assign(A);
+	diag.viewPart(A.rows(),A.columns(),B.rows(),B.columns()).assign(B);
+	diag.viewPart(A.rows()+B.rows(),A.columns()+B.columns(),C.rows(),C.columns()).assign(C);
+	return diag;
+}
+/**
+Splits a block matrix into its constituent blocks; Copies blocks of a matrix into the given parts.
+The inverse to method {@link #compose(DoubleMatrix2D[][])}.
+<p>
+All matrices of a given column within <tt>parts</tt> must have the same number of columns.
+All matrices of a given row within <tt>parts</tt> must have the same number of rows.
+Otherwise an <tt>IllegalArgumentException</tt> is thrown. 
+Note that <tt>null</tt>s within <tt>parts[row,col]</tt> are an exception to this rule: they are ignored.
+Cells are copied.
+Example:
+<table border="1" cellspacing="0">
+  <tr align="left" valign="top"> 
+	<td><tt>Code</tt></td>
+	<td><tt>matrix</tt></td>
+	<td><tt>--&gt; parts </tt></td>
+  </tr>
+  <tr align="left" valign="top"> 
+	<td> 
+	  <pre>
+DoubleMatrix2D matrix = ... ;
+DoubleMatrix2D _ = null;
+DoubleMatrix2D A,B,C,D;
+A = make(2,2); B = make (4,4);
+C = make(4,3); D = make (2,2);
+DoubleMatrix2D[][] parts = 
+{
+&nbsp;&nbsp;&nbsp;{ _, A, _ },
+&nbsp;&nbsp;&nbsp;{ B, _, C },
+&nbsp;&nbsp;&nbsp;{ _, D, _ }
+};
+decompose(parts,matrix);
+System.out.println(&quot;\nA = &quot;+A);
+System.out.println(&quot;\nB = &quot;+B);
+System.out.println(&quot;\nC = &quot;+C);
+System.out.println(&quot;\nD = &quot;+D);
+</pre>
+	</td>
+	<td><tt>8&nbsp;x&nbsp;9&nbsp;matrix<br>
+	  9&nbsp;9&nbsp;9&nbsp;9&nbsp;1&nbsp;1&nbsp;9&nbsp;9&nbsp;9<br>
+	  9&nbsp;9&nbsp;9&nbsp;9&nbsp;1&nbsp;1&nbsp;9&nbsp;9&nbsp;9<br>
+	  2&nbsp;2&nbsp;2&nbsp;2&nbsp;9&nbsp;9&nbsp;3&nbsp;3&nbsp;3<br>
+	  2&nbsp;2&nbsp;2&nbsp;2&nbsp;9&nbsp;9&nbsp;3&nbsp;3&nbsp;3<br>
+	  2&nbsp;2&nbsp;2&nbsp;2&nbsp;9&nbsp;9&nbsp;3&nbsp;3&nbsp;3<br>
+	  2&nbsp;2&nbsp;2&nbsp;2&nbsp;9&nbsp;9&nbsp;3&nbsp;3&nbsp;3<br>
+	  9&nbsp;9&nbsp;9&nbsp;9&nbsp;4&nbsp;4&nbsp;9&nbsp;9&nbsp;9<br>
+	  9&nbsp;9&nbsp;9&nbsp;9&nbsp;4&nbsp;4&nbsp;9&nbsp;9&nbsp;9</tt></td>
+	<td> 
+	  <p><tt>A = 2&nbsp;x&nbsp;2&nbsp;matrix<br>
+		1&nbsp;1<br>
+		1&nbsp;1</tt></p>
+	  <p><tt>B = 4&nbsp;x&nbsp;4&nbsp;matrix<br>
+		2&nbsp;2&nbsp;2&nbsp;2<br>
+		2&nbsp;2&nbsp;2&nbsp;2<br>
+		2&nbsp;2&nbsp;2&nbsp;2<br>
+		2&nbsp;2&nbsp;2&nbsp;2</tt></p>
+	  <p><tt>C = 4&nbsp;x&nbsp;3&nbsp;matrix<br>
+		3&nbsp;3&nbsp;3<br>
+		3&nbsp;3&nbsp;3<br>
+		</tt><tt>3&nbsp;3&nbsp;3<br>
+		</tt><tt>3&nbsp;3&nbsp;3</tt></p>
+	  <p><tt>D = 2&nbsp;x&nbsp;2&nbsp;matrix<br>
+		4&nbsp;4<br>
+		4&nbsp;4</tt></p>
+	  </td>
+  </tr>
+</table>
+@throws IllegalArgumentException subject to the conditions outlined above.
+*/
+public void decompose(DoubleMatrix2D[][] parts, DoubleMatrix2D matrix) {
+	checkRectangularShape(parts);
+	int rows = parts.length;
+	int columns = 0;
+	if (parts.length > 0) columns = parts[0].length;
+	if (rows==0 || columns==0) return;
+
+	// determine maximum column width of each column
+	int[] maxWidths = new int[columns];
+	for (int column=columns; --column >= 0; ) {
+		int maxWidth = 0;
+		for (int row=rows; --row >= 0; ) {
+			DoubleMatrix2D part = parts[row][column];		
+			if (part != null) {
+				int width = part.columns();
+				if (maxWidth>0 && width>0 && width!=maxWidth) throw new IllegalArgumentException("Different number of columns.");
+				maxWidth = Math.max(maxWidth,width);
+			}
+		}
+		maxWidths[column] = maxWidth;
+	}
+
+	// determine row height of each row
+	int[] maxHeights = new int[rows];
+	for (int row=rows; --row >= 0; ) {
+		int maxHeight = 0;
+		for (int column=columns; --column >= 0; ) {
+			DoubleMatrix2D part = parts[row][column];		
+			if (part != null) {
+				int height = part.rows();
+				if (maxHeight>0  && height>0 && height!=maxHeight) throw new IllegalArgumentException("Different number of rows.");
+				maxHeight = Math.max(maxHeight,height);
+			}
+		}
+		maxHeights[row] = maxHeight;
+	}
+
+
+	// shape of result parts
+	int resultRows = 0;
+	for (int row=rows; --row >= 0; ) resultRows += maxHeights[row];
+	int resultCols = 0;
+	for (int column=columns; --column >= 0; ) resultCols += maxWidths[column];
+
+	if (matrix.rows() < resultRows || matrix.columns() < resultCols) throw new IllegalArgumentException("Parts larger than matrix.");
+	
+	// copy
+	int r=0;
+	for (int row=0; row < rows; row++) {
+		int c=0;
+		for (int column=0; column < columns; column++) {
+			DoubleMatrix2D part = parts[row][column];
+			if (part != null) {
+				part.assign(matrix.viewPart(r,c,part.rows(),part.columns()));
+			}
+			c += maxWidths[column];
+		}
+		r += maxHeights[row];
+	}
+	
+}
+/**
+ * Demonstrates usage of this class.
+ */
+public void demo1() {
+System.out.println("\n\n");
+DoubleMatrix2D[][] parts1 = 
+{
+	{ null,        make(2,2,1), null        },
+	{ make(4,4,2), null,        make(4,3,3) },
+	{ null,        make(2,2,4), null        }
+};
+System.out.println("\n"+compose(parts1));
+//System.out.println("\n"+org.apache.mahout.colt.matrixpattern.Converting.toHTML(make(parts1).toString()));
+
+/*
+//
+illegal 2 != 3
+DoubleMatrix2D[][] parts2 = 
+{
+	{ null,        make(2,2,1), null        },
+	{ make(4,4,2), null,        make(4,3,3) },
+	{ null,        make(2,3,4), null        }
+};
+System.out.println("\n"+make(parts2));
+*/
+
+DoubleMatrix2D[][] parts3 = 
+{
+	{ identity(3),               null,                        },
+	{ null,                      identity(3).viewColumnFlip() },
+	{ identity(3).viewRowFlip(), null                         }
+};
+System.out.println("\n"+compose(parts3));
+//System.out.println("\n"+org.apache.mahout.colt.matrixpattern.Converting.toHTML(make(parts3).toString()));
+
+DoubleMatrix2D A = ascending(2,2);
+DoubleMatrix2D B = descending(2,2);
+DoubleMatrix2D _ = null;
+
+DoubleMatrix2D[][] parts4 = 
+{
+	{ A, _, A, _ },
+	{ _, A, _, B }
+};
+System.out.println("\n"+compose(parts4));
+//System.out.println("\n"+org.apache.mahout.colt.matrixpattern.Converting.toHTML(make(parts4).toString()));
+
+}
+/**
+ * Demonstrates usage of this class.
+ */
+public void demo2() {
+System.out.println("\n\n");
+DoubleMatrix2D matrix;
+DoubleMatrix2D A,B,C,D,E,F,G;
+DoubleMatrix2D _ = null;
+A = make(2,2,1); B = make (4,4,2); C = make(4,3,3); D = make (2,2,4);
+DoubleMatrix2D[][] parts1 = 
+{
+	{ _, A, _ },
+	{ B, _, C },
+	{ _, D, _ }
+};
+matrix = compose(parts1);
+System.out.println("\n"+matrix);
+
+A.assign(9); B.assign(9); C.assign(9); D.assign(9);
+decompose(parts1,matrix);
+System.out.println(A);
+System.out.println(B);
+System.out.println(C);
+System.out.println(D);
+//System.out.println("\n"+org.apache.mahout.colt.matrixpattern.Converting.toHTML(make(parts1).toString()));
+
+/*
+//
+illegal 2 != 3
+DoubleMatrix2D[][] parts2 = 
+{
+	{ null,        make(2,2,1), null        },
+	{ make(4,4,2), null,        make(4,3,3) },
+	{ null,        make(2,3,4), null        }
+};
+System.out.println("\n"+Factory2D.make(parts2));
+*/
+
+/*
+DoubleMatrix2D[][] parts3 = 
+{
+	{ identity(3),               null,                        },
+	{ null,                      identity(3).viewColumnFlip() },
+	{ identity(3).viewRowFlip(), null                         }
+};
+System.out.println("\n"+make(parts3));
+//System.out.println("\n"+org.apache.mahout.colt.matrixpattern.Converting.toHTML(make(parts3).toString()));
+
+DoubleMatrix2D A = ascending(2,2);
+DoubleMatrix2D B = descending(2,2);
+DoubleMatrix2D _ = null;
+
+DoubleMatrix2D[][] parts4 = 
+{
+	{ A, _, A, _ },
+	{ _, A, _, B }
+};
+System.out.println("\n"+make(parts4));
+//System.out.println("\n"+org.apache.mahout.colt.matrixpattern.Converting.toHTML(make(parts4).toString()));
+*/
+}
+/**
+Constructs a matrix with cells having descending values.
+For debugging purposes.
+Example:
+<pre>
+5 4 3 
+2 1 0
+</pre>
+*/
+public DoubleMatrix2D descending(int rows, int columns) {
+	DoubleMatrix2D matrix = make(rows,columns);
+	int v = 0;
+	for (int row=rows; --row >= 0;) {
+		for (int column=columns; --column >= 0;) {
+			matrix.setQuick(row, column, v++);
+		}
+	}
+	return matrix;
+}
+/**
+Constructs a new diagonal matrix whose diagonal elements are the elements of <tt>vector</tt>.
+Cells values are copied. The new matrix is not a view.
+Example:
+<pre>
+5 4 3 -->
+5 0 0
+0 4 0
+0 0 3
+</pre>
+@return a new matrix.
+*/
+public DoubleMatrix2D diagonal(DoubleMatrix1D vector) {
+	int size = vector.size();
+	DoubleMatrix2D diag = make(size,size);
+	for (int i=size; --i >= 0; ) {
+		diag.setQuick(i,i, vector.getQuick(i));
+	}
+	return diag;
+}
+/**
+Constructs a new vector consisting of the diagonal elements of <tt>A</tt>.
+Cells values are copied. The new vector is not a view.
+Example:
+<pre>
+5 0 0 9
+0 4 0 9
+0 0 3 9
+--> 5 4 3
+</pre>
+@param A the matrix, need not be square.
+@return a new vector.
+*/
+public DoubleMatrix1D diagonal(DoubleMatrix2D A) {
+	int min = Math.min(A.rows(),A.columns());
+	DoubleMatrix1D diag = make1D(min);
+	for (int i=min; --i >= 0; ) {
+		diag.setQuick(i, A.getQuick(i,i));
+	}
+	return diag;
+}
+/**
+ * Constructs an identity matrix (having ones on the diagonal and zeros elsewhere).
+ */
+public DoubleMatrix2D identity(int rowsAndColumns) {
+	DoubleMatrix2D matrix = make(rowsAndColumns,rowsAndColumns);
+	for (int i=rowsAndColumns; --i >= 0; ) {
+		matrix.setQuick(i,i, 1);
+	}
+	return matrix;
+}
+/**
+ * Constructs a matrix with the given cell values.
+ * <tt>values</tt> is required to have the form <tt>values[row][column]</tt>
+ * and have exactly the same number of columns in every row.
+ * <p>
+ * The values are copied. So subsequent changes in <tt>values</tt> are not reflected in the matrix, and vice-versa.
+ *
+ * @param values The values to be filled into the new matrix.
+ * @throws IllegalArgumentException if <tt>for any 1 &lt;= row &lt; values.length: values[row].length != values[row-1].length</tt>.
+ */
+public DoubleMatrix2D make(double[][] values) {
+	if (this==sparse) return new SparseDoubleMatrix2D(values);
+	else return new DenseDoubleMatrix2D(values);
+}
+/** 
+Construct a matrix from a one-dimensional column-major packed array, ala Fortran.
+Has the form <tt>matrix.get(row,column) == values[row + column*rows]</tt>.
+The values are copied.
+
+@param values One-dimensional array of doubles, packed by columns (ala Fortran).
+@param rows  the number of rows.
+@exception  IllegalArgumentException <tt>values.length</tt> must be a multiple of <tt>rows</tt>.
+*/
+public DoubleMatrix2D make(double values[], int rows) {
+	int columns = (rows != 0 ? values.length/rows : 0);
+	if (rows*columns != values.length) 
+		throw new IllegalArgumentException("Array length must be a multiple of m.");
+		
+	DoubleMatrix2D matrix = make(rows,columns);
+	for (int row=0; row < rows; row++) {
+		for (int column=0; column < columns; column++) {
+			matrix.setQuick(row,column, values[row + column*rows]);
+		}
+	}
+	return matrix;
+}
+/**
+ * Constructs a matrix with the given shape, each cell initialized with zero.
+ */
+public DoubleMatrix2D make(int rows, int columns) {
+	if (this==sparse) return new SparseDoubleMatrix2D(rows,columns);
+	if (this==rowCompressed) return new RCDoubleMatrix2D(rows,columns);
+	//if (this==rowCompressedModified) return new RCMDoubleMatrix2D(rows,columns);
+	else return new DenseDoubleMatrix2D(rows,columns);
+}
+/**
+ * Constructs a matrix with the given shape, each cell initialized with the given value.
+ */
+public DoubleMatrix2D make(int rows, int columns, double initialValue) {
+	if (initialValue == 0) return make(rows,columns);
+	return make(rows,columns).assign(initialValue);
+}
+/**
+ * Constructs a 1d matrix of the right dynamic type.
+ */
+protected DoubleMatrix1D make1D(int size) {
+	return make(0,0).like1D(size);
+}
+/**
+ * Constructs a matrix with uniformly distributed values in <tt>(0,1)</tt> (exclusive).
+ */
+public DoubleMatrix2D random(int rows, int columns) {
+	return make(rows,columns).assign(org.apache.mahout.jet.math.Functions.random());
+}
+/**
+C = A||A||..||A; Constructs a new matrix which is duplicated both along the row and column dimension.
+Example:
+<pre>
+0 1
+2 3
+repeat(2,3) -->
+0 1 0 1 0 1
+2 3 2 3 2 3
+0 1 0 1 0 1
+2 3 2 3 2 3
+</pre>
+*/
+public DoubleMatrix2D repeat(DoubleMatrix2D A, int rowRepeat, int columnRepeat) {
+	int r = A.rows();
+	int c = A.columns();
+	DoubleMatrix2D matrix = make(r*rowRepeat, c*columnRepeat);
+	for (int i=rowRepeat; --i >= 0; ) {
+		for (int j=columnRepeat; --j >= 0; ) {
+			matrix.viewPart(r*i,c*j,r,c).assign(A);
+		}
+	}
+	return matrix;
+}
+/**
+ * Constructs a randomly sampled matrix with the given shape.
+ * Randomly picks exactly <tt>Math.round(rows*columns*nonZeroFraction)</tt> cells and initializes them to <tt>value</tt>, all the rest will be initialized to zero.
+ * Note that this is not the same as setting each cell with probability <tt>nonZeroFraction</tt> to <tt>value</tt>.
+ * Note: The random seed is a constant.
+ * @throws IllegalArgumentException if <tt>nonZeroFraction < 0 || nonZeroFraction > 1</tt>.
+ * @see org.apache.mahout.jet.random.sampling.RandomSampler
+ */
+public DoubleMatrix2D sample(int rows, int columns, double value, double nonZeroFraction)  {
+	DoubleMatrix2D matrix = make(rows,columns);
+	sample(matrix,value,nonZeroFraction);
+	return matrix;
+}
+/**
+ * Modifies the given matrix to be a randomly sampled matrix.
+ * Randomly picks exactly <tt>Math.round(rows*columns*nonZeroFraction)</tt> cells and initializes them to <tt>value</tt>, all the rest will be initialized to zero.
+ * Note that this is not the same as setting each cell with probability <tt>nonZeroFraction</tt> to <tt>value</tt>.
+ * Note: The random seed is a constant.
+ * @throws IllegalArgumentException if <tt>nonZeroFraction < 0 || nonZeroFraction > 1</tt>.
+ * @see org.apache.mahout.jet.random.sampling.RandomSampler
+ */
+public DoubleMatrix2D sample(DoubleMatrix2D matrix, double value, double nonZeroFraction)  {
+	int rows = matrix.rows();
+	int columns = matrix.columns();
+	double epsilon = 1e-09;
+	if (nonZeroFraction < 0 - epsilon || nonZeroFraction > 1 + epsilon) throw new IllegalArgumentException();
+	if (nonZeroFraction < 0) nonZeroFraction = 0;
+	if (nonZeroFraction > 1) nonZeroFraction = 1;
+	
+	matrix.assign(0);
+
+	int size = rows*columns;
+	int n = (int) Math.round(size*nonZeroFraction);
+	if (n==0) return matrix;
+
+	org.apache.mahout.jet.random.sampling.RandomSamplingAssistant sampler = new org.apache.mahout.jet.random.sampling.RandomSamplingAssistant(n,size,new org.apache.mahout.jet.random.engine.MersenneTwister());
+	for (int i=0; i < size; i++) {
+		if (sampler.sampleNextElement()) {
+			int row = (int) (i/columns);
+			int column = (int) (i%columns);
+			matrix.set(row,column, value);
+		}
+	}
+	
+	return matrix;
+}
+}

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

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleFactory3D.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleFactory3D.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleFactory3D.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleFactory3D.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,112 @@
+/*
+Copyright � 1999 CERN - European Organization for Nuclear Research.
+Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose 
+is hereby granted without fee, provided that the above copyright notice appear in all copies and 
+that both that copyright notice and this permission notice appear in supporting documentation. 
+CERN makes no representations about the suitability of this software for any purpose. 
+It is provided "as is" without expressed or implied warranty.
+*/
+package org.apache.mahout.colt.matrix;
+
+import org.apache.mahout.colt.matrix.impl.DenseDoubleMatrix3D;
+import org.apache.mahout.colt.matrix.impl.SparseDoubleMatrix3D;
+/**
+Factory for convenient construction of 3-d matrices holding <tt>double</tt> cells. 
+Use idioms like <tt>DoubleFactory3D.dense.make(4,4,4)</tt> to construct dense matrices, 
+<tt>DoubleFactory3D.sparse.make(4,4,4)</tt> to construct sparse matrices.
+
+If the factory is used frequently it might be useful to streamline the notation. 
+For example by aliasing:
+<table>
+<td class="PRE"> 
+<pre>
+DoubleFactory3D F = DoubleFactory3D.dense;
+F.make(4,4,4);
+F.descending(10,20,5);
+F.random(4,4,5);
+...
+</pre>
+</td>
+</table>
+
+@author wolfgang.hoschek@cern.ch
+@version 1.0, 09/24/99
+*/
+/** 
+ * @deprecated until unit tests are in place.  Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public class DoubleFactory3D extends org.apache.mahout.colt.PersistentObject {
+	/**
+	 * A factory producing dense matrices.
+	 */
+	public static final DoubleFactory3D dense  = new DoubleFactory3D();
+
+	/**
+	 * A factory producing sparse matrices.
+	 */
+	public static final DoubleFactory3D sparse = new DoubleFactory3D();
+/**
+ * Makes this class non instantiable, but still let's others inherit from it.
+ */
+protected DoubleFactory3D() {}
+/**
+ * Constructs a matrix with cells having ascending values.
+ * For debugging purposes.
+ */
+public DoubleMatrix3D ascending(int slices, int rows, int columns) {
+	org.apache.mahout.jet.math.Functions F = org.apache.mahout.jet.math.Functions.functions;
+	return descending(slices,rows,columns).assign(F.chain(F.neg,F.minus(slices*rows*columns)));
+}
+/**
+ * Constructs a matrix with cells having descending values.
+ * For debugging purposes.
+ */
+public DoubleMatrix3D descending(int slices, int rows, int columns) {
+	DoubleMatrix3D matrix = make(slices,rows,columns);
+	int v = 0;
+	for (int slice=slices; --slice >= 0;) {
+		for (int row=rows; --row >= 0;) {
+			for (int column=columns; --column >= 0;) {
+				matrix.setQuick(slice, row, column, v++);
+			}
+		}
+	}
+	return matrix;
+}
+/**
+ * Constructs a matrix with the given cell values.
+ * <tt>values</tt> is required to have the form <tt>values[slice][row][column]</tt>
+ * and have exactly the same number of slices, rows and columns as the receiver.
+ * <p>
+ * The values are copied. So subsequent changes in <tt>values</tt> are not reflected in the matrix, and vice-versa.
+ *
+ * @param    values the values to be filled into the cells.
+ * @return <tt>this</tt> (for convenience only).
+ * @throws IllegalArgumentException if <tt>values.length != slices() || for any 0 &lt;= slice &lt; slices(): values[slice].length != rows()</tt>.
+ * @throws IllegalArgumentException if <tt>for any 0 &lt;= column &lt; columns(): values[slice][row].length != columns()</tt>.
+ */
+public DoubleMatrix3D make(double[][][] values) {
+	if (this==sparse) return new SparseDoubleMatrix3D(values);
+	return new DenseDoubleMatrix3D(values);
+}
+/**
+ * Constructs a matrix with the given shape, each cell initialized with zero.
+ */
+public DoubleMatrix3D make(int slices, int rows, int columns) {
+	if (this==sparse) return new SparseDoubleMatrix3D(slices,rows,columns);
+	return new DenseDoubleMatrix3D(slices,rows,columns);
+}
+/**
+ * Constructs a matrix with the given shape, each cell initialized with the given value.
+ */
+public DoubleMatrix3D make(int slices, int rows, int columns, double initialValue) {
+	return make(slices,rows,columns).assign(initialValue);
+}
+/**
+ * Constructs a matrix with uniformly distributed values in <tt>(0,1)</tt> (exclusive).
+ */
+public DoubleMatrix3D random(int slices, int rows, int columns) {
+	return make(slices,rows,columns).assign(org.apache.mahout.jet.math.Functions.random());
+}
+}

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

Added: lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleMatrix1D.java
URL: http://svn.apache.org/viewvc/lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleMatrix1D.java?rev=883365&view=auto
==============================================================================
--- lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleMatrix1D.java (added)
+++ lucene/mahout/trunk/matrix/src/main/java/org/apache/mahout/matrix/matrix/DoubleMatrix1D.java Mon Nov 23 15:14:26 2009
@@ -0,0 +1,812 @@
+/*
+Copyright � 1999 CERN - European Organization for Nuclear Research.
+Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose 
+is hereby granted without fee, provided that the above copyright notice appear in all copies and 
+that both that copyright notice and this permission notice appear in supporting documentation. 
+CERN makes no representations about the suitability of this software for any purpose. 
+It is provided "as is" without expressed or implied warranty.
+*/
+package org.apache.mahout.colt.matrix;
+
+import org.apache.mahout.colt.list.DoubleArrayList;
+import org.apache.mahout.colt.list.IntArrayList;
+import org.apache.mahout.colt.matrix.impl.AbstractMatrix1D;
+/**
+Abstract base class for 1-d matrices (aka <i>vectors</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>
+A matrix has a number of cells (its <i>size</i>), which are assigned upon instance construction.
+Elements are accessed via zero based indexes.
+Legal indexes are of the form <tt>[0..size()-1]</tt>.
+Any attempt to access an element at a coordinate <tt>index&lt;0 || index&gt;=size()</tt> will throw an <tt>IndexOutOfBoundsException</tt>.
+
+@author wolfgang.hoschek@cern.ch
+@version 1.0, 09/24/99
+*/
+/** 
+ * @deprecated until unit tests are in place.  Until this time, this class/interface is unsupported.
+ */
+@Deprecated
+public abstract class DoubleMatrix1D extends AbstractMatrix1D {
+/**
+ * Makes this class non instantiable, but still let's others inherit from it.
+ */
+protected DoubleMatrix1D() {}
+/**
+Applies a function to each cell and aggregates the results.
+Returns a value <tt>v</tt> such that <tt>v==a(size())</tt> where <tt>a(i) == aggr( a(i-1), f(get(i)) )</tt> and terminators are <tt>a(1) == f(get(0)), a(0)==Double.NaN</tt>.
+<p>
+<b>Example:</b>
+<pre>
+org.apache.mahout.jet.math.Functions F = org.apache.mahout.jet.math.Functions.functions;
+matrix = 0 1 2 3 
+
+// Sum( x[i]*x[i] ) 
+matrix.aggregate(F.plus,F.square);
+--> 14
+</pre>
+For further examples, see the <a href="package-summary.html#FunctionObjects">package doc</a>.
+
+@param aggr an aggregation function taking as first argument the current aggregation and as second argument the transformed current cell value.
+@param f a function transforming the current cell value.
+@return the aggregated measure.
+@see org.apache.mahout.jet.math.Functions
+*/
+public double aggregate(org.apache.mahout.colt.function.DoubleDoubleFunction aggr, org.apache.mahout.colt.function.DoubleFunction f) {
+	if (size==0) return Double.NaN;
+	double a = f.apply(getQuick(size-1));
+	for (int i=size-1; --i >= 0; ) {
+		a = aggr.apply(a, f.apply(getQuick(i)));
+	}
+	return a;
+}
+/**
+Applies a function to each corresponding cell of two matrices and aggregates the results.
+Returns a value <tt>v</tt> such that <tt>v==a(size())</tt> where <tt>a(i) == aggr( a(i-1), f(get(i),other.get(i)) )</tt> and terminators are <tt>a(1) == f(get(0),other.get(0)), a(0)==Double.NaN</tt>.
+<p>
+<b>Example:</b>
+<pre>
+org.apache.mahout.jet.math.Functions F = org.apache.mahout.jet.math.Functions.functions;
+x = 0 1 2 3 
+y = 0 1 2 3 
+
+// Sum( x[i]*y[i] )
+x.aggregate(y, F.plus, F.mult);
+--> 14
+
+// Sum( (x[i]+y[i])^2 )
+x.aggregate(y, F.plus, F.chain(F.square,F.plus));
+--> 56
+</pre>
+For further examples, see the <a href="package-summary.html#FunctionObjects">package doc</a>.
+
+@param aggr an aggregation function taking as first argument the current aggregation and as second argument the transformed current cell values.
+@param f a function transforming the current cell values.
+@return the aggregated measure.
+@throws	IllegalArgumentException if <tt>size() != other.size()</tt>.
+@see org.apache.mahout.jet.math.Functions
+*/
+public double aggregate(DoubleMatrix1D other, org.apache.mahout.colt.function.DoubleDoubleFunction aggr, org.apache.mahout.colt.function.DoubleDoubleFunction f) {
+	checkSize(other);
+	if (size==0) return Double.NaN;
+	double a = f.apply(getQuick(size-1),other.getQuick(size-1));
+	for (int i=size-1; --i >= 0; ) {
+		a = aggr.apply(a, f.apply(getQuick(i),other.getQuick(i)));
+	}
+	return a;
+}
+/**
+ * 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 (values.length != size) throw new IllegalArgumentException("Must have same number of cells: length="+values.length+"size()="+size());
+	for (int i=size; --i >= 0;) {
+		setQuick(i,values[i]);
+	}
+	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) {
+	for (int i=size; --i >= 0;) {
+		setQuick(i,value);
+	}
+	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) {
+	for (int i=size; --i >= 0; ) {
+		setQuick(i, function.apply(getQuick(i)));
+	}
+	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     other   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 other) {
+	if (other==this) return this;
+	checkSize(other);
+	if (haveSharedCells(other)) other = other.copy();
+	
+	for (int i=size; --i >= 0;) {
+		setQuick(i,other.getQuick(i));
+	}
+	return this;
+}
+/**
+Assigns the result of a function to each cell; <tt>x[i] = function(x[i],y[i])</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
+</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) {
+	checkSize(y);
+	for (int i=size; --i >= 0; ) {
+		setQuick(i, function.apply(getQuick(i), y.getQuick(i)));
+	}
+	return this;
+}
+/**
+Assigns the result of a function to each cell; <tt>x[i] = function(x[i],y[i])</tt>.
+(Iterates downwards from <tt>[size()-1]</tt> to <tt>[0]</tt>).
+<p>
+<b>Example:</b>
+<pre>
+// assign x[i] = x[i]<sup>y[i]</sup>
+m1 = 0 1 2 3;
+m2 = 0 2 4 6;
+m1.assign(m2, org.apache.mahout.jet.math.Functions.pow);
+-->
+m1 == 1 1 16 729
+
+// for non-standard functions there is no shortcut: 
+m1.assign(m2,
+&nbsp;&nbsp;&nbsp;new DoubleDoubleFunction() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public double apply(double x, double y) { return Math.pow(x,y); }
+&nbsp;&nbsp;&nbsp;}
+);
+</pre>
+For further examples, see the <a href="package-summary.html#FunctionObjects">package doc</a>.
+
+@param y the secondary matrix to operate on.
+@param function a function object taking as first argument the current cell's value of <tt>this</tt>,
+and as second argument the current cell's value of <tt>y</tt>,
+@return <tt>this</tt> (for convenience only).
+@throws	IllegalArgumentException if <tt>size() != y.size()</tt>.
+@see org.apache.mahout.jet.math.Functions
+*/
+public DoubleMatrix1D assign(DoubleMatrix1D y, org.apache.mahout.colt.function.DoubleDoubleFunction function, org.apache.mahout.colt.list.IntArrayList nonZeroIndexes) {
+	checkSize(y);
+	int[] nonZeroElements = nonZeroIndexes.elements();
+
+	// specialized for speed
+	if (function== org.apache.mahout.jet.math.Functions.mult) {  // x[i] = x[i] * y[i]
+	    int j = 0;
+		for (int index=nonZeroIndexes.size(); --index >= 0; ) {
+			int i = nonZeroElements[index];
+			for (; j<i; j++) setQuick(j,0); // x[i] = 0 for all zeros
+			setQuick(i, getQuick(i) * y.getQuick(i));  // x[i] * y[i] for all nonZeros
+			j++;
+		}
+	}
+	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 index=nonZeroIndexes.size(); --index >= 0; ) {
+				int i = nonZeroElements[index];
+				setQuick(i, getQuick(i) + y.getQuick(i));
+			}
+		}
+		else if (multiplicator == -1) { // x[i] = x[i] - y[i]
+			for (int index=nonZeroIndexes.size(); --index >= 0; ) {
+				int i = nonZeroElements[index];
+				setQuick(i, getQuick(i) - y.getQuick(i));
+			}
+		}
+		else { // the general case x[i] = x[i] + mult*y[i]
+			for (int index=nonZeroIndexes.size(); --index >= 0; ) {
+				int i = nonZeroElements[index];
+				setQuick(i, getQuick(i) + multiplicator*y.getQuick(i));
+			}
+		}
+	}
+	else { // the general case x[i] = f(x[i],y[i])
+		return assign(y,function);
+	}
+	return this;
+}
+/**
+ * Returns the number of cells having non-zero values; ignores tolerance.
+ */
+public int cardinality() {
+	int cardinality = 0;
+	for (int i=size; --i >= 0;) {
+		if (getQuick(i) != 0) cardinality++;
+	}
+	return cardinality;
+}
+/**
+ * Returns the number of cells having non-zero values, but at most maxCardinality; ignores tolerance.
+ */
+protected int cardinality(int maxCardinality) {
+	int cardinality = 0;
+	int i=size; 
+	while (--i >= 0 && cardinality < maxCardinality) {
+		if (getQuick(i) != 0) cardinality++;
+	}
+	return cardinality;
+}
+/**
+ * Constructs and returns a deep copy of the receiver.
+ * <p>
+ * <b>Note that the returned matrix is an independent deep copy.</b>
+ * The returned matrix is not backed by this matrix, so changes in the returned matrix are not reflected in this matrix, and vice-versa. 
+ *
+ * @return  a deep copy of the receiver.
+ */
+public DoubleMatrix1D copy() {
+	DoubleMatrix1D copy = like();
+	copy.assign(this);
+	return copy;
+}
+/**
+ * Returns whether all cells are equal to the given value.
+ *
+ * @param     value the value to test against.
+ * @return    <tt>true</tt> if all cells are equal to the given value, <tt>false</tt> otherwise.
+ */
+public boolean equals(double value) {
+	return org.apache.mahout.colt.matrix.linalg.Property.DEFAULT.equals(this,value);
+}
+/**
+ * Compares this object against the specified object.
+ * The result is <code>true</code> if and only if the argument is 
+ * not <code>null</code> and is at least a <code>DoubleMatrix1D</code> object
+ * that has the same sizes as the receiver and 
+ * has exactly the same values at the same indexes.
+ * @param   obj   the object to compare with.
+ * @return  <code>true</code> if the objects are the same;
+ *          <code>false</code> otherwise.
+ */
+public boolean equals(Object obj) {
+	if (this == obj) return true;
+	if (obj == null) return false;
+	if (!(obj instanceof DoubleMatrix1D)) return false;
+
+	return org.apache.mahout.colt.matrix.linalg.Property.DEFAULT.equals(this,(DoubleMatrix1D) obj);
+}
+/**
+ * Returns the matrix cell value at coordinate <tt>index</tt>.
+ *
+ * @param     index   the index of the cell.
+ * @return    the value of the specified cell.
+ * @throws	IndexOutOfBoundsException if <tt>index&lt;0 || index&gt;=size()</tt>.
+ */
+public double get(int index) {
+	if (index<0 || index>=size) checkIndex(index);
+	return getQuick(index);
+}
+/**
+ * Returns the content of this matrix if it is a wrapper; or <tt>this</tt> otherwise.
+ * Override this method in wrappers.
+ */
+protected DoubleMatrix1D getContent() {
+	return this;
+}
+/**
+Fills the coordinates and values of cells having non-zero values into the specified lists.
+Fills into the lists, starting at index 0.
+After this call returns the specified lists all have a new size, the number of non-zero values.
+<p>
+In general, fill order is <i>unspecified</i>.
+This implementation fills like: <tt>for (index = 0..size()-1)  do ... </tt>.
+However, subclasses are free to us any other order, even an order that may change over time as cell values are changed.
+(Of course, result lists indexes are guaranteed to correspond to the same cell).
+<p>
+<b>Example:</b>
+<br>
+<pre>
+0, 0, 8, 0, 7
+-->
+indexList  = (2,4)
+valueList  = (8,7)
+</pre>
+In other words, <tt>get(2)==8, get(4)==7</tt>.
+
+@param indexList the list to be filled with indexes, can have any size.
+@param valueList the list to be filled with values, can have any size.
+*/
+public void getNonZeros(IntArrayList indexList, DoubleArrayList valueList) {
+	boolean fillIndexList = indexList != null;
+	boolean fillValueList = valueList != null;
+	if (fillIndexList) indexList.clear(); 
+	if (fillValueList) valueList.clear();
+	int s = size;
+	for (int i=0; i < s; i++) {
+		double value = getQuick(i);
+		if (value != 0) {
+			if (fillIndexList) indexList.add(i);
+			if (fillValueList) valueList.add(value);
+		}
+	}
+}
+/**
+Fills the coordinates and values of cells having non-zero values into the specified lists.
+Fills into the lists, starting at index 0.
+After this call returns the specified lists all have a new size, the number of non-zero values.
+<p>
+In general, fill order is <i>unspecified</i>.
+This implementation fills like: <tt>for (index = 0..size()-1)  do ... </tt>.
+However, subclasses are free to us any other order, even an order that may change over time as cell values are changed.
+(Of course, result lists indexes are guaranteed to correspond to the same cell).
+<p>
+<b>Example:</b>
+<br>
+<pre>
+0, 0, 8, 0, 7
+-->
+indexList  = (2,4)
+valueList  = (8,7)
+</pre>
+In other words, <tt>get(2)==8, get(4)==7</tt>.
+
+@param indexList the list to be filled with indexes, can have any size.
+@param valueList the list to be filled with values, can have any size.
+*/
+public void getNonZeros(IntArrayList indexList, DoubleArrayList valueList, int maxCardinality) {
+	boolean fillIndexList = indexList != null;
+	boolean fillValueList = valueList != null;
+	int card = cardinality(maxCardinality);
+	if (fillIndexList) indexList.setSize(card);
+	if (fillValueList) valueList.setSize(card);
+	if (!(card<maxCardinality)) return;
+
+	if (fillIndexList) indexList.setSize(0);
+	if (fillValueList) valueList.setSize(0);
+	int s = size;
+	for (int i=0; i < s; i++) {
+		double value = getQuick(i);
+		if (value != 0) {
+			if (fillIndexList) indexList.add(i);
+			if (fillValueList) valueList.add(value);
+		}
+	}
+}
+/**
+ * Returns the matrix cell value at coordinate <tt>index</tt>.
+ *
+ * <p>Provided with invalid parameters this method may return invalid objects without throwing any exception.
+ * <b>You should only use this method when you are absolutely sure that the coordinate is within bounds.</b>
+ * Precondition (unchecked): <tt>index&lt;0 || index&gt;=size()</tt>.
+ *
+ * @param     index   the index of the cell.
+ * @return    the value of the specified cell.
+ */
+public abstract double getQuick(int index);
+/**
+ * Returns <tt>true</tt> if both matrices share at least one identical cell.
+ */
+protected boolean haveSharedCells(DoubleMatrix1D other) {
+	if (other==null) return false;
+	if (this==other) return true;
+	return getContent().haveSharedCellsRaw(other.getContent());
+}	
+/**
+ * Returns <tt>true</tt> if both matrices share at least one identical cell.
+ */
+protected boolean haveSharedCellsRaw(DoubleMatrix1D other) {
+	return false;
+}	
+/**
+ * Construct and returns a new empty matrix <i>of the same dynamic type</i> as the receiver, having the same 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.
+ *
+ * @return  a new empty matrix of the same dynamic type.
+ */
+public DoubleMatrix1D like() {
+	return like(size);
+}
+/**
+ * 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 abstract DoubleMatrix1D like(int 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 abstract DoubleMatrix2D like2D(int rows, int columns);
+/**
+ * Sets the matrix cell at coordinate <tt>index</tt> to the specified value.
+ *
+ * @param     index   the index of the cell.
+ * @param    value the value to be filled into the specified cell.
+ * @throws	IndexOutOfBoundsException if <tt>index&lt;0 || index&gt;=size()</tt>.
+ */
+public void set(int index, double value) {
+	if (index<0 || index>=size) checkIndex(index);
+	setQuick(index,value);
+}
+/**
+ * Sets the matrix cell at coordinate <tt>index</tt> to the specified value.
+ *
+ * <p>Provided with invalid parameters this method may access illegal indexes without throwing any exception.
+ * <b>You should only use this method when you are absolutely sure that the coordinate is within bounds.</b>
+ * Precondition (unchecked): <tt>index&lt;0 || index&gt;=size()</tt>.
+ *
+ * @param     index   the index of the cell.
+ * @param    value the value to be filled into the specified cell.
+ */
+public abstract void setQuick(int index, double 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) {
+	checkSize(other);
+	for (int i=size; --i >= 0; ) {
+		double tmp = getQuick(i);
+		setQuick(i, other.getQuick(i));
+		other.setQuick(i, tmp);
+	}
+	return;
+}
+/**
+Constructs and returns a 1-dimensional array containing the cell values.
+The values are copied. So subsequent changes in <tt>values</tt> are not reflected in the matrix, and vice-versa.
+The returned array <tt>values</tt> has the form 
+<br>
+<tt>for (int i=0; i < size(); i++) values[i] = get(i);</tt>
+
+@return an array filled with the values of the cells.
+*/
+public double[] toArray() {
+	double[] values = new double[size];
+	toArray(values);
+	return values;
+}
+/**
+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");
+	for (int i=size; --i >= 0; ) {
+		values[i] = getQuick(i);
+	}
+}
+/**
+ * Returns a string representation using default formatting.
+ * @see org.apache.mahout.colt.matrix.doublealgo.Formatter
+ */
+public String toString() {
+	return new org.apache.mahout.colt.matrix.doublealgo.Formatter().toString(this);
+}
+/**
+ * Constructs and returns a new view equal to the receiver.
+ * The view is a shallow clone. Calls <code>clone()</code> and casts the result.
+ * <p>
+ * <b>Note that the view is not a deep copy.</b>
+ * The returned matrix is backed by this matrix, so changes in the returned matrix are reflected in this matrix, and vice-versa. 
+ * <p>
+ * Use {@link #copy()} to construct an independent deep copy rather than a new view.
+ *
+ * @return  a new view of the receiver.
+ */
+protected DoubleMatrix1D view() {
+	return (DoubleMatrix1D) clone();
+}
+/**
+Constructs and returns a new <i>flip view</i>.
+What used to be index <tt>0</tt> is now index <tt>size()-1</tt>, ..., what used to be index <tt>size()-1</tt> is now index <tt>0</tt>.
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa.
+
+@return a new flip view.
+*/
+public DoubleMatrix1D viewFlip() {
+	return (DoubleMatrix1D) (view().vFlip());
+}
+/**
+Constructs and returns a new <i>sub-range view</i> that is a <tt>width</tt> sub matrix starting at <tt>index</tt>.
+
+Operations on the returned view can only be applied to the restricted range.
+Any attempt to access coordinates not contained in the view will throw an <tt>IndexOutOfBoundsException</tt>.
+<p>
+<b>Note that the view is really just a range restriction:</b> 
+The returned matrix is backed by this matrix, so changes in the returned matrix are reflected in this matrix, and vice-versa. 
+<p>
+The view contains the cells from <tt>index..index+width-1</tt>.
+and has <tt>view.size() == width</tt>.
+A view's legal coordinates are again zero based, as usual.
+In other words, legal coordinates of the view are <tt>0 .. view.size()-1==width-1</tt>.
+As usual, any attempt to access a cell at other coordinates will throw an <tt>IndexOutOfBoundsException</tt>.
+
+@param     index   The index of the first cell.
+@param     width   The width of the range.
+@throws	IndexOutOfBoundsException if <tt>index<0 || width<0 || index+width>size()</tt>.
+@return the new view.
+		
+*/
+public DoubleMatrix1D viewPart(int index, int width) {
+	return (DoubleMatrix1D) (view().vPart(index,width));
+}
+/**
+Constructs and returns a new <i>selection view</i> that is a matrix holding the indicated cells.
+There holds <tt>view.size() == indexes.length</tt> and <tt>view.get(i) == this.get(indexes[i])</tt>.
+Indexes can occur multiple times and can be in arbitrary order.
+<p>
+<b>Example:</b>
+<br>
+<pre>
+this     = (0,0,8,0,7)
+indexes  = (0,2,4,2)
+-->
+view     = (0,8,7,8)
+</pre>
+Note that modifying <tt>indexes</tt> after this call has returned has no effect on the view.
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa. 
+
+@param  indexes   The indexes of the cells that shall be visible in the new view. To indicate that <i>all</i> cells shall be visible, simply set this parameter to <tt>null</tt>.
+@return the new view.
+@throws IndexOutOfBoundsException if <tt>!(0 <= indexes[i] < size())</tt> for any <tt>i=0..indexes.length()-1</tt>.
+*/
+public DoubleMatrix1D viewSelection(int[] indexes) {
+	// check for "all"
+	if (indexes==null) {
+		indexes = new int[size];
+		for (int i=size; --i >= 0; ) indexes[i] = i;
+	}
+	
+	checkIndexes(indexes);
+	int[] offsets = new int[indexes.length];
+	for (int i=indexes.length; --i >= 0; ) {
+		offsets[i] = index(indexes[i]);
+	}
+	return viewSelectionLike(offsets);
+}
+/**
+Constructs and returns a new <i>selection view</i> that is a matrix holding the cells matching the given condition.
+Applies the condition to each cell and takes only those cells where <tt>condition.apply(get(i))</tt> yields <tt>true</tt>.
+<p>
+<b>Example:</b>
+<br>
+<pre>
+// extract and view all cells with even value
+matrix = 0 1 2 3 
+matrix.viewSelection( 
+&nbsp;&nbsp;&nbsp;new DoubleProcedure() {
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public final boolean apply(double a) { return a % 2 == 0; }
+&nbsp;&nbsp;&nbsp;}
+);
+-->
+matrix ==  0 2
+</pre>
+For further examples, see the <a href="package-summary.html#FunctionObjects">package doc</a>.
+The returned view is backed by this matrix, so changes in the returned view are reflected in this matrix, and vice-versa. 
+
+@param  condition The condition to be matched.
+@return the new view.
+*/
+public DoubleMatrix1D viewSelection(org.apache.mahout.colt.function.DoubleProcedure condition) {
+	IntArrayList matches = new IntArrayList();
+	for (int i=0; i < size; i++) {
+		if (condition.apply(getQuick(i))) matches.add(i);
+	}
+	matches.trimToSize();
+	return viewSelection(matches.elements());
+}
+/**
+ * Construct and returns a new selection view.
+ *
+ * @param offsets the offsets of the visible elements.
+ * @return  a new view.
+ */
+protected abstract DoubleMatrix1D viewSelectionLike(int[] offsets);
+/**
+Sorts the vector into ascending order, according to the <i>natural ordering</i>.
+This sort is guaranteed to be <i>stable</i>.
+For further information, see {@link org.apache.mahout.colt.matrix.doublealgo.Sorting#sort(DoubleMatrix1D)}.
+For more advanced sorting functionality, see {@link org.apache.mahout.colt.matrix.doublealgo.Sorting}.
+@return a new sorted vector (matrix) view.
+*/
+public DoubleMatrix1D viewSorted() {
+	return org.apache.mahout.colt.matrix.doublealgo.Sorting.mergeSort.sort(this);
+}
+/**
+Constructs and returns a new <i>stride view</i> which is a sub matrix consisting of every i-th cell.
+More specifically, the view has size <tt>this.size()/stride</tt> holding cells <tt>this.get(i*stride)</tt> for all <tt>i = 0..size()/stride - 1</tt>.
+
+@param  stride  the step factor.
+@throws	IndexOutOfBoundsException if <tt>stride <= 0</tt>.
+@return the new view.
+		
+*/
+public DoubleMatrix1D viewStrides(int stride) {
+	return (DoubleMatrix1D) (view().vStrides(stride));
+}
+/**
+ * Applies a procedure to each cell's value.
+ * Iterates downwards from <tt>[size()-1]</tt> to <tt>[0]</tt>,
+ * as demonstrated by this snippet:
+ * <pre>
+ * for (int i=size(); --i >=0;) {
+ *    if (!procedure.apply(getQuick(i))) return false;
+ * }
+ * return true;
+ * </pre>
+ * Note that an implementation may use more efficient techniques, but must not use any other order.
+ *
+ * @param procedure a procedure object taking as argument the current cell's value. Stops iteration if the procedure returns <tt>false</tt>, otherwise continues. 
+ * @return <tt>false</tt> if the procedure stopped before all elements where iterated over, <tt>true</tt> otherwise. 
+ */
+private boolean xforEach(final org.apache.mahout.colt.function.DoubleProcedure procedure) {
+	for (int i=size; --i >= 0;) {
+		if (!procedure.apply(getQuick(i))) return false;
+	}
+	return true;
+}
+/**
+ * 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>0 .. Math.min(size(),y.size())</tt>.
+ * @param y the second vector.
+ * @return the sum of products.
+ */
+public double zDotProduct(DoubleMatrix1D y) {
+	return zDotProduct(y,0,size);
+}
+/**
+ * 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 (from<0 || length<=0) return 0;
+	
+	int tail = from+length;
+	if (size < tail) tail = size;
+	if (y.size < tail) tail = y.size;
+	length = tail-from;
+	
+	double sum = 0;
+	int i = tail-1;
+	for (int k=length; --k >= 0; i--) {
+		sum += getQuick(i) * y.getQuick(i);
+	}
+	return sum;
+}
+/**
+ * Returns the dot product of two vectors x and y, which is <tt>Sum(x[i]*y[i])</tt>.
+ * Where <tt>x == this</tt>.
+ * @param y the second vector.
+ * @param nonZeroIndexes the indexes of cells in <tt>y</tt>having a non-zero value.
+ * @return the sum of products.
+ */
+public double zDotProduct(DoubleMatrix1D y, int from, int length, IntArrayList nonZeroIndexes) {
+	// determine minimum length
+	if (from<0 || length<=0) return 0;
+	
+	int tail = from+length;
+	if (size < tail) tail = size;
+	if (y.size < tail) tail = y.size;
+	length = tail-from;
+	if (length<=0) return 0;
+
+	// setup
+	int[] nonZeroIndexElements = nonZeroIndexes.elements();
+	int index = 0;
+	int s = nonZeroIndexes.size();
+	
+	// skip to start	
+	while ((index < s) && nonZeroIndexElements[index]<from) index++; 
+
+	// now the sparse dot product
+	int i;
+	double sum = 0;
+	while ((--length >= 0) && (index < s) && ((i=nonZeroIndexElements[index]) < tail)) {
+		sum += getQuick(i) * y.getQuick(i);
+		index++;
+	}
+	
+	return sum;
+}
+/**
+ * Returns the dot product of two vectors x and y, which is <tt>Sum(x[i]*y[i])</tt>.
+ * Where <tt>x == this</tt>.
+ * @param y the second vector.
+ * @param nonZeroIndexes the indexes of cells in <tt>y</tt>having a non-zero value.
+ * @return the sum of products.
+ */
+protected double zDotProduct(DoubleMatrix1D y, IntArrayList nonZeroIndexes) {
+	return zDotProduct(y,0,size,nonZeroIndexes);
+	/*
+	double sum = 0;
+	int[] nonZeroIndexElements = nonZeroIndexes.elements();
+	for (int index=nonZeroIndexes.size(); --index >= 0; ) {
+		int i = nonZeroIndexElements[index];
+		sum += getQuick(i) * y.getQuick(i);
+	}
+	return sum;
+	*/
+}
+/**
+ * Returns the sum of all cells; <tt>Sum( x[i] )</tt>.
+ * @return the sum.
+ */
+public double zSum() {
+	if (size()==0) return 0;
+	return aggregate(org.apache.mahout.jet.math.Functions.plus, org.apache.mahout.jet.math.Functions.identity);
+}
+}

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