class RMatrix::M
Constants
- OPERATIONS_MAP
Attributes
named_inspect[RW]
column_label_map[RW]
column_map[R]
invert_next_operation[RW]
matrix[W]
narray[RW]
row_label_map[RW]
row_map[R]
typecode[RW]
Public Class Methods
[](*inputs, typecode: Typecode::FLOAT, row_map: nil, column_map: nil, column_label_map: nil, row_label_map: nil)
click to toggle source
# File lib/rmatrix/matrix.rb, line 408 def self.[](*inputs, typecode: Typecode::FLOAT, row_map: nil, column_map: nil, column_label_map: nil, row_label_map: nil) if inputs.length == 1 && Matrix === inputs[0] inputs[0] elsif inputs.length == 1 && [String, Symbol].include?(inputs[0].class) if ['byte', 'sint', 'int', 'sfloat', 'float', 'scomplex', 'complex', 'object'].include?(inputs[0]) ->(*source){ Matrix.new(source, inputs[0], row_map: row_map, column_map: column_map, row_label_map: row_label_map, column_label_map: column_label_map)} else Matrix.new(inputs[0], typecode, row_map: row_map, column_map: column_map, row_label_map: row_label_map, column_label_map: column_label_map) end else Matrix.new(inputs, typecode, row_map: row_map, column_map: column_map, row_label_map: row_label_map, column_label_map: column_label_map) end end
_load(arg)
click to toggle source
# File lib/rmatrix/matrix.rb, line 88 def self._load arg split_index, buffer, index = 0, '', arg.length - 1 split = Array.new(3) while split_index < 3 case char = arg[index] when ':' split[split_index] = buffer.reverse.to_i split_index += 1 buffer = '' else buffer << char end index -= 1 end arg[index+1..-1] = '' self.new(NArray.to_na(arg, split[0]).reshape(split[2], split[1]), split[0]) end
blank(rows: 1, columns: 1, typecode: Typecode::FLOAT, initial: 0, column_map: nil, row_map: nil)
click to toggle source
# File lib/rmatrix/matrix.rb, line 48 def self.blank(rows: 1, columns: 1, typecode: Typecode::FLOAT, initial: 0, column_map: nil, row_map: nil) source = self.new(NArray.new(typecode, columns, rows), typecode, column_map: column_map, row_map: row_map) source.narray[]= initial unless source.empty? source end
gen_delegator(name)
click to toggle source
# File lib/rmatrix/matrix.rb, line 461 def self.gen_delegator(name) define_method(name) do |*args, &blk| result = matrix.send(name, *args, &blk) case result when NArray then Matrix.new(result, typecode) else result end end end
gen_matrix_delegator(name)
click to toggle source
# File lib/rmatrix/matrix.rb, line 442 def self.gen_matrix_delegator(name) define_method(name) do |*args, &blk| Matrix.new(matrix.send(name, *args, &blk), typecode) end end
gen_mutator(name)
click to toggle source
# File lib/rmatrix/matrix.rb, line 426 def self.gen_mutator(name) define_method(name) do |*args, &blk| matrix.send(name, *args, &blk) self end end
gen_typeconstructor(name)
click to toggle source
# File lib/rmatrix/matrix.rb, line 471 def self.gen_typeconstructor(name) define_singleton_method(name) do ->(*source){ Matrix.new(source, name.to_s) } end end
gen_vec_or_matrix_delegator(name)
click to toggle source
# File lib/rmatrix/matrix.rb, line 433 def self.gen_vec_or_matrix_delegator(name) define_method(name) do |*args, &blk| case self when Vector then Vector.new(matrix.send(name, *args, &blk), typecode) when Matrix then Matrix.new(matrix.send(name, *args, &blk), typecode) end end end
identity(size)
click to toggle source
# File lib/rmatrix/matrix.rb, line 174 def self.identity(size) blank = self.blank(rows: size, columns: size) blank.diagonal(1) end
new(source, typecode=Typecode::FLOAT, column_map: nil, row_map: nil, column_label_map: nil, row_label_map: nil)
click to toggle source
# File lib/rmatrix/matrix.rb, line 18 def initialize(source, typecode=Typecode::FLOAT, column_map: nil, row_map: nil, column_label_map: nil, row_label_map: nil) self.typecode = typecode self.narray = two_dimensional(source, typecode) self.row_map = row_map self.column_map = column_map end
ones(rows: 1, columns: 1)
click to toggle source
# File lib/rmatrix/matrix.rb, line 179 def self.ones(rows: 1, columns: 1) self.blank(rows: rows, columns: columns, initial: 1) end
seed(seed)
click to toggle source
# File lib/rmatrix/matrix.rb, line 510 def self.seed(seed) NArray.srand(seed) end
translate_op(op)
click to toggle source
# File lib/rmatrix/matrix.rb, line 482 def self.translate_op(op) OPERATIONS_MAP.fetch(op, op) end
Public Instance Methods
*(other)
click to toggle source
# File lib/rmatrix/matrix.rb, line 302 def *(other) if other.kind_of?(Matrix) raise "Matrix A columns(#{self.columns}) != Matrix B rows(#{other.columns})" if other.rows != self.columns Matrix.new(self.matrix * other.matrix, typecode) else self.class.new(apply_scalar(:*, other), typecode) end end
==(other)
click to toggle source
# File lib/rmatrix/matrix.rb, line 315 def ==(other) self.narray == Matrix[other].narray end
_dump(level)
click to toggle source
# File lib/rmatrix/matrix.rb, line 58 def _dump(level) narray.to_s << ':' << columns.to_s << ':' << rows.to_s << ':' << narray.typecode.to_s end
abs()
click to toggle source
# File lib/rmatrix/matrix.rb, line 148 def abs (self ** 2) ** 0.5 end
adjoint()
click to toggle source
# File lib/rmatrix/matrix.rb, line 298 def adjoint self.cofactor_matrix.transpose end
Also aliased as: A
box_lines(lines, add_dots)
click to toggle source
# File lib/rmatrix/matrix.rb, line 323 def box_lines(lines, add_dots) "[#{lines.map{|l| "[#{l}#{add_dots ? ' ...' : '' }]"}.join(",\n ")}]" end
coerce(other)
click to toggle source
# File lib/rmatrix/matrix.rb, line 152 def coerce(other) self.invert_next_operation = true [self, other] end
cofactor_matrix(*args)
click to toggle source
# File lib/rmatrix/matrix.rb, line 273 def cofactor_matrix(*args) return cofactor(*args) if args.length == 2 result = [] rows.times do |i| result << [] columns.times do |j| result[i] << cofactor(i, j) end end return Matrix.new(result, typecode) end
Also aliased as: C
column_map=(column_map)
click to toggle source
# File lib/rmatrix/matrix.rb, line 30 def column_map=(column_map) @column_map = parse_map(column_map) @column_label_map = @column_map.invert unless !@column_map || @column_map.default_proc end
columns()
click to toggle source
# File lib/rmatrix/matrix.rb, line 165 def columns self.shape.first end
Also aliased as: cols
concat(*others, rows: true)
click to toggle source
# File lib/rmatrix/matrix.rb, line 191 def concat(*others, rows: true) others.map!{|o| Matrix === o ? o.narray : NArray.to_na(o)} joined = case rows when true # raise "Rows must match #{self.rows}, #{others.map(&:rows)}" unless [self.rows, *others.map(&:shape).map(&:last)].uniq.count.one? height = self.rows + others.map(&:shape).map(&:last).inject(:+) width = others[0].shape.first joined = ::NArray.new(typecode, width, height) joined[true, 0...self.rows] = self.narray current_row = self.rows others.each do |slice| slice_height = slice.shape[1] joined[true, current_row...current_row+slice_height] = slice current_row += slice_height end joined else width = self.columns + others.map(&:shape).map(&:first).inject(:+) height = others[0].shape.last joined = ::NArray.new(typecode, width, height) joined[0...self.columns, true] = self.narray current_col = self.columns others.each do |slice| slice_width = slice.shape[0] joined[current_col...current_col+slice_width, true] = slice current_col += slice_width end joined # raise "Rows must match #{self.columns}, #{others.map(&:columns)}" unless [self.columns, *others.map(&:columns)].uniq.count.one? end Matrix.new(joined, typecode) end
condensed(sz=10, sig=6, vdots='\\vdots', cdots='\\cdots', ddots='\\ddots')
click to toggle source
# File lib/rmatrix/matrix.rb, line 376 def condensed(sz=10, sig=6, vdots='\\vdots', cdots='\\cdots', ddots='\\ddots') width = [sz, self.cols].min height = [sz, self.rows].min insert_cdots = self.cols > sz insert_vdots = self.rows > sz width += 1 if insert_cdots height += 1 if insert_vdots blank = M.blank(rows: height, columns: width, typecode: Typecode::OBJECT) blank.narray[0...width, 0...height] = self.narray[0...width, 0...height] blank.narray[0...width, -1] = self.narray[0...width, -1] blank.narray[-1,0...height] = self.narray[-1, 0...height] blank.narray[0...width, -2] = vdots if insert_vdots blank.narray[-2, 0...height] = cdots if insert_cdots if insert_cdots && insert_vdots blank.narray[-2, -2] = ddots blank.narray[-1, -2] = vdots blank.narray[-2, -1] = cdots blank.narray[-1, -1] = self.narray[-1, -1] end blank.narray.to_a.map{|line| (sig ? Array(line).map{|v| Numeric === v ? to_significant_figures(v,sig) : v } : Array(line))} end
determinant()
click to toggle source
# File lib/rmatrix/matrix.rb, line 286 def determinant raise "Cannot calculate determinant of non-square matrix" unless columns == rows return self.raw[0, 0] * self.raw[1, 1]- self.raw[0, 1] * self.raw[1, 0] if(self.columns == 2) sign = 1 det = 0 self.columns.times do |i| det += sign * self.raw[0,i] * self.minor(0, i).determinant sign *= -1 end return det end
Also aliased as: D
diag(dim=0)
click to toggle source
# File lib/rmatrix/matrix.rb, line 169 def diag(dim=0) raise "Must be square matrix" unless self.shape[0] == self.shape[1] Matrix.new((self.class.identity(self.shape[0]).mult self).sum(dim)) end
each(&block)
click to toggle source
# File lib/rmatrix/matrix.rb, line 105 def each(&block) e = Enumerator.new do |enum| matrix.each do |elm| enum << elm end end block_given? ? e.each(&block) : e end
each_column(&block)
click to toggle source
# File lib/rmatrix/matrix.rb, line 114 def each_column(&block) e = Enumerator.new do |enum| (0...self.columns).each do |i| enum << self.raw[true, i] end end block_given? ? e.each(&block) : e end
each_row(&block)
click to toggle source
# File lib/rmatrix/matrix.rb, line 123 def each_row(&block) e = Enumerator.new do |enum| (0...self.rows).each do |i| enum << self.raw[i, true] end end block_given? ? e.each(&block) : e end
flat_map(&block)
click to toggle source
# File lib/rmatrix/matrix.rb, line 68 def flat_map(&block) map(&block).flatten(1) end
gplot(type: 'lines', series_names: [], xrange: nil, yrange: nil, title: '', ylabel: '', xlabel: '', style: nil) { |ds| ... }
click to toggle source
# File lib/rmatrix/plot.rb, line 2 def gplot(type: 'lines', series_names: [], xrange: nil, yrange: nil, title: '', ylabel: '', xlabel: '', style: nil) require 'gnuplot' require 'base64' output_file = Tempfile.new(['plt','.png']).path plot = nil Gnuplot.open do |gp| plot = Gnuplot::Plot.new( gp ) do |plot| plot.xrange "[#{xrange.begin}:#{xrange.end}]" if xrange plot.title title plot.ylabel ylabel plot.xlabel xlabel plot.set("style", style) if style plot.terminal 'png size 1000,1000' x = (0..50).collect { |v| v.to_f } y = x.collect { |v| v ** 2 } plot.output(output_file) plot.data = self.each_row.map.with_index do |row, i| Gnuplot::DataSet.new(row.to_a) do |ds| ds.with = type ds.title = series_names[i] || '' yield ds if block_given? end end end end puts "\033]1337;File=inline=1:#{Base64.encode64(IO.read(output_file))}\a"; end
gruff(title: '', type: 'Line', labels:{}, series_names: [], hide_legend: false, theme: Gruff::Themes::RAILS_KEYNOTE)
click to toggle source
# File lib/rmatrix/plot.rb, line 35 def gruff(title: '', type: 'Line', labels:{}, series_names: [], hide_legend: false, theme: Gruff::Themes::RAILS_KEYNOTE) require 'gruff' g = Gruff.const_get(type).new # g.theme = { # :colors => ["#3366CC","#DC3912","#FF9900","#109618","#990099","#3B3EAC","#0099C6","#DD4477","#66AA00","#B82E2E","#316395","#994499","#22AA99","#AAAA11","#6633CC","#E67300","#8B0707","#329262","#5574A6","#3B3EAC"], # :marker_color => '#dddddd', # :font_color => 'black', # :background_colors => ['white', '#acacac'] # # :background_image => File.expand_path(File.dirname(__FILE__) + "/../assets/backgrounds/43things.png") # } # g.hide_legend = true if hide_legend || series_names.empty? && self.rows.to_i > 10 # g.title = title # g.labels = {} self.each_row.map.with_index do |row, i| series_name = (series_names[i] || i).to_s g.data series_name, row.to_a[0..5].map{|v| v.round(2)} end if self.rows fname = "/tmp/chrt-#{Random.rand(1000000...9999999)}.png" g.write(fname) puts "\033]1337;File=inline=1:#{Base64.encode64(g.to_blob)}\a"; end
inspect(sz: 10, sig: 6, names: RMatrix::Matrix.named_inspect)
click to toggle source
# File lib/rmatrix/matrix.rb, line 339 def inspect(sz: 10, sig: 6, names: RMatrix::Matrix.named_inspect) desc = case when self.is_vector? then "Vector(#{self.length})" else "Matrix(#{rows} x #{columns})" end "#{desc}\n#{RMatrix::MatrixTable.new(self).to_s}" end
is_vector?()
click to toggle source
# File lib/rmatrix/matrix.rb, line 331 def is_vector? [rows, columns].include?(1) end
join(other)
click to toggle source
# File lib/rmatrix/matrix.rb, line 226 def join(other) case true when self.rows == 1 && other.rows == 1 self.class.new(NArray.to_na([self.narray,other.narray]).to_type(self.typecode).reshape(self.columns + other.columns, 1)) when self.columns == 1 && other.columns == 1 self.class.new(NArray.to_na([self.narray,other.narray]).to_type(self.typecode).reshape(1, self.rows + other.rows)) else raise "Couldn't join mismatched dimensions" end end
map(flatten: true) { |x| ... }
click to toggle source
# File lib/rmatrix/matrix.rb, line 62 def map(flatten: true) narray.to_type(RMatrix::Matrix::Typecode::OBJECT).map do |x| yield x end.to_a end
mask() { |elm) ? 0 : elm| ... }
click to toggle source
# File lib/rmatrix/matrix.rb, line 142 def mask mmap do |elm| (yield elm) ? 0 : elm end end
matrix()
click to toggle source
# File lib/rmatrix/matrix.rb, line 44 def matrix @matrix ||= narray.empty? ? narray : NMatrix.refer(narray) end
minor(x,y)
click to toggle source
# File lib/rmatrix/matrix.rb, line 269 def minor(x,y) return self.delete_at(y,x) end
Also aliased as: M
mmap() { |elm| ... }
click to toggle source
# File lib/rmatrix/matrix.rb, line 132 def mmap return self.class.new(matrix, typecode) if shape.length == 0 as_na = NArray.to_na( matrix.each.map do |elm| yield elm end ).to_type(typecode) self.class.new(as_na.reshape(*shape), typecode) end
mult(other)
click to toggle source
# File lib/rmatrix/matrix.rb, line 311 def mult(other) self.class.new(self.narray * other.narray, typecode) end
parse_map(map, invert: false)
click to toggle source
# File lib/rmatrix/matrix.rb, line 35 def parse_map(map, invert: false) case map when nil then map when Array then invert ? map.each.with_index.map.to_h.invert : map.each.with_index.map.to_h when Hash then map else raise 'Invalid map type encountered' end end
round(dp)
click to toggle source
# File lib/rmatrix/matrix.rb, line 327 def round(dp) mmap{|x| x.round(dp) } end
row_map=(row_map)
click to toggle source
# File lib/rmatrix/matrix.rb, line 25 def row_map=(row_map) @row_map = parse_map(row_map) @row_label_map = @row_map.invert unless !@row_map || @row_map.default_proc end
rows()
click to toggle source
# File lib/rmatrix/matrix.rb, line 161 def rows self.shape.last end
set_all(value)
click to toggle source
# File lib/rmatrix/matrix.rb, line 54 def set_all(value) narray[]=(value) end
size()
click to toggle source
# File lib/rmatrix/matrix.rb, line 157 def size self.shape.inject(:*).to_i end
Also aliased as: length
sum(dim=nil)
click to toggle source
# File lib/rmatrix/matrix.rb, line 448 def sum(dim=nil) case dim when nil then res = self.narray.sum NArray === res ? Matrix.new(0, typecode)[0] : res else Matrix.new(self.matrix.sum(dim), typecode) end end
sum_columns()
click to toggle source
# File lib/rmatrix/matrix.rb, line 187 def sum_columns sum(0) end
sum_rows()
click to toggle source
# File lib/rmatrix/matrix.rb, line 183 def sum_rows sum(1) end
threed_gplot(pm3d: false)
click to toggle source
# File lib/rmatrix/plot.rb, line 57 def threed_gplot(pm3d: false) require 'gnuplot' output_file = Tempfile.new(['plt','.png']).path plot = nil Gnuplot.open do |gp| plot = Gnuplot::SPlot.new( gp ) do |plot| case IRuby::Kernel.instance when nil puts "Setting output" plot.terminal 'png' plot.output(output_file) end # see sin_wave.rb plot.pm3d if pm3d plot.hidden3d plot.data << Gnuplot::DataSet.new( self.to_a ) do |ds| ds.with = 'lines' ds.matrix = true end end end puts "\033]1337;File=inline=1:#{Base64.encode64(IO.read(output_file))}\a"; end
to_a()
click to toggle source
# File lib/rmatrix/matrix.rb, line 506 def to_a return narray.to_a end
to_f()
click to toggle source
# File lib/rmatrix/matrix.rb, line 72 def to_f if length === 1 self.narray[0].to_f else raise "Can only call to_f on vectors of length 1" end end
to_i()
click to toggle source
# File lib/rmatrix/matrix.rb, line 80 def to_i if length === 1 self.narray[0].to_i else raise "Can only call to_i on vectors of length 1" end end
to_m()
click to toggle source
# File lib/rmatrix/matrix.rb, line 514 def to_m self end
to_s()
click to toggle source
# File lib/rmatrix/matrix.rb, line 319 def to_s inspect end
to_significant_figures(x, p)
click to toggle source
# File lib/rmatrix/matrix.rb, line 335 def to_significant_figures(x, p) ("%-.#{p}e" % x).gsub(/0+e/,'e').gsub('.e+00','').gsub('e+00','') end
to_tex(sz = 10, sig=6)
click to toggle source
# File lib/rmatrix/matrix.rb, line 347 def to_tex(sz = 10, sig=6) values = condensed(sz, sig) column_headers = column_label_map ? values[0].map.with_index do |v, i| case v when '\\cdots' then '\\cdots' else (column_label_map && column_label_map[i]) || i end end : [] row_headers = row_label_map ? values.map.with_index do |v, i| case v[0] when '\\vdots' then '\\vdots' else (row_label_map && row_label_map[i]) || i end end : [] <<-TEX $ \\begin{array}{c} & \\begin{array}{c} #{column_headers.join(" & ")} \\end{array}\\\\ \\begin{array}{c} #{row_headers.join(" \\\\ ")} \\end{array} & \\left(\\begin{array}{ccc} #{values.map{|line| line.join(" & ")}.join(" \\\\ ")} \\end{array}\\right) \\end{array} $ TEX end
to_type(type)
click to toggle source
# File lib/rmatrix/matrix.rb, line 457 def to_type(type) self.class.new(narray.to_type(type), type) end
transpose()
click to toggle source
# File lib/rmatrix/matrix.rb, line 404 def transpose() Matrix.new(self.matrix.transpose, typecode, column_map: self.row_map, row_map: self.column_map, column_label_map: self.row_label_map, row_label_map: self.column_label_map) end
Also aliased as: T
two_dimensional(source, type)
click to toggle source
# File lib/rmatrix/matrix.rb, line 237 def two_dimensional(source, type) case source when NArray if NMatrix === source @matrix = source source = NArray.refer(source) end when Numeric source = NArray.to_na([source]) else source = NArray.to_na(source) if type != RMatrix::Matrix::Typecode::OBJECT && source.typecode == RMatrix::Matrix::Typecode::OBJECT && RMatrix::Matrix === source[0] source = NArray.to_na(source.map(&:to_a).to_a).to_type(typecode) end source end source = source.to_type(type) unless type == source.typecode case source.dim when 1 source.reshape(source.length, 1) when 2, 0 source else raise "Source for matrix must be either one or two dimensional" unless source.shape[2..-1].all?{|x| x == 1} source.reshape(source.shape[0], source.shape[1]) end end
zip(*others)
click to toggle source
Calls superclass method
# File lib/rmatrix/matrix.rb, line 422 def zip(*others) Matrix.new(super(*others), self.typecode) end
Private Instance Methods
apply_elementwise(op, other)
click to toggle source
# File lib/rmatrix/matrix.rb, line 536 def apply_elementwise(op, other) if test_inverse other.narray.send(op, self.narray) else narray.send(op, other.narray) end end
apply_scalar(op, other)
click to toggle source
# File lib/rmatrix/matrix.rb, line 544 def apply_scalar(op, other) if test_inverse other.send(op, self.narray) else narray.send(op, other) end end
cofactor(i, j)
click to toggle source
# File lib/rmatrix/matrix.rb, line 530 def cofactor(i, j) minor = self.minor(i, j) sign = ((i * self.columns + j) % 2).zero? ? 1 : -1; return sign * minor.determinant end
test_inverse()
click to toggle source
# File lib/rmatrix/matrix.rb, line 523 def test_inverse if self.invert_next_operation self.invert_next_operation = false return true end end