mahout-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From apalu...@apache.org
Subject mahout git commit: MAHOUT-1813: Functional 'apply' DSL for distributed and in-memory matrices closes apache/mahout#194
Date Tue, 15 Mar 2016 22:22:25 GMT
Repository: mahout
Updated Branches:
  refs/heads/flink-binding d9deb68ff -> 812ae398c


MAHOUT-1813:  Functional 'apply' DSL for distributed and in-memory matrices closes apache/mahout#194


Project: http://git-wip-us.apache.org/repos/asf/mahout/repo
Commit: http://git-wip-us.apache.org/repos/asf/mahout/commit/812ae398
Tree: http://git-wip-us.apache.org/repos/asf/mahout/tree/812ae398
Diff: http://git-wip-us.apache.org/repos/asf/mahout/diff/812ae398

Branch: refs/heads/flink-binding
Commit: 812ae398c257b6e2ec87bcc8ef986d50c28e6025
Parents: d9deb68
Author: Andrew Palumbo <apalumbo@apache.org>
Authored: Tue Mar 15 18:19:49 2016 -0400
Committer: Andrew Palumbo <apalumbo@apache.org>
Committed: Tue Mar 15 18:21:22 2016 -0400

----------------------------------------------------------------------
 .../org/apache/mahout/math/drm/DrmLikeOps.scala | 23 ++++++-
 .../mahout/math/scalabindings/MatrixOps.scala   | 63 ++++++++++++++++++--
 .../mahout/math/scalabindings/package.scala     |  6 ++
 .../mahout/math/drm/RLikeDrmOpsSuiteBase.scala  | 14 +++++
 .../math/scalabindings/MatrixOpsSuite.scala     | 12 ++++
 5 files changed, 112 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mahout/blob/812ae398/math-scala/src/main/scala/org/apache/mahout/math/drm/DrmLikeOps.scala
----------------------------------------------------------------------
diff --git a/math-scala/src/main/scala/org/apache/mahout/math/drm/DrmLikeOps.scala b/math-scala/src/main/scala/org/apache/mahout/math/drm/DrmLikeOps.scala
index e2c6e17..43b4f56 100644
--- a/math-scala/src/main/scala/org/apache/mahout/math/drm/DrmLikeOps.scala
+++ b/math-scala/src/main/scala/org/apache/mahout/math/drm/DrmLikeOps.scala
@@ -19,7 +19,7 @@ package org.apache.mahout.math.drm
 
 import scala.reflect.ClassTag
 import org.apache.mahout.math.scalabindings._
-import org.apache.mahout.math.drm.logical.{OpPar, OpMapBlock, OpRowRange}
+import org.apache.mahout.math.drm.logical.{OpAewUnaryFunc, OpPar, OpMapBlock, OpRowRange}
 
 /** Common Drm ops */
 class DrmLikeOps[K](protected[drm] val drm: DrmLike[K]) {
@@ -116,4 +116,25 @@ class DrmLikeOps[K](protected[drm] val drm: DrmLike[K]) {
 
     } else rowSrc
   }
+
+  /**
+    * Apply a function element-wise.
+    *
+    * @param f         element-wise function
+    * @param evalZeros Do we have to process zero elements? true, false, auto: if auto, we
will test
+    *                  the supplied function for `f(0) != 0`, and depending on the result,
will
+    *                  decide if we want evaluation for zero elements. WARNING: the AUTO
setting
+    *                  may not always work correctly for functions that are meant to run
in a specific
+    *                  backend context, or non-deterministic functions, such as {-1,0,1}
random
+    *                  generators.
+    * @return new DRM with the element-wise function applied.
+    */
+  def apply(f: Double ⇒ Double, evalZeros: AutoBooleanEnum.T = AutoBooleanEnum.AUTO) =
{
+    val ezeros = evalZeros match {
+      case AutoBooleanEnum.TRUE ⇒ true
+      case AutoBooleanEnum.FALSE ⇒ false
+      case AutoBooleanEnum.AUTO ⇒ f(0) != 0
+    }
+    new OpAewUnaryFunc[K](drm, f, ezeros)
+  }
 }

http://git-wip-us.apache.org/repos/asf/mahout/blob/812ae398/math-scala/src/main/scala/org/apache/mahout/math/scalabindings/MatrixOps.scala
----------------------------------------------------------------------
diff --git a/math-scala/src/main/scala/org/apache/mahout/math/scalabindings/MatrixOps.scala
b/math-scala/src/main/scala/org/apache/mahout/math/scalabindings/MatrixOps.scala
index cb92e1d..f3be285 100644
--- a/math-scala/src/main/scala/org/apache/mahout/math/scalabindings/MatrixOps.scala
+++ b/math-scala/src/main/scala/org/apache/mahout/math/scalabindings/MatrixOps.scala
@@ -128,10 +128,60 @@ class MatrixOps(val m: Matrix) {
   }
 
   /**
-   * Warning: This provides read-only view only.
+    * Apply a function element-wise without side-effects to the argument (creates a new matrix).
+    *
+    * @param f         element-wise function "value" ⇒ "new value"
+    * @param evalZeros Do we have to process zero elements? true, false, auto: if auto, we
will test
+    *                  the supplied function for `f(0) != 0`, and depending on the result,
will
+    *                  decide if we want evaluation for zero elements. WARNING: the AUTO
setting
+    *                  may not always work correctly for functions that are meant to run
in a specific
+    *                  backend context, or non-deterministic functions, such as {-1,0,1}
random
+    *                  generators.
+    * @return new DRM with the element-wise function applied.
+    */
+  def apply(f: Double ⇒ Double, evalZeros: AutoBooleanEnum.T): Matrix = {
+    val ezeros = evalZeros match {
+      case AutoBooleanEnum.TRUE ⇒ true
+      case AutoBooleanEnum.FALSE ⇒ false
+      case AutoBooleanEnum.AUTO ⇒ f(0) != 0
+    }
+    if (ezeros) m.cloned := f else m.cloned ::= f
+  }
+
+  /**
+    * Apply a function element-wise without side-effects to the argument (creates a new matrix).
+    *
+    * @param f         element-wise function (row, column, value) ⇒ "new value"
+    * @param evalZeros Do we have to process zero elements? true, false, auto: if auto, we
will test
+    *                  the supplied function for `f(0) != 0`, and depending on the result,
will
+    *                  decide if we want evaluation for zero elements. WARNING: the AUTO
setting
+    *                  may not always work correctly for functions that are meant to run
in a specific
+    *                  backend context, or non-deterministic functions, such as {-1,0,1}
random
+    *                  generators.
+    * @return new DRM with the element-wise function applied.
+    */
+  def apply(f: (Int, Int, Double) ⇒ Double, evalZeros: AutoBooleanEnum.T): Matrix = {
+    val ezeros = evalZeros match {
+      case AutoBooleanEnum.TRUE ⇒ true
+      case AutoBooleanEnum.FALSE ⇒ false
+      case AutoBooleanEnum.AUTO ⇒ f(0,0,0) != 0
+    }
+    if (ezeros) m.cloned := f else m.cloned ::= f
+  }
+
+  /** A version of function apply with default AUTO treatment of `evalZeros`. */
+  def apply(f: Double ⇒ Double): Matrix = apply(f, AutoBooleanEnum.AUTO)
+
+  /** A version of function apply with default AUTO treatment of `evalZeros`. */
+  def apply(f: (Int, Int, Double) ⇒ Double): Matrix = apply(f, AutoBooleanEnum.AUTO)
+
+
+  /**
+    * 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
+    *
+    * @return transposed view
    */
   def t = Matrices.transposedView(m)
 
@@ -143,7 +193,8 @@ class MatrixOps(val m: Matrix) {
 
   /**
    * Assigning from a row-wise collection of vectors
-   * @param that -
+    *
+    * @param that -
    */
   def :=(that: TraversableOnce[Vector]) = {
     var row = 0
@@ -212,7 +263,8 @@ class MatrixOps(val m: Matrix) {
    * 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
+    *
+    * @param that
    * @return
    */
   def equiv(that: Matrix) =
@@ -233,7 +285,8 @@ class MatrixOps(val m: Matrix) {
 
   /**
    * test if rank == min(nrow,ncol).
-   * @return
+    *
+    * @return
    */
   def isFullRank: Boolean =
     new QRDecomposition(if (nrow < ncol) m t else m cloned).hasFullRank

http://git-wip-us.apache.org/repos/asf/mahout/blob/812ae398/math-scala/src/main/scala/org/apache/mahout/math/scalabindings/package.scala
----------------------------------------------------------------------
diff --git a/math-scala/src/main/scala/org/apache/mahout/math/scalabindings/package.scala
b/math-scala/src/main/scala/org/apache/mahout/math/scalabindings/package.scala
index 426996b..6a3aa06 100644
--- a/math-scala/src/main/scala/org/apache/mahout/math/scalabindings/package.scala
+++ b/math-scala/src/main/scala/org/apache/mahout/math/scalabindings/package.scala
@@ -29,6 +29,12 @@ package object scalabindings {
   // Reserved "ALL" range
   final val `::`: Range = null
 
+  // Some enums
+  object AutoBooleanEnum extends Enumeration {
+    type T = Value
+    val TRUE, FALSE, AUTO = Value
+  }
+
   implicit def seq2Vector(s: TraversableOnce[AnyVal]) =
     new DenseVector(s.map(_.asInstanceOf[Number].doubleValue()).toArray)
 

http://git-wip-us.apache.org/repos/asf/mahout/blob/812ae398/math-scala/src/test/scala/org/apache/mahout/math/drm/RLikeDrmOpsSuiteBase.scala
----------------------------------------------------------------------
diff --git a/math-scala/src/test/scala/org/apache/mahout/math/drm/RLikeDrmOpsSuiteBase.scala
b/math-scala/src/test/scala/org/apache/mahout/math/drm/RLikeDrmOpsSuiteBase.scala
index f18d23b..5d6d142 100644
--- a/math-scala/src/test/scala/org/apache/mahout/math/drm/RLikeDrmOpsSuiteBase.scala
+++ b/math-scala/src/test/scala/org/apache/mahout/math/drm/RLikeDrmOpsSuiteBase.scala
@@ -637,5 +637,19 @@ trait RLikeDrmOpsSuiteBase extends DistributedMahoutSuite with Matchers
{
 
   }
 
+  test("functional apply()") {
+    val mxA = sparse (
+      (1 -> 3) :: (7 -> 7) :: Nil,
+      (4 -> 5) :: (5 -> 8) :: Nil
+    )
+
+    val mxAControl = mxA cloned
+    val drmA = drmParallelize(mxA)
+
+    (drmA(x => x + 1).collect - (mxAControl + 1)).norm should be < 1e-7
+    (drmA(x => x * 2).collect - (2 * mxAControl)).norm should be < 1e-7
+
+  }
+
 
 }

http://git-wip-us.apache.org/repos/asf/mahout/blob/812ae398/math-scala/src/test/scala/org/apache/mahout/math/scalabindings/MatrixOpsSuite.scala
----------------------------------------------------------------------
diff --git a/math-scala/src/test/scala/org/apache/mahout/math/scalabindings/MatrixOpsSuite.scala
b/math-scala/src/test/scala/org/apache/mahout/math/scalabindings/MatrixOpsSuite.scala
index 5c8a310..1296d9e 100644
--- a/math-scala/src/test/scala/org/apache/mahout/math/scalabindings/MatrixOpsSuite.scala
+++ b/math-scala/src/test/scala/org/apache/mahout/math/scalabindings/MatrixOpsSuite.scala
@@ -131,6 +131,18 @@ class MatrixOpsSuite extends FunSuite with MahoutSuite {
     g.sum shouldBe 3
   }
 
+  test("functional apply()") {
+    val mxA = sparse (
+      (1 -> 3) :: (7 -> 7) :: Nil,
+      (4 -> 5) :: (5 -> 8) :: Nil
+    )
+    val mxAControl = mxA cloned
+
+    (mxA(x ⇒ x + 1) - (mxAControl + 1)).norm should be < 1e-7
+    (mxA(x ⇒ x * 2) - (2 * mxAControl)).norm should be < 1e-7
+
+  }
+
   test("sparse") {
 
     val a = sparse((1, 3) :: Nil,


Mime
View raw message