Scala Task- product of two vectors

I am beginner in Scala and trying to create a product of two vectors using scala. Eg: uv = u1v1 + u2v2 + u3v3 …+ unvn. I want to use List to create a group of numbers and using a variable I am tryibg to write a function.

val u = List(2, 5, 3)
val v = List(4, 3, 7)
val dot = function
print(dot)

I tried following code:

val u = List(2, 5, 3)
val v = List(4, 3, 7)
val dot = List(2, 5, 3).zip(List(4 , 3, 7))
print(dot)
val product = dot.map(x => u * v)
product.reduce(+)

But it didn’t worked. can someone help?

Why it didn’t work?

Didn’t compile? If so, which error message did you get?
Did it crash at runtime? If so, which exception did you get?
Did it produce a wrong result? If so, which result did it produced and which one did you want?

You’re in the right track.
Take a look at the line:
val product = dot.map(x => u * v)

In particular to x => u * v

What x, u, and v should be?

It failed at compile time with error:

Value * is not a member of List[int]
Val product= dot.map(x=> u*v)

I want it to give result say u =(2,5,3)
v=(4,3,7)

u.v= 24 + 53 + 3*7= 44

I want it to give result say u =(2,5,3)
v=(4,3,7)

u.v= 24 + 53 + 3*7

dot is a List of pairs. For each pair, you want to multiply the first element with the second, so:


val product = dot.map(pair => pair._1 * pair._2)

1 Like

Or using pattern matching.

val product = dot.map {
  case (ui, vi) => ui * vi
}

That should work.


Note, this should produce the answer you are looking for, but it traverses the lists more times that it is needed.
You shouldn’t care for this while learning, but just for the sake of reference, here is a more efficient way to do that.

def dotProduct(u: List[Int], v: List[Int]): Int =
  (u lazyZip v).foldLeft(0) {
    case (acc, (ui, vi)) => acc + (ui * vi)
  }

Thanks Balmung San the first piece of code worked:

val u = List(2, 5, 3)
val v = List(4, 3, 7)
val dot = List(2, 5, 3).zip(List(4 , 3, 7))
print(dot)
val product = dot.map {
case (u, v) => u * v
}
product.reduce(+)

Output: Int = 44

Bu the second piece of code didn’t worked. Also can you tell what are lazyzip, acc and foldLeft doing?

def dotProduct(u: List[Int], v: List[Int]): Int =
(u lazyZip v).foldLeft(0) {
case (acc, (ui, vi)) => acc + (ui * vi)
}

Thanks Balmung San the first piece of code worked.

Great :smiley:

PS: product.reduce(+) is the same as product.sum

But the second piece of code didn’t worked.

I assume you get a compile error like: lazyZip not found
If so, that is because lazyZip was added on 2.13 if you are using an older version of Scala, I believe you can (u, v).zipped instead.

Also can you tell what are lazyzip, acc and foldLeft doing.

Of course, but remember the scaladoc is your friend.
(also foldLeft is quite a basic function that most tutorial should cover, what are you following for learning Scala?)

  • lazyZip lazily zips both lists into one. What does zip mean? Well, I guess the best way to show it is through code.
// Assume two lists:
val l1 = List(1, 2, 3, 4)
val l2 = List('a', 'b', 'c', 'd')

// Then.
val l3 = l1 zip l2

// Is the same as.
val l3: List[(Int, Char)] = List((1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'))

So, as you can see, it joins both lists into one, element by element.
And what does the “lazily” part mean? That instead of creating the Lists of Tuples right away, it just knows that it has to do that, but it waits for a further operation to consume the tuples.

  • foldLeft as the name suggests, folds (combines) all the elements of the list into one.
    It receives a zero element and, a function that takes the current accumulated value and the current value of the list and returns the new accumulated value.

So:

(u lazyZip v).foldLeft(0) {
  case (acc, (ui, vi)) => acc + (ui * vi)
}

0 is the zero element, so we start the accumulation with a zero.
case (acc, (ui, vi)) the acc is the current accumulated value, and (ui, vi) is the current value of the list of tuples.
acc + (ui * vi) the new accumulated value is the previous accumulated plus the product of the current tuple.

I hope that makes sense.