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?
CodePudding user response:
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