user25959
user25959

Reputation: 130

Defining matrix multiplication; wrong rows being modified

I'm trying to define a matrix multiplication function as follows:

def matrix_mult(a, b)
  #a is mxn, b is nxq, so prod of a and b is mxq
  m = a.length; n = a[0].length;
  n = b.length; q = b[0].length;

  prod=Array.new(m, Array.new(q,0));
  (0...m).each do |i|
    (0...q).each do |j|
    #dot i-th row of m with j-th row of n:
      (0...n).each {|k| prod[i][j]+=(a[i][k])*(b[k][j])}
      #puts "i="+i.to_s
      #puts "j="+j.to_s
      #print prod; print "\n"
    end
  end
  return prod
end

When testing on a 2-by-2 sample, in the first iteration (where i=j=0), the line with variable "k" correctly computes prod[0][0]. However, it simultaneously sets prod[1][0] to the same value even though the block should only be modifying prod[0][0]. Similarly, when i=0 and j=1, I get the correct value for prod[0][1], but prod[1][1] is getting modified at the same time.

Below is an example of what I'm getting, to illustrate the issue:

a=[[1, 2], [3, 2]]; b=[[3, 2], [1, 1]])
##output below
i =0
j =0
[[5, 0], [5, 0]] ##I don't know why the second row was made [5,0]
i =0
j =1
[[5, 4], [5, 4]]
i =1
j =0
[[16, 4], [16, 4]]
i =1
j =1
[[16, 12], [16, 12]]

Could someone explain what is causing this?

Upvotes: 0

Views: 63

Answers (1)

peak
peak

Reputation: 116710

If you modify the beginning of your def as follows, you'll find it works:

def matrix_mult(a, b)
  #a is mxn, b is nxq, so prod of a and b is mxq
  m = a.length; n = a[0].length;
  n = b.length; q = b[0].length;
  prod=Array.new(m,0);
  (0...m).each do |i|
    prod[i] = Array.new(q,0);
    (0...q).each do |j|
    ....

Since your prod is an array of arrays, it's essential that each top-level element be a separate array.

There is one other important change which should be made. Your code sets n twice, whereas it should really be checking that the prerequisite condition is satisfied.

Upvotes: 1

Related Questions