rserve-client 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig CHANGED
@@ -1 +1 @@
1
- ]�#M2� �h >-�%�̤��AlՏ�Ĥ�v�o�"*&�i-��8��������{����G�e��)\�@RM΄��P�O���e�=�h��S�� �@p3uA����|%z$���}C+M���B�c�����5}�I���fFM�xL�.$���J�tW�TT��[��4����TgϠ&0�;,v&C~Ť�؍����.zI� �y-�Q�s7s�1R��TYD0��q��k^�5�V�ny �=ϺI_
1
+ !8��M���C�+G[I��j�8����%��\`k��"�H��}m��܎����y�_�M� �!ƩV9-�y�&�mL<�ˆ�74>�B"{CW�}â:__}����Y{��Lw{2H���>�SL�璛����52��H��,)4M�^�+Y���,p����ٝ�0/�^+<��$Ye����TWΏ�eܔ1��#�"
@@ -1,3 +1,7 @@
1
+ === 0.2.1 / 2010-06-18
2
+ * Added suport to assign ruby std lib Matrix. Bug fix on retrieving matrix
3
+ * Fixed whitespace problem on README.txt
4
+
1
5
  === 0.2.0 / 2010-06-15
2
6
  * Session implemented.
3
7
  * Retrieve auth information from server first responde. TODO: Implement authentification
data/README.txt CHANGED
@@ -15,19 +15,19 @@ Follows closely the new Java client API, but maintains all Ruby conventions when
15
15
  * Uses TCP/IP sockets to interchange data and commands
16
16
  * Requires Rserve installed on the server machine. On debian / ubuntu, you should use <tt>sudo apt-get install r-cran-rserve</tt>
17
17
  Pros:
18
- * Work with Ruby 1.8, 1.9 and JRuby 1.5.
19
- * Work on Windows. Rserve limitations on that plataform applies (single connection, crash on parse errors)
20
- * Retrieve and assign various R's datatypes: integer, doubles, chars, logical vectors, lists and raw data.
21
- * Session allows to process data asynchronously. You start a command, detach the process and retrieve result later. You can marshall the session, store on file or database and use it when you need it.
22
- * Ruby API follows closely the Java API, so any change on the server API could be adopted without much problem
23
- * Fast: 5-10 times faster than RinRuby.
24
- * Easy management of differences between R and Ruby, or "You can have your cake and eat it, too!"
25
- * From R side: The evaluation of expression retrieves REXP object, with a lot of information from original variables on R. You can construct your REXP objects and <tt>assign</tt> them to variables on R fast using binary TCP/IP port or send complex expression without lost of time using <tt>void_eval</tt>
26
- * Between R and Ruby: Every REXP object implements methods to convert to specific Ruby type: as_integers, as_doubles, as_strings
27
- * From Ruby side: Every REXP objects has a <tt>to_ruby</tt> method, which automagicly converts every R type on equivalent Ruby type. So, a vector of size 1 is converted to an integer or double, a vector of size>1 returns an array, a named list returns a hash and so on. If you need to create a complex expression, you could always use method <tt>eval</tt> without problem
18
+ * Work with Ruby 1.8, 1.9 and JRuby 1.5.
19
+ * Work on Windows. Rserve limitations on that plataform applies (single connection, crash on parse errors)
20
+ * Retrieve and assign various R's datatypes: integer, doubles, chars, logical vectors, lists and raw data.
21
+ * Session allows to process data asynchronously. You start a command, detach the process and retrieve result later. You can marshall the session, store on file or database and use it when you need it.
22
+ * Ruby API follows closely the Java API, so any change on the server API could be adopted without much problem
23
+ * Fast: 5-10 times faster than RinRuby.
24
+ * Easy management of differences between R and Ruby, or "You can have your cake and eat it, too!"
25
+ * From R side: The evaluation of expression retrieves REXP object, with a lot of information from original variables on R. You can construct your REXP objects and <tt>assign</tt> them to variables on R fast using binary TCP/IP port or send complex expression without lost of time using <tt>void_eval</tt>
26
+ * Between R and Ruby: Every REXP object implements methods to convert to specific Ruby type: as_integers, as_doubles, as_strings
27
+ * From Ruby side: Every REXP objects has a <tt>to_ruby</tt> method, which automagicly converts every R type on equivalent Ruby type. So, a vector of size 1 is converted to an integer or double, a vector of size>1 returns an array, a named list returns a hash and so on. If you need to create a complex expression, you could always use method <tt>eval</tt> without problem
28
28
  Cons:
29
- * Requires Rserve
30
-
29
+ * Requires Rserve
30
+
31
31
  == RELATED LIBRARIES (Ruby / R)
32
32
 
33
33
  * Rinruby [http://rinruby.ddahl.org/]
@@ -1,7 +1,7 @@
1
1
  require 'socket'
2
2
 
3
3
  module Rserve
4
- VERSION = '0.2.0'
4
+ VERSION = '0.2.1'
5
5
  end
6
6
 
7
7
 
@@ -323,26 +323,31 @@ module Rserve
323
323
  dim = get_attribute "dim"
324
324
  raise MismatchException, "array (dim attribute missing" if dim.nil?
325
325
  ds = dim.as_integers.reverse
326
-
327
326
  split_array(ct,ds)
328
327
  end
329
328
 
330
329
  def split_array(ar, dims) # :nodoc:
331
- # puts "#{ar} - #{dims}"
330
+ #puts "#{ar} - #{dims}"
332
331
  if dims.size==1
333
332
  raise "Improper size ar:#{ar} , dims=#{dims[0]}" if ar.size!=dims[0]
334
333
  return ar
335
334
  elsif dims.size==2
335
+ dims.reverse!
336
336
  # should rearrange values as R do
337
+ # dims[0]=cols, dims[1]=rows
338
+ if(true)
337
339
  out=[]
338
340
  ar.each_with_index {|v,i|
339
- r=(i/dims[1]).to_i;
340
- c=i%dims[1];
341
- # p "#{r} : #{c}";
342
- out[c*dims[0]+r]=v
341
+ r=(i/dims[0]).to_i;
342
+ c=i%dims[0];
343
+ #p "#{r} : #{c}";
344
+ out[c*dims[1]+r]=v
343
345
  }
346
+ #p out
347
+
344
348
  raise "out size should equal to ar size" if ar.size!=out.size
345
349
  ar=out
350
+ end
346
351
  end
347
352
  dims_c=dims.dup
348
353
  current_dim=dims_c.shift
@@ -11,28 +11,45 @@ module Rserve
11
11
  module Wrapper
12
12
  def self.wrap(o)
13
13
  return o if o.is_a? REXP
14
+ return o.to_REXP if o.respond_to? :to_REXP
14
15
  case o
15
- when TrueClass
16
- REXP::Logical.new(1)
17
- when FalseClass
18
- REXP::Logical.new(0)
19
- when NilClass
20
- REXP::Null.new()
21
- when ::String
22
- REXP::String.new(o)
23
- when Integer
24
- REXP::Integer.new(o)
25
- when Fixnum
26
- REXP::Integer.new(o)
27
- when Float
28
- REXP::Double.new(o)
29
- when Array
30
- find_type_of_array(o)
31
- else
32
- puts "Clase:#{o.class}"
33
- nil
16
+ when TrueClass
17
+ REXP::Logical.new(1)
18
+ when FalseClass
19
+ REXP::Logical.new(0)
20
+ when NilClass
21
+ REXP::Null.new()
22
+ when ::String
23
+ REXP::String.new(o)
24
+ when Integer
25
+ REXP::Integer.new(o)
26
+ when Fixnum
27
+ REXP::Integer.new(o)
28
+ when Float
29
+ REXP::Double.new(o)
30
+ when Array
31
+ find_type_of_array(o)
32
+ when ::Matrix
33
+ create_matrix(o)
34
+ else
35
+ nil
34
36
  end
35
37
  end
38
+ def self.create_matrix(o)
39
+ data= o.column_size.times.map {|j|
40
+ o.column(j).to_a
41
+ }.flatten
42
+ attr=REXP::List.new(
43
+ Rlist.new(
44
+ [
45
+ REXP::String.new("matrix"),
46
+ REXP::Integer.new([o.row_size, o.column_size])
47
+ ],
48
+ ["class", "dim" ]
49
+ )
50
+ )
51
+ REXP::Double.new(data, attr)
52
+ end
36
53
  def self.find_type_of_array(o)
37
54
  if o.all? {|v| v.nil?}
38
55
  REXP::Integer.new([REXP::Integer::NA]*o.size)
@@ -123,11 +123,21 @@ describe Rserve::Connection do
123
123
  @r.eval("x").should==x
124
124
  end
125
125
  it "should assign a matrix" do
126
- x=@r.eval("matrix(1:9,3,3)")
126
+ x=@r.eval("matrix(1:12,6,2)")
127
127
  @r.assign("x",x)
128
128
  @r.eval("x").should==x
129
-
130
129
  end
130
+ it "should assign a ruby matrix" do
131
+ mat_ruby=Matrix[[1,7],[2,8],[3,9],[4,10],[5,11],[6,12]]
132
+ @r.assign('x',mat_ruby)
133
+ x=@r.eval('x')
134
+ y=@r.eval('y<-matrix(c(1,2,3,4,5,6,7,8,9,10,11,12),6,2)')
135
+ #p x.attr.to_ruby
136
+ x.as_floats.should==y.as_floats
137
+ x.attr.as_list['dim'].should==y.attr.as_list['dim']
138
+ x.to_ruby.should==mat_ruby
139
+ end
140
+
131
141
  after do
132
142
  @r.void_eval("rm(x)")
133
143
  end
@@ -38,7 +38,7 @@ describe "Rserve::REXP#to_ruby" do
38
38
  a.attributes['names'].should==%w{a b c}
39
39
  end
40
40
  it "should return a Ruby Matrix with R matrix" do
41
- @r.eval("matrix(c(1,2,3,4),2,2)").to_ruby.should==Matrix[[1,3],[2,4]]
41
+ @r.eval("matrix(c(1:12),6,2)").to_ruby.should==Matrix[[1,7],[2,8],[3,9],[4,10],[5,11], [6,12]]
42
42
  end
43
43
  it "should return a nested array of Ruby Matrixes with vector with more than tree dimensions" do
44
44
  @r.void_eval("a<-1:16; attr(a,'dim')<-c(2,2,2,2)")
@@ -1,5 +1,5 @@
1
1
  require File.dirname(__FILE__)+"/spec_helper.rb"
2
-
2
+ require 'matrix'
3
3
  describe Rserve::REXP::Wrapper do
4
4
  it "should wrap single value" do
5
5
  Rserve::REXP::Wrapper.wrap(1).should==Rserve::REXP::Integer.new(1)
@@ -13,6 +13,20 @@ describe Rserve::REXP::Wrapper do
13
13
  Rserve::REXP::Wrapper.wrap([true,false]).should==Rserve::REXP::Logical.new([1,0])
14
14
  Rserve::REXP::Wrapper.wrap(["a","b"]).should==Rserve::REXP::String.new(["a","b"])
15
15
  end
16
+ it "should wrap a standard library matrix" do
17
+ mat=Matrix[[1,2],[3,4]]
18
+ expected=Rserve::REXP::Double.new([1,3,2,4], Rserve::REXP::List.new( Rserve::Rlist.new(
19
+ [
20
+ Rserve::REXP::String.new('matrix'),
21
+ Rserve::REXP::Integer.new([2,2])
22
+ ],
23
+ ['class','dim']
24
+ )
25
+ )
26
+ )
27
+ Rserve::REXP::Wrapper.wrap(mat).should==expected
28
+ end
29
+
16
30
  it "should wrap on a list mixed values" do
17
31
  r=Rserve::Connection.new
18
32
  Rserve::REXP::Wrapper.wrap([1,2.0,false,"a"]).should==
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 2
8
- - 0
9
- version: 0.2.0
8
+ - 1
9
+ version: 0.2.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Claudio Bustos
@@ -35,7 +35,7 @@ cert_chain:
35
35
  rpP0jjs0
36
36
  -----END CERTIFICATE-----
37
37
 
38
- date: 2010-06-16 00:00:00 -04:00
38
+ date: 2010-06-18 00:00:00 -04:00
39
39
  default_executable:
40
40
  dependencies:
41
41
  - !ruby/object:Gem::Dependency
metadata.gz.sig CHANGED
Binary file