如何实现可接受Breeze Vector或Breeze Matrix为入参的泛型方法
问题原因
Breeze的数值运算符没有基于类继承实现,而是采用类型类模式做泛型兼容,你没有对泛型T做任何运算能力约束,编译器找不到对应*、+运算符的重载实现,所以会报错。
解决方案
通过Breeze内置的运算符类型类约束泛型T的能力,不需要修改方法内部的运算逻辑,只需要补充隐式参数约束即可:
import breeze.linalg.operators.{OpAdd, OpMulScalar} private def updateExponentialMovingAverage[T]( tau: Double, initTheta: T, theta: T )(implicit // 约束Double和T做乘法返回T的能力 mulDouble: OpMulScalar.Impl2[Double, T, T], // 约束两个T做加法返回T的能力 addT: OpAdd.Impl2[T, T, T] ): T = { tau * theta + (1 - tau) * initTheta }
Breeze的Vector、Matrix(包括稠密、稀疏实现)都默认实现了上述两个类型类,调用方法时直接传入对应类型参数即可正常运行。
简化写法
如果你使用Scala 2.13及以上版本,可以用上下文绑定语法简化为如下形式,效果完全一致:
import breeze.linalg.operators.{OpAdd, OpMulScalar} private def updateExponentialMovingAverage[ T: OpMulScalar.Impl2[Double, *, T]: OpAdd.Impl2[*, *, T] ](tau: Double, initTheta: T, theta: T): T = { tau * theta + (1 - tau) * initTheta }
内容的提问来源于stack exchange,提问作者amarchin
相关产品推荐
相关产品推荐

