rust 0.7 → 0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 35c41ec98f5b286ef597096152249f19825a27bc33030e85ea196df8b778d3b1
4
- data.tar.gz: 48b2e61f707ebcd05fa5f593016c8c0fb4b9d1e58751dd5deae83715583bd978
3
+ metadata.gz: aaa404db11033ff42b529516ae4a3f3e252bdddf7677d082847ee06625144f8e
4
+ data.tar.gz: f72ebc2c95385b87a445f3fb8de3e517579b002e0606209903acd2327616befd
5
5
  SHA512:
6
- metadata.gz: b0cc1289721d52cd376e0a242c2be419ea511f03a0fdd42c4c7a1973cde24e8dfc467e9d355693f85632cccb98af6986777aa020b715db5f06aa88a63d154ea0
7
- data.tar.gz: 4c91c808773dcd04913a594cfcaa7956318908e6d590ebec1d9a04beef18986adc70a3c5e480c39bdc9f753b5edf920a1939208b8b530ccfc67124ac153a4804
6
+ metadata.gz: 00567c9b6216f7e9dc1a4135dbea263eecae2178273851c023980233531729313e15147e1bec8e9521df2d4fee15e2c4c8bf9bd4a0e2d1475f1d383339a17c21
7
+ data.tar.gz: 89800fff95be559e6f6bbbc05b6b5f5b52b7d59c54c61cd76ef679876ce5de0c08b405d88eadf0b254c95306ad98f38120e5960a92ce8358fca19ed6cc5c181d
data/bin/ruby-rust ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/ruby
2
+
3
+ system "irb -r \"rust\""
@@ -1,4 +1,5 @@
1
- require_relative 'rust-core'
1
+ require_relative '../core'
2
+ require 'csv'
2
3
 
3
4
  module Rust
4
5
  class CSV
@@ -0,0 +1,157 @@
1
+ require 'code-assertions'
2
+ require 'stringio'
3
+ require 'rinruby'
4
+
5
+ module Rust
6
+ CLIENT_MUTEX = Mutex.new
7
+ R_MUTEX = Mutex.new
8
+
9
+ R_ENGINE = RinRuby.new(echo: false)
10
+
11
+ private_constant :R_ENGINE
12
+ private_constant :R_MUTEX
13
+ private_constant :CLIENT_MUTEX
14
+
15
+ @@debugging = $RUST_DEBUG || false
16
+ @@in_client_mutex = false
17
+
18
+ def self.debug
19
+ @@debugging = true
20
+ end
21
+
22
+ def self.debug?
23
+ return @@debugging
24
+ end
25
+
26
+ def self.exclusive
27
+ result = nil
28
+ CLIENT_MUTEX.synchronize do
29
+ @@in_client_mutex = true
30
+ result = yield
31
+ @@in_client_mutex = false
32
+ end
33
+ return result
34
+ end
35
+
36
+ def self.[]=(variable, value)
37
+ if value.is_a?(RustDatatype)
38
+ value.load_in_r_as(variable.to_s)
39
+ elsif value.is_a?(String) || value.is_a?(Numeric) || value.is_a?(Array) || value.is_a?(::Matrix)
40
+ R_ENGINE.assign(variable, value)
41
+ else
42
+ raise "Trying to assign #{variable} with #{value.class}; expected RustDatatype, String, Numeric, or Array"
43
+ end
44
+
45
+ end
46
+
47
+ def self.[](variable)
48
+ return RustDatatype.pull_variable(variable)
49
+ end
50
+
51
+ def self._eval_big(r_command, return_warnings = false)
52
+ r_command = r_command.join("\n") if r_command.is_a?(Array)
53
+
54
+ self._rexec(r_command, return_warnings) do |cmd|
55
+ result = true
56
+ instructions = cmd.lines
57
+
58
+ while instructions.size > 0
59
+ current_command = ""
60
+
61
+ while (instructions.size > 0) && (current_command.length + instructions.first.length < 10000)
62
+ current_command << instructions.shift
63
+ end
64
+
65
+ result &= R_ENGINE.eval(current_command)
66
+ end
67
+
68
+ result
69
+ end
70
+ end
71
+
72
+ def self._pull(r_command, return_warnings = false)
73
+ self._rexec(r_command, return_warnings) { |cmd| R_ENGINE.pull(cmd) }
74
+ end
75
+
76
+ def self._eval(r_command, return_warnings = false)
77
+ self._rexec(r_command, return_warnings) { |cmd| R_ENGINE.eval(cmd) }
78
+ end
79
+
80
+ def self._rexec(r_command, return_warnings = false)
81
+ puts "Calling _rexec with command: #{r_command}" if @@debugging
82
+ R_MUTEX.synchronize do
83
+ assert("This command must be executed in an exclusive block") { @@in_client_mutex }
84
+
85
+ result = nil
86
+ begin
87
+ $stdout = StringIO.new
88
+ if return_warnings
89
+ R_ENGINE.echo(true, true)
90
+ else
91
+ R_ENGINE.echo(false, false)
92
+ end
93
+ result = yield(r_command)
94
+ ensure
95
+ R_ENGINE.echo(false, false)
96
+ warnings = $stdout.string
97
+ $stdout = STDOUT
98
+ end
99
+
100
+ if return_warnings
101
+ puts " Got #{warnings.size} warnings, with result #{result.inspect[0...100]}" if @@debugging
102
+ return result, warnings.lines.map { |w| w.strip.chomp }
103
+ else
104
+ puts " Result: #{result.inspect[0...100]}" if @@debugging
105
+ return result
106
+ end
107
+ end
108
+ end
109
+
110
+ def self.check_library(name)
111
+ self.exclusive do
112
+ result, _ = self._pull("require(\"#{name}\", character.only = TRUE)", true)
113
+ return result
114
+ end
115
+ end
116
+
117
+ def self.load_library(name)
118
+ self.exclusive do
119
+ self._eval("library(\"#{name}\", character.only = TRUE)")
120
+ end
121
+
122
+ return nil
123
+ end
124
+
125
+ def self.install_library(name)
126
+ self.exclusive do
127
+ self._eval("install.packages(\"#{name}\", dependencies = TRUE)")
128
+ end
129
+
130
+ return nil
131
+ end
132
+
133
+ def self.prerequisite(library)
134
+ self.install_library(library) unless self.check_library(library)
135
+ self.load_library(library)
136
+ end
137
+ end
138
+
139
+ module Rust::RBindings
140
+ def data_frame(*args)
141
+ Rust::DataFrame.new(*args)
142
+ end
143
+ end
144
+
145
+ module Rust::TestCases
146
+ def self.sample_dataframe(columns, size=100)
147
+ result = Rust::DataFrame.new(columns)
148
+ size.times do |i|
149
+ result << columns.map { |c| yield i, c }
150
+ end
151
+ return result
152
+ end
153
+ end
154
+
155
+ def bind_r!
156
+ include Rust::RBindings
157
+ end
@@ -0,0 +1,4 @@
1
+ self_path = File.expand_path(__FILE__)
2
+ Dir.glob(File.dirname(self_path) + "/*.rb").each do |lib|
3
+ require_relative lib unless lib == self_path
4
+ end
@@ -1,123 +1,20 @@
1
- require 'code-assertions'
2
- require 'stringio'
3
- require 'rinruby'
4
- require 'csv'
1
+ require_relative 'datatype'
5
2
 
6
3
  module Rust
7
- CLIENT_MUTEX = Mutex.new
8
- R_MUTEX = Mutex.new
9
-
10
- R_ENGINE = RinRuby.new(echo: false)
11
-
12
- private_constant :R_ENGINE
13
- private_constant :R_MUTEX
14
- private_constant :CLIENT_MUTEX
15
-
16
- @@debugging = false
17
- @@in_client_mutex = false
18
-
19
- def self.debug
20
- @@debugging = true
21
- end
22
-
23
- def self.exclusive
24
- result = nil
25
- CLIENT_MUTEX.synchronize do
26
- @@in_client_mutex = true
27
- result = yield
28
- @@in_client_mutex = false
29
- end
30
- return result
31
- end
32
-
33
- def self.[]=(variable, value)
34
- if value.is_a?(RustDatatype)
35
- value.load_in_r_as(variable.to_s)
36
- elsif value.is_a?(String) || value.is_a?(Numeric) || value.is_a?(Array)
37
- R_ENGINE.assign(variable, value)
38
- else
39
- raise "Given #{value.class}, expected RustDatatype, String, Numeric, or Array"
4
+ class DataFrame < RustDatatype
5
+ def self.can_pull?(type, klass)
6
+ return [klass].flatten.include?("data.frame")
40
7
  end
41
8
 
42
- end
43
-
44
- def self.[](variable, type=RustDatatype)
45
- return type.pull_variable(variable)
46
- end
47
-
48
- def self._eval_big(r_command, return_warnings = false)
49
- r_command = r_command.join("\n") if r_command.is_a?(Array)
50
-
51
- self._rexec(r_command, return_warnings) do |cmd|
52
- result = true
53
- instructions = cmd.lines
54
-
55
- while instructions.size > 0
56
- current_command = ""
57
-
58
- while (instructions.size > 0) && (current_command.length + instructions.first.length < 10000)
59
- current_command << instructions.shift
60
- end
61
-
62
- result &= R_ENGINE.eval(current_command)
63
- end
64
-
65
- result
66
- end
67
- end
68
-
69
- def self._pull(r_command, return_warnings = false)
70
- self._rexec(r_command, return_warnings) { |cmd| R_ENGINE.pull(cmd) }
71
- end
72
-
73
- def self._eval(r_command, return_warnings = false)
74
- self._rexec(r_command, return_warnings) { |cmd| R_ENGINE.eval(cmd) }
75
- end
76
-
77
- def self._rexec(r_command, return_warnings = false)
78
- puts "Calling _rexec with command: #{r_command}" if @@debugging
79
- R_MUTEX.synchronize do
80
- assert("This command must be executed in an exclusive block") { @@in_client_mutex }
81
-
82
- result = nil
83
- begin
84
- $stdout = StringIO.new
85
- if return_warnings
86
- R_ENGINE.echo(true, true)
87
- else
88
- R_ENGINE.echo(false, false)
89
- end
90
- result = yield(r_command)
91
- ensure
92
- R_ENGINE.echo(false, false)
93
- warnings = $stdout.string
94
- $stdout = STDOUT
95
- end
96
-
97
- if return_warnings
98
- return result, warnings.lines.map { |w| w.strip.chomp }
99
- else
100
- return result
101
- end
102
- end
103
- end
104
-
105
- class RustDatatype
106
- def self.pull_variable(variable)
107
- return Rust._pull(variable)
9
+ def self.pull_priority
10
+ 1
108
11
  end
109
12
 
110
- def load_in_r_as(r_instance, variable_name)
111
- raise "Not implemented"
112
- end
113
- end
114
-
115
- class DataFrame < RustDatatype
116
- def self.pull_variable(variable)
13
+ def self.pull_variable(variable, type, klass)
117
14
  hash = {}
118
- colnames = Rust._pull("colnames(#{variable})")
15
+ colnames = Rust["colnames(#{variable})"]
119
16
  colnames.each do |col|
120
- hash[col] = Rust._pull("#{variable}$#{col}")
17
+ hash[col] = Rust["#{variable}$\"#{col}\""]
121
18
  end
122
19
  return DataFrame.new(hash)
123
20
  end
@@ -373,6 +270,14 @@ module Rust
373
270
  row_index += 1
374
271
  end
375
272
 
273
+ self.column_names.each do |name|
274
+ column = self.column(name)
275
+
276
+ if column.is_a?(Factor)
277
+ command << "#{variable_name}[,#{name.to_R}] <- factor(#{variable_name}[,#{name.to_R}], labels=#{column.levels.to_R})"
278
+ end
279
+ end
280
+
376
281
  Rust._eval_big(command)
377
282
  end
378
283
 
@@ -586,82 +491,6 @@ module Rust
586
491
  end
587
492
  end
588
493
 
589
- class Matrix < RustDatatype
590
- def self.pull_variable(variable)
591
- return Rust._pull(variable)
592
- end
593
-
594
- def initialize(data)
595
- if data.flatten.size == 0
596
- raise "Empty matrices are not allowed"
597
- else
598
- raise TypeError, "Expected array of array" unless data.is_a?(Array) && data[0].is_a?(Array)
599
- raise TypeError, "Only numeric matrices are supported" unless data.all? { |row| row.all? { |e| e.is_a?(Numeric) } }
600
- raise "All the rows must have the same size" unless data.map { |row| row.size }.uniq.size == 1
601
- @data = data.clone
602
- end
603
- end
604
-
605
- def [](i, j)
606
- return @data[i][j]
607
- end
608
-
609
- def rows
610
- @data.size
611
- end
612
-
613
- def cols
614
- @data[0].size
615
- end
616
-
617
- def []=(i, j, value)
618
- raise "Wrong i" unless i.between?(0, @data.size - 1)
619
- raise "Wrong j" unless j.between?(0, @data[0].size - 1)
620
- @data[i][j] = value
621
- end
622
-
623
- def load_in_r_as(variable_name)
624
- Rust._eval("#{variable_name} <- matrix(c(#{@data.flatten.join(",")}), nrow=#{self.rows}, ncol=#{self.cols}, byrow=T)")
625
- end
626
- end
627
-
628
- class Sequence < RustDatatype
629
- attr_reader :min
630
- attr_reader :max
631
-
632
- def initialize(min, max, step=1)
633
- @min = min
634
- @max = max
635
- @step = step
636
- end
637
-
638
- def step(step)
639
- @step = step
640
- end
641
-
642
- def each
643
- (@min..@max).step(@step) do |v|
644
- yield v
645
- end
646
- end
647
-
648
- def to_a
649
- result = []
650
- self.each do |v|
651
- result << v
652
- end
653
- return result
654
- end
655
-
656
- def to_R
657
- "seq(from=#@min, to=#@max, by=#@step)"
658
- end
659
-
660
- def load_in_r_as(variable_name)
661
- Rust._eval("#{variable_name} <- #{self.to_R}")
662
- end
663
- end
664
-
665
494
  class DataFrameArray < Array
666
495
  def bind_all
667
496
  return nil if self.size == 0
@@ -689,151 +518,4 @@ module Rust
689
518
  return result
690
519
  end
691
520
  end
692
-
693
- class MathArray < Array
694
- def -(other)
695
- raise ArgumentError, "Expected array or numeric" if !other.is_a?(::Array) && !other.is_a?(Numeric)
696
- raise ArgumentError, "The two arrays must have the same size" if other.is_a?(::Array) && self.size != other.size
697
-
698
- result = self.clone
699
- other = [other] * self.size if other.is_a?(Numeric)
700
- for i in 0...self.size
701
- result[i] -= other[i]
702
- end
703
-
704
- return result
705
- end
706
-
707
- def *(other)
708
- raise ArgumentError, "Expected array or numeric" if !other.is_a?(::Array) && !other.is_a?(Numeric)
709
- raise ArgumentError, "The two arrays must have the same size" if other.is_a?(::Array) && self.size != other.size
710
-
711
- result = self.clone
712
- other = [other] * self.size if other.is_a?(Numeric)
713
- for i in 0...self.size
714
- result[i] *= other[i]
715
- end
716
-
717
- return result
718
- end
719
-
720
- def +(other)
721
- raise ArgumentError, "Expected array or numeric" if !other.is_a?(::Array) && !other.is_a?(Numeric)
722
- raise ArgumentError, "The two arrays must have the same size" if other.is_a?(::Array) && self.size != other.size
723
-
724
- result = self.clone
725
- other = [other] * self.size if other.is_a?(Numeric)
726
- for i in 0...self.size
727
- result[i] += other[i]
728
- end
729
-
730
- return result
731
- end
732
-
733
- def /(other) #To recover the syntax highlighting but in Kate: /
734
- raise ArgumentError, "Expected array or numeric" if !other.is_a?(::Array) && !other.is_a?(Numeric)
735
- raise ArgumentError, "The two arrays must have the same size" if other.is_a?(::Array) && self.size != other.size
736
-
737
- result = self.clone
738
- other = [other] * self.size if other.is_a?(Numeric)
739
- for i in 0...self.size
740
- result[i] /= other[i]
741
- end
742
-
743
- return result
744
- end
745
-
746
- def **(other)
747
- raise ArgumentError, "Expected numeric" if !other.is_a?(Numeric)
748
-
749
- result = self.clone
750
- for i in 0...self.size
751
- result[i] = result[i] ** other
752
- end
753
-
754
- return result
755
- end
756
- end
757
- end
758
-
759
- class TrueClass
760
- def to_R
761
- "TRUE"
762
- end
763
- end
764
-
765
- class FalseClass
766
- def to_R
767
- "FALSE"
768
- end
769
- end
770
-
771
- class Object
772
- def to_R
773
- raise TypeError, "Unsupported type for #{self.class}"
774
- end
775
- end
776
-
777
- class NilClass
778
- def to_R
779
- return "NULL"
780
- end
781
- end
782
-
783
- class Numeric
784
- def to_R
785
- self.inspect
786
- end
787
- end
788
-
789
- class Float
790
- def to_R
791
- return self.nan? ? "NA" : super
792
- end
793
- end
794
-
795
- class Array
796
- def to_R
797
- return "c(#{self.map { |e| e.to_R }.join(",")})"
798
- end
799
-
800
- def distribution
801
- result = {}
802
- self.each do |value|
803
- result[value] = result[value].to_i + 1
804
- end
805
- return result
806
- end
807
- end
808
-
809
- class String
810
- def to_R
811
- return self.inspect
812
- end
813
- end
814
-
815
- class Range
816
- def to_R
817
- [range.min, range.max].to_R
818
- end
819
- end
820
-
821
- module Rust::RBindings
822
- def data_frame(*args)
823
- Rust::DataFrame.new(*args)
824
- end
825
- end
826
-
827
- module Rust::TestCases
828
- def self.sample_dataframe(columns, size=100)
829
- result = Rust::DataFrame.new(columns)
830
- size.times do |i|
831
- result << columns.map { |c| yield i, c }
832
- end
833
- return result
834
- end
835
- end
836
-
837
- def bind_r!
838
- include Rust::RBindings
839
521
  end