-1

(Before start, I am using Ruby 1.8.7, so I won't be able to use fancy stuff.)

As title says, I want to calculate the average of column or row. But, I can't even find the way to traverse/iterate Matrix form of array from online.

Let's say you have this

require 'mathn'

m = Matrix[[1,2,3],[4,5,6],[7,8,9]]

Somehow the way I iterate a simple 3x3 array doesn't work with Matrix form of array (Or may be just my code is weird)..What is the proper way to do this? Also, is there a syntax that calculate row and column average of matrix??

Sagar Pandya
  • 9,060
  • 2
  • 21
  • 34
GothLoli
  • 19
  • 1
  • 5
  • 2
    [`Matrix`](http://ruby-doc.org/stdlib-1.8.7/libdoc/matrix/rdoc/Matrix.html) has `rows`, `columns`, `row_size`, `column_size`, `[i,j]`, ... methods (even in 1.8.7), that should be enough to compute your averages. Can you show us what you've tried? Is the problem just that you end up doing integer division? – mu is too short May 02 '18 at 22:51
  • http://ruby-doc.org/core-1.8.7/ . It's all there. – Sagar Pandya May 02 '18 at 23:00

2 Answers2

2

Here's one way to calculate the average of a specific row or column within a given matrix:

require 'matrix'

m = Matrix[
            [1, 2, 3],
            [4, 5, 6],
            [7, 8, 9]
          ]

def vector_average(matrix, vector_type, vector_index)
  vector = matrix.send(vector_type, vector_index)
  vector.inject(:+) / vector.size.to_f
end

# Average of first row
vector_average(m, :row, 0)
# => 2.0

# Average of second column
vector_average(m, :column, 1)
# => 5.0

Hope this helps!

Zoran
  • 3,930
  • 2
  • 19
  • 31
  • 1
    You could also write `vector.inject(:+).fdiv(vector.size)` or (Ruby v2.4+) `vector.sum.fdiv(vector.size)`. This uses [Integer#fdiv](http://ruby-doc.org/core-2.4.0/Integer.html#method-i-fdiv), [Float#fdiv](http://ruby-doc.org/core-2.4.0/Float.html#method-i-fdiv) or [Numeric#fdiv](http://ruby-doc.org/core-2.4.0/Numeric.html#method-i-fdiv), depending on the receiver's class (but I haven't checked to see when these methods were introduced). – Cary Swoveland May 03 '18 at 06:43
1

If you wish to compute all row averages and/or all column averages you could do the following.

require 'matrix'

def row_averages(m)
  (m * Vector[*[1.0/m.column_size]*m.column_size]).to_a
end

def col_averages(m)
  row_averages(m.transpose)
end

For example,

m = Matrix[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

row_averages(m)
  #=> [2.0, 5.0, 8.0]
col_averages(m)
  #=> [3.9999999999999996, 5.0, 6.0]

See Matrix and Vector.

Cary Swoveland
  • 94,081
  • 5
  • 54
  • 87