scalascala-breeze

Generic method that take as input Breeze Vector or Breeze Matrix


I am trying to implement a method that can accept as input either a Breeze Vector or a Breeze Matrix. Something like

  private def updateExponentialMovingAverage[T](tau: Double, initTheta: T, theta: T): T = {
    tau * theta + (1 - tau) * initTheta
  }

However this raises an issue with overloading and I cannot find an appropriate type to restrict T. Do you have any suggestions?


Solution

  • Breezes uses type classes for most of these kinds of things. The easiest thing to do is to use the VectorSpace type class, though unfortunately for DenseMatrices the VectorSpace typeclass is gated behind another import, which I regret.

    import breeze.linalg._
    import breeze.math._
    import breeze.linalg.DenseMatrix.FrobeniusInnerProductDenseMatrixSpace.space
    
    def updateExponentialMovingAverage[T](tau: Double, initTheta: T, theta: T)(implicit vs: VectorSpace[T, Double]): T = {
       import vs._
       theta * tau + initTheta * (1 - tau)
    }
    
    scala> val dv = DenseVector.rand(3)
    val dv: breeze.linalg.DenseVector[Double] = DenseVector(0.21025028035007942, 0.6257503866073217, 0.8304592391242225)
    
    scala> updateExponentialMovingAverage(0.8, dv, dv)
    val res0: breeze.linalg.DenseVector[Double] = DenseVector(0.21025028035007942, 0.6257503866073217, 0.8304592391242225)
    
    scala> val dm = DenseMatrix.rand(3, 3)
    val dm: breeze.linalg.DenseMatrix[Double] = 0.6848513069340505  0.8995141354384266   0.3889904836678608  
    0.4554398871938874  0.03297082723969558  0.6708501327709948  
    0.4456539828672945  0.04289112062985678  0.9679002485942578  
    
    updateExponentialMovingAverage(0.8, dm, dm)
    val res1: breeze.linalg.DenseMatrix[Double] = 0.6848513069340505  0.8995141354384266   0.3889904836678608  
    0.4554398871938874  0.03297082723969558  0.6708501327709948  
    0.4456539828672945  0.04289112062985678  0.9679002485942578