Michael Burrows
Michael Burrows

Reputation: 331

How would I write a Vector class in Scala?

I'd like it to have the performance characteristics and include most of methods of Array[Double] but have additional extension methods such as dotProduct(), +, -, etc. I can write the additional extension methods but need help on the implementation of the existing traits and the measures needed to get Array like performance.

class Vec(private val content:Array[Double]) extends WrappedArray[Double] {
  /* Trait implementation methods - incomplete */
  def array = content
  def apply(i:Int) = content(i)
  def length = content.length
  def update(i:Int, v:Double) = content.update(i, v)
  def elemTag = ???

  /* Example extension methods */
  def plus(that:Vec) = Vec(this.indices.map{ i => this(i) + that(i)})
  def elementProduct(that:Vec) = Vec(this.indices.map{ i => this(i) * that(i)})
  def sum = content.sum
  def dotProduct(that:Vec) = elementProduct(that).sum
}

object Vec {
  def apply(seq:IndexedSeq[Double]) = new Vec(seq.toArray)
}

Upvotes: 0

Views: 160

Answers (1)

Tim
Tim

Reputation: 27356

If you just want Array[Double] with some new methods then the best way to do this is to define an implicit class that provides the additional methods. Something like this:

implicit class ArrayOps(vec: Array[Double]) {
  def plus(that: Array[Double]): Array[Double] =
    vec.indices.map(i => vec(i) + that(i))(collection.breakOut)

  def elementProduct(that: Array[Double]): Array[Double] =
    vec.indices.map(i => vec(i)*that(i))(collection.breakOut)

  def dotProduct(that: Array[Double]): Double =
    (vec elementProduct that).sum
}

You can then call plus, elementProduct and dotProduct on any Array[Double] and it will perform the appropriate operation from the implicit class.

Upvotes: 1

Related Questions