我想在Scala中编写一个Matrix类,我可以实例化这样的对象:
val m1 = new Matrix( (1.,2.,3.),(4.,5.,6.),(7.,8.,9.) )
val m2 = new Matrix( (1.,2.,3.),(4.,5.,6.) )
val m3 = new Matrix( (1.,2.),(3.,4.) )
val m4 = new Matrix( (1.,2.),(3.,4.),(5.,6.) )
我试过这个:
class Matrix(a: (List[Double])* ) { }
然后我得到一个类型不匹配,因为矩阵行不是List [Double]类型。
此外,只需输入整数(1,2,3)而不是(1.,2.,3。),但仍然可以得到双矩阵。
如何解决这个问题?
谢谢! 马尔特
答案 0 :(得分:1)
(1.0, 2.0)
是Tuple2[Double, Double]
而不是List[Double]
。同样,(1.0, 2.0, 3.0)
是Tuple3[Double, Double, Double]
。
如果你需要处理固定数量的基数,普通香草scala中最简单的解决方案就是
class Matrix2(rows: Tuple2[Double, Double]*)
class Matrix3(rows: Tuple3[Double, Double, Double]*)
等等。
由于存在从Int
到Double
的隐式转换,您可以传递一个int元组,它会自动转换。
new Matrix2((1, 2), (3, 4))
如果您需要对行基数进行抽象,使用类型强制执行NxM
,则必须使用一些更复杂的解决方案,可能使用无形库。
或者您可以使用实际列表,但是您不能限制基数,即您不能确保所有行具有相同的长度(再次,在vanilla scala中,无形可以帮助)
class Matrix(rows: List[Double]*)
new Matrix(List(1, 2), List(3, 4))
最后,自scala 2.10起,1.
文字语法已被弃用,并在scala 2.11中删除。请改用1.0
。
答案 1 :(得分:1)
如果您需要支持非常大的矩阵,请考虑使用现有的实现,如Breeze。 Breeze有DenseMatrix,可能符合您的要求。出于性能原因,Breeze将更复杂的操作卸载到本机代码中。
使矩阵代数正确是一项艰难的练习,除非您专门实施矩阵学习/分配,否则最好使用经过验证的库。
根据以下评论进行编辑:
您可以考虑以下设计。
class Row(n : Int*)
class Matrix(rows: Row*) {...}
用法:
val m = new Matrix(Row(1, 2, 3), Row(2,3,4))
您需要验证所有行的长度并拒绝输入(如果不是。
)答案 2 :(得分:0)
我已经破解了一个解决方案 - 我认为 - 有点不可思议的方式
class Matrix(values: Object*) { // values is of type WrappedArray[Object]
var arr : Array[Double] = null
val rows : Integer = values.size
var cols : Integer = 0
var _arrIndex = 0
for(row <- values) {
// if Tuple (Tuple extends Product)
if(row.isInstanceOf[Product]) {
var colcount = row.asInstanceOf[Product].productIterator.length
assert(colcount > 0, "empty row")
assert(cols == 0 || colcount == cols, "varying number of columns")
cols = colcount
if(arr == null) {
arr = new Array[Double](rows*cols)
}
for(el <- row.asInstanceOf[Product].productIterator) {
var x : Double = 0.0
if(el.isInstanceOf[Integer]) {
x = el.asInstanceOf[Integer].toDouble
}
else {
assert(el.isInstanceOf[Double], "unknown element type")
x = el.asInstanceOf[Double]
}
arr(_arrIndex) = x
_arrIndex = _arrIndex + 1
}
}
}
}
就像
一样object ScalaMatrix extends App {
val m1 = new Matrix((1.0,2.0,3.0),(5,4,5))
val m2 = new Matrix((9,8),(7,6))
println(m1.toString())
println(m2.toString())
}
我真的不喜欢它。你觉得怎么样?