module RMatrix::Indices
Public Instance Methods
[](*args)
click to toggle source
# 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)
click to toggle source
# File lib/rmatrix/indices.rb, line 4 def []=(*args, value) indices = unmap_args(args) raw[*indices] = value end
build_result_map(existing, indices, size)
click to toggle source
# 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)
click to toggle source
# 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
method_missing(name, *args, &block)
click to toggle source
Calls superclass method
# 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
raw()
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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})
click to toggle source
# 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