You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mahout.apache.org by dl...@apache.org on 2013/11/12 01:50:47 UTC

svn commit: r1540905 - in /mahout/trunk: ./ math-scala/ math-scala/src/ math-scala/src/main/ math-scala/src/main/scala/ math-scala/src/main/scala/mahout/ math-scala/src/main/scala/mahout/math/ math-scala/src/test/ math-scala/src/test/scala/ math-scala/...

Author: dlyubimov
Date: Tue Nov 12 00:50:47 2013
New Revision: 1540905

URL: http://svn.apache.org/r1540905
Log:
MAHOUT-1297: initial write-up of in-core mahout scala DSL

Squashed commit of the following:

commit 9fff9c190f908133d288512c1ae1deef617a0845
Merge: 62aa138 ebfb3a3
Author: Dmitriy Lyubimov <dl...@apache.org>
Date:   Mon Nov 11 16:19:27 2013 -0800

    Merge branch 'trunk' into MAHOUT-1297

commit 62aa1387067d33b1d9253e093dea59f7393308a0
Author: Dmitriy Lyubimov <dl...@apache.org>
Date:   Tue Nov 5 14:35:59 2013 -0800

    Fixing license headers.

commit dd921c4261af0d8d48437b166a964373a30d6f85
Author: Dmitriy Lyubimov <dl...@apache.org>
Date:   Tue Nov 5 14:28:42 2013 -0800

    cutting off MAHOUT-1297 from the head of scala-dev branch using tree merge for the math-scala subtree.

Added:
    mahout/trunk/math-scala/
    mahout/trunk/math-scala/pom.xml
    mahout/trunk/math-scala/src/
    mahout/trunk/math-scala/src/main/
    mahout/trunk/math-scala/src/main/scala/
    mahout/trunk/math-scala/src/main/scala/mahout/
    mahout/trunk/math-scala/src/main/scala/mahout/math/
    mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeMatrixOps.scala
    mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeOps.scala
    mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeTimesOps.scala
    mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeVectorOps.scala
    mahout/trunk/math-scala/src/main/scala/mahout/math/MatrixOps.scala
    mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeMatrixOps.scala
    mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeOps.scala
    mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeTimesOps.scala
    mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeVectorOps.scala
    mahout/trunk/math-scala/src/main/scala/mahout/math/SSVD.scala
    mahout/trunk/math-scala/src/main/scala/mahout/math/VectorOps.scala
    mahout/trunk/math-scala/src/main/scala/mahout/math/package.scala
    mahout/trunk/math-scala/src/test/
    mahout/trunk/math-scala/src/test/scala/
    mahout/trunk/math-scala/src/test/scala/mahout/
    mahout/trunk/math-scala/src/test/scala/mahout/math/
    mahout/trunk/math-scala/src/test/scala/mahout/math/MathSuite.scala
    mahout/trunk/math-scala/src/test/scala/mahout/math/MatlabLikeMatrixOpsSuite.scala
    mahout/trunk/math-scala/src/test/scala/mahout/math/MatrixOpsSuite.scala
    mahout/trunk/math-scala/src/test/scala/mahout/math/RLikeMatrixOpsSuite.scala
    mahout/trunk/math-scala/src/test/scala/mahout/math/RLikeVectorOpsSuite.scala
    mahout/trunk/math-scala/src/test/scala/mahout/math/VectorOpsSuite.scala
Modified:
    mahout/trunk/pom.xml

Added: mahout/trunk/math-scala/pom.xml
URL: http://svn.apache.org/viewvc/mahout/trunk/math-scala/pom.xml?rev=1540905&view=auto
==============================================================================
--- mahout/trunk/math-scala/pom.xml (added)
+++ mahout/trunk/math-scala/pom.xml Tue Nov 12 00:50:47 2013
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements.  See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.mahout</groupId>
+    <artifactId>mahout</artifactId>
+    <version>0.9-SNAPSHOT</version>
+    <relativePath>../pom.xml</relativePath>
+  </parent>
+
+  <artifactId>mahout-math-scala</artifactId>
+  <name>Mahout Math/Scala wrappers</name>
+  <description>High performance scientific and technical computing data structures and methods,
+    mostly based on CERN's
+    Colt Java API
+  </description>
+
+  <packaging>jar</packaging>
+
+  <!-- this is needed for scalatest plugin until they publish it to central -->
+  <pluginRepositories>
+    <pluginRepository>
+      <id>sonatype</id>
+      <url>https://oss.sonatype.org/content/groups/public</url>
+      <releases>
+        <enabled>true</enabled>
+      </releases>
+    </pluginRepository>
+  </pluginRepositories>
+
+  <build>
+    <defaultGoal>install</defaultGoal>
+
+    <plugins>
+
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>add-source</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>add-source</goal>
+            </goals>
+            <configuration>
+              <sources>
+                <source>${project.build.directory}/generated-sources/mahout</source>
+              </sources>
+            </configuration>
+          </execution>
+          <execution>
+            <id>add-test-source</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>add-test-source</goal>
+            </goals>
+            <configuration>
+              <sources>
+                <source>${project.build.directory}/generated-test-sources/mahout</source>
+              </sources>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!-- create test jar so other modules can reuse the math test utility classes. -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+            <phase>package</phase>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-javadoc-plugin</artifactId>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-source-plugin</artifactId>
+      </plugin>
+
+      <plugin>
+        <groupId>org.scala-tools</groupId>
+        <artifactId>maven-scala-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>compile</goal>
+              <goal>testCompile</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <sourceDir>src/main/scala</sourceDir>
+          <jvmArgs>
+            <jvmArg>-Xms64m</jvmArg>
+            <jvmArg>-Xmx1024m</jvmArg>
+          </jvmArgs>
+        </configuration>
+      </plugin>
+
+      <!--this is what scalatest recommends to do to enable scala tests -->
+
+      <!-- disable surefire -->
+      <!--<plugin>-->
+        <!--<groupId>org.apache.maven.plugins</groupId>-->
+        <!--<artifactId>maven-surefire-plugin</artifactId>-->
+        <!--<version>2.7</version>-->
+        <!--<configuration>-->
+          <!--<skipTests>true</skipTests>-->
+        <!--</configuration>-->
+      <!--</plugin>-->
+      <!-- enable scalatest -->
+      <plugin>
+        <groupId>org.scalatest</groupId>
+        <artifactId>scalatest-maven-plugin</artifactId>
+        <version>1.0-M2</version>
+        <configuration>
+          <reportsDirectory>${project.build.directory}/scalatest-reports</reportsDirectory>
+          <junitxml>.</junitxml>
+          <filereports>WDF TestSuite.txt</filereports>
+        </configuration>
+        <executions>
+          <execution>
+            <id>test</id>
+            <goals>
+              <goal>test</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+    </plugins>
+  </build>
+
+  <dependencies>
+
+    <dependency>
+      <groupId>org.apache.mahout</groupId>
+      <artifactId>mahout-math</artifactId>
+      <version>${pom.version}</version>
+    </dependency>
+
+
+    <!--  3rd-party -->
+
+    <!-- scala stuff -->
+    <dependency>
+      <groupId>org.scala-lang</groupId>
+      <artifactId>scala-library</artifactId>
+      <version>2.9.3</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.scalatest</groupId>
+      <artifactId>scalatest_2.9.2</artifactId>
+      <version>1.9.1</version>
+      <scope>test</scope>
+    </dependency>
+
+  </dependencies>
+</project>

Added: mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeMatrixOps.scala
URL: http://svn.apache.org/viewvc/mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeMatrixOps.scala?rev=1540905&view=auto
==============================================================================
--- mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeMatrixOps.scala (added)
+++ mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeMatrixOps.scala Tue Nov 12 00:50:47 2013
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package mahout.math
+
+import org.apache.mahout.math.{Vector, Matrix}
+import scala.collection.JavaConversions._
+import RLikeOps._
+
+class MatlabLikeMatrixOps(_m: Matrix) extends MatrixOps(_m) {
+
+  /**
+   * matrix-matrix multiplication
+   * @param that
+   * @return
+   */
+  def *(that: Matrix) = m.times(that)
+
+  /**
+   * matrix-vector multiplication
+   * @param that
+   * @return
+   */
+  def *(that: Vector) = m.times(that)
+
+  /**
+   * Hadamard product
+   *
+   * @param that
+   * @return
+   */
+
+  private[math] def *@(that: Matrix) = cloned *= that
+
+  private[math] def *@(that: Double) = cloned *= that
+
+  /**
+   * in-place Hadamard product. We probably don't want to use assign
+   * to optimize for sparse operations, in case of Hadamard product
+   * it really can be done
+   * @param that
+   */
+  private[math] def *@=(that: Matrix) = {
+    m.zip(that).foreach(t => t._1.vector *= t._2.vector)
+    m
+  }
+
+  private[math] def *@=(that: Double) = {
+    m.foreach(_.vector() *= that)
+    m
+  }
+}
+

Added: mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeOps.scala
URL: http://svn.apache.org/viewvc/mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeOps.scala?rev=1540905&view=auto
==============================================================================
--- mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeOps.scala (added)
+++ mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeOps.scala Tue Nov 12 00:50:47 2013
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mahout.math
+
+import org.apache.mahout.math.{Vector, MatrixTimesOps, Matrix}
+
+/**
+ * Matlab-like operators. Declare <code>import MatlabLikeOps._</code> to enable.
+ *
+ * (This option is mutually exclusive to other translations such as RLikeOps).
+ */
+object MatlabLikeOps {
+
+  implicit def v2vOps(v: Vector) = new MatlabLikeVectorOps(v)
+
+  implicit def times2timesOps(m: MatrixTimesOps) = new MatlabLikeTimesOps(m)
+
+  implicit def m2mOps(m: Matrix) = new MatlabLikeMatrixOps(m)
+
+}

Added: mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeTimesOps.scala
URL: http://svn.apache.org/viewvc/mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeTimesOps.scala?rev=1540905&view=auto
==============================================================================
--- mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeTimesOps.scala (added)
+++ mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeTimesOps.scala Tue Nov 12 00:50:47 2013
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mahout.math
+
+import org.apache.mahout.math.{Matrix, MatrixTimesOps}
+
+class MatlabLikeTimesOps(m: MatrixTimesOps) {
+
+  def :*(that: Matrix) = m.timesRight(that)
+
+  def *:(that: Matrix) = m.timesLeft(that)
+
+}

Added: mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeVectorOps.scala
URL: http://svn.apache.org/viewvc/mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeVectorOps.scala?rev=1540905&view=auto
==============================================================================
--- mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeVectorOps.scala (added)
+++ mahout/trunk/math-scala/src/main/scala/mahout/math/MatlabLikeVectorOps.scala Tue Nov 12 00:50:47 2013
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mahout.math
+
+import org.apache.mahout.math.Vector
+import org.apache.mahout.math.function.Functions
+import RLikeOps._
+
+/**
+ * R-like operators.
+ *
+ * For now, all element-wise operators are declared private to math package
+ * since we are still discussing what is the best approach to have to replace
+ * Matlab syntax for elementwise '.*' since it is not directly available for
+ * Scala DSL.
+ *
+ * @param _v
+ */
+class MatlabLikeVectorOps(_v: Vector) extends VectorOps(_v) {
+
+  /** Elementwise *= */
+  private[math] def *@=(that: Vector) = v.assign(that, Functions.MULT)
+
+  /** Elementwise /= */
+  private[math] def /@=(that: Vector) = v.assign(that, Functions.DIV)
+
+  /** Elementwise *= */
+  private[math] def *@=(that: Double) = v.assign(Functions.MULT, that)
+
+  /** Elementwise /= */
+  private[math] def /@=(that: Double) = v.assign(Functions.DIV, that)
+
+  /** Elementwise right-associative /= */
+  private[math] def /@=:(that: Double) = v.assign(Functions.INV).assign(Functions.MULT, that)
+
+  /** Elementwise right-associative /= */
+  private[math] def /@=:(that: Vector) = v.assign(Functions.INV).assign(that, Functions.MULT)
+
+  /** Elementwise * */
+  private[math] def *@(that: Vector) = cloned *= that
+
+  /** Elementwise * */
+  private[math] def *@(that: Double) = cloned *= that
+
+  /** Elementwise / */
+  private[math] def /@(that: Vector) = cloned /= that
+
+  /** Elementwise / */
+  private[math] def /@(that: Double) = cloned /= that
+
+  /** Elementwise right-associative / */
+  private[math] def /@:(that: Double) = that /=: v.cloned
+
+  /** Elementwise right-associative / */
+  private[math] def /@:(that: Vector) = that.cloned /= v
+
+
+}
\ No newline at end of file

Added: mahout/trunk/math-scala/src/main/scala/mahout/math/MatrixOps.scala
URL: http://svn.apache.org/viewvc/mahout/trunk/math-scala/src/main/scala/mahout/math/MatrixOps.scala?rev=1540905&view=auto
==============================================================================
--- mahout/trunk/math-scala/src/main/scala/mahout/math/MatrixOps.scala (added)
+++ mahout/trunk/math-scala/src/main/scala/mahout/math/MatrixOps.scala Tue Nov 12 00:50:47 2013
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mahout.math
+
+import org.apache.mahout.math.{Matrices, QRDecomposition, Vector, Matrix}
+import scala.collection.JavaConversions._
+import org.apache.mahout.math.function.{DoubleFunction, Functions}
+import scala.math._
+
+class MatrixOps(val m: Matrix) {
+
+  import MatrixOps._
+
+  def nrow = m.rowSize()
+
+  def ncol = m.columnSize()
+
+
+  def unary_- = m.assign(Functions.NEGATE)
+
+  def +=(that: Matrix) = m.assign(that, Functions.PLUS)
+
+  def -=(that: Matrix) = m.assign(that, Functions.MINUS)
+
+  def +=(that: Double) = m.assign(new DoubleFunction {
+    def apply(x: Double): Double = x + that
+  })
+
+  def -=(that: Double) = +=(-that)
+
+  def +(that: Matrix) = cloned += that
+
+  def -(that: Matrix) = cloned -= that
+
+  // m.plus(that)?
+
+  def +(that: Double) = cloned += that
+
+  def -(that: Double) = cloned -= that
+
+
+  def norm = sqrt(m.aggregate(Functions.PLUS, Functions.SQUARE))
+
+  def pnorm(p: Int) = pow(m.aggregate(Functions.PLUS, Functions.chain(Functions.ABS, Functions.pow(p))), 1.0 / p)
+
+  def apply(row: Int, col: Int) = m.get(row, col)
+
+  def update(row: Int, col: Int, v: Double): Matrix = {
+    m.setQuick(row, col, v);
+    m
+  }
+
+  def update(rowRange: Range, colRange: Range, that: Matrix) = apply(rowRange, colRange) := that
+
+  def update(row: Int, colRange: Range, that: Vector) = apply(row, colRange) := that
+
+  def update(rowRange: Range, col: Int, that: Vector) = apply(rowRange, col) := that
+
+  def apply(rowRange: Range, colRange: Range): Matrix = {
+
+    if (rowRange == :: &&
+        colRange == ::) return m
+
+    val rr = if (rowRange == ::) (0 until m.nrow)
+    else rowRange
+    val cr = if (colRange == ::) (0 until m.ncol)
+    else colRange
+
+    return m.viewPart(rr.start, rr.length, cr.start, cr.length)
+
+  }
+
+  def apply(row: Int, colRange: Range): Vector = {
+    var r = m.viewRow(row)
+    if (colRange != ::) r = r.viewPart(colRange.start, colRange.length)
+    r
+  }
+
+  def apply(rowRange: Range, col: Int): Vector = {
+    var c = m.viewColumn(col)
+    if (rowRange != ::) c = c.viewPart(rowRange.start, rowRange.length)
+    c
+  }
+
+  /**
+   * Warning: This provides read-only view only.
+   * In most cases that's what one wants. To get a copy,
+   * use <code>m.t cloned</code>
+   * @return transposed view
+   */
+  def t = Matrices.transposedView(m)
+
+  def det = m.determinant()
+
+  def sum = m.zSum()
+
+  def :=(that: Matrix) = m.assign(that)
+
+  /**
+   * Assigning from a row-wise collection of vectors
+   * @param that
+   */
+  def :=(that: TraversableOnce[Vector]) = {
+    var row = 0
+    that.foreach(v => {
+      m.assignRow(row, v)
+      row += 1
+    })
+  }
+
+  def :=(f: (Int, Int, Double) => Double): Matrix = {
+    for (r <- 0 until nrow; c <- 0 until ncol) m(r, c) = f(r, c, m(r, c))
+    m
+  }
+
+  def cloned: Matrix = m.like := m
+
+  /**
+   * Ideally, we would probably want to override equals(). But that is not
+   * possible without modifying AbstractMatrix implementation in Mahout
+   * which would require discussion at Mahout team.
+   * @param that
+   * @return
+   */
+  def equiv(that: Matrix) =
+    that != null &&
+        nrow == that.nrow &&
+        m.view.zip(that).forall(t => {
+          t._1.equiv(t._2)
+        })
+
+  def nequiv(that: Matrix) = !equiv(that)
+
+  def ===(that: Matrix) = equiv(that)
+
+  def !==(that: Matrix) = nequiv(that)
+
+  /**
+   * test if rank == min(nrow,ncol).
+   * @return
+   */
+  def isFullRank: Boolean =
+    new QRDecomposition(if (nrow < ncol) m t else m cloned).hasFullRank
+}
+
+object MatrixOps {
+  implicit def m2ops(m: Matrix): MatrixOps = new MatrixOps(m)
+
+  implicit def v2ops(v: Vector): VectorOps = new VectorOps(v)
+}
\ No newline at end of file

Added: mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeMatrixOps.scala
URL: http://svn.apache.org/viewvc/mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeMatrixOps.scala?rev=1540905&view=auto
==============================================================================
--- mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeMatrixOps.scala (added)
+++ mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeMatrixOps.scala Tue Nov 12 00:50:47 2013
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package mahout.math
+
+import org.apache.mahout.math.{Vector, Matrix}
+import scala.collection.JavaConversions._
+import RLikeOps._
+
+class RLikeMatrixOps(_m: Matrix) extends MatrixOps(_m) {
+
+  /**
+   * matrix-matrix multiplication
+   * @param that
+   * @return
+   */
+  def %*%(that: Matrix) = m.times(that)
+
+  /**
+   * matrix-vector multiplication
+   * @param that
+   * @return
+   */
+  def %*%(that: Vector) = m.times(that)
+
+  /**
+   * Hadamard product
+   *
+   * @param that
+   * @return
+   */
+
+  def *(that: Matrix) = cloned *= that
+
+  def *(that: Double) = cloned *= that
+
+  /**
+   * in-place Hadamard product. We probably don't want to use assign
+   * to optimize for sparse operations, in case of Hadamard product
+   * it really can be done
+   * @param that
+   */
+  def *=(that: Matrix) = {
+    m.zip(that).foreach(t => t._1.vector *= t._2.vector)
+    m
+  }
+
+  def *=(that: Double) = {
+    m.foreach(_.vector() *= that)
+    m
+  }
+}
+

Added: mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeOps.scala
URL: http://svn.apache.org/viewvc/mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeOps.scala?rev=1540905&view=auto
==============================================================================
--- mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeOps.scala (added)
+++ mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeOps.scala Tue Nov 12 00:50:47 2013
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mahout.math
+
+import org.apache.mahout.math.{Vector, MatrixTimesOps, Matrix}
+
+/**
+ * R-like operators. Declare <code>import RLikeOps._</code> to enable.
+ */
+object RLikeOps {
+
+  implicit def v2vOps(v: Vector) = new RLikeVectorOps(v)
+
+  implicit def times2timesOps(m: MatrixTimesOps) = new RLikeTimesOps(m)
+
+  implicit def m2mOps(m: Matrix) = new RLikeMatrixOps(m)
+
+}

Added: mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeTimesOps.scala
URL: http://svn.apache.org/viewvc/mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeTimesOps.scala?rev=1540905&view=auto
==============================================================================
--- mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeTimesOps.scala (added)
+++ mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeTimesOps.scala Tue Nov 12 00:50:47 2013
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mahout.math
+
+import org.apache.mahout.math.{Matrix, MatrixTimesOps}
+
+class RLikeTimesOps(m: MatrixTimesOps) {
+
+  def :%*%(that: Matrix) = m.timesRight(that)
+
+  def %*%:(that: Matrix) = m.timesLeft(that)
+
+}

Added: mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeVectorOps.scala
URL: http://svn.apache.org/viewvc/mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeVectorOps.scala?rev=1540905&view=auto
==============================================================================
--- mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeVectorOps.scala (added)
+++ mahout/trunk/math-scala/src/main/scala/mahout/math/RLikeVectorOps.scala Tue Nov 12 00:50:47 2013
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mahout.math
+
+import org.apache.mahout.math.Vector
+import org.apache.mahout.math.function.Functions
+import RLikeOps._
+
+/**
+ * R-like operators
+ *
+ * @param _v
+ */
+class RLikeVectorOps(_v: Vector) extends VectorOps(_v) {
+
+  /** Elementwise *= */
+  def *=(that: Vector) = v.assign(that, Functions.MULT)
+
+  /** Elementwise /= */
+  def /=(that: Vector) = v.assign(that, Functions.DIV)
+
+  /** Elementwise *= */
+  def *=(that: Double) = v.assign(Functions.MULT, that)
+
+  /** Elementwise /= */
+  def /=(that: Double) = v.assign(Functions.DIV, that)
+
+  /** Elementwise right-associative /= */
+  def /=:(that: Double) = v.assign(Functions.INV).assign(Functions.MULT, that)
+
+  /** Elementwise right-associative /= */
+  def /=:(that: Vector) = v.assign(Functions.INV).assign(that, Functions.MULT)
+
+  /** Elementwise * */
+  def *(that: Vector) = cloned *= that
+
+  /** Elementwise * */
+  def *(that: Double) = cloned *= that
+
+  /** Elementwise / */
+  def /(that: Vector) = cloned /= that
+
+  /** Elementwise / */
+  def /(that: Double) = cloned /= that
+
+  /** Elementwise right-associative / */
+  def /:(that: Double) = that /=: v.cloned
+
+  /** Elementwise right-associative / */
+  def /:(that: Vector) = that.cloned /= v
+
+
+}
\ No newline at end of file

Added: mahout/trunk/math-scala/src/main/scala/mahout/math/SSVD.scala
URL: http://svn.apache.org/viewvc/mahout/trunk/math-scala/src/main/scala/mahout/math/SSVD.scala?rev=1540905&view=auto
==============================================================================
--- mahout/trunk/math-scala/src/main/scala/mahout/math/SSVD.scala (added)
+++ mahout/trunk/math-scala/src/main/scala/mahout/math/SSVD.scala Tue Nov 12 00:50:47 2013
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mahout.math
+
+import math._
+import org.apache.mahout.math.{Matrices, Matrix}
+import RLikeOps._
+import org.apache.mahout.common.RandomUtils
+
+private[math] object SSVD {
+
+  /**
+   * In-core SSVD algorithm.
+   *
+   * @param a input matrix A
+   * @param k request SSVD rank
+   * @param p oversampling parameter
+   * @param q number of power iterations
+   * @return (U,V,s)
+   */
+  def ssvd(a: Matrix, k: Int, p: Int = 15, q: Int = 0) = {
+    val m = a.nrow
+    val n = a.ncol
+    if (k > min(m, n))
+      throw new IllegalArgumentException(
+        "k cannot be greater than smaller of m,n")
+    val pfxed = min(p, min(m, n) - k)
+
+    // actual decomposition rank
+    val r = k + pfxed
+
+    val rnd = RandomUtils.getRandom
+    val omega = Matrices.symmetricUniformView(n, r, rnd.nextInt)
+
+    var y = a %*% omega
+    var yty = y.t %*% y
+    val at = a.t
+    var ch = chol(yty)
+    var bt = ch.solveRight(at %*% y)
+
+
+    // power iterations
+    for (i <- 0 until q) {
+      y = a %*% bt
+      yty = y.t %*% y
+      ch = chol(yty)
+      bt = ch.solveRight(at %*% y)
+    }
+
+    val bbt = bt.t %*% bt
+    val (uhat, d) = eigen(bbt)
+
+    val s = d.sqrt
+    val u = ch.solveRight(y) %*% uhat
+    val v = bt %*% (uhat %*%: diagv(1 /: s))
+
+    (u(::, 0 until k), v(::, 0 until k), s(0 until k))
+
+  }
+
+}

Added: mahout/trunk/math-scala/src/main/scala/mahout/math/VectorOps.scala
URL: http://svn.apache.org/viewvc/mahout/trunk/math-scala/src/main/scala/mahout/math/VectorOps.scala?rev=1540905&view=auto
==============================================================================
--- mahout/trunk/math-scala/src/main/scala/mahout/math/VectorOps.scala (added)
+++ mahout/trunk/math-scala/src/main/scala/mahout/math/VectorOps.scala Tue Nov 12 00:50:47 2013
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mahout.math
+
+import org.apache.mahout.math.Vector
+import scala.collection.JavaConversions._
+import org.apache.mahout.math.function.Functions
+
+/**
+ * Syntactic sugar for mahout vectors
+ * @param v Mahout vector
+ */
+class VectorOps(val v: Vector) {
+
+  import VectorOps.v2ops
+
+  def apply(i: Int) = v.get(i)
+
+  def update(i: Int, that: Double) = v.setQuick(i, that)
+
+  /** Warning: we only support consecutive views, step is not supported directly */
+  def apply(r: Range) = if (r == ::) v else v.viewPart(r.start, r.length * r.step)
+
+  def update(r: Range, that: Vector) = apply(r) := that
+
+  def sum = v.zSum()
+
+  def :=(that: Vector): Vector = {
+
+    // assign op in Mahout requires same
+    // cardinality between vectors .
+    // we want to relax it here and require
+    // v to have _at least_ as large cardinality
+    // as "that".
+    if (that.length == v.size())
+      v.assign(that)
+    else if (that.length < v.size) {
+      v.assign(0.0)
+      that.nonZeroes().foreach(t => v.setQuick(t.index, t.get))
+      v
+    } else throw new IllegalArgumentException("Assigner's cardinality less than assignee's")
+  }
+
+  def :=(that: Double): Vector = v.assign(that)
+
+  def :=(f: (Int, Double) => Double): Vector = {
+    for (i <- 0 until length) v(i) = f(i, v(i))
+    v
+  }
+
+  def equiv(that: Vector) =
+    length == that.length &&
+        v.all.view.zip(that.all).forall(t => t._1.get == t._2.get)
+
+  def ===(that: Vector) = equiv(that)
+
+  def !==(that: Vector) = nequiv(that)
+
+  def nequiv(that: Vector) = !equiv(that)
+
+  def unary_- = v.assign(Functions.NEGATE)
+
+  def +=(that: Vector) = v.assign(that, Functions.PLUS)
+
+  def -=(that: Vector) = v.assign(that, Functions.MINUS)
+
+  def +=(that: Double) = v.assign(Functions.PLUS, that)
+
+  def -=(that: Double) = +=(-that)
+
+  def -=:(that: Vector) = v.assign(Functions.NEGATE).assign(that, Functions.PLUS)
+
+  def -=:(that: Double) = v.assign(Functions.NEGATE).assign(Functions.PLUS, that)
+
+  def +(that: Vector) = cloned += that
+
+  def -(that: Vector) = cloned -= that
+
+  def -:(that: Vector) = that.cloned -= v
+
+  def +(that: Double) = cloned += that
+
+  def -(that: Double) = cloned -= that
+
+  def -:(that: Double) = that -=: v.cloned
+
+  def length = v.size()
+
+  def cloned: Vector = v.like := v
+
+  def sqrt = v.cloned.assign(Functions.SQRT)
+
+}
+
+object VectorOps {
+  private implicit def v2ops(v: Vector): VectorOps = new VectorOps(v)
+}

Added: mahout/trunk/math-scala/src/main/scala/mahout/math/package.scala
URL: http://svn.apache.org/viewvc/mahout/trunk/math-scala/src/main/scala/mahout/math/package.scala?rev=1540905&view=auto
==============================================================================
--- mahout/trunk/math-scala/src/main/scala/mahout/math/package.scala (added)
+++ mahout/trunk/math-scala/src/main/scala/mahout/math/package.scala Tue Nov 12 00:50:47 2013
@@ -0,0 +1,236 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mahout
+
+import org.apache.mahout.math._
+import scala.Tuple2
+import org.apache.mahout.math.solver.EigenDecomposition
+
+/**
+ * Mahout matrices and vectors' scala syntactic sugar
+ */
+package object math {
+
+  // Reserved "ALL" range
+  final val `::`: Range = null
+
+  implicit def seq2Vector(s: TraversableOnce[AnyVal]) =
+    new DenseVector(s.map(_.asInstanceOf[Number].doubleValue()).toArray)
+
+  implicit def tuple2TravOnce2svec[V <: AnyVal](sdata: TraversableOnce[(Int, V)]) = svec(sdata)
+
+  implicit def t1vec(s: Tuple1[AnyVal]): Vector = prod2Vec(s)
+
+  implicit def t2vec(s: Tuple2[AnyVal, AnyVal]): Vector = prod2Vec(s)
+
+  implicit def t3vec(s: Tuple3[AnyVal, AnyVal, AnyVal]): Vector = prod2Vec(s)
+
+  implicit def t4vec(s: Tuple4[AnyVal, AnyVal, AnyVal, AnyVal]): Vector = prod2Vec(s)
+
+  implicit def t5vec(s: Tuple5[AnyVal, AnyVal, AnyVal, AnyVal, AnyVal]): Vector = prod2Vec(s)
+
+  implicit def t6vec(s: Tuple6[AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal]): Vector = prod2Vec(s)
+
+  implicit def t7vec(s: Tuple7[AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal]): Vector = prod2Vec(s)
+
+  implicit def t8vec(s: Tuple8[AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal]): Vector = prod2Vec(s)
+
+  implicit def t9vec(s: Tuple9[AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal]): Vector =
+    prod2Vec(s)
+
+  implicit def t10vec(s: Tuple10[AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal])
+  : Vector = prod2Vec(s)
+
+  implicit def t11vec(s: Tuple11[AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal
+      , AnyVal])
+  : Vector = prod2Vec(s)
+
+  implicit def t12vec(s: Tuple12[AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal
+      , AnyVal, AnyVal])
+  : Vector = prod2Vec(s)
+
+  implicit def t13vec(s: Tuple13[AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal
+      , AnyVal, AnyVal, AnyVal])
+  : Vector = prod2Vec(s)
+
+  implicit def t14vec(s: Tuple14[AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal
+      , AnyVal, AnyVal, AnyVal, AnyVal])
+  : Vector = prod2Vec(s)
+
+  implicit def t15vec(s: Tuple15[AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal
+      , AnyVal, AnyVal, AnyVal, AnyVal, AnyVal])
+  : Vector = prod2Vec(s)
+
+  implicit def t16vec(s: Tuple16[AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal
+      , AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal])
+  : Vector = prod2Vec(s)
+
+  implicit def t17vec(s: Tuple17[AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal
+      , AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal])
+  : Vector = prod2Vec(s)
+
+  implicit def t18vec(s: Tuple18[AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal
+      , AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal])
+  : Vector = prod2Vec(s)
+
+  implicit def t19vec(s: Tuple19[AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal
+      , AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal])
+  : Vector = prod2Vec(s)
+
+  implicit def t20vec(s: Tuple20[AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal
+      , AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal])
+  : Vector = prod2Vec(s)
+
+  implicit def t21vec(s: Tuple21[AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal
+      , AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal])
+  : Vector = prod2Vec(s)
+
+  implicit def t22vec(s: Tuple22[AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal
+      , AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal, AnyVal])
+  : Vector = prod2Vec(s)
+
+
+  def prod2Vec(s: Product) = new DenseVector(s.productIterator.
+      map(_.asInstanceOf[Number].doubleValue()).toArray)
+
+  def diagv(v: Vector): DiagonalMatrix = new DiagonalMatrix(v)
+
+  def diag(v: Double, size: Int): DiagonalMatrix =
+    new DiagonalMatrix(new DenseVector(Array.fill(size)(v)))
+
+  def eye(size: Int) = new DiagonalMatrix(1.0, size)
+
+  /**
+   * Create dense matrix out of inline arguments -- rows -- which can be tuples,
+   * iterables of Double, or just single Number (for columnar vectors)
+   * @param rows
+   * @tparam R
+   * @return
+   */
+  def dense[R](rows: R*): DenseMatrix = {
+    import MatrixOps._
+    val data = for (r <- rows) yield {
+      r match {
+        case n: Number => Array(n.doubleValue())
+        case t: Product => t.productIterator.map(_.asInstanceOf[Number].doubleValue()).toArray
+        case t: Vector => Array.tabulate(t.length)(t(_))
+        case t: Array[Double] => t
+        case t: Iterable[Double] => t.toArray
+        case t: Array[Array[Double]] => if (rows.size == 1)
+          return new DenseMatrix(t)
+        else
+          throw new IllegalArgumentException(
+            "double[][] data parameter can be the only argumentn for dense()")
+        case _ => throw new IllegalArgumentException("unsupported type in the inline Matrix initializer")
+      }
+    }
+    new DenseMatrix(data.toArray)
+  }
+
+  /**
+   * Default initializes are always row-wise.
+   * create a sparse,
+   * e.g.
+   * m = sparse(
+   * (0,5)::(9,3)::Nil,
+   * (2,3.5)::(7,8)::Nil
+   * )
+   *
+   * @param rows
+   * @return
+   */
+
+  def sparse(rows: Vector*): SparseRowMatrix = {
+    import MatrixOps._
+    val nrow = rows.size
+    val ncol = rows.map(_.size()).max
+    val m = new SparseRowMatrix(nrow, ncol)
+    m := rows
+    m
+
+  }
+
+  /**
+   * create a sparse vector out of list of tuple2's
+   * @param sdata
+   * @return
+   */
+  def svec(sdata: TraversableOnce[(Int, AnyVal)]) = {
+    val cardinality = if (sdata.size > 0) sdata.map(_._1).max + 1 else 0
+    val initialCapacity = sdata.size
+    val sv = new RandomAccessSparseVector(cardinality, initialCapacity)
+    sdata.foreach(t => sv.setQuick(t._1, t._2.asInstanceOf[Number].doubleValue()))
+    sv
+  }
+
+  def dvec(ddata: TraversableOnce[Double]) = new DenseVector(ddata.toArray)
+
+  def dvec(numbers: Number*) = new DenseVector(numbers.map(_.doubleValue()).toArray)
+
+  def chol(m: Matrix, typ: Boolean = false) = new CholeskyDecomposition(m, typ)
+
+  /**
+   * computes SVD
+   * @param m svd input
+   * @return (U,V, singular-values-vector)
+   */
+  def svd(m: Matrix) = {
+    val svdObj = new SingularValueDecomposition(m)
+    (svdObj.getU, svdObj.getV, new DenseVector(svdObj.getSingularValues))
+  }
+
+  /**
+   * Computes Eigendecomposition of a symmetric matrix
+   * @param m symmetric input matrix
+   * @return (V, eigen-values-vector)
+   */
+  def eigen(m: Matrix) = {
+    val ed = new EigenDecomposition(m, true)
+    (ed.getV, ed.getRealEigenvalues)
+  }
+
+
+  /**
+   * More general version of eigen decomposition
+   * @param m
+   * @param symmetric
+   * @return (V, eigenvalues-real-vector, eigenvalues-imaginary-vector)
+   */
+  def eigenFull(m: Matrix, symmetric: Boolean = true) {
+    val ed = new EigenDecomposition(m, symmetric)
+    (ed.getV, ed.getRealEigenvalues, ed.getImagEigenvalues)
+  }
+
+  /**
+   * QR.
+   *
+   * Right now Mahout's QR seems to be using argument for in-place transformations,
+   * so the matrix context gets messed after this. Hence we force cloning of the
+   * argument before passing it to Mahout's QR so to keep expected semantics.
+   * @param m
+   * @return (Q,R)
+   */
+  def qr(m: Matrix) = {
+    import MatrixOps._
+    val qrdec = new QRDecomposition(m cloned)
+    (qrdec.getQ, qrdec.getR)
+  }
+
+  def ssvd(a: Matrix, k: Int, p: Int = 15, q: Int = 0) = SSVD.ssvd(a, k, p, q)
+
+}

Added: mahout/trunk/math-scala/src/test/scala/mahout/math/MathSuite.scala
URL: http://svn.apache.org/viewvc/mahout/trunk/math-scala/src/test/scala/mahout/math/MathSuite.scala?rev=1540905&view=auto
==============================================================================
--- mahout/trunk/math-scala/src/test/scala/mahout/math/MathSuite.scala (added)
+++ mahout/trunk/math-scala/src/test/scala/mahout/math/MathSuite.scala Tue Nov 12 00:50:47 2013
@@ -0,0 +1,165 @@
+package mahout.math
+
+import org.scalatest.FunSuite
+import org.apache.mahout.math.DenseSymmetricMatrix
+import math._
+import RLikeOps._
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class MathSuite extends FunSuite {
+
+  test("chol") {
+
+    // try to solve Ax=b with cholesky:
+    // this requires
+    // (LL')x = B
+    // L'x= (L^-1)B
+    // x=(L'^-1)(L^-1)B
+
+    val a = dense((1, 2, 3), (2, 3, 4), (3, 4, 5.5))
+
+    // make sure it is symmetric for a valid solution
+    a := a.t %*% a
+
+    printf("A= \n%s\n", a)
+
+    val b = dense((9, 8, 7)).t
+
+    printf("b = \n%s\n", b)
+
+    // fails if chol(a,true)
+    val ch = chol(a)
+
+    printf("L = \n%s\n", ch.getL)
+
+    printf("(L^-1)b =\n%s\n", ch.solveLeft(b))
+
+    val x = ch.solveRight(eye(3)) %*% ch.solveLeft(b)
+
+    printf("x = \n%s\n", x.toString)
+
+    val axmb = (a %*% x) - b
+
+    printf("AX - B = \n%s\n", axmb.toString)
+
+    assert(axmb.norm < 1e-10)
+
+  }
+
+  test("chol2") {
+
+    val vtv = new DenseSymmetricMatrix(
+      Array(
+        0.0021401286568947376, 0.001309251254596442, 0.0016003218703045058,
+        0.001545407014131058, 0.0012772546647977234,
+        0.001747768702674435
+      ), true)
+
+    printf("V'V=\n%s\n", vtv cloned)
+
+    val vblock = dense(
+      (0.0012356809018514347, 0.006141139195280868, 8.037742467936037E-4),
+      (0.007910767859830255, 0.007989899899005457, 0.006877961936587515),
+      (0.007011211118759952, 0.007458865101641882, 0.0048344749320346795),
+      (0.006578789899685284, 0.0010812485516549452, 0.0062146270886981655)
+    )
+
+    val d = diag(15.0, 4)
+
+
+    val b = dense(
+      (0.36378319648203084),
+      (0.3627384439613304),
+      (0.2996934112658234))
+
+    printf("B=\n%s\n", b)
+
+
+    val cholArg = vtv + (vblock.t %*% d %*% vblock) + diag(4e-6, 3)
+
+    printf("cholArg=\n%s\n", cholArg)
+
+    printf("V'DV=\n%s\n", (vblock.t %*% d %*% vblock))
+
+    printf("V'V+V'DV=\n%s\n", vtv + (vblock.t %*% d %*% vblock))
+
+    val ch = chol(cholArg)
+
+    printf("L=\n%s\n", ch.getL)
+
+    val x = ch.solveRight(eye(cholArg.nrow)) %*% ch.solveLeft(b)
+
+    printf("X=\n%s\n", x)
+
+    assert((cholArg %*% x - b).norm < 1e-10)
+
+  }
+
+  test("qr") {
+    val a = dense((1, 2, 3), (2, 3, 6), (3, 4, 5), (4, 7, 8))
+    val (q, r) = qr(a)
+
+    printf("Q=\n%s\n", q)
+    printf("R=\n%s\n", r)
+
+    for (i <- 0 until q.ncol; j <- i + 1 until q.ncol)
+      assert(abs(q(::, i) dot q(::, j)) < 1e-10)
+  }
+
+  test("svd") {
+
+    val a = dense((1, 2, 3), (3, 4, 5))
+
+    val (u, v, s) = svd(a)
+
+    printf("U:\n%s\n", u.toString)
+    printf("V:\n%s\n", v.toString)
+    printf("Sigma:\n%s\n", s.toString)
+
+    val aBar = u %*% diagv(s) %*% v.t
+
+    val amab = a - aBar
+
+    printf("A-USV'=\n%s\n", amab.toString)
+
+    assert(amab.norm < 1e-10)
+
+  }
+
+  test("ssvd") {
+
+    val a = dense((1, 2, 3), (3, 4, 5))
+
+    val (u, v, s) = ssvd(a, 2, q = 1)
+
+    printf("U:\n%s\n", u)
+    printf("V:\n%s\n", v)
+    printf("Sigma:\n%s\n", s)
+
+    val aBar = u %*% diagv(s) %*% v.t
+
+    val amab = a - aBar
+
+    printf("A-USV'=\n%s\n", amab)
+
+    assert(amab.norm < 1e-10)
+
+  }
+
+}

Added: mahout/trunk/math-scala/src/test/scala/mahout/math/MatlabLikeMatrixOpsSuite.scala
URL: http://svn.apache.org/viewvc/mahout/trunk/math-scala/src/test/scala/mahout/math/MatlabLikeMatrixOpsSuite.scala?rev=1540905&view=auto
==============================================================================
--- mahout/trunk/math-scala/src/test/scala/mahout/math/MatlabLikeMatrixOpsSuite.scala (added)
+++ mahout/trunk/math-scala/src/test/scala/mahout/math/MatlabLikeMatrixOpsSuite.scala Tue Nov 12 00:50:47 2013
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mahout.math
+
+import org.scalatest.FunSuite
+import MatlabLikeOps._
+import scala.Predef._
+
+class MatlabLikeMatrixOpsSuite extends FunSuite {
+
+  test("multiplication") {
+
+    val a = dense((1, 2, 3), (3, 4, 5))
+    val b = dense(1, 4, 5)
+    val m = a * b
+
+    assert(m(0, 0) == 24)
+    assert(m(1, 0) == 44)
+    println(m.toString)
+  }
+
+  test("Hadamard") {
+    val a = dense(
+      (1, 2, 3),
+      (3, 4, 5)
+    )
+    val b = dense(
+      (1, 1, 2),
+      (2, 1, 1)
+    )
+
+    val c = a *@ b
+
+    printf("C=\n%s\n", c)
+
+    assert(c(0, 0) == 1)
+    assert(c(1, 2) == 5)
+    println(c.toString)
+
+    val d = a *@ 5.0
+    assert(d(0, 0) == 5)
+    assert(d(1, 1) == 20)
+
+    a *@= b
+    assert(a(0, 0) == 1)
+    assert(a(1, 2) == 5)
+    println(a.toString)
+
+  }
+
+}

Added: mahout/trunk/math-scala/src/test/scala/mahout/math/MatrixOpsSuite.scala
URL: http://svn.apache.org/viewvc/mahout/trunk/math-scala/src/test/scala/mahout/math/MatrixOpsSuite.scala?rev=1540905&view=auto
==============================================================================
--- mahout/trunk/math-scala/src/test/scala/mahout/math/MatrixOpsSuite.scala (added)
+++ mahout/trunk/math-scala/src/test/scala/mahout/math/MatrixOpsSuite.scala Tue Nov 12 00:50:47 2013
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mahout.math
+
+import org.scalatest.FunSuite
+import org.apache.mahout.math.DenseSymmetricMatrix
+import scala.math._
+import MatrixOps._
+
+
+class MatrixOpsSuite extends FunSuite {
+
+
+  test("equivalence") {
+    val a = dense((1, 2, 3), (3, 4, 5))
+    val b = dense((1, 2, 3), (3, 4, 5))
+    val c = dense((1, 4, 3), (3, 4, 5))
+    assert(a === b)
+    assert(a !== c)
+
+  }
+  test("elementwise plus, minus") {
+    val a = dense((1, 2, 3), (3, 4, 5))
+    val b = dense((1, 1, 2), (2, 1, 1))
+
+    val c = a + b
+    assert(c(0, 0) == 2)
+    assert(c(1, 2) == 6)
+    println(c.toString)
+
+  }
+
+  test("matrix, vector slicing") {
+
+    val a = dense((1, 2, 3), (3, 4, 5))
+
+    assert(a(::, 0).sum == 4)
+    assert(a(1, ::).sum == 12)
+
+    assert(a(0 to 1, 1 to 2).sum == 14)
+
+    // assign to slice-vector
+    a(0, 0 to 1) :=(3, 5)
+    // or
+    a(0, 0 to 1) = (3, 5)
+
+    assert(a(0, ::).sum == 11)
+
+    println(a.toString)
+
+    // assign to a slice-matrix
+    a(0 to 1, 0 to 1) := dense((1, 1), (2, 2.5))
+
+    // or
+    a(0 to 1, 0 to 1) = dense((1, 1), (2, 2.5))
+
+    println(a.toString)
+    println(a.sum)
+
+  }
+
+  test("assignments") {
+
+    val a = dense((1, 2, 3), (3, 4, 5))
+
+    val b = a cloned
+
+    b(0, 0) = 2.0
+
+    printf("B=\n%s\n", b)
+
+    assert((b - a).norm - 1 < 1e-10)
+
+    val e = eye(5)
+
+    printf("I(5)=\n%s\n", e)
+
+    a(0 to 1, 1 to 2) = dense((3, 2), (2, 3))
+    a(0 to 1, 1 to 2) := dense((3, 2), (2, 3))
+
+
+  }
+
+
+
+  test("sparse") {
+
+    val a = sparse((1, 3) :: Nil,
+      (0, 2) ::(1, 2.5) :: Nil
+    )
+    println(a.toString)
+  }
+
+}
\ No newline at end of file

Added: mahout/trunk/math-scala/src/test/scala/mahout/math/RLikeMatrixOpsSuite.scala
URL: http://svn.apache.org/viewvc/mahout/trunk/math-scala/src/test/scala/mahout/math/RLikeMatrixOpsSuite.scala?rev=1540905&view=auto
==============================================================================
--- mahout/trunk/math-scala/src/test/scala/mahout/math/RLikeMatrixOpsSuite.scala (added)
+++ mahout/trunk/math-scala/src/test/scala/mahout/math/RLikeMatrixOpsSuite.scala Tue Nov 12 00:50:47 2013
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mahout.math
+
+import org.scalatest.FunSuite
+import RLikeOps._
+
+class RLikeMatrixOpsSuite extends FunSuite {
+
+  test("multiplication") {
+
+    val a = dense((1, 2, 3), (3, 4, 5))
+    val b = dense(1, 4, 5)
+    val m = a %*% b
+
+    assert(m(0, 0) == 24)
+    assert(m(1, 0) == 44)
+    println(m.toString)
+  }
+
+  test("Hadamard") {
+    val a = dense(
+      (1, 2, 3),
+      (3, 4, 5)
+    )
+    val b = dense(
+      (1, 1, 2),
+      (2, 1, 1)
+    )
+
+    val c = a * b
+
+    printf("C=\n%s\n", c)
+
+    assert(c(0, 0) == 1)
+    assert(c(1, 2) == 5)
+    println(c.toString)
+
+    val d = a * 5.0
+    assert(d(0, 0) == 5)
+    assert(d(1, 1) == 20)
+
+    a *= b
+    assert(a(0, 0) == 1)
+    assert(a(1, 2) == 5)
+    println(a.toString)
+
+  }
+
+}

Added: mahout/trunk/math-scala/src/test/scala/mahout/math/RLikeVectorOpsSuite.scala
URL: http://svn.apache.org/viewvc/mahout/trunk/math-scala/src/test/scala/mahout/math/RLikeVectorOpsSuite.scala?rev=1540905&view=auto
==============================================================================
--- mahout/trunk/math-scala/src/test/scala/mahout/math/RLikeVectorOpsSuite.scala (added)
+++ mahout/trunk/math-scala/src/test/scala/mahout/math/RLikeVectorOpsSuite.scala Tue Nov 12 00:50:47 2013
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mahout.math
+
+import org.scalatest.FunSuite
+import org.apache.mahout.math.Vector
+import RLikeOps._
+
+/**
+ *
+ * @author dmitriy
+ */
+class RLikeVectorOpsSuite extends FunSuite {
+
+  test("Hadamard") {
+    val a: Vector = (1, 2, 3)
+    val b = (3, 4, 5)
+
+    val c = a * b
+    println(c)
+    assert(c ===(3, 8, 15))
+  }
+
+}

Added: mahout/trunk/math-scala/src/test/scala/mahout/math/VectorOpsSuite.scala
URL: http://svn.apache.org/viewvc/mahout/trunk/math-scala/src/test/scala/mahout/math/VectorOpsSuite.scala?rev=1540905&view=auto
==============================================================================
--- mahout/trunk/math-scala/src/test/scala/mahout/math/VectorOpsSuite.scala (added)
+++ mahout/trunk/math-scala/src/test/scala/mahout/math/VectorOpsSuite.scala Tue Nov 12 00:50:47 2013
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mahout.math
+
+import org.scalatest.FunSuite
+import org.apache.mahout.math.{RandomAccessSparseVector, Vector}
+import MatrixOps._
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: dmitriy
+ * Date: 6/21/13
+ * Time: 10:26 PM
+ * To change this template use File | Settings | File Templates.
+ */
+class VectorOpsSuite extends FunSuite {
+
+  test("inline create") {
+
+    val sparseVec = svec((5 -> 1) :: (10 -> 2.0) :: Nil)
+    println(sparseVec)
+
+    val sparseVec2: Vector = (5 -> 1.0) :: (10 -> 2.0) :: Nil
+    println(sparseVec2)
+
+    val sparseVec3: Vector = new RandomAccessSparseVector(100) := (5 -> 1.0) :: Nil
+    println(sparseVec3)
+
+    val denseVec1: Vector = (1.0, 1.1, 1.2)
+    println(denseVec1)
+
+    val denseVec2 = dvec(1, 0, 1.1, 1.2)
+    println(denseVec2)
+  }
+
+  test("plus minus") {
+
+    val a: Vector = (1, 2, 3)
+    val b: Vector = (0 -> 3) :: (1 -> 4) :: (2 -> 5) :: Nil
+
+    val c = a + b
+    val d = b - a
+    val e = -b - a
+
+    assert(c ===(4, 6, 8))
+    assert(d ===(2, 2, 2))
+    assert(e ===(-4, -6, -8))
+
+  }
+
+  test("dot") {
+
+    val a: Vector = (1, 2, 3)
+    val b = (3, 4, 5)
+
+    val c = a dot b
+    println(c)
+    assert(c == 26)
+
+  }
+
+}

Modified: mahout/trunk/pom.xml
URL: http://svn.apache.org/viewvc/mahout/trunk/pom.xml?rev=1540905&r1=1540904&r2=1540905&view=diff
==============================================================================
--- mahout/trunk/pom.xml (original)
+++ mahout/trunk/pom.xml Tue Nov 12 00:50:47 2013
@@ -764,6 +764,7 @@
     <module>integration</module>
     <module>examples</module>
     <module>distribution</module>
+    <module>math-scala</module>
   </modules>
   <profiles>
     <profile>