I want to design an NDArray struct like numpy’s ndarray, which may have various shape and dimenssion.
The ideal data assessing of NDArray is something as:
val nda = NDArray(Array.range(0, 9), shape=Seq(3, 3)) // A 2D NDArray
nda(1, 1) = 100 // update the value of position (1, 1)
println(nda(1, 1)) // get the value of position (1, 1)
// or a 3d array
val nda3 = NDArray(Array.range(0, 24), shape=Seq(2, 3, 4))
nda3(1, 2, 3) = 123
println(nda3(1, 2, 3))
A not work implementation:
class NDArray[A](val data: Array[A], val shape: Seq[Int]):
def strides: Seq[Int] = shape.scanRight(1)(_ * _).tail
def offset(index: Int*): Int = index.zip(strides).map(_ * _).sum
def apply(index: Int*): A = data(offset(index*))
// def update(index: Int*, value: A): Unit = data.update(offset(index*), value)
// def update(index: Int*)(value: A): Unit = data.update(offset(index*))(value)
The update method does not compile since current update only accept two parameters, and its first parameter cannot be a varargs.