Permalink
Browse files

added rarray to handle r arrays in ruby

  • Loading branch information...
Aarong93 committed Jan 12, 2012
1 parent e2787d8 commit e100fcc28db358a1265b50659a5ecdb10645044e
Showing with 115 additions and 9 deletions.
  1. +23 −7 ext/Converters.c
  2. +2 −2 ext/Converters.h
  3. BIN ext/Converters.o
  4. +1 −0 lib/rsruby.rb
  5. +89 −0 lib/rsruby/rarray.rb
View
@@ -412,8 +412,7 @@ to_ruby_vector(SEXP robj, VALUE *obj, int mode)
dim = GET_DIM(robj);
if (dim != R_NilValue) {
len = GET_LENGTH(dim);
*obj = to_ruby_array(tmp, INTEGER(dim), len);
*obj = to_ruby_array(tmp, robj);
return 1;
}
@@ -647,10 +646,24 @@ VALUE ltranspose(VALUE list, int *dims, int *strides,
/* Convert a R Array to a Ruby Array (in the form of
* array of arrays of ...) */
VALUE to_ruby_array(VALUE obj, int *dims, int l)
VALUE to_ruby_array(VALUE obj, SEXP robj)
{
VALUE list;
int i, c, *strides;
VALUE rarrayComponents[3]; //values, dimnames, dimnamesnames
VALUE cRArray;
VALUE rarray;
SEXP dim;
int i, c, *strides,l;
int *dims;
int status;
dim = GET_DIM(robj);
dims = INTEGER(dim);
l = GET_LENGTH(dim);
status = to_ruby_vector(GET_DIMNAMES(robj),&rarrayComponents[1],VECTOR_CONVERSION);
if (!status)
rb_raise(rb_eRuntimeError,"Could not convert dimnames\n");
status = to_ruby_vector(GET_NAMES(GET_DIMNAMES(robj)),&rarrayComponents[2],VECTOR_CONVERSION);
if (!status)
rb_raise(rb_eRuntimeError,"Could not convert dimnames names\n");
strides = (int *)ALLOC_N(int,l);
if (!strides)
@@ -662,8 +675,11 @@ VALUE to_ruby_array(VALUE obj, int *dims, int l)
c *= dims[i];
}
list = ltranspose(obj, dims, strides, 0, 0, l);
rarrayComponents[0] = ltranspose(obj, dims, strides, 0, 0, l);
free(strides);
return list;
cRArray = rb_const_get(rb_cObject,rb_intern("RArray"));
rarray = rb_class_new_instance(3,rarrayComponents,cRArray);
return rarray;
}
View
@@ -56,10 +56,10 @@ VALUE call_proc(VALUE data);
VALUE reset_mode(VALUE mode);
VALUE to_ruby_hash(VALUE obj, SEXP names);
VALUE to_ruby_array(VALUE obj, int *dims, int l);
VALUE to_ruby_array(VALUE obj, SEXP robj);
VALUE ltranspose(VALUE list, int *dims, int *strides,
int pos, int shift, int len);
int pos, int shift, int len);
//Macros for quick checks
#define Robj_Check(v) (rb_obj_is_instance_of(v,rb_const_get(rb_cObject,rb_intern("RObj"))))
View
BIN +60.8 KB ext/Converters.o
Binary file not shown.
View
@@ -1,4 +1,5 @@
require 'rsruby/robj'
require 'rsruby/rarray'
require 'rsruby_c'
require 'singleton'
View
@@ -0,0 +1,89 @@
require 'rsruby'
class RArray
attr_reader :array
def initialize(_array,_dimnames,_dimnamesorder)
@array = _array
@dimnames = _dimnames
@dimnamesorder = _dimnamesorder
end
# def method_missing(m,*args)
# if args.length>0
# @array.send(m,args)
# else
# @array.send(m)
# end
# end
def [](index)
@array[index]
end
# trim the innermost dimension to n
# innermost dimension is outermost dimension in R
def trim(_n)
end
#we must handle either array or hash of dim names
#since we don't know what rsruby is going to give
def dimension_count
@dimnames.length
end
def subset(_keys,_dim)
all_keys = dimnames_along_dimension(_dim)
new_order = _keys.map{|x|
all_keys.index(x)
}
new_order=new_order.compact
new_array = subset_helper(@array,new_order,0,_dim)
if @dimnames.is_a? Array
new_dimnames = @dimnames.dup
new_dimnames[_dim] = _keys
RArray.new(new_array,new_dimnames,nil)
else #hash
new_dimnames = @dimnames.merge({@dimnamesorder[_dim] => _keys})
RArray.new(new_array,new_dimnames,@dimnamesorder.dup)
end
end
def subset_helper(_array,_new_order,_current_depth,_target_depth)
if _current_depth == _target_depth
_new_order.map{|x|
_array.fetch(x)
}
else
_array.map{|x|
subset_helper(x,_new_order,_current_depth+1,_target_depth)
}
end
end
def get(*_args)
indices = _args.each_with_index.map{|x,i|
d = dimnames_along_dimension(i)
j= d.index(x)
return nil unless j
j
}
a=@array
indices.each{|i|
a=a[i]
}
a
end
# def first(_n)
# new_array = @array.first(_n)
# new_dimnames = nil
# if @dimnames.is_a? Array
# new_dimnames = dimnames.dup
# new_dimnames[0] = new_dimnames[0].first(_n)
# else #hash
# new_dimnames = @dimnames.merge ({@dimnamesorder[0] => dimnames(0).first(_n)})
# end
# RArray.new(new_array,new_dimnames,@dimnamesorder)
# end
def dimnames_along_dimension(_index)
return @dimnames[_index] if @dimnames.is_a? Array
return @dimnames[@dimnamesorder[_index]] if @dimnames.is_a? Hash
raise "unsupported dimnames"
end
def dimension_names
return @dimnamesorder
end
end

0 comments on commit e100fcc

Please sign in to comment.