Module: RMatrix::Indices
- Included in:
- Matrix
- Defined in:
- lib/rmatrix/indices.rb
Instance Method Summary collapse
- #[](*args) ⇒ Object
- #[]=(*args, value) ⇒ Object
- #build_result_map(existing, indices, size) ⇒ Object
- #indexify(indices, results, size, total = 0) ⇒ Object
- #method_missing(name, *args, &block) ⇒ Object
- #raw ⇒ Object
- #unmap_args(args) ⇒ Object
- #unmap_index(map, columns) ⇒ Object
- #walk_indices(indices, parent, i = {index: 0}) ⇒ Object
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
38 39 40 41 42 43 44 45 46 |
# File 'lib/rmatrix/indices.rb', line 38 def method_missing(name, *args, &block) if row_map && row_map.include?(name) self[name, true] elsif column_map && column_map.include?(name) self[true, name] else super end end |
Instance Method Details
#[](*args) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/rmatrix/indices.rb', line 9 def [](*args) indices = unmap_args(args) result_row_map = build_result_map(self.row_map, indices.first, self.rows) if self.row_map result_column_map = build_result_map(self.column_map, indices.last, self.columns) if self.column_map row_indices, column_indices = indices result_column_label_map = nil result_row_label_map = nil if row_label_map case row_indices when true then result_row_label_map = row_label_map else result_row_label_map = walk_indices(row_indices, row_label_map).each_slice(2).to_h end end if column_label_map case column_indices when true then result_column_label_map = column_label_map else result_column_label_map = walk_indices(column_indices, column_label_map).each_slice(2).to_h end end raw[*indices, column_map: result_column_map, column_label_map: result_column_label_map, row_map: result_row_map, row_label_map: result_row_label_map] end |
#[]=(*args, value) ⇒ Object
4 5 6 7 |
# File 'lib/rmatrix/indices.rb', line 4 def []=(*args, value) indices = unmap_args(args) raw[*indices] = value end |
#build_result_map(existing, indices, size) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/rmatrix/indices.rb', line 77 def build_result_map(existing, indices, size) return existing if indices == true result_map = {} indexify(indices, result_map, size) result_map.default_proc = ->(h,k) do existing_index = existing[k] case existing_index when TrueClass existing_index when Range if existing_index.exclude_end? h[k] = h[existing_index.first]...h[existing_index.end] else h[k] = h[existing_index.first]..h[existing_index.end] end when nil raise "Couldn't find key #{k} in index mapping" else h[existing_index] end end result_map end |
#indexify(indices, results, size, total = 0) ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/rmatrix/indices.rb', line 101 def indexify(indices, results, size, total=0) Array(indices).each do |index| case index when TrueClass (0...size).each do |i| results[i] = i end when 1.class results[index] ||= total total += 1 when Array indexify(index, results, size, total) when Range inclusive = index.exclude_end? ? index.first..(index.end - 1) : index flat_range = inclusive.end < inclusive.first ? [*inclusive.end..inclusive.first].reverse : [*inclusive] flat_range.each do |elm| indexify(elm, results, size, total) end end end end |
#raw ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/rmatrix/indices.rb', line 59 def raw @raw ||= begin raw = Struct.new(:narray, :typecode).new(self.narray, self.typecode) def raw.[](*args, column_map: nil, row_map: nil, row_label_map: nil, column_label_map: nil) begin args.all?{|x| 1.class === x } ? narray[*args.reverse] : Matrix.new(narray[*args.reverse], typecode, column_map: column_map, row_map: row_map, row_label_map: row_label_map, column_label_map: column_label_map) rescue StandardError => e raise IndexError.new("Error #{e.message} - accessing index at #{args}. Shape is #{narray.shape.reverse}") end end def raw.[]=(*args, value) narray[*args.reverse] = value end raw end end |
#unmap_args(args) ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/rmatrix/indices.rb', line 123 def unmap_args(args) if args.length == 1 if row_map return [Array(unmap_index(self.row_map, args[0])), true] rescue nil end if column_map return [true, Array(unmap_index(self.column_map, args[0]))] rescue nil end return [args[0]] else row_index = self.row_map ? unmap_index(self.row_map, args[0]) : args[0] column_index = self.column_map ? unmap_index(self.column_map, args[1]) : args[1] column_index = [column_index] if column_index.kind_of?(1.class) [ row_index, column_index ] end end |
#unmap_index(map, columns) ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/rmatrix/indices.rb', line 143 def unmap_index(map, columns) case columns when TrueClass, FalseClass columns when Array columns.map{|col| unmap_index(map, col)}.flatten when Range first = unmap_index(map, columns.first) last = unmap_index(map, columns.end) first = Range === first ? first.first : first if columns.exclude_end? last = Range === last ? last.first : last first...last else last = Range === last ? last.end : last first..last end else index = (map[columns] rescue nil) index = columns if !index && columns.kind_of?(1.class) raise "Value not present in index mapping: #{columns}" unless index index end end |
#walk_indices(indices, parent, i = {index: 0}) ⇒ Object
48 49 50 51 52 53 54 55 56 57 |
# File 'lib/rmatrix/indices.rb', line 48 def walk_indices(indices, parent, i={index: 0}) Array(indices).flat_map do |index| res = case index when Array, Range then walk_indices(index.to_a, parent, i) else [i[:index], parent[index]] end i[:index] += 1 res end end |