Scala error Could not find implicit value for parameter

Saulo Ricci picture Saulo Ricci · Mar 12, 2015 · Viewed 7.3k times · Source

I have the function flagVectorOutlier as showed in the code bellow. I'm using Breeze's DenseVector and DenseMatrix objects to calculate the value of distance. I expect as coded on the function signature, to get a Spark RDD[(Double, Boolean)]. mi and invCovMatrix are respectively Breeze's DenseVector[Double] and DenseMatrix[Double]:

  def flagVectorOutlier(testVectors: RDD[(String, SparkVector)], distanceThreshold: Double): RDD[(Double, Boolean)] = {
    val testVectorsDenseRDD = testVectors.map { vector => DenseVector(vector._2.toArray)}
    val mahalanobisDistancesRDD = testVectorsDenseRDD.map { vector =>
      val distance = DenseVector[Double](DenseVector(Transpose(vector - mi) * invCovMatrix) * DenseVector(vector - mi)).toArray
      (distance(0), if(distance(0) >= distanceThreshold) true else false)
    }

    mahalanobisDistancesRDD
  }

The compiler ends up showing me the following 2 errors:

Error:(75, 93) could not find implicit value for parameter op: breeze.linalg.operators.OpMulMatrix.Impl2[breeze.linalg.DenseVector[breeze.linalg.Transpose[breeze.linalg.DenseVector[Double]]],breeze.linalg.DenseVector[breeze.linalg.DenseVector[Double]],That]
      val distance = DenseVector[Double](DenseVector(Transpose(vector - mi) * invCovMatrix) * DenseVector(vector - mi)).toArray
                                                                                            ^

and

Error:(75, 93) not enough arguments for method *: (implicit op: breeze.linalg.operators.OpMulMatrix.Impl2[breeze.linalg.DenseVector[breeze.linalg.Transpose[breeze.linalg.DenseVector[Double]]],breeze.linalg.DenseVector[breeze.linalg.DenseVector[Double]],That])That.
Unspecified value parameter op.
      val distance = DenseVector[Double](DenseVector(Transpose(vector - mi) * invCovMatrix) * DenseVector(vector - mi)).toArray
                                                                                            ^

What point am I missing? I'm considering that's possible to do a multiplication between Breeze's DenseVector's in that way.

Answer

dlwh picture dlwh · Mar 12, 2015

If you look at the error message carefully, it tells you what went wrong.

(implicit op: OpMulMatrix.Impl2[
       DenseVector[Transpose[DenseVector[Double]]],
       DenseVector[DenseVector[Double]],
       That])

The operands for your multiply are almost certainly not what you intended. The LHS is a DenseVector whose elements are Transpose'd DenseVectors. The RHS is a DenseVector[DenseVector[Double]]. Your outer DenseVector(..) calls are wrapping their arguments in new DenseVectors, rather than turning the argument into a DenseVector.

I believe this is what you wanted:

val diff = (vector - mi).toDenseVector
(diff.t * invCovMatrix * diff)