Class: SimpleMatrix

Inherits:
Object
  • Object
show all
Defined in:
lib/simple_matrix.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ SimpleMatrix

todo args are yet used, it should populate the columns/rows if provided



8
9
10
11
12
13
# File 'lib/simple_matrix.rb', line 8

def initialize(*args) # todo args are yet used, it should populate the columns/rows if provided
  @colnames =  []
  @rownames =  []
  @rows = [  ]
  @cols = [  ]
end

Instance Attribute Details

#colnamesObject

Returns the value of attribute colnames.



6
7
8
# File 'lib/simple_matrix.rb', line 6

def colnames
  @colnames
end

#rownamesObject

Returns the value of attribute rownames.



6
7
8
# File 'lib/simple_matrix.rb', line 6

def rownames
  @rownames
end

Instance Method Details

#add_column(name, col) ⇒ Object

Add column to the matrix. Parameter:

- name:  Column name, must be unique.
- col: Array of values of the same length as the current columns.

Raises:

  • (ArgumentError)


79
80
81
82
83
84
85
86
87
88
# File 'lib/simple_matrix.rb', line 79

def add_column(name, col)
  raise ArgumentError, "Column was #{col.length}, expected #{@rownames.length} elements." unless col.length.eql? @rownames.length
  raise ArgumentError, "Duplicate column names not allowed: #{name}" if @colnames.index(name)

  @cols << col.to_a
  col.each_with_index do |c, i|
    @rows[i] << c
  end
  @colnames << name.to_s
end

#add_row(name, row) ⇒ Object

Add row to the matrix. Parameter:

- name:  Row name, does not need to be unique.  However if it is not then retrieving elements by named row
         will not be predictable.
- row: Array of values of the same length as the current rows.

Raises:

  • (ArgumentError)


64
65
66
67
68
69
70
71
72
73
# File 'lib/simple_matrix.rb', line 64

def add_row(name, row)
  raise ArgumentError, "Row was #{row.length}, expected #{@colnames.length} elements." unless row.length.eql? @colnames.length
  raise ArgumentError, "Duplicate row names not allowed: #{name}" if @rownames.index(name)

  @rows << row.to_a
  row.each_with_index do |r, i|
    @cols[i] << r
  end
  @rownames << name.to_s
end

#colname(i, name) ⇒ Object

Set the column name at the given index



22
23
24
# File 'lib/simple_matrix.rb', line 22

def colname(i, name)
  @colnames[i] = name
end

#column(name) ⇒ Object

Retrieve column by name. If multiple columns have the same name only the first one will be returned.



48
49
50
51
# File 'lib/simple_matrix.rb', line 48

def column(name)
  index = @colnames.index(name.to_s)
  @cols[index]
end

#columnsObject

Returns all columns.



38
39
40
# File 'lib/simple_matrix.rb', line 38

def columns
  @cols
end

#element(row, col) ⇒ Object

Returns element at given location. Row/column names can be provided, but if one is a name both are treated as such. Otherwise they are expected to be indicies.



128
129
130
131
132
133
134
135
136
# File 'lib/simple_matrix.rb', line 128

def element(row, col)
  if (row.is_a? String or col.is_a? String)
    i = @rownames.index(row.to_s)
    j = @colnames.index(col.to_s)
  else
    i = row; j = col
  end
  return @rows[i][j]
end

#row(name) ⇒ Object

Retrieve row by name. If multiple rows have the same name only the first one will be returned.



54
55
56
57
# File 'lib/simple_matrix.rb', line 54

def row(name)
  index = @rownames.index(name.to_s)
  @rows[index]
end

#rowname(i, name) ⇒ Object

Set row name at a given index



27
28
29
# File 'lib/simple_matrix.rb', line 27

def rowname(i, name)
  @rownames[i] = name
end

#rowsObject

Returns all rows.



43
44
45
# File 'lib/simple_matrix.rb', line 43

def rows
  @rows
end

#sizeObject

Return array [total rows, total columns]



139
140
141
# File 'lib/simple_matrix.rb', line 139

def size
  return [@rows.length, @cols.length]
end

#to_matrixObject

Get the Ruby Matrix object that is usable for matrix mathematical operations.



175
176
177
178
# File 'lib/simple_matrix.rb', line 175

def to_matrix
  puts "Rows of #{self.name} are not integers. Matrix math operations may not work." if (rows.select { |e| !e.is_a? Integer }.empty?)
  return Matrix::Matrix.rows(self.rows)
end

#to_s(rownames = true, colnames = true) ⇒ Object

Returns matrix as a string. Opts:

:rownames => true  (default)  Output row names.
:colnames => true  (default)  Output column names.


147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/simple_matrix.rb', line 147

def to_s(rownames = true, colnames = true)
  matrix_string = ""
  matrix_string = "\t" unless rownames.eql? false
  matrix_string += @colnames.join("\t") + "\n" unless colnames.eql? false # unless (opts[:colnames] and opts[:colnames].eql?false)
  rowname = ""
  @rows.each_with_index do |row, i|
    rowname = "#{@rownames[i]}\t" unless rownames.eql? false # opts[:rownames].eql?false
    row = row.to_a
    matrix_string += rowname + row.join("\t") + "\n"
  end
  return matrix_string
end

#update_column(col, values) ⇒ Object

WARNING THIS CHANGES ALL VALUES FOR A GIVEN COLUMN

Raises:

  • (ArgumentError)


110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/simple_matrix.rb', line 110

def update_column(col, values)
  raise ArgumentError, "Expect #{@rownames.length} values for the #{col} column." unless values.length.eql? @rownames.length

  i = col
  if col.is_a? String
    i = @colnames.index(col)
  end
  raise ArgumentError, "No column found for #{col}" if i.nil? or @cols[i].nil?

  @cols[i] = values
  values.each_with_index do |e, j|
    @rows[j][i] = e
  end
end

#update_element(row, col, e) ⇒ Object

Update element at a given position Parameters:

- row: Row name or index.
- col: Column name or index.
- e: Element to be added at the coordinates specified.


95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/simple_matrix.rb', line 95

def update_element(row, col, e)
  if (row.is_a? String or col.is_a? String)
    i = @rownames.index(row.to_s)
    raise ArgumentError, "Row '#{row}' does not exist." if i.nil?
    j = @colnames.index(col.to_s)
    raise ArgumentError, "Column '#{col}' does not exist." if j.nil?
  else
    i = row; j = col
    raise ArgumentError, "Row(#{i}) or Col(#{j}) is out of bounds" unless (@rows[i] and @cols[j])
  end
  @rows[i][j] = e
  @cols[j][i] = e
end

#write(file = nil, opts = {}) ⇒ Object

Write the matrix to a file or to STDOUT Opts:

:rownames => true  (default)  Output row names.
:colnames => true  (default)  Output column names.


164
165
166
167
168
169
170
171
172
# File 'lib/simple_matrix.rb', line 164

def write(file = nil, opts = {})
  matrix_string = self.to_s(opts[:rownames], opts[:colnames])
  if file
    File.open(file, 'w') { |fout| fout.write(matrix_string) }
    puts "#{file} written."
  else
    puts matrix_string
  end
end