Class: Rust::Matrix

Inherits:
RustDatatype show all
Defined in:
lib/rust/core/types/matrix.rb

Overview

Mirror of the matrix type in R.

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from RustDatatype

pull_priority, #r_hash, #r_mirror, #r_mirror_to

Constructor Details

#initialize(data, row_names = nil, column_names = nil) ⇒ Matrix

Creates a new matrix with the given data (Ruby Matrix). Optionally, row_names and column_names can be specified.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/rust/core/types/matrix.rb', line 38

def initialize(data, row_names = nil, column_names = nil)
    @data = data.clone
    
    @row_names = row_names
    @column_names = column_names
    
    if @data.is_a?(::Matrix)
        @data = @data.row_vectors.map { |v| v.to_a }
    end
    
    if self.flatten.size == 0
        raise "Empty matrices are not allowed"
    else
        raise TypeError, "Expected array of array" unless @data.is_a?(Array) || @data[0].is_a?(Array)
        raise TypeError, "Only numeric matrices are supported" unless self.flatten.all? { |e| e.is_a?(Numeric) }
        raise "All the rows must have the same size" unless @data.map { |row| row.size }.uniq.size == 1
        raise ArgumentError, "Expected row names #@row_names to match the number of rows in #{self.inspect}" if @row_names && @row_names.size != self.rows
        raise ArgumentError, "Expected column names #@column_names to match the number of columns in #{self.inspect}" if @column_names && @column_names.size != self.cols
    end
end

Class Method Details

.can_pull?(type, klass) ⇒ Boolean

Returns:

  • (Boolean)


9
10
11
# File 'lib/rust/core/types/matrix.rb', line 9

def self.can_pull?(type, klass)
    return klass.is_a?(Array) && klass.include?("matrix")
end

.pull_variable(variable, type, klass) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/rust/core/types/matrix.rb', line 13

def self.pull_variable(variable, type, klass)
    if Rust._pull("length(#{variable})") == 1
        core = ::Matrix[[Rust._pull("#{variable}[1]")]]
    else
        core = Rust._pull(variable)
    end
    row_names = [Rust["rownames(#{variable})"]].flatten
    column_names = [Rust["colnames(#{variable})"]].flatten
    
    row_names = nil if row_names.all? { |v| v == nil }
    column_names = nil if column_names.all? { |v| v == nil }
    
    Matrix.new(core, row_names, column_names)
end

Instance Method Details

#[](i, j) ⇒ Object

Returns the matrix element at row i and column j.



62
63
64
65
66
# File 'lib/rust/core/types/matrix.rb', line 62

def [](i, j)
    i, j = indices(i, j)
    
    return @data[i][j]
end

#[]=(i, j, value) ⇒ Object

Sets the matrix element at row i and column j with value.



71
72
73
74
75
# File 'lib/rust/core/types/matrix.rb', line 71

def []=(i, j, value)
    i, j = indices(i, j)
    
    @data[i][j] = value
end

#colsObject

Returns the number of columns.



87
88
89
# File 'lib/rust/core/types/matrix.rb', line 87

def cols
    @data[0].size
end

#flattenObject

Returns a flattened version of the matrix (Array).



94
95
96
# File 'lib/rust/core/types/matrix.rb', line 94

def flatten
    return @data.flatten
end

#inspectObject



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/rust/core/types/matrix.rb', line 98

def inspect
    row_names = @row_names || (0...self.rows).to_a.map { |v| v.to_s }
    column_names = @column_names || (0...self.cols).to_a.map { |v| v.to_s }
    
    separator = " | "
    col_widths = column_names.map do |colname| 
        [
            colname, 
            (
                [colname ? colname.length : 1] + 
                @data.map {|r| r[column_names.index(colname)]}.map { |e| e.inspect.length }
            ).max
        ]
    end.to_h
    col_widths[:rowscol] = row_names.map { |rowname| rowname.length }.max + 3
    
    result = ""
    result << "-" * (col_widths.values.sum + ((col_widths.size - 1) * separator.length)) + "\n"
    result << (" " * col_widths[:rowscol]) + column_names.map { |colname| (" " * (col_widths[colname] - colname.length)) + colname }.join(separator) + "\n"
    result << "-" * (col_widths.values.sum + ((col_widths.size - 1) * separator.length)) + "\n"
    
    @data.each_with_index do |row, i|
        row_name = row_names[i]
        row = column_names.zip(row)
        
        index_part = "[" + (" " * (col_widths[:rowscol] - row_name.length - 3)) + "#{row_name}] "
        row_part   = row.map { |colname, value| (" " * (col_widths[colname] - value.inspect.length)) + value.inspect }.join(separator)
        
        result << index_part + row_part + "\n"
    end
    
    result << "-" * (col_widths.values.sum + ((col_widths.size - 1) * separator.length))
    
    return result
end

#load_in_r_as(variable_name) ⇒ Object



28
29
30
31
32
# File 'lib/rust/core/types/matrix.rb', line 28

def load_in_r_as(variable_name)
    matrix = ::Matrix[*@data]
    
    Rust[variable_name] = matrix
end

#rowsObject

Returns the number of rows.



80
81
82
# File 'lib/rust/core/types/matrix.rb', line 80

def rows
    @data.size
end