【发布时间】:2015-09-30 16:01:47
【问题描述】:
我正在尝试使用 ejml 库为矩阵运算编写 scala 包装器。基本上我只使用 SimpleMatrix。但是,我想要矩阵和向量的不同类,例如只能反转矩阵或明确声明函数返回向量,而不是矩阵。目前,我无法返回具体类而不是特征。
我从一个特征开始,MLMatrixLike:
trait MLMatrixLike {
def data: SimpleMatrix
protected def internalMult(implicit that: MLMatrixLike): SimpleMatrix = {
data.mult(that.data)
}
def *(implicit that: MLMatrixLike): MLVector = MLVector(internalMult)
}
我的矩阵类和向量类都在扩展这个特征:
case class MLMatrix(data: SimpleMatrix) extends MLMatrixLike {
def this(rawData: Array[Array[Double]]) = this(new SimpleMatrix(rawData))
def apply(row: Int, col:Int): Double = data.get(row, col)
def transpose(): MLMatrix = MLMatrix(data.transpose())
def invert(): MLMatrix = MLMatrix(data.invert())
def *(implicit that: MLMatrix): MLMatrix = MLMatrix(internalMult)
def *(that: Double): MLMatrix = MLMatrix(data.scale(that))
def -(that: MLMatrix): MLMatrix = MLMatrix(data.minus(that.data))
}
object MLMatrix {
def apply(rawData: Array[Array[Double]]) = new MLMatrix(rawData)
}
case class MLVector(data: SimpleMatrix) extends MLMatrixLike {
def this(rawData: Array[Double]) = {
this(new SimpleMatrix(Array(rawData)).transpose())
}
def apply(index: Int): Double = data.get(index)
def transpose(): MLVector = MLVector(data.transpose())
def -(that: MLVector): MLVector = MLVector(data.minus(that.data))
}
object MLVector {
def apply(rawData: Array[Double]) = new MLVector(rawData)
}
在我看来,这个设置不是很好。我只想定义一次乘法 (*),因为 SimpleMatrix 调用总是相同的,我可以从参数“that”的类型推断返回类型应该是矩阵还是向量。因此,我想在 MLMatrixLike 中按照这个(不工作的)函数定义一个函数:
def *[T <: MLMatrixLike](that :T): T = {
new T(data.mult(that.data))
}
当然,这是行不通的,因为没有这样的构造函数 T,但目前我看不到,我怎样才能得到类似的东西。返回 MLMatrixLike 在我看来是不正确的,因为这样我无法在编译期间检查是否返回了正确的类型。
类似的问题适用于转置和减号 - 这里的返回类型始终是自己的类。
非常感谢!
【问题讨论】:
标签: scala