Class: CArray

Inherits:
Object
  • Object
show all
Defined in:
ext/ruby_carray.c

Direct Known Subclasses

CAVirtual, CAWrap, CScalar

Defined Under Namespace

Classes: Boolean, Cmplx128, Cmplx256, Cmplx64, DataTypeError, Fixlen, Float128, Float32, Float64, Int16, Int32, Int64, Int8, Object, UInt16, UInt32, UInt64, UInt8

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data_type, dim, bytes = 0) ⇒ Object

Constructs a new CArray object of data_type, which has the ndim and the dimensions specified by an Array of Integer or an argument list of Integer. The byte size of each element for the fixed length data type (data_type == CA_FIXLEN) is specified optional argument bytes. Otherwise, this optional argument has no effect. If the block is given, the new CArray object will be initialized by the value returned from the block.



721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
# File 'ext/ca_obj_array.c', line 721

static VALUE
rb_ca_initialize (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE rtype, rdim, ropt, rbytes = Qnil;
  CArray *ca;
  int8_t data_type, ndim;
  ca_size_t dim[CA_RANK_MAX];
  ca_size_t bytes;
  int8_t i;

  rb_scan_args(argc, argv, "21", (VALUE *)&rtype, (VALUE *) &rdim, (VALUE *) &ropt);
  rb_scan_options(ropt, "bytes", &rbytes);

  rb_ca_guess_type_and_bytes(rtype, rbytes, &data_type, &bytes);
  rb_ca_data_type_import(self, rtype);

  Check_Type(rdim, T_ARRAY);
  ndim = RARRAY_LEN(rdim);
  for (i=0; i<ndim; i++) {
    dim[i] = NUM2SIZE(rb_ary_entry(rdim, i));
  }

  Data_Get_Struct(self, CArray, ca);
  carray_safe_setup(ca, data_type, ndim, dim, bytes, NULL);

  if ( rb_block_given_p() ) {
    volatile VALUE rval = rb_yield(self);
    if ( rval != self ) {
      rb_ca_store_all(self, rval);
    }
  }

  return Qnil;
}

Class Method Details

.attach(*arrays) ⇒ Object

(Internal) Guarantees that the reference memory block is attached. The memory block is detached at the end of the block evaluation. It is not ensured the syncing the memory block at the end of the block evaluation.

Yields:



1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
# File 'ext/carray_core.c', line 1008

static VALUE
rb_ca_s_attach (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE list, obj;
  int i;

  list = rb_ary_new4(argc, argv);

  for (i=0; i<RARRAY_LEN(list); i++) {
    obj = rb_ary_entry(list, i);
    rb_ca_attach_i(obj);
  }

  return rb_ensure(rb_yield_splat, list, rb_ca_s_ensure_detach, list);
}

.attach!(*arrays) ⇒ Object

(Internal) Guarantees that the reference memory block is attached. The memory block is detached at the end of the block evaluation. It is ensured the syncing the memory block at the end of the block evaluation.

Yields:



1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
# File 'ext/carray_core.c', line 1048

static VALUE
rb_ca_s_attach_bang (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE list, obj;
  int i;

  list = rb_ary_new4(argc, argv);

  for (i=0; i<RARRAY_LEN(list); i++) {
    obj = rb_ary_entry(list, i);
    rb_ca_modify(obj);
    rb_ca_attach_i(obj);
  }

  return rb_ensure(rb_yield_splat, list, rb_ca_s_ensure_sync_detach, list);
}

.big_endian?Boolean

(Inquiry) Returns true if the byte order of the architecture is big endian.

Returns:



33
34
35
36
37
# File 'ext/carray_class.c', line 33

static VALUE
rb_ca_s_big_endian_p (VALUE klass)
{
  return ( ca_endian == CA_BIG_ENDIAN ) ? Qtrue : Qfalse;
}

.boolean(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:boolean, dim, bytes: bytes) { ... }



789
790
791
792
# File 'ext/ca_obj_array.c', line 789

static VALUE rb_ca_s_boolean (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_BOOLEAN);
}

.uint8(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:uint8, dim, bytes: bytes) { ... }



809
810
811
812
# File 'ext/ca_obj_array.c', line 809

static VALUE rb_ca_s_uint8 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_UINT8);
}

.cast(value) ⇒ Object

[TBD]



1016
1017
1018
1019
1020
# File 'ext/carray_cast.c', line 1016

static VALUE
rb_ca_s_cast (VALUE klass, VALUE val)
{
  return rb_ca_cast(val);
}

.cast_self_or_other(other) ⇒ Object

[TBD]



1176
1177
1178
1179
1180
1181
# File 'ext/carray_cast.c', line 1176

VALUE
rb_ca_s_cast_self_or_other (VALUE klass, VALUE self, VALUE other)
{
  rb_ca_cast_self_or_other(&self, &other);
  return rb_assoc_new(self, other);
}

.cmplx128(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:cmplx128, dim, bytes: bytes) { ... }



920
921
922
923
# File 'ext/ca_obj_array.c', line 920

static VALUE rb_ca_s_cmplx128 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_CMPLX128);
}

.cmplx256(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:cmplx256, dim, bytes: bytes) { ... }



930
931
932
933
# File 'ext/ca_obj_array.c', line 930

static VALUE rb_ca_s_cmplx256 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_CMPLX256);
}

.cmplx64(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:cmplx64, dim, bytes: bytes) { ... }



910
911
912
913
# File 'ext/ca_obj_array.c', line 910

static VALUE rb_ca_s_cmplx64 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_CMPLX64);
}

.cmplx64(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:cmplx64, dim, bytes: bytes) { ... }



910
911
912
913
# File 'ext/ca_obj_array.c', line 910

static VALUE rb_ca_s_cmplx64 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_CMPLX64);
}

.data_class?Boolean

Returns:



219
220
221
222
223
# File 'ext/carray_test.c', line 219

static VALUE
rb_ca_s_is_data_class (VALUE self, VALUE rklass)
{
  return rb_obj_is_data_class(rklass);
}

.data_type?(data_type) ⇒ Boolean

(Inquiry) Returns true if the given data_type indicate the valid data_type.

Returns:



79
80
81
82
83
84
85
86
87
88
# File 'ext/carray_class.c', line 79

static VALUE
rb_ca_s_data_type (VALUE klass, VALUE rtype)
{
  int8_t data_type = rb_ca_guess_type(rtype);
  if ( data_type <= CA_NONE || data_type >= CA_NTYPE ) {
    rb_raise(rb_eArgError,
            "data type is out of range (%i..%i)", CA_NONE+1, CA_NTYPE-1);
  }
  return ca_valid[data_type] == 1 ? Qtrue : Qfalse;
}

.data_type_name(data_type) ⇒ Object

(Inquiry) Returns string representaion of the data_type specifier.



97
98
99
100
101
102
103
# File 'ext/carray_class.c', line 97

static VALUE
rb_ca_s_data_type_name (VALUE klass, VALUE type)
{
  int8_t data_type = NUM2INT(type);
  CA_CHECK_DATA_TYPE(data_type);
  return rb_str_new2(ca_type_name[data_type]);
}

.cmplx128(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:cmplx128, dim, bytes: bytes) { ... }



920
921
922
923
# File 'ext/ca_obj_array.c', line 920

static VALUE rb_ca_s_cmplx128 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_CMPLX128);
}

.float64(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:float64, dim, bytes: bytes) { ... }



889
890
891
892
# File 'ext/ca_obj_array.c', line 889

static VALUE rb_ca_s_float64 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_FLOAT64);
}

.each_index(*shape) ⇒ Object

(Iterator) Iterates with the multi-dimensional indeces for the given dimension numbers.

 CArray.each_index(3,2){|i,j| print "(#{i} #{j}) " }
 produces:
 (0 0) (0 1) (1 0) (1 1) (2 0) (2 1) (3 0) (3 1)


54
55
56
57
58
59
60
61
62
# File 'ext/carray_loop.c', line 54

static VALUE
rb_ca_s_each_index (int ndim, VALUE *dim, VALUE self)
{
  volatile VALUE ridx = rb_ary_new2(ndim);
#if RUBY_VERSION_CODE >= 190
  RETURN_ENUMERATOR(self, ndim, dim);
#endif
  return rb_ca_s_each_index_internal(ndim, dim, 0, ridx);
}

.endianObject

(Inquiry) Returns the machine endianness. 0 (CA_LITTLE_ENDIAN) 1 (CA_BIG_ENDIAN)



21
22
23
24
25
# File 'ext/carray_class.c', line 21

static VALUE
rb_ca_s_endian (VALUE klass)
{
  return INT2NUM(ca_endian);
}

.fixlen(*dim, bytes: ) ⇒ Object

(Construction) Short-Hand of CArray.new(:fixlen, dim, bytes: ) { ... }



762
763
764
765
766
767
768
769
# File 'ext/ca_obj_array.c', line 762

static VALUE
rb_ca_s_fixlen (int argc, VALUE *argv, VALUE klass)  
{                                                     
  volatile VALUE ropt = rb_pop_options(&argc, &argv); 
  volatile VALUE rdim = rb_ary_new4(argc, argv);      
  VALUE args[3] = { INT2NUM(CA_FIXLEN), rdim, ropt };      
  return rb_class_new_instance(3, args, klass);       
}

.float32(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:float32, dim, bytes: bytes) { ... }



879
880
881
882
# File 'ext/ca_obj_array.c', line 879

static VALUE rb_ca_s_float32 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_FLOAT32);
}

.float128(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:float128, dim, bytes: bytes) { ... }



899
900
901
902
# File 'ext/ca_obj_array.c', line 899

static VALUE rb_ca_s_float128 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_FLOAT128);
}

.float32(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:float32, dim, bytes: bytes) { ... }



879
880
881
882
# File 'ext/ca_obj_array.c', line 879

static VALUE rb_ca_s_float32 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_FLOAT32);
}

.float64(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:float64, dim, bytes: bytes) { ... }



889
890
891
892
# File 'ext/ca_obj_array.c', line 889

static VALUE rb_ca_s_float64 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_FLOAT64);
}

.int32(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:int32, dim, bytes: bytes) { ... }



839
840
841
842
# File 'ext/ca_obj_array.c', line 839

static VALUE rb_ca_s_int32 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_INT32);
}

.int16(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:int16, dim, bytes: bytes) { ... }



819
820
821
822
# File 'ext/ca_obj_array.c', line 819

static VALUE rb_ca_s_int16 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_INT16);
}

.int32(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:int32, dim, bytes: bytes) { ... }



839
840
841
842
# File 'ext/ca_obj_array.c', line 839

static VALUE rb_ca_s_int32 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_INT32);
}

.int64(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:int64, dim, bytes: bytes) { ... }



859
860
861
862
# File 'ext/ca_obj_array.c', line 859

static VALUE rb_ca_s_int64 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_INT64);
}

.int8(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:int8, dim, bytes: bytes) { ... }



799
800
801
802
# File 'ext/ca_obj_array.c', line 799

static VALUE rb_ca_s_int8 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_INT8);
}

.little_endian?Boolean

(Inquiry) Returns true if the byte order of the architecture is little endian.

Returns:



46
47
48
49
50
# File 'ext/carray_class.c', line 46

static VALUE
rb_ca_s_little_endian_p (VALUE klass)
{
  return ( ca_endian == CA_LITTLE_ENDIAN ) ? Qtrue : Qfalse;
}

.object(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:object, dim, bytes: bytes) { ... }



941
942
943
944
# File 'ext/ca_obj_array.c', line 941

static VALUE rb_ca_s_VALUE (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_OBJECT);
}

.int16(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:int16, dim, bytes: bytes) { ... }



819
820
821
822
# File 'ext/ca_obj_array.c', line 819

static VALUE rb_ca_s_int16 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_INT16);
}

.sizeof(data_type) ⇒ Object

(Inquiry) Returns the byte length of an element of the given data type. Retruns 0 if data_type is equal to CA_FIXLEN. CArray.sizeof(CA_INT32) #=> 4 CArray.sizeof(CA_DOUBLE) #=> 8 CArray.sizeof(CA_FIXLEN) #=> 0



63
64
65
66
67
68
69
70
# File 'ext/carray_class.c', line 63

static VALUE
rb_ca_s_sizeof (VALUE klass, VALUE rtype)
{
  int8_t data_type;
  ca_size_t bytes;
  rb_ca_guess_type_and_bytes(rtype, INT2NUM(0), &data_type, &bytes);
  return SIZE2NUM(bytes);
}

.uint16(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:uint16, dim, bytes: bytes) { ... }



829
830
831
832
# File 'ext/ca_obj_array.c', line 829

static VALUE rb_ca_s_uint16 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_UINT16);
}

.uint32(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:uint32, dim, bytes: bytes) { ... }



849
850
851
852
# File 'ext/ca_obj_array.c', line 849

static VALUE rb_ca_s_uint32 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_UINT32);
}

.uint64(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:uint64, dim, bytes: bytes) { ... }



869
870
871
872
# File 'ext/ca_obj_array.c', line 869

static VALUE rb_ca_s_uint64 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_UINT64);
}

.uint8(*dim) ⇒ Object

(Construction) Short-Hand of CArray.new(:uint8, dim, bytes: bytes) { ... }



809
810
811
812
# File 'ext/ca_obj_array.c', line 809

static VALUE rb_ca_s_uint8 (int argc, VALUE *argv, VALUE klass)
{
  rb_ca_s_body(CA_UINT8);
}

.wrap(data_type, dim, bytes = 0{ target }) ⇒ Object

TBD target should have method "wrap_as_carray(obj)"



973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
# File 'ext/ca_obj_array.c', line 973

static VALUE
rb_ca_s_wrap (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE obj, target, rtype, rdim, ropt, rbytes = Qnil;
  CArray *ca;
  int8_t data_type, ndim;
  ca_size_t dim[CA_RANK_MAX];
  ca_size_t bytes;
  int8_t i;

  rb_scan_args(argc, argv, "21", (VALUE *) &rtype, (VALUE *) &rdim, (VALUE *) &ropt);
  rb_scan_options(ropt, "bytes", &rbytes);

  rb_ca_guess_type_and_bytes(rtype, rbytes, &data_type, &bytes);

  Check_Type(rdim, T_ARRAY);
  ndim = RARRAY_LEN(rdim);
  for (i=0; i<ndim; i++) {
    dim[i] = NUM2SIZE(rb_ary_entry(rdim, i));
  }

  target = rb_yield_values(0);

  obj = Data_Make_Struct(rb_cCAWrap, CAWrap, ca_mark, ca_free, ca);
  ca_wrap_setup_null(ca, data_type, ndim, dim, bytes, NULL);

  rb_funcall(target, rb_intern("wrap_as_carray"), 1, obj);
  rb_ivar_set(obj, rb_intern("referred_object"), target);

  return obj;
}

.wrap_readonly(other, date_type = nil) ⇒ Object

[TBD]



965
966
967
968
969
970
971
# File 'ext/carray_cast.c', line 965

static VALUE
rb_ca_s_wrap_readonly (int argc, VALUE *argv, VALUE klass)
{
  volatile VALUE obj, rtype;
  rb_scan_args(argc, argv, "11", (VALUE *) &obj, (VALUE *) &rtype);
  return rb_ca_wrap_readonly(obj, rtype);
}

.wrap_writable(other, date_type = nil) ⇒ Object

[TBD]



842
843
844
845
846
847
848
# File 'ext/carray_cast.c', line 842

static VALUE
rb_ca_s_wrap_writable (int argc, VALUE *argv, VALUE klass)
{
  volatile VALUE obj, rtype;
  rb_scan_args(argc, argv, "11", (VALUE *) &obj, (VALUE *) &rtype);
  return rb_ca_wrap_writable(obj, rtype);
}

Instance Method Details

#==(other) ⇒ Object Also known as: eql?

(Inquiry) Returns true if the object equals the given array.



467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
# File 'ext/carray_test.c', line 467

static VALUE
rb_ca_equal (VALUE self, VALUE other)
{
  CArray *ca, *cb;

  if ( ! rb_obj_is_carray(other) )  {    /* check kind_of?(CArray) */
    return Qfalse;
  }

  if ( rb_ca_has_data_class(self) || rb_ca_has_data_class(other) ) {
    if ( rb_ca_has_data_class(self) ^ rb_ca_has_data_class(other) ) {
      return Qfalse;
    }
    else {
      VALUE dc1 = rb_ca_data_class(self);
      VALUE dc2 = rb_ca_data_class(other);
      if ( ! rb_funcall(dc1, rb_intern("=="), 1, dc2) ) {
        return Qfalse;
      }
    }
  }

  Data_Get_Struct(self, CArray, ca);
  Data_Get_Struct(other, CArray, cb);

  return ( ca_equal(ca, cb) ) ? Qtrue : Qfalse;
}

#__attach__Object

(Internal, DevelopperOnly) Attaches the reference memory block. User must call "CArray#detach" appropreate timing.



1119
1120
1121
1122
1123
1124
# File 'ext/carray_core.c', line 1119

static VALUE
rb_ca__attach__ (VALUE self)
{
  rb_ca_attach_i(self);
  return self;
}

#__detach__Object

(Internal, DevelopperOnly) Detaches the reference memory block.



1144
1145
1146
1147
1148
1149
# File 'ext/carray_core.c', line 1144

static VALUE
rb_ca__detach__ (VALUE self)
{
  rb_ca_detach_i(self);
  return self;
}

#__detach__Object

(Internal, DevelopperOnly) Syncs the reference memory block to the parent array.



1131
1132
1133
1134
1135
1136
1137
# File 'ext/carray_core.c', line 1131

static VALUE
rb_ca__sync__ (VALUE self)
{
  rb_ca_modify(self);
  rb_ca_sync_i(self);
  return self;
}

#all_masked?Boolean

(Masking, Inquiry) Returns true if all elements of self are masked.

Returns:



600
601
602
603
604
605
606
# File 'ext/carray_mask.c', line 600

VALUE
rb_ca_is_all_masked (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ( ca_is_all_masked(ca) ) ? Qtrue : Qfalse;
}

#ancestorsObject

(Attribute) Returns the list of objects in the chain of reference.



803
804
805
806
807
808
809
810
811
# File 'ext/carray_attribute.c', line 803

static VALUE
rb_ca_ancestors (VALUE self)
{
  volatile VALUE list;
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  list = rb_ary_new();
  return rb_ca_ancestors_loop(self, list);
}

#any_masked?Boolean

(Masking, Inquiry) Returns true if self has at least one masked element.

Returns:



586
587
588
589
590
591
592
# File 'ext/carray_mask.c', line 586

VALUE
rb_ca_is_any_masked (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ( ca_is_any_masked(ca) ) ? Qtrue : Qfalse;
}

#as_booleanObject

(Reference) Short-Hand of CArray#as_type(:boolean)



581
582
583
584
# File 'ext/carray_cast.c', line 581

VALUE rb_ca_as_boolean (VALUE self)
{
  rb_ca_as_type_method_body(CA_BOOLEAN);
}

#as_cmplx128Object Also known as: as_dcomplex

(Reference) Short-Hand of CArray#as_type(:cmplx128)



698
699
700
701
# File 'ext/carray_cast.c', line 698

VALUE rb_ca_as_cmplx128 (VALUE self)
{
  rb_ca_as_type_method_body(CA_CMPLX128);
}

#as_cmplx256Object

(Reference) Short-Hand of CArray#as_type(:cmplx256)



707
708
709
710
# File 'ext/carray_cast.c', line 707

VALUE rb_ca_as_cmplx256 (VALUE self)
{
  rb_ca_as_type_method_body(CA_CMPLX256);
}

#as_cmplx64Object Also known as: as_complex

(Reference) Short-Hand of CArray#as_type(:cmplx64)



689
690
691
692
# File 'ext/carray_cast.c', line 689

VALUE rb_ca_as_cmplx64 (VALUE self)
{
  rb_ca_as_type_method_body(CA_CMPLX64);
}

#as_fixlen(bytes: nil) ⇒ Object

(Reference) Short-Hand of CArray#as_type(:fixlen, bytes: nil)



566
567
568
569
570
571
572
573
574
575
# File 'ext/carray_cast.c', line 566

VALUE
rb_ca_as_fixlen (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE rtype, ropt = rb_pop_options(&argc, &argv);
  VALUE list[2];
  rb_scan_args(argc, argv, "01", (VALUE *)  &rtype);
  list[0] = ( NIL_P(rtype) ) ? INT2NUM(CA_FIXLEN) : rtype;
  list[1] = ropt;
  return rb_ca_as_type_internal(2, list, self);
}

#as_float128Object

(Reference) Short-Hand of CArray#as_type(:float128)



680
681
682
683
# File 'ext/carray_cast.c', line 680

VALUE rb_ca_as_float128 (VALUE self)
{
  rb_ca_as_type_method_body(CA_FLOAT128);
}

#as_float32Object Also known as: as_float

(Reference) Short-Hand of CArray#as_type(:float32)



662
663
664
665
# File 'ext/carray_cast.c', line 662

VALUE rb_ca_as_float32 (VALUE self)
{
  rb_ca_as_type_method_body(CA_FLOAT32);
}

#as_float64Object Also known as: as_double

(Reference) Short-Hand of CArray#as_type(:float64)



671
672
673
674
# File 'ext/carray_cast.c', line 671

VALUE rb_ca_as_float64 (VALUE self)
{
  rb_ca_as_type_method_body(CA_FLOAT64);
}

#as_int16Object Also known as: as_short

(Reference) Short-Hand of CArray#as_type(:int16)



608
609
610
611
# File 'ext/carray_cast.c', line 608

VALUE rb_ca_as_int16 (VALUE self)
{
  rb_ca_as_type_method_body(CA_INT16);
}

#as_int32Object Also known as: as_int

(Reference) Short-Hand of CArray#as_type(:int32)



626
627
628
629
# File 'ext/carray_cast.c', line 626

VALUE rb_ca_as_int32 (VALUE self)
{
  rb_ca_as_type_method_body(CA_INT32);
}

#as_int64Object

(Reference) Short-Hand of CArray#as_type(:int64)



644
645
646
647
# File 'ext/carray_cast.c', line 644

VALUE rb_ca_as_int64 (VALUE self)
{
  rb_ca_as_type_method_body(CA_INT64);
}

#as_int8Object

(Reference) Short-Hand of CArray#as_type(:int8)



590
591
592
593
# File 'ext/carray_cast.c', line 590

VALUE rb_ca_as_int8 (VALUE self)
{
  rb_ca_as_type_method_body(CA_INT8);
}

#as_objectObject

(Reference) Short-Hand of CArray#as_type(:object)



716
717
718
719
# File 'ext/carray_cast.c', line 716

VALUE rb_ca_as_VALUE (VALUE self)
{
  rb_ca_as_type_method_body(CA_OBJECT);
}

#as_typeObject

CArray#as_type



516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
# File 'ext/carray_cast.c', line 516

static VALUE
rb_ca_as_type_internal (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE obj, rtype = Qnil, ropt, rbytes = Qnil;
  CArray *ca;
  int8_t data_type;
  ca_size_t bytes;

  rb_scan_args(argc, argv, "11", (VALUE *) &rtype, (VALUE *) &ropt);
  rb_scan_options(ropt, "bytes", &rbytes);

  rb_ca_guess_type_and_bytes(rtype, rbytes, &data_type, &bytes);

  Data_Get_Struct(self, CArray, ca);
  if ( ca->data_type == data_type ) {
    if ( ! ca_is_fixlen_type(ca) ) {
      return self;
    }
  }

  obj = rb_ca_fake_type(self, rtype, rbytes);
  rb_ca_data_type_import(obj, rtype);

  return obj;
}

#as_uint16Object

(Reference) Short-Hand of CArray#as_type(:uint16)



617
618
619
620
# File 'ext/carray_cast.c', line 617

VALUE rb_ca_as_uint16 (VALUE self)
{
  rb_ca_as_type_method_body(CA_UINT16);
}

#as_uint32Object

(Reference) Short-Hand of CArray#as_type(:uint32)



635
636
637
638
# File 'ext/carray_cast.c', line 635

VALUE rb_ca_as_uint32 (VALUE self)
{
  rb_ca_as_type_method_body(CA_UINT32);
}

#as_uint64Object

(Reference) Short-Hand of CArray#as_type(:uint64)



653
654
655
656
# File 'ext/carray_cast.c', line 653

VALUE rb_ca_as_uint64 (VALUE self)
{
  rb_ca_as_type_method_body(CA_UINT64);
}

#as_uint8Object Also known as: as_byte

(Reference) Short-Hand of CArray#as_type(:uint8)



599
600
601
602
# File 'ext/carray_cast.c', line 599

VALUE rb_ca_as_uint8 (VALUE self)
{
  rb_ca_as_type_method_body(CA_UINT8);
}

#attachObject

(Internal) Guarantees that the reference memory block is attached. The memory block is detached at the end of the block evaluation. It is ensured the syncing the memory block at the end of the block evaluation.

Yields:



1081
1082
1083
1084
1085
1086
# File 'ext/carray_core.c', line 1081

static VALUE
rb_ca_attach (VALUE self)
{
  rb_ca_attach_i(self);
  return rb_ensure(rb_yield, self, rb_ca_ensure_detach, self);
}

#attach!Object

(Internal) Guarantees that the reference memory block is attached. The memory block is detached at the end of the block evaluation. It is ensured the syncing the memory block at the end of the block evaluation.

Yields:



1105
1106
1107
1108
1109
1110
1111
# File 'ext/carray_core.c', line 1105

static VALUE
rb_ca_attach_bang (VALUE self)
{
  rb_ca_modify(self);
  rb_ca_attach_i(self);
  return rb_ensure(rb_yield, self, rb_ca_ensure_sync_detach, self);
}

#attached?Boolean

(Inquiry) Returns true if the object is attached.

Returns:



264
265
266
267
268
269
270
# File 'ext/carray_attribute.c', line 264

VALUE
rb_ca_is_attached (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ( ca_is_attached(ca) ) ? Qtrue : Qfalse;
}

#bitarrayObject Also known as: bits

[TBD]



470
471
472
473
474
475
476
477
478
479
480
481
# File 'ext/ca_obj_bitarray.c', line 470

VALUE
rb_ca_bitarray (VALUE self)
{
  volatile VALUE obj;
  CArray *ca;

  Data_Get_Struct(self, CArray, ca);

  obj = rb_ca_bitarray_new(self);

  return obj;
}

#bitfield(range, type) ⇒ Object

[TBD]



565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
# File 'ext/ca_obj_bitfield.c', line 565

VALUE
rb_ca_bitfield (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE rrange, rtype;
  CArray *ca;
  ca_size_t offset, bitlen, step;
  int data_type = CA_NONE;
  ca_size_t bitsize;

  rb_scan_args(argc, argv, "11", (VALUE *) &rrange, (VALUE *) &rtype);

  Data_Get_Struct(self, CArray, ca);

  if ( TYPE(rrange) == T_FIXNUM ) {
    offset = NUM2INT(rrange);
    bitlen = 1;
  }
  else {
    bitsize = ca->bytes * 8;
    ca_parse_range(rrange, bitsize, &offset, &bitlen, &step);
    if ( step != 1 ) {
      rb_raise(rb_eIndexError, "invalid bit range specified for bit field");
    }
  }

  if ( ! NIL_P(rtype) ) {
    data_type = rb_ca_guess_type(rtype);
  }

  return rb_ca_bitfield_new(self, offset, bitlen);
}

#fixlen(bytes: ) ⇒ Object

(Conversion) Short-Hand of "CArray#to_type(:boolean)"



372
373
374
375
# File 'ext/carray_cast.c', line 372

VALUE rb_ca_to_boolean (VALUE self)
{
  rb_ca_to_type_method_body(CA_BOOLEAN);
}

#boolean?Boolean

(Inquiry) Return true if self is boolean type array

Returns:



422
423
424
425
426
427
428
# File 'ext/carray_attribute.c', line 422

VALUE
rb_ca_is_boolean_type (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ca_is_boolean_type(ca) ? Qtrue : Qfalse;
}

#bsearchObject

Returns a new CArray object containing ca's elements sorted.



444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
# File 'ext/carray_order.c', line 444

static VALUE
rb_ca_binary_search (VALUE self, volatile VALUE rval)
{
  volatile VALUE out;
  CArray *ca;
  char *val;
  Data_Get_Struct(self, CArray, ca);

  /* FIXME : treat mask */
  /*
  if ( ca_has_mask(ca) && ca_is_any_masked(self) ) {
    VALUE val  = rb_funcall(self, rb_intern("value"), 0);
    VALUE select = rb_ca_is_not_masked(self);
    VALUE obj    = rb_funcall(val, rb_intern("[]"), 1, select);
    return rb_ca_binary_search(obj, rval);
  }
  */

  if ( ca_is_any_masked(ca) ) {
    rb_raise(rb_eRuntimeError, 
             "CArray#bsearch can't be applied to carray with masked element.");
  }

  ca_attach(ca);

  if ( rb_obj_is_carray(rval) ) {
    volatile VALUE vidx;
    CArray *cv, *co;
    char *ptr, *val;
    ca_size_t i, idx;
    Data_Get_Struct(rval, CArray, cv);
    if ( ca->data_type != cv->data_type ) {
      cv = ca_wrap_readonly(rval, ca->data_type);
    }
    co = carray_new(CA_SIZE, cv->ndim, cv->dim, 0, NULL);
    out = ca_wrap_struct(co);
    ca_attach(cv);
    if ( ca_is_fixlen_type(ca) ) {
      cmp_data *cmp_ptr, *p, *ptr, cmp_val;
      char *q;
      ca_size_t i;
      cmp_val.bytes = ca->bytes;
      cmp_ptr = malloc_with_check(sizeof(cmp_data)*ca->elements);
      for (i=0, p=cmp_ptr, q=ca->ptr; i<ca->elements; i++, p++, q+=ca->bytes) {
        p->bytes = ca->bytes;
        p->ptr   = q;
      }
      for (i=0; i<cv->elements; i++) {
        cmp_val.ptr = ca_ptr_at_addr(cv, i);
        ptr = bsearch(&cmp_val, cmp_ptr, ca->elements, sizeof(cmp_data),
                      ca_qsort_cmp[CA_FIXLEN]);
        vidx = ( ! ptr ) ? CA_UNDEF : SIZE2NUM(ptr - cmp_ptr);      
        rb_ca_store_addr(out, i, vidx);
      }
      free(cmp_ptr);
    }
    else {
      for (i=0; i<cv->elements; i++) {
        val = ca_ptr_at_addr(cv, i);
        ptr = bsearch(val, ca->ptr, ca->elements, ca->bytes,
                      ca_qsort_cmp[ca->data_type]);
        if ( ! ptr ) {
          rb_ca_store_addr(out, i, CA_UNDEF);
        }
        else {
          idx = (ptr - ca->ptr)/ca->bytes;      
          ca_store_addr(co, i, &idx);
        }
      }
    }
    ca_detach(cv);
  }
  else {
    val = ALLOCA_N(char, ca->bytes);
    rb_ca_obj2ptr(self, rval, val);
    if ( ca_is_fixlen_type(ca) ) {
      cmp_data *cmp_ptr, *p, *ptr, cmp_val;
      char *q;
      ca_size_t i;
      cmp_val.bytes = ca->bytes;
      cmp_val.ptr   = val;
      cmp_ptr = malloc_with_check(sizeof(cmp_data)*ca->elements);
      for (i=0, p=cmp_ptr, q=ca->ptr; i<ca->elements; i++, p++, q+=ca->bytes) {
        p->bytes = ca->bytes;
        p->ptr   = q;
      }
      ptr = bsearch(&cmp_val, cmp_ptr, ca->elements, sizeof(cmp_data),
                    ca_qsort_cmp[CA_FIXLEN]);
      out = ( ! ptr ) ? Qnil : SIZE2NUM((ptr - cmp_ptr));
      free(cmp_ptr);
    }
    else {
      char *ptr;
      ptr = bsearch(val, ca->ptr, ca->elements, ca->bytes,
                    ca_qsort_cmp[ca->data_type]);
      out = ( ! ptr ) ? Qnil : SIZE2NUM((ptr - ca->ptr)/ca->bytes);
    }
  }
  ca_detach(ca);
  return out;
}

#bsearch_indexObject

[TBD].



551
552
553
554
555
556
# File 'ext/carray_order.c', line 551

static VALUE
rb_ca_binary_search_index (VALUE self, volatile VALUE rval)
{
  VALUE raddr = rb_ca_binary_search(self, rval);
  return ( NIL_P(raddr) ) ? Qnil : rb_ca_addr2index(self, raddr);
}

#bytesObject

(Attribute) Returns the byte size of each element (e.g. 4 for CA_INT32, 8 for CA_FLOAT64). The byte size can be obtained using CArray.sizeof(data_type) for the numerical data types, but the byte size of fixed-length data type can be known only by this method.



69
70
71
72
73
74
75
# File 'ext/carray_attribute.c', line 69

VALUE
rb_ca_bytes (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return SIZE2NUM(ca->bytes);
}

#cast_with(other) ⇒ Object

[TBD]



1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
# File 'ext/carray_cast.c', line 1268

VALUE
rb_ca_cast_with (VALUE self, VALUE other)
{
  if ( rb_obj_is_carray(self) ) {
    rb_ca_cast_self_or_other(&self, &other);
  }
  else {
    rb_raise(rb_eRuntimeError, "first argument should be a carray");
  }
  return rb_assoc_new(self, other);
}

#clip(idx, ary) ⇒ Object

(copy) Clips the data at idx from self to ary.



397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
# File 'ext/carray_copy.c', line 397

static VALUE
rb_ca_clip (VALUE self, VALUE roffset, VALUE rsrc)
{
  CArray *ca, *cs;
  ca_size_t offset[CA_RANK_MAX];
  int i;

  Data_Get_Struct(self, CArray, ca);

  Check_Type(roffset, T_ARRAY);

  if ( RARRAY_LEN(roffset) != ca->ndim ) {
    rb_raise(rb_eArgError,
             "# of arguments should equal to the ndim");
  }

  for (i=0; i<ca->ndim; i++) {
    offset[i] = NUM2SIZE(rb_ary_entry(roffset, i));
  }

  cs = ca_wrap_writable(rsrc, ca->data_type);

  ca_clip(ca, offset, cs);

  return rsrc;
}

#cmplx128Object Also known as: dcomplex

(Conversion) Short-Hand of "CArray#to_type(:cmplx128)"



489
490
491
492
# File 'ext/carray_cast.c', line 489

VALUE rb_ca_to_cmplx128 (VALUE self)
{
  rb_ca_to_type_method_body(CA_CMPLX128);
}

#cmplx256Object

(Conversion) Short-Hand of "CArray#to_type(:cmplx256)"



498
499
500
501
# File 'ext/carray_cast.c', line 498

VALUE rb_ca_to_cmplx256 (VALUE self)
{
  rb_ca_to_type_method_body(CA_CMPLX256);
}

#cmplx64Object Also known as: complex

(Conversion) Short-Hand of "CArray#to_type(:cmplx64)"



480
481
482
483
# File 'ext/carray_cast.c', line 480

VALUE rb_ca_to_cmplx64 (VALUE self)
{
  rb_ca_to_type_method_body(CA_CMPLX64);
}

#coerece(other) ⇒ Object

[TBD]



476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
# File 'ext/carray_operator.c', line 476

static VALUE
rb_ca_coerce (VALUE self, VALUE other)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);

  if ( rb_obj_is_carray(other) ) {
    return Qnil;
  }
  else if ( rb_respond_to(other, rb_intern("ca")) ) {
    return rb_ca_coerce(self, rb_funcall(other,rb_intern("ca"),0));
  }
  else if ( rb_respond_to(other, rb_intern("to_ca")) ) {
    return rb_ca_coerce(self, rb_funcall(other,rb_intern("to_ca"),0));
  }
  else {
    /* do implicit casting and resolving unbound repeat array */
    rb_ca_cast_self_or_other(&self, &other);
    return rb_assoc_new(other, self);
  }
}

#map!({|elem| ... }) ⇒ Object

(Iterator, Destructive) Iterates all elements of the object and stores the return from the block to the element.



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'ext/carray_loop.c', line 179

static VALUE
rb_ca_map_bang (VALUE self)
{
  volatile VALUE obj;
  CArray *ca;
  ca_size_t elements = NUM2SIZE(rb_ca_elements(self));
  ca_size_t i;
#if RUBY_VERSION_CODE >= 190
  RETURN_ENUMERATOR(self, 0, 0);
#endif
  rb_ca_modify(self);
  Data_Get_Struct(self, CArray, ca);
  ca_attach(ca);
  for (i=0; i<elements; i++) {
    obj = rb_yield(rb_ca_fetch_addr(self, i));
    rb_ca_store_addr(self, i, obj);
  }
  ca_sync(ca);
  ca_detach(ca);
  return self;
}

#map_addr!({|addr| ... }) ⇒ Object

[TBD]



388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
# File 'ext/carray_loop.c', line 388

static VALUE
rb_ca_map_addr_bang (VALUE self)
{
  volatile VALUE obj;
  CArray *ca;
  ca_size_t elements = NUM2SIZE(rb_ca_elements(self));
  ca_size_t i;
#if RUBY_VERSION_CODE >= 190
  RETURN_ENUMERATOR(self, 0, 0);
#endif
  rb_ca_modify(self);
  Data_Get_Struct(self, CArray, ca);
  ca_attach(ca);
  for (i=0; i<elements; i++) {
    obj = rb_yield(SIZE2NUM(i));
    rb_ca_store_addr(self, i, obj);
  }
  ca_sync(ca);
  ca_detach(ca);
  return self;
}

#map_index!({|idx| ... }) ⇒ Object

[TBD]



333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
# File 'ext/carray_loop.c', line 333

static VALUE
rb_ca_map_index_bang (VALUE self)
{
  volatile VALUE ridx;
  CArray *ca;
  ca_size_t idx[CA_RANK_MAX];
  int8_t  ndim = NUM2INT(rb_ca_ndim(self));
#if RUBY_VERSION_CODE >= 190
  RETURN_ENUMERATOR(self, 0, 0);
#endif
  rb_ca_modify(self);
  Data_Get_Struct(self, CArray, ca);
  ca_attach(ca);
  ridx = rb_ary_new2(ndim);
  rb_ca_map_index_bang_internal(self, 0, idx, ridx);
  ca_sync(ca);
  ca_detach(ca);
  return self;
}

#map_with_addr!({|elem, addr| ... }) ⇒ Object

[TBD]



359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
# File 'ext/carray_loop.c', line 359

static VALUE
rb_ca_map_with_addr_bang (VALUE self)
{
  volatile VALUE obj;
  CArray *ca;
  ca_size_t elements = NUM2SIZE(rb_ca_elements(self));
  ca_size_t i;
#if RUBY_VERSION_CODE >= 190
  RETURN_ENUMERATOR(self, 0, 0);
#endif
  rb_ca_modify(self);
  Data_Get_Struct(self, CArray, ca);
  ca_attach(ca);
  for (i=0; i<elements; i++) {
    obj = rb_yield_values(2, rb_ca_fetch_addr(self, i), SIZE2NUM(i));
    rb_ca_store_addr(self, i, obj);
  }
  ca_sync(ca);
  ca_detach(ca);
  return self;
}

#map_with_index({|elem, idx| ... }) ⇒ Object

[TBD]



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'ext/carray_loop.c', line 281

static VALUE
rb_ca_map_with_index_bang (VALUE self)
{
  volatile VALUE ridx;
  CArray *ca;
  ca_size_t idx[CA_RANK_MAX];
  int8_t  ndim = NUM2INT(rb_ca_ndim(self));
#if RUBY_VERSION_CODE >= 190
  RETURN_ENUMERATOR(self, 0, 0);
#endif
  rb_ca_modify(self);
  Data_Get_Struct(self, CArray, ca);
  ca_attach(ca);
  ridx = rb_ary_new2(ndim);
  rb_ca_map_with_index_bang_internal(self, 0, idx, ridx);
  ca_sync(ca);
  ca_detach(ca);
  return self;
}

#complex?Boolean

(Inquiry) Returns true if self is complex type array

Returns:



544
545
546
547
548
549
550
# File 'ext/carray_attribute.c', line 544

VALUE
rb_ca_is_complex_type (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ca_is_complex_type(ca) ? Qtrue : Qfalse;
}

#convert(data_type = nil, dim = nil{ |elem| ... }) ⇒ Object

(Conversion) Returns new array which elements are caluculated in the iteration block. The output array is internally created using CArray#template to which the arguments is passed.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'ext/carray_conversion.c', line 74

static VALUE
rb_ca_convert (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE obj;
  CArray *ca;
  ca_size_t i;

  obj = rb_apply(self, rb_intern("template"), rb_ary_new4(argc, argv));

  Data_Get_Struct(self, CArray, ca);
  ca_attach(ca);
  if ( ca_has_mask(ca) ) {
    for (i=0; i<ca->elements; i++) {
      if ( ! ca->mask->ptr[i] ) {
	rb_ca_store_addr(obj, i, rb_yield(rb_ca_fetch_addr(self, i)));
      }
      else {
	rb_ca_store_addr(obj, i, CA_UNDEF);
      }
    }
  }
  else {
    for (i=0; i<ca->elements; i++) {
      rb_ca_store_addr(obj, i, rb_yield(rb_ca_fetch_addr(self, i)));
    }
  }
  ca_detach(ca);

  return obj;
}

#data_classObject

(Attribute) Returns data_class if self is fixed-length type and it has the data class.



613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
# File 'ext/carray_attribute.c', line 613

VALUE
rb_ca_data_class (VALUE self)
{
  volatile VALUE parent, data_class;
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  if ( ca_test_flag(ca, CA_FLAG_NOT_DATA_CLASS) ) {
    return Qnil;
  }
  if ( ! ca_is_fixlen_type(ca) ) {      /* not a fixlen array */
    ca_set_flag(ca, CA_FLAG_NOT_DATA_CLASS);
    return Qnil;
  }
  data_class = rb_ivar_get(self, id_data_class);
  if ( ! NIL_P(data_class) ) {
    return data_class;
  }
  else {
    return Qnil;
    if ( ca_is_entity(ca) ) {  /* no further parent */
      ca_set_flag(ca, CA_FLAG_NOT_DATA_CLASS);
      return Qnil;
    }
    else {
      parent = rb_ca_parent(self);
      if ( NIL_P(parent) ) {   /* no parent */
        ca_set_flag(ca, CA_FLAG_NOT_DATA_CLASS);
        return Qnil;
      }
      else {
        CArray *cr;
        Data_Get_Struct(parent, CArray, cr);
        if ( cr->bytes != ca->bytes ) {  /* byte size mismatch */
          ca_set_flag(ca, CA_FLAG_NOT_DATA_CLASS);
          return Qnil;
        }
        else {
          data_class = rb_ca_data_class(parent); /* parent's data class */
          if ( ! NIL_P(data_class) ) {
            return data_class;
          }
          else {
            ca_set_flag(ca, CA_FLAG_NOT_DATA_CLASS);
            return Qnil;
          }
        }
      }
    }
  }
}

#data_class=Object



714
715
716
717
718
719
720
721
722
723
724
725
726
# File 'ext/carray_attribute.c', line 714

static VALUE
rb_ca_set_data_class (VALUE self, VALUE klass)
{
  if ( RTEST(rb_ca_is_fixlen_type(self)) &&
       rb_obj_is_data_class(klass) ) {
    rb_ivar_set(self, rb_intern("member"), rb_hash_new());
    return rb_ivar_set(self, id_data_class, klass);
  }
  else {
    rb_raise(rb_eTypeError, "invalid data_class or self is not fixlen array.");
  }
  return Qnil;
}

#data_typeObject

(Attribute) Returns the data type of each element (e.g. CA_INT32, CA_FLOAT64, ...).



37
38
39
40
41
42
43
# File 'ext/carray_attribute.c', line 37

VALUE
rb_ca_data_type (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return INT2NUM(ca->data_type);
}

#data_type_nameObject

(Attribute) Returns the string representaion of the data_type (e.g. "int32", "fixlen")



178
179
180
181
182
183
184
# File 'ext/carray_attribute.c', line 178

VALUE
rb_ca_data_type_name (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return rb_str_new2(ca_type_name[ca->data_type]);
}

#dimObject

(Attribute) Returns the Array object contains the dimensional shape of array (e.g. [2,3] for 2D 2x3 array, ...).



98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'ext/carray_attribute.c', line 98

VALUE
rb_ca_dim (VALUE self)
{
  volatile VALUE dim;
  CArray *ca;
  int i;
  Data_Get_Struct(self, CArray, ca);
  dim = rb_ary_new2(ca->ndim);
  for (i=0; i<ca->ndim; i++) {
    rb_ary_store(dim, i, SIZE2NUM(ca->dim[i]));
  }
  return dim;
}

#dim0Object

(Attribute) Short-hand for "dim[0]"



119
120
121
122
123
124
125
# File 'ext/carray_attribute.c', line 119

VALUE
rb_ca_dim0 (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return SIZE2NUM(ca->dim[0]);
}

#dim1Object

(Attribute) Short-hand for "dim[1]"



134
135
136
137
138
139
140
# File 'ext/carray_attribute.c', line 134

VALUE
rb_ca_dim1 (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ( ca->ndim >= 2 ) ? SIZE2NUM(ca->dim[1]) : Qnil;
}

#dim2Object

(Attribute) Short-hand for 'dim[2]'



149
150
151
152
153
154
155
# File 'ext/carray_attribute.c', line 149

VALUE
rb_ca_dim2 (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ( ca->ndim >= 3 ) ? SIZE2NUM(ca->dim[2]) : Qnil;
}

#dim3Object

(Attribute) Short-hand for "dim[3]"



164
165
166
167
168
169
170
# File 'ext/carray_attribute.c', line 164

VALUE
rb_ca_dim3 (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ( ca->ndim >= 4 ) ? SIZE2NUM(ca->dim[3]) : Qnil;
}

#dump_binaryObject

(IO) Dumps the value array to the given IO stream



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'ext/carray_conversion.c', line 111

static VALUE
rb_ca_dump_binary (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE io;
  CArray *ca;

  Data_Get_Struct(self, CArray, ca);

  if ( ca_is_object_type(ca) ) {
    rb_raise(rb_eCADataTypeError, "don't dump object array");
  }

  if ( argc == 0 ) {
    io = rb_str_new(NULL, 0);
  }
  else if ( argc == 1 ) {
    io = argv[0];
  }
  else {
    rb_raise(rb_eArgError, "invalid # of arguments (%i for 1)", argc);
  }

  switch ( TYPE(io) ) {
  case T_STRING:
    if ( ca_length(ca) != RSTRING_LEN(io) ) {
      rb_str_resize(io, ca_length(ca));
    }
    ca_copy_data(ca, StringValuePtr(io));
    StringValuePtr(io)[ca_length(ca)] = '\0';
    OBJ_TAINT(io);
    break;
#if RUBY_VERSION_CODE >= 190
  case T_FILE: {
    volatile VALUE str;
    rb_io_t *iop;
    GetOpenFile(io, iop);
    rb_io_check_writable(iop);
    ca_attach(ca);
    str = rb_str_new(ca->ptr, ca->bytes*ca->elements);
    rb_io_write(io, str);
    ca_detach(ca);
    break;
  }
#else
  case T_FILE: {
    OpenFile *iop;
    size_t total;
    GetOpenFile(io, iop);
    rb_io_check_writable(iop);
    ca_attach(ca);
    total = fwrite(ca->ptr, ca->bytes, ca->elements, iop->f);
    ca_detach(ca);
    if ( total < ca->elements ) {
      rb_raise(rb_eIOError, "I/O write error in CArray#dump_binary");
    }
    break;
  }
#endif
  default:
    if ( rb_respond_to(io, rb_intern("write") ) ) {
      volatile VALUE buf = rb_str_new(NULL, ca_length(ca));
      ca_copy_data(ca, StringValuePtr(buf));
      OBJ_INFECT(buf, self);
      rb_funcall(io, rb_intern("write"), 1, buf);
    }
    else {
      rb_raise(rb_eRuntimeError, "IO like object should have 'write' method");
    }
  }

  return io;
}

#each({|elem| ... }) ⇒ Object

(Iterator) Iterates all the elements of the object.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'ext/carray_loop.c', line 72

static VALUE
rb_ca_each (VALUE self)
{
  volatile VALUE ret = Qnil;
  ca_size_t elements = NUM2SIZE(rb_ca_elements(self));
  ca_size_t i;
#if RUBY_VERSION_CODE >= 190
  RETURN_ENUMERATOR(self, 0, 0);
#endif
  for (i=0; i<elements; i++) {
    ret = rb_yield(rb_ca_fetch_addr(self, i));
  }
  return ret;
}

#each_addr({|addr| ... }) ⇒ Object

(Iterator) Iterates all address of the object.



113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'ext/carray_loop.c', line 113

static VALUE
rb_ca_each_addr (VALUE self)
{
  volatile VALUE ret = Qnil;
  ca_size_t elements = NUM2SIZE(rb_ca_elements(self));
  ca_size_t i;
#if RUBY_VERSION_CODE >= 190
  RETURN_ENUMERATOR(self, 0, 0);
#endif
  for (i=0; i<elements; i++) {
    ret = rb_yield(SIZE2NUM(i));
  }
  return ret;
}

#each_index({|idx| ... }) ⇒ Object

(Iterator) Iterates all index of the object.

   CArray.int(3,2).each_index(){|i,j| print "(#{i} #{j}) " }

 <em>produces:</em>

    (0 0) (0 1) (1 0) (1 1) (2 0) (2 1) (3 0) (3 1)


162
163
164
165
166
167
168
169
170
171
172
# File 'ext/carray_loop.c', line 162

static VALUE
rb_ca_each_index (VALUE self)
{
  volatile VALUE ridx;
  int8_t ndim = NUM2INT(rb_ca_ndim(self));
  ridx = rb_ary_new2(ndim);
#if RUBY_VERSION_CODE >= 190
  RETURN_ENUMERATOR(self, 0, 0);
#endif
  return rb_ca_each_index_internal(self, 0, ridx);
}

#each_with_addr({|elem, addr| ... }) ⇒ Object

(Iterator) Iterates all the elements of the object.



93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'ext/carray_loop.c', line 93

static VALUE
rb_ca_each_with_addr (VALUE self)
{
  volatile VALUE ret = Qnil;
  ca_size_t elements = NUM2SIZE(rb_ca_elements(self));
  ca_size_t i;
#if RUBY_VERSION_CODE >= 190
  RETURN_ENUMERATOR(self, 0, 0);
#endif
  for (i=0; i<elements; i++) {
    ret = rb_yield_values(2, rb_ca_fetch_addr(self, i), SIZE2NUM(i));
  }
  return ret;
}

#each_with_index({|elem, idx| ... }) ⇒ Object

[TBD]



233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'ext/carray_loop.c', line 233

static VALUE
rb_ca_each_with_index (VALUE self)
{
  volatile VALUE ridx, ret;
  ca_size_t idx[CA_RANK_MAX];
  int8_t  ndim = NUM2INT(rb_ca_ndim(self));
#if RUBY_VERSION_CODE >= 190
  RETURN_ENUMERATOR(self, 0, 0);
#endif
  rb_ca_modify(self);
  ridx = rb_ary_new2(ndim);
  ret  = rb_ca_each_with_index_internal(self, 0, idx, ridx);
  return ret;
}

#elem_copy(idx1, idx2) ⇒ Object

(Element) Copies the value of the element of idx1 to the element of idx2



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'ext/carray_element.c', line 131

VALUE
rb_ca_elem_copy (VALUE self, VALUE ridx1, VALUE ridx2)
{
  CArray *ca;
  ca_size_t idx1[CA_RANK_MAX], idx2[CA_RANK_MAX];
  ca_size_t addr1 = 0, addr2 = 0;
  int8_t  i;
  ca_size_t k;
  int     has_mask;
  char   _val[32];
  char   *val = _val;
  boolean8_t m = 0;

  rb_ca_modify(self);

  Data_Get_Struct(self, CArray, ca);

  ca_update_mask(ca);
  has_mask = ( ca->mask ) ? 1 : 0;

  if ( ca->bytes > 32 ) {
    val = malloc_with_check(ca->bytes);
  }

  if ( TYPE(ridx1) == T_ARRAY ) {
    for (i=0; i<ca->ndim; i++) {
      k = NUM2SIZE(rb_ary_entry(ridx1, i));
      CA_CHECK_INDEX(k, ca->dim[i]);
      idx1[i] = k;
    }
    ca_fetch_index(ca, idx1, val);
    if ( has_mask ) {
      ca_fetch_index(ca->mask, idx1, &m);
    }
  }
  else {
    k = NUM2SIZE(ridx1);
    CA_CHECK_INDEX(k, ca->elements);
    addr1 = k;
    ca_fetch_addr(ca, addr1, val);
    if ( has_mask ) {
      ca_fetch_addr(ca->mask, addr1, &m);
    }
  }

  if ( TYPE(ridx2) == T_ARRAY ) {
    for (i=0; i<ca->ndim; i++) {
      k = NUM2SIZE(rb_ary_entry(ridx2, i));
      CA_CHECK_INDEX(k, ca->dim[i]);
      idx2[i] = k;
    }
    ca_store_index(ca, idx2, val);
    if ( has_mask ) {
      ca_store_index(ca->mask, idx2, &m);
    }
  }
  else {
    k = NUM2SIZE(ridx2);
    CA_CHECK_INDEX(k, ca->elements);
    addr2 = k;
    ca_store_addr(ca, addr2, val);
    if ( has_mask ) {
      ca_store_addr(ca->mask, addr2, &m);
    }
  }

  if ( ca->bytes > 32 ) {
    free(val);
  }

  return self;
}

#elem_decr(idx) ⇒ Object

(Element) Decrements the value by 1 at the element of idx.



362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
# File 'ext/carray_element.c', line 362

VALUE
rb_ca_elem_decr (VALUE self, VALUE ridx1)
{
  volatile VALUE out;
  CArray *ca;
  ca_size_t idx1[CA_RANK_MAX];
  ca_size_t addr1 = 0;
  int8_t  i;
  ca_size_t k;
  int     has_index1 = 0;
  int     has_mask;
  char   _val[8];
  char   *val = _val;
  boolean8_t m = 0;

  rb_ca_modify(self);

  Data_Get_Struct(self, CArray, ca);

  if ( ! ca_is_integer_type(ca) ) {
    rb_raise(rb_eCADataTypeError,
             "decremented array should be an integer array");
  }

  ca_update_mask(ca);
  has_mask = ( ca->mask ) ? 1 : 0;

  if ( TYPE(ridx1) == T_ARRAY ) {
    for (i=0; i<ca->ndim; i++) {
      k = NUM2SIZE(rb_ary_entry(ridx1, i));
      CA_CHECK_INDEX(k, ca->dim[i]);
      idx1[i] = k;
    }
    if ( has_mask ) {
      ca_fetch_index(ca->mask, idx1, &m);
    }
    if ( m ) {
      return Qnil;
    }
    else {
      ca_fetch_index(ca, idx1, val);
    }
    has_index1 = 1;
  }
  else {
    k = NUM2SIZE(ridx1);
    CA_CHECK_INDEX(k, ca->elements);
    addr1 = k;
    if ( has_mask ) {
      ca_fetch_addr(ca->mask, addr1, &m);
    }
    if ( m ) {
      return Qnil;
    }
    else {
      ca_fetch_addr(ca, addr1, val);
    }
  }

  switch ( ca->data_type ) {
  case CA_INT8:   out = INT2NUM(--*((int8_t*)  val)); break;
  case CA_UINT8:  out = UINT2NUM(--*((uint8_t*)  val)); break;
  case CA_INT16:  out = INT2NUM(--*((int16_t*) val)); break;
  case CA_UINT16: out = UINT2NUM(--*((uint16_t*) val)); break;
  case CA_INT32:  out = INT2NUM(--*((int32_t*) val)); break;
  case CA_UINT32: out = UINT2NUM(--*((uint32_t*) val)); break;
  case CA_INT64:  out = INT2NUM(--*((int64_t*) val)); break;
  case CA_UINT64: out = UINT2NUM(--*((uint64_t*) val)); break;
  }

  if ( has_index1 ) {
    ca_store_index(ca, idx1, val);
  }
  else {
    ca_store_addr(ca, addr1, val);
  }

  return out;
}

#elem_fetch(idx) ⇒ Object

(Element) Fetches the object value at the element of idx.



245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'ext/carray_element.c', line 245

VALUE
rb_ca_elem_fetch (VALUE self, VALUE ridx)
{
  CArray *ca;
  ca_size_t idx[CA_RANK_MAX];
  ca_size_t addr = 0;
  int8_t  i;
  ca_size_t k;

  Data_Get_Struct(self, CArray, ca);

  if ( TYPE(ridx) == T_ARRAY ) {
    for (i=0; i<ca->ndim; i++) {
      k = NUM2SIZE(rb_ary_entry(ridx, i));
      CA_CHECK_INDEX(k, ca->dim[i]);
      idx[i] = k;
    }
    return rb_ca_fetch_index(self, idx);
  }
  else {
    k = NUM2SIZE(ridx);
    CA_CHECK_INDEX(k, ca->elements);
    addr = k;
    return rb_ca_fetch_addr(self, addr);
  }
}

#elem_incr(idx) ⇒ Object

(Element) Increments the value by 1 at the element of idx.



277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
# File 'ext/carray_element.c', line 277

VALUE
rb_ca_elem_incr (VALUE self, VALUE ridx1)
{
  volatile VALUE out;
  CArray *ca;
  ca_size_t idx1[CA_RANK_MAX];
  ca_size_t addr1 = 0;
  int8_t  i;
  ca_size_t k;
  int     has_index1 = 0;
  int     has_mask;
  char   _val[8];
  char   *val = _val;
  boolean8_t m = 0;

  rb_ca_modify(self);

  Data_Get_Struct(self, CArray, ca);

  if ( ! ca_is_integer_type(ca) ) {
    rb_raise(rb_eCADataTypeError,
             "incremented array should be an integer array");
  }

  ca_update_mask(ca);
  has_mask = ( ca->mask ) ? 1 : 0;

  if ( TYPE(ridx1) == T_ARRAY ) {
    for (i=0; i<ca->ndim; i++) {
      k = NUM2SIZE(rb_ary_entry(ridx1, i));
      CA_CHECK_INDEX(k, ca->dim[i]);
      idx1[i] = k;
    }
    if ( has_mask ) {
      ca_fetch_index(ca->mask, idx1, &m);
    }
    if ( m ) {
      return Qnil;
    }
    else {
      ca_fetch_index(ca, idx1, val);
    }
    has_index1 = 1;
  }
  else {
    k = NUM2SIZE(ridx1);
    CA_CHECK_INDEX(k, ca->elements);
    addr1 = k;
    if ( has_mask ) {
      ca_fetch_addr(ca->mask, addr1, &m);
    }
    if ( m ) {
      return Qnil;
    }
    else {
      ca_fetch_addr(ca, addr1, val);
    }
  }

  switch ( ca->data_type ) {
  case CA_INT8:   out = INT2NUM(++*((int8_t*)  val)); break;
  case CA_UINT8:  out = UINT2NUM(++*((uint8_t*)  val)); break;
  case CA_INT16:  out = INT2NUM(++*((int16_t*) val)); break;
  case CA_UINT16: out = UINT2NUM(++*((uint16_t*) val)); break;
  case CA_INT32:  out = INT2NUM(++*((int32_t*) val)); break;
  case CA_UINT32: out = UINT2NUM(++*((uint32_t*) val)); break;
  case CA_INT64:  out = LL2NUM(++*((int64_t*) val)); break;
  case CA_UINT64: out = ULL2NUM(++*((uint64_t*) val)); break;
  }

  if ( has_index1 ) {
    ca_store_index(ca, idx1, val);
  }
  else {
    ca_store_addr(ca, addr1, val);
  }

  return out;
}

#elem_masked?(idx) ⇒ Boolean

(Masking, Element) Returns true if the element at given idx is masked.

Returns:



447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
# File 'ext/carray_element.c', line 447

VALUE
rb_ca_elem_test_masked (VALUE self, VALUE ridx1)
{
  CArray *ca;
  ca_size_t idx1[CA_RANK_MAX];
  ca_size_t addr1 = 0;
  int8_t  i;
  ca_size_t k;
  boolean8_t m = 0;

  Data_Get_Struct(self, CArray, ca);

  ca_update_mask(ca);

  if ( TYPE(ridx1) == T_ARRAY ) {
    for (i=0; i<ca->ndim; i++) {
      k = NUM2SIZE(rb_ary_entry(ridx1, i));
      CA_CHECK_INDEX(k, ca->dim[i]);
      idx1[i] = k;
    }
    if ( ca->mask ) {
      ca_fetch_index(ca->mask, idx1, &m);
    }
  }
  else {
    k = NUM2SIZE(ridx1);
    CA_CHECK_INDEX(k, ca->elements);
    addr1 = k;
    if ( ca->mask ) {
      ca_fetch_addr(ca->mask, addr1, &m);
    }
  }

  return m ? Qtrue : Qfalse;
}

#elem_store(idx, obj) ⇒ Object

(Element) Stores the object value in the element of idx.



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'ext/carray_element.c', line 209

VALUE
rb_ca_elem_store (VALUE self, VALUE ridx, VALUE obj)
{
  CArray *ca;
  ca_size_t idx[CA_RANK_MAX];
  ca_size_t addr = 0;
  int8_t  i;
  ca_size_t k;

  rb_ca_modify(self);

  Data_Get_Struct(self, CArray, ca);

  if ( TYPE(ridx) == T_ARRAY ) {
    for (i=0; i<ca->ndim; i++) {
      k = NUM2SIZE(rb_ary_entry(ridx, i));
      CA_CHECK_INDEX(k, ca->dim[i]);
      idx[i] = k;
    }
    rb_ca_store_index(self, idx, obj);
  }
  else {
    k = NUM2SIZE(ridx);
    CA_CHECK_INDEX(k, ca->elements);
    addr = k;
    rb_ca_store_addr(self, addr, obj);
  }

  return obj;
}

#elem_swap(idx1, idx2) ⇒ Object

(Element) Swaps the values at the elements which are specified by arguments.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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
# File 'ext/carray_element.c', line 21

VALUE
rb_ca_elem_swap (VALUE self, VALUE ridx1, VALUE ridx2)
{
  CArray *ca;
  ca_size_t idx1[CA_RANK_MAX], idx2[CA_RANK_MAX];
  ca_size_t addr1 = 0, addr2 = 0;
  int8_t  i;
  ca_size_t k;
  int     has_mask, has_index1, has_index2;
  char   _val1[32], _val2[32];
  char   *val1 = _val1, *val2 = _val2;
  boolean8_t m1 = 0, m2 = 0;

  rb_ca_modify(self);

  Data_Get_Struct(self, CArray, ca);

  ca_update_mask(ca);
  has_mask = ( ca->mask ) ? 1 : 0;

  if ( ca->bytes > 32 ) {
    val1 = malloc_with_check(ca->bytes);
    val2 = malloc_with_check(ca->bytes);
  }

  if ( TYPE(ridx1) == T_ARRAY ) {
    for (i=0; i<ca->ndim; i++) {
      k = NUM2SIZE(rb_ary_entry(ridx1, i));
      CA_CHECK_INDEX(k, ca->dim[i]);
      idx1[i] = k;
    }
    has_index1 = 1;
    ca_fetch_index(ca, idx1, val1);
    if ( has_mask ) {
      ca_fetch_index(ca->mask, idx1, &m1);
    }
  }
  else {
    k = NUM2SIZE(ridx1);
    CA_CHECK_INDEX(k, ca->elements);
    addr1 = k;
    has_index1 = 0;
    ca_fetch_addr(ca, addr1, val1);
    if ( has_mask ) {
      ca_fetch_addr(ca->mask, addr1, &m1);
    }
  }

  if ( TYPE(ridx2) == T_ARRAY ) {
    for (i=0; i<ca->ndim; i++) {
      k = NUM2SIZE(rb_ary_entry(ridx2, i));
      CA_CHECK_INDEX(k, ca->dim[i]);
      idx2[i] = k;
    }
    has_index2 = 1;
    ca_fetch_index(ca, idx2, val2);
    if ( has_mask ) {
      ca_fetch_index(ca->mask, idx2, &m2);
    }
  }
  else {
    k = NUM2SIZE(ridx2);
    CA_CHECK_INDEX(k, ca->elements);
    addr2 = k;
    has_index2 = 0;
    ca_fetch_addr(ca, addr2, val2);
    if ( has_mask ) {
      ca_fetch_addr(ca->mask, addr2, &m2);
    }
  }

  if ( has_index1 ) {
    ca_store_index(ca, idx1, val2);
    if ( has_mask ) {
      ca_store_index(ca->mask, idx1, &m2);
    }
  }
  else {
    ca_store_addr(ca, addr1, val2);
    if ( has_mask ) {
      ca_store_addr(ca->mask, addr1, &m2);
    }
  }

  if ( has_index2 ) {
    ca_store_index(ca, idx2, val1);
    if ( has_mask ) {
      ca_store_index(ca->mask, idx2, &m1);
    }
  }
  else {
    ca_store_addr(ca, addr2, val1);
    if ( has_mask ) {
      ca_store_addr(ca->mask, addr2, &m1);
    }
  }

  if ( ca->bytes > 32 ) {
    free(val1);
    free(val2);
  }

  return self;
}

#elementsObject

(Attribute) Returns the number of elements



83
84
85
86
87
88
89
# File 'ext/carray_attribute.c', line 83

VALUE
rb_ca_elements (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return SIZE2NUM(ca->elements);
}

#empty?Boolean

(Inquiry) Returns true if the object is empty.

Returns:



279
280
281
282
283
284
285
# File 'ext/carray_attribute.c', line 279

VALUE
rb_ca_is_empty (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ( ca->elements == 0 ) ? Qtrue : Qfalse;
}

#entity?Boolean

(Inquiry) Returns true if self is an entity array (not a virtual array).

Returns:



235
236
237
238
239
240
241
# File 'ext/carray_attribute.c', line 235

VALUE
rb_ca_is_entity (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ( ca_is_virtual(ca) ) ? Qfalse : Qtrue;
}

#fetch_linear_addrObject



1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
# File 'ext/carray_order.c', line 1145

static VALUE
rb_ca_fetch_linear_addr (volatile VALUE self, volatile VALUE vx)
{
  volatile VALUE out, out0;
  CArray *ca, *sc, *cx, *co0, *co;
  double *x;
  double *px;
  double *po;
  ca_size_t nlist, nreq;
  ca_size_t i;
  boolean8_t *mx, *mo;

  Data_Get_Struct(self, CArray, ca);

  if ( rb_ca_is_any_masked(self) ) {
    rb_raise(rb_eRuntimeError, "self should not have any masked elements");
  }

  sc = ca_wrap_readonly(self, CA_FLOAT64);
  cx = ca_wrap_readonly(vx, CA_FLOAT64);

  if ( sc->ndim != 1 ) {
    rb_raise(rb_eRuntimeError, "ndim of self should be 1");
  }
	
	nlist = sc->dim[0];

  nreq = 1;
  for (i=1; i<cx->ndim; i++) {
		nreq *= cx->dim[i];
	}

  co0 = carray_new(ca->data_type, cx->ndim, cx->dim, 0, NULL);
  out = out0 = ca_wrap_struct(co0);
  co = ca_wrap_writable(out, CA_FLOAT64);

  ca_attach_n(3, sc, cx, co);

  x  = (double*) sc->ptr;
  px = (double*) cx->ptr;
  po = (double*) co->ptr;

  ca_create_mask(co);
  ca_update_mask(cx);

  if ( cx->mask ) {
    mx = (boolean8_t *) cx->mask->ptr;
    mo = (boolean8_t *) co->mask->ptr;
    for (i=0; i<nreq; i++) {
      if ( ! *mx ) {
        if ( fetch_linear_addr(nlist, x, *px, po) ) {
        	*mo = 1;
        }
      }
      else {
        *mo = 1;
      }
      mx++; mo++; px++, po++;
    }
  }
  else {
    mo = (boolean8_t *) co->mask->ptr;
    for (i=0; i<nreq; i++) {
      if ( fetch_linear_addr(nlist, x, *px, po) ) {
      	*mo = 1;
      }
      mo++; px++; po++; 
    }
  }

  ca_sync(co);
  ca_detach_n(3, sc, cx, co);

  if ( rb_ca_is_scalar(vx) ) {
    return rb_funcall(out0, rb_intern("[]"), 1, INT2NUM(0));
  }
  else {
    return out0;
  }
}

#fieldsObject

(Reference) Returns an array of data class members (fields)



1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
# File 'ext/carray_core.c', line 1255

VALUE
rb_ca_fields (VALUE self)
{
  volatile VALUE data_class = rb_ca_data_class(self);
  volatile VALUE member_names, list;
  int i;
  if ( NIL_P(data_class) ) {
    rb_raise(rb_eRuntimeError, "carray doesn't have data class");
  }
  member_names = rb_const_get(data_class, rb_intern("MEMBERS"));
  list = rb_ary_new2(RARRAY_LEN(member_names));
  for (i=0; i<RARRAY_LEN(member_names); i++) {
    VALUE name = rb_ary_entry(member_names, i);
    rb_ary_store(list, i, rb_ca_field_as_member(self, name));
  }
  return list;
}

#fields_at(*names) ⇒ Object

Returns an array of data class members (fields) with names specified



1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
# File 'ext/carray_core.c', line 1278

VALUE
rb_ca_fields_at (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE data_class = rb_ca_data_class(self);
  volatile VALUE member_names, list;
  int i;
  if ( NIL_P(data_class) ) {
    rb_raise(rb_eRuntimeError, "carray doesn't have data class");
  }
  member_names = rb_ary_new4(argc, argv);
  list = rb_ary_new2(RARRAY_LEN(member_names));
  for (i=0; i<RARRAY_LEN(member_names); i++) {
    VALUE name = rb_ary_entry(member_names, i);
    rb_ary_store(list, i, rb_ca_field_as_member(self, name));
  }
  return list;
}

#fixlen(bytes: ) ⇒ Object

(Conversion) Short-Hand of "CArray#to_type(:fixlen, bytes:)"



357
358
359
360
361
362
363
364
365
366
# File 'ext/carray_cast.c', line 357

VALUE
rb_ca_to_fixlen (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE ropt = rb_pop_options(&argc, &argv);
  VALUE list[2];
//  rb_scan_args(argc, argv, "0");
  list[0] = INT2NUM(CA_FIXLEN);
  list[1] = ropt;
  return rb_ca_to_type_internal(2, list, self);
}

#fixlen?Boolean

(Inquiry) Returns true if self is fixed-length type array

Returns:



400
401
402
403
404
405
406
# File 'ext/carray_attribute.c', line 400

VALUE
rb_ca_is_fixlen_type (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ca_is_fixlen_type(ca) ? Qtrue : Qfalse;
}

#float128Object

(Conversion) Short-Hand of "CArray#to_type(:float128)"



471
472
473
474
# File 'ext/carray_cast.c', line 471

VALUE rb_ca_to_float128 (VALUE self)
{
  rb_ca_to_type_method_body(CA_FLOAT128);
}

#float32Object Also known as: float

(Conversion) Short-Hand of "CArray#to_type(:float32)"



453
454
455
456
# File 'ext/carray_cast.c', line 453

VALUE rb_ca_to_float32 (VALUE self)
{
  rb_ca_to_type_method_body(CA_FLOAT32);
}

#float64Object Also known as: double

(Conversion) Short-Hand of "CArray#to_type(:float64)"



462
463
464
465
# File 'ext/carray_cast.c', line 462

VALUE rb_ca_to_float64 (VALUE self)
{
  rb_ca_to_type_method_body(CA_FLOAT64);
}

#float?Boolean

(Inquiry) Returns true if self is float type array

Returns:



521
522
523
524
525
526
527
# File 'ext/carray_attribute.c', line 521

VALUE
rb_ca_is_float_type (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ca_is_float_type(ca) ? Qtrue : Qfalse;
}

#freezeObject

Freeze the object.



589
590
591
592
593
594
595
596
# File 'ext/carray_test.c', line 589

VALUE
rb_ca_freeze (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  ca_set_flag(ca, CA_FLAG_READ_ONLY);
  return rb_obj_freeze(self);
}

#has_data_class?Boolean

(Inquiry) Returns true if self is fixed-length type and has the data class.

Returns:



669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
# File 'ext/carray_attribute.c', line 669

VALUE
rb_ca_has_data_class (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  if ( ca_test_flag(ca, CA_FLAG_NOT_DATA_CLASS) ) {
    return Qfalse;
  }
  else {
    if ( ca_is_fixlen_type(ca) ) {
      if ( RTEST(rb_ca_data_class(self)) ) {
        return Qtrue;
      }
    }
    ca_set_flag(ca, CA_FLAG_NOT_DATA_CLASS);
    return Qfalse;
  }
}

#has_mask?Boolean

(Masking, Inquiry) Returns true if self has the mask array.

Returns:



572
573
574
575
576
577
578
# File 'ext/carray_mask.c', line 572

VALUE
rb_ca_has_mask (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ( ca_has_mask(ca) ) ? Qtrue : Qfalse;
}

#hashObject

(Inquiry) Returns the hash value of the object.



557
558
559
560
561
562
563
564
565
566
# File 'ext/carray_test.c', line 557

VALUE
rb_ca_hash (VALUE self)
{
  CArray *ca;
  int32_t hash;

  Data_Get_Struct(self, CArray, ca);
  hash = ca_hash(ca);
  return ULONG2NUM(hash);
}

#incr_addr(addr) ⇒ Object

(Element) Increment the value at the element of addr.



490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
# File 'ext/carray_element.c', line 490

static VALUE
rb_ca_incr_addr (volatile VALUE self, volatile VALUE raddr)
{
  CArray  *ca, *ci;
  int64_t *q, *p;
  ca_size_t k, elements;
  ca_size_t i;
  boolean8_t *m;

  rb_ca_modify(self);

  self = rb_ca_wrap_writable(self, INT2NUM(CA_INT64));
  raddr = rb_ca_wrap_readonly(raddr, INT2NUM(CA_INT64));
  
  Data_Get_Struct(self, CArray, ca);
  Data_Get_Struct(raddr, CArray, ci);

  ca_attach_n(2, ca, ci);

  q = (int64_t *) ca->ptr;
  p = (int64_t *) ci->ptr;
  m = ( ci->mask ) ? (boolean8_t *) ci->mask->ptr : NULL;

  elements = ca->elements;

  if ( m ) {
    #ifdef _OPENMP
    #pragma omp parallel for 
    #endif
    for (i=0; i<ci->elements; i++) {
      if ( ! *(m+i) ) {
        k = *(p+i);
        CA_CHECK_INDEX(k, elements);
        *(q + k) += 1;
      }
    }
  }
  else {
    #ifdef _OPENMP
    #pragma omp parallel for 
    #endif
    for (i=0; i<ci->elements; i++) {
      k = *(p+i);
      CA_CHECK_INDEX(k, elements);
      *(q + k) += 1;
    }
  }

  ca_sync(ca);
  ca_detach_n(2, ca, ci);

  return Qnil;
}

#inherit_mask(*others: ) ⇒ Object

(Masking, Destructive) Sets the mask array of self by the logical sum of the mask states of self and arrays given in arguments.



986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
# File 'ext/carray_mask.c', line 986

static VALUE
rb_ca_inherit_mask_method (int argc, VALUE *argv, VALUE self)
{
  CArray **slist;
  CArray *ca, *cs;
  int i;

  rb_ca_modify(self);

  Data_Get_Struct(self, CArray, ca);

  slist = malloc_with_check(sizeof(CArray *)*argc);
  for (i=0; i<argc; i++) {
    if ( rb_obj_is_carray(argv[i]) ) {
      Data_Get_Struct(argv[i], CArray, cs);
      slist[i] = cs;
    }
    else {
      slist[i] = NULL;
    }
  }
  ca_copy_mask_overlay_n(ca, ca->elements, argc, slist);

  free(slist);

  return self;
}

#inherit_mask_replace(*others) ⇒ Object

Sets the mask array of self by the logical sum of the mask states of arrays given in arguments. This method does not inherit the mask states of itself (different point from CArray#inherit_mask)



1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
# File 'ext/carray_mask.c', line 1065

static VALUE
rb_ca_inherit_mask_replace_method (int argc, VALUE *argv, VALUE self)
{
  CArray **slist;
  CArray *ca, *cs;
  int i;

  rb_ca_modify(self);

  Data_Get_Struct(self, CArray, ca);

  slist = malloc_with_check(sizeof(CArray *)*argc);
  for (i=0; i<argc; i++) {
    if ( rb_obj_is_carray(argv[i]) ) {
      Data_Get_Struct(argv[i], CArray, cs);
      slist[i] = cs;
    }
    else {
      slist[i] = NULL;
    }
  }
  ca_copy_mask_overwrite_n(ca, ca->elements, argc, slist);

  free(slist);

  return self;
}

#initialize_copy(other) ⇒ Object



949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
# File 'ext/ca_obj_array.c', line 949

static VALUE
rb_ca_initialize_copy (VALUE self, VALUE other)
{
  CArray *ca, *cs;

  rb_call_super(1, &other);

  Data_Get_Struct(self,  CArray, ca);
  Data_Get_Struct(other, CArray, cs);

  ca_update_mask(cs);
  carray_setup(ca, cs->data_type, cs->ndim, cs->dim, cs->bytes, cs->mask);

  memcpy(ca->ptr, cs->ptr, ca_length(cs));

  return self;
}

#int16Object Also known as: short

(Conversion) Short-Hand of "CArray#to_type(:int16)"



399
400
401
402
# File 'ext/carray_cast.c', line 399

VALUE rb_ca_to_int16 (VALUE self)
{
  rb_ca_to_type_method_body(CA_INT16);
}

#int32Object Also known as: int

(Conversion) Short-Hand of "CArray#to_type(:int32)"



417
418
419
420
# File 'ext/carray_cast.c', line 417

VALUE rb_ca_to_int32 (VALUE self)
{
  rb_ca_to_type_method_body(CA_INT32);
}

#int64Object

(Conversion) Short-Hand of "CArray#to_type(:int64)"



435
436
437
438
# File 'ext/carray_cast.c', line 435

VALUE rb_ca_to_int64 (VALUE self)
{
  rb_ca_to_type_method_body(CA_INT64);
}

#int8Object

(Conversion) Short-Hand of "CArray#to_type(:int8)"



381
382
383
384
# File 'ext/carray_cast.c', line 381

VALUE rb_ca_to_int8 (VALUE self)
{
  rb_ca_to_type_method_body(CA_INT8);
}

#integer?Boolean

(Inquiry) Returns true if self is integer type array

Returns:



468
469
470
471
472
473
474
# File 'ext/carray_attribute.c', line 468

VALUE
rb_ca_is_integer_type (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ca_is_integer_type(ca) ? Qtrue : Qfalse;
}

#invert_maskObject

(Masking, Destructive) Inverts mask state.



970
971
972
973
974
975
976
977
# File 'ext/carray_mask.c', line 970

VALUE
rb_ca_invert_mask (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  ca_invert_mask(ca);
  return self;
}

#is_maskedObject

(Masking, Element-Wise Inquiry) Returns new boolean type array of same shape with self. The returned array has 1 for the masked elements and 0 for not-masked elements.



749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
# File 'ext/carray_mask.c', line 749

VALUE
rb_ca_is_masked (VALUE self)
{
  volatile VALUE mask;
  CArray *ca, *cm, *co;
  boolean8_t zero = 0;
  boolean8_t *m, *p;
  ca_size_t i;

  Data_Get_Struct(self, CArray, ca);

  if ( ca_is_scalar(ca) ) {
    co = cscalar_new(CA_BOOLEAN, ca->bytes, NULL);        
  }
  else {
    co = carray_new(CA_BOOLEAN, ca->ndim, ca->dim, ca->bytes, NULL);    
  }

  ca_update_mask(ca);
  if ( ! ca->mask ) {
    ca_fill(co, &zero);
  }
  else {
    mask = rb_ca_mask_array(self);
    Data_Get_Struct(mask, CArray, cm);
    ca_attach(cm);
    m = (boolean8_t *) cm->ptr;
    p = (boolean8_t *) co->ptr;
    for (i=0; i<ca->elements; i++) {
      *p = ( *m ) ? 1 : 0;
      m++; p++;
    }
    ca_detach(cm);
  }

  return ca_wrap_struct(co);
}

#is_not_maskedObject

(Masking, Element-Wise Inquiry) Returns new boolean type array of same shape with self. The returned array has 0 for the masked elements and 1 for not-masked elements.



795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
# File 'ext/carray_mask.c', line 795

VALUE
rb_ca_is_not_masked (VALUE self)
{
  volatile VALUE mask;
  CArray *ca, *cm, *co;
  boolean8_t one = 1;
  boolean8_t *m, *p;
  ca_size_t i;

  Data_Get_Struct(self, CArray, ca);

  if ( ca_is_scalar(ca) ) {
    co = cscalar_new(CA_BOOLEAN, ca->bytes, NULL);        
  }
  else {
    co = carray_new(CA_BOOLEAN, ca->ndim, ca->dim, ca->bytes, NULL);    
  }

  ca_update_mask(ca);
  if ( ! ca->mask ) {
    ca_fill(co, &one);
  }
  else {
    mask = rb_ca_mask_array(self);
    Data_Get_Struct(mask, CArray, cm);
    ca_attach(cm);
    m = (boolean8_t *) cm->ptr;
    p = (boolean8_t *) co->ptr;
    for (i=0; i<ca->elements; i++) {
      *p = ( *m ) ? 0 : 1;
      m++; p++;
    }
    ca_detach(cm);
  }

  return ca_wrap_struct(co);
}

#elementsObject

(Attribute) Returns the number of elements



83
84
85
86
87
88
89
# File 'ext/carray_attribute.c', line 83

VALUE
rb_ca_elements (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return SIZE2NUM(ca->elements);
}

#load_binary(io) ⇒ Object

(IO) Loads the value array from the given IO stream



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'ext/carray_conversion.c', line 202

static VALUE
rb_ca_load_binary (VALUE self, VALUE io)
{
  CArray *ca;

  Data_Get_Struct(self, CArray, ca);

  if ( ca_is_object_type(ca) ) {
    rb_raise(rb_eCADataTypeError, "don't load object array");
  }

  switch ( TYPE(io) ) {
  case T_STRING:
    if ( ca_length(ca) > RSTRING_LEN(io) ) {
      rb_raise(rb_eRuntimeError,
               "data size mismatch (%lld for %lld)",
               (ca_size_t) RSTRING_LEN(io), (ca_size_t) ca_length(ca));
    }
    ca_allocate(ca);
    memcpy(ca->ptr, StringValuePtr(io), ca_length(ca));
    ca_sync(ca);
    ca_detach(ca);
    OBJ_INFECT(self, io);
    return self;
    break;
  default:
    if ( rb_respond_to(io, rb_intern("read") ) ) {
      volatile VALUE buf = rb_funcall(io, rb_intern("read"), 1, SIZE2NUM(ca_length(ca)));
      return rb_ca_load_binary(self, buf);
    }
    else {
      rb_raise(rb_eRuntimeError, "IO like object should have 'read' method");
    }
  }

  return self;
}

#map!({|elem| ... }) ⇒ Object

(Iterator, Destructive) Iterates all elements of the object and stores the return from the block to the element.



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'ext/carray_loop.c', line 179

static VALUE
rb_ca_map_bang (VALUE self)
{
  volatile VALUE obj;
  CArray *ca;
  ca_size_t elements = NUM2SIZE(rb_ca_elements(self));
  ca_size_t i;
#if RUBY_VERSION_CODE >= 190
  RETURN_ENUMERATOR(self, 0, 0);
#endif
  rb_ca_modify(self);
  Data_Get_Struct(self, CArray, ca);
  ca_attach(ca);
  for (i=0; i<elements; i++) {
    obj = rb_yield(rb_ca_fetch_addr(self, i));
    rb_ca_store_addr(self, i, obj);
  }
  ca_sync(ca);
  ca_detach(ca);
  return self;
}

#map_addr!({|addr| ... }) ⇒ Object

[TBD]



388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
# File 'ext/carray_loop.c', line 388

static VALUE
rb_ca_map_addr_bang (VALUE self)
{
  volatile VALUE obj;
  CArray *ca;
  ca_size_t elements = NUM2SIZE(rb_ca_elements(self));
  ca_size_t i;
#if RUBY_VERSION_CODE >= 190
  RETURN_ENUMERATOR(self, 0, 0);
#endif
  rb_ca_modify(self);
  Data_Get_Struct(self, CArray, ca);
  ca_attach(ca);
  for (i=0; i<elements; i++) {
    obj = rb_yield(SIZE2NUM(i));
    rb_ca_store_addr(self, i, obj);
  }
  ca_sync(ca);
  ca_detach(ca);
  return self;
}

#map_index!({|idx| ... }) ⇒ Object

[TBD]



333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
# File 'ext/carray_loop.c', line 333

static VALUE
rb_ca_map_index_bang (VALUE self)
{
  volatile VALUE ridx;
  CArray *ca;
  ca_size_t idx[CA_RANK_MAX];
  int8_t  ndim = NUM2INT(rb_ca_ndim(self));
#if RUBY_VERSION_CODE >= 190
  RETURN_ENUMERATOR(self, 0, 0);
#endif
  rb_ca_modify(self);
  Data_Get_Struct(self, CArray, ca);
  ca_attach(ca);
  ridx = rb_ary_new2(ndim);
  rb_ca_map_index_bang_internal(self, 0, idx, ridx);
  ca_sync(ca);
  ca_detach(ca);
  return self;
}

#map_with_addr!({|elem, addr| ... }) ⇒ Object

[TBD]



359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
# File 'ext/carray_loop.c', line 359

static VALUE
rb_ca_map_with_addr_bang (VALUE self)
{
  volatile VALUE obj;
  CArray *ca;
  ca_size_t elements = NUM2SIZE(rb_ca_elements(self));
  ca_size_t i;
#if RUBY_VERSION_CODE >= 190
  RETURN_ENUMERATOR(self, 0, 0);
#endif
  rb_ca_modify(self);
  Data_Get_Struct(self, CArray, ca);
  ca_attach(ca);
  for (i=0; i<elements; i++) {
    obj = rb_yield_values(2, rb_ca_fetch_addr(self, i), SIZE2NUM(i));
    rb_ca_store_addr(self, i, obj);
  }
  ca_sync(ca);
  ca_detach(ca);
  return self;
}

#map_with_index({|elem, idx| ... }) ⇒ Object

[TBD]



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'ext/carray_loop.c', line 281

static VALUE
rb_ca_map_with_index_bang (VALUE self)
{
  volatile VALUE ridx;
  CArray *ca;
  ca_size_t idx[CA_RANK_MAX];
  int8_t  ndim = NUM2INT(rb_ca_ndim(self));
#if RUBY_VERSION_CODE >= 190
  RETURN_ENUMERATOR(self, 0, 0);
#endif
  rb_ca_modify(self);
  Data_Get_Struct(self, CArray, ca);
  ca_attach(ca);
  ridx = rb_ary_new2(ndim);
  rb_ca_map_with_index_bang_internal(self, 0, idx, ridx);
  ca_sync(ca);
  ca_detach(ca);
  return self;
}

#maskObject

(Masking, Inquiry) Returns new array which refers the mask state of self. The mask array can't be set mask.



672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
# File 'ext/carray_mask.c', line 672

VALUE
rb_ca_mask_array (VALUE self)
{
  VALUE obj;
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);

  ca_update_mask(ca);
  if ( ca->mask ) {
    obj = Data_Wrap_Struct(ca_class[ca->mask->obj_type],
            ca_mark, ca_free_nop, ca->mask);
    rb_ivar_set(obj, rb_intern("masked_array"), self);
    if ( OBJ_FROZEN(self) ) {
      rb_ca_freeze(obj);
    }
    return obj;
  }
  else {
    return INT2NUM(0);
  }
}

#mask=(new_mask) ⇒ Object

(Mask, Modification) Asigns new_mask to the mask array of self. If self doesn't have a mask array, it will be created before asignment.



702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
# File 'ext/carray_mask.c', line 702

VALUE
rb_ca_set_mask (VALUE self, VALUE rval)
{
  volatile VALUE rmask = rval;
  CArray *ca, *cv;

  rb_ca_modify(self);

  Data_Get_Struct(self, CArray, ca);

  if ( ca_is_value_array(ca) ) {
    rb_raise(rb_eRuntimeError,
             "can not create mask for the value array");
  }

  if ( ca_is_mask_array(ca) ) {
    rb_raise(rb_eRuntimeError,
             "can not create mask for the mask array");
  }

  ca_update_mask(ca);
  if ( ! ca->mask ) {
    ca_create_mask(ca);
  }

  if ( rb_obj_is_carray(rmask) ) {
    Data_Get_Struct(rmask, CArray, cv);
    if ( ! ca_is_boolean_type(cv) ) {
      cv = ca_wrap_readonly(rval, CA_BOOLEAN);
    }
    ca_setup_mask(ca, cv);
    ca_copy_mask_overlay(ca, ca->elements, 1, cv);
    return rval;
  }
  else {
    return rb_ca_store_all(rb_ca_mask_array(self), rmask);
  }
}

#mask_array?Boolean

(Inquiry) Returns true if self is mask array (don't confuse with "masked array")

Returns:



345
346
347
348
349
350
351
# File 'ext/carray_attribute.c', line 345

VALUE
rb_ca_is_mask_array (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ( ca_is_mask_array(ca) ) ? Qtrue : Qfalse;
}

#membersObject

(Inquiry) Returns data class member names



1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
# File 'ext/carray_core.c', line 1186

VALUE
rb_ca_members (VALUE self)
{
  volatile VALUE data_class = rb_ca_data_class(self);
  if ( NIL_P(data_class) ) {
    rb_raise(rb_eRuntimeError, "carray doesn't have data class");
  }
  else {
    return rb_obj_clone(rb_const_get(data_class, rb_intern("MEMBERS")));
  }
}

#mul_add(weight, min_count = nil, fill_value = nil) ⇒ Object

[TBD]



540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
# File 'ext/carray_operator.c', line 540

static VALUE
rb_ca_mul_add (int argc, VALUE *argv, volatile VALUE self)
{
  volatile VALUE out;
  volatile VALUE weight = Qnil;
  volatile VALUE rmin_count = Qnil;
  volatile VALUE rfval = Qnil;
  CArray *ca, *cw;
  boolean8_t *mi = NULL;
  ca_size_t min_count;

  /* FIXME: to parse :mask_limit, :fill_value */
  rb_scan_args(argc, argv, "12", (VALUE *) &weight, (VALUE *) &rmin_count, (VALUE *) &rfval);

  /* do implicit casting and resolving unbound repeat array */
  rb_ca_cast_self_or_other(&self, &weight);

  Data_Get_Struct(self, CArray, ca);
  Data_Get_Struct(weight, CArray, cw);

  /* checking elements and data_type */
  ca_check_same_elements(ca, cw);
  ca_check_same_data_type(ca, cw);

  if ( ca->elements == 0 ) {
    return ( NIL_P(rfval) ) ? CA_UNDEF : rfval;
  }

  if ( ca_has_mask(ca) || ca_has_mask(cw) ) {
    mi = ca_allocate_mask_iterator(2, ca, cw);
  }

  min_count = ( NIL_P(rmin_count) || ( ! mi ) ) ?
                                   ca->elements - 1 : NUM2SIZE(rmin_count);

  if ( min_count < 0 ) {
    min_count += ca->elements;
  }

  ca_attach_n(2, ca, cw);

  switch ( ca->data_type ) {
  case CA_INT8:     proc_mul_add(int8_t, ,LONG2NUM);           break;
  case CA_UINT8:    proc_mul_add(uint8_t,,ULONG2NUM);         break;
  case CA_INT16:    proc_mul_add(int16_t,,LONG2NUM);           break;
  case CA_UINT16:   proc_mul_add(uint16_t,,ULONG2NUM);        break;
  case CA_INT32:    proc_mul_add(int32_t,,LONG2NUM);           break;
  case CA_UINT32:   proc_mul_add(uint32_t,,ULONG2NUM);        break;
  case CA_INT64:    proc_mul_add(int64_t,,LL2NUM);             break;
  case CA_UINT64:   proc_mul_add(uint64_t,,ULL2NUM);          break;
  case CA_FLOAT32:  proc_mul_add(float32_t,,rb_float_new);     break;
  case CA_FLOAT64:  proc_mul_add(float64_t,,rb_float_new);     break;
  case CA_FLOAT128: proc_mul_add(float128_t,,rb_float_new);    break;
#ifdef HAVE_COMPLEX_H
  case CA_CMPLX64:  proc_mul_add(cmplx64_t,,rb_ccomplex_new);  break;
  case CA_CMPLX128: proc_mul_add(cmplx128_t,,rb_ccomplex_new); break;
  case CA_CMPLX256: proc_mul_add(cmplx256_t,,rb_ccomplex_new); break;
#endif
/*  case CA_OBJECT:   proc_mul_add(VALUE,NUM2DBL,rb_float_new); break; */
  default: rb_raise(rb_eCADataTypeError, "invalid data type");
  }

  ca_detach_n(2, ca, cw);

  free(mi);

  return out;
}

#ndimObject

(Attribute) Returns the number of dimensions (e.g. 1 for 1D array, 3 for 3D array, ...).



51
52
53
54
55
56
57
# File 'ext/carray_attribute.c', line 51

VALUE
rb_ca_ndim (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return INT2NUM(ca->ndim);
}

#numeric?Boolean

(Inquiry) Returns true if self is numeric type array

Returns:



445
446
447
448
449
450
451
# File 'ext/carray_attribute.c', line 445

VALUE
rb_ca_is_numeric_type (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ca_is_numeric_type(ca) ? Qtrue : Qfalse;
}

#obj_typeObject

(Attribute) Returns the object type (e.g. CA_OBJ_ARRAY, CA_OBJ_BLOCK, ...). Since the object type can be known from the class of the object, this attribute methods is rarely used.



23
24
25
26
27
28
29
# File 'ext/carray_attribute.c', line 23

VALUE
rb_ca_obj_type (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return INT2NUM(ca->obj_type);
}

#objectObject

(Conversion) Short-Hand of "CArray#to_type(:object)"



507
508
509
510
# File 'ext/carray_cast.c', line 507

VALUE rb_ca_to_VALUE (VALUE self)
{
  rb_ca_to_type_method_body(CA_OBJECT);
}

#object?Boolean

(Inquiry) Returns true if self is object type array

Returns:



566
567
568
569
570
571
572
# File 'ext/carray_attribute.c', line 566

VALUE
rb_ca_is_object_type (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ca_is_object_type(ca) ? Qtrue : Qfalse;
}

#parentObject

(Attribute) Returns the parent carray if self has parent, or returns nil if self has no parent.



585
586
587
588
589
# File 'ext/carray_attribute.c', line 585

VALUE
rb_ca_parent (VALUE self)
{
  return rb_ivar_get(self, id_parent);
}

#paste(idx, ary) ⇒ Object

(Copy) Pastes ary to self at the index idx. idx should be Array object with the length same as self.ndim. ary should have same shape with self.



285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'ext/carray_copy.c', line 285

static VALUE
rb_ca_paste (VALUE self, VALUE roffset, VALUE rsrc)
{
  CArray *ca, *cs;
  ca_size_t offset[CA_RANK_MAX];
  int i;

  rb_ca_modify(self);

  Data_Get_Struct(self, CArray, ca);

  Check_Type(roffset, T_ARRAY);

  if ( RARRAY_LEN(roffset) != ca->ndim ) {
    rb_raise(rb_eArgError,
             "# of arguments should equal to the ndim");
  }

  for (i=0; i<ca->ndim; i++) {
    offset[i] = NUM2SIZE(rb_ary_entry(roffset,i));
  }

  cs = ca_wrap_readonly(rsrc, ca->data_type);

  ca_paste(ca, offset, cs);

  return self;
}

#project(idx, lval = nil, uval = nil) ⇒ Object

[TBD]. Creates new array the element of the object as address.



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'ext/carray_order.c', line 146

VALUE
rb_ca_project (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE obj, ridx, vlfval, vufval;
  CArray *ca, *ci, *co;
  char *lfval, *ufval;

  rb_scan_args(argc, argv, "12", (VALUE *)&ridx, (VALUE *) &vlfval, (VALUE *) &vufval);

  Data_Get_Struct(self, CArray, ca);

  rb_check_carray_object(ridx);
  ci = ca_wrap_readonly(ridx, CA_SIZE);

  lfval = malloc_with_check(ca->bytes);
  ufval = malloc_with_check(ca->bytes);

  if ( ! NIL_P(vlfval) ) {
    rb_ca_obj2ptr(self, vlfval, lfval);
    rb_ca_obj2ptr(self, vlfval, ufval);
  }

  if ( ! NIL_P(vufval) ) {
    rb_ca_obj2ptr(self, vufval, ufval);
  }

  co = ca_project(ca, ci,
                 ( ! NIL_P(vlfval) ) ? lfval : NULL,
                 ( ( ! NIL_P(vufval) ) || ( ! NIL_P(vlfval) ) ) ? ufval : NULL);

  free(lfval);
  free(ufval);

  obj = ca_wrap_struct(co);
  rb_ca_data_type_inherit(obj, self);

  if ( ! ca_is_any_masked(co) ) {
    obj = rb_ca_unmask_copy(obj);
  }

  return obj;
}

#ndimObject

(Attribute) Returns the number of dimensions (e.g. 1 for 1D array, 3 for 3D array, ...).



51
52
53
54
55
56
57
# File 'ext/carray_attribute.c', line 51

VALUE
rb_ca_ndim (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return INT2NUM(ca->ndim);
}

#read_only?Boolean

(Inquiry) Returns true if the object is read-only

Returns:



312
313
314
315
316
317
318
# File 'ext/carray_attribute.c', line 312

VALUE
rb_ca_is_read_only (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ( ca_is_readonly(ca) ) ? Qtrue : Qfalse;
}

#reverseObject

Returns a new CArray object containing ca's elements in reverse order.



281
282
283
284
285
286
287
# File 'ext/carray_order.c', line 281

static VALUE
rb_ca_reversed_copy (VALUE self)
{
  volatile VALUE out = rb_ca_copy(self);
  rb_ca_data_type_inherit(out, self);
  return rb_ca_reverse_bang(out);
}

#reverse!Object

Reverses the elements of +ca+ in place.



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'ext/carray_order.c', line 231

static VALUE
rb_ca_reverse_bang (VALUE self)
{
  CArray *ca;

  rb_ca_modify(self);

  Data_Get_Struct(self, CArray, ca);
  ca_attach(ca);

  switch ( ca->data_type ) {
  case CA_FIXLEN: proc_reverse_bang_data();  break;
  case CA_BOOLEAN:
  case CA_INT8:
  case CA_UINT8:    proc_reverse_bang(int8_t);  break;
  case CA_INT16:
  case CA_UINT16:   proc_reverse_bang(int16_t); break;
  case CA_INT32:
  case CA_UINT32:
  case CA_FLOAT32:  proc_reverse_bang(int32_t); break;
  case CA_INT64:
  case CA_UINT64:
  case CA_FLOAT64:  proc_reverse_bang(float64_t);  break;
  case CA_FLOAT128: proc_reverse_bang(float128_t);  break;
#ifdef HAVE_COMPLEX_H
  case CA_CMPLX64:  proc_reverse_bang(float64_t);  break;
  case CA_CMPLX128: proc_reverse_bang(cmplx128_t);  break;
  case CA_CMPLX256: proc_reverse_bang(cmplx256_t);  break;
#endif
  case CA_OBJECT:   proc_reverse_bang(VALUE);  break;
  default:
    rb_raise(rb_eCADataTypeError, "[BUG] array has an unknown data type");
  }

  if ( ca_has_mask(ca) ) {
    proc_reverse_bang_mask();
  }

  ca_sync(ca);
  ca_detach(ca);

  return self;
}

#root_arrayObject

(Attribute) Returns the object at the root of chain of reference.



754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
# File 'ext/carray_attribute.c', line 754

static VALUE
rb_ca_root_array (VALUE self)
{
  volatile VALUE refary;
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  if ( ca_is_entity(ca) ) {
    return self;
  }
  else {
    refary = rb_ca_parent(self);
    if ( NIL_P(refary) ) {
      return self;
    }
    else {
      return rb_ca_root_array(refary);
    }
  }
}

#has_same_shape?Boolean

(Inquiry) Returns true if the object has the same shape with the given array.

Returns:



294
295
296
297
298
299
300
301
# File 'ext/carray_test.c', line 294

static VALUE
rb_ca_has_same_shape (VALUE self, VALUE other)
{
  CArray *ca, *cb;
  Data_Get_Struct(self, CArray, ca);
  cb = ca_wrap_readonly(other, ca->data_type);
  return ca_has_same_shape(ca, cb) ? Qtrue : Qfalse;
}

#scalar?Boolean

(Inquiry) Returns true if the object is a CScalar

Returns:



200
201
202
203
204
205
206
# File 'ext/carray_attribute.c', line 200

VALUE
rb_ca_is_scalar (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ( ca_is_scalar(ca) ) ? Qtrue : Qfalse;
}

#searchObject

[TBD].



698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
# File 'ext/carray_order.c', line 698

static VALUE
rb_ca_linear_search (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE value, veps;
  CArray *ca;
  ca_size_t addr;

  rb_scan_args(argc, argv, "11", (VALUE *) &value, (VALUE *) &veps);

  Data_Get_Struct(self, CArray, ca);

  ca_attach(ca);

  addr = -1;

  switch ( ca->data_type ) {
  case CA_BOOLEAN:
  case CA_INT8:
  case CA_UINT8:    proc_find_value(int8_t);    break;
  case CA_INT16:
  case CA_UINT16:   proc_find_value(int16_t);   break;
  case CA_INT32:    proc_find_value(int32_t);   break;
  case CA_UINT32:   proc_find_value(uint32_t); break;
  case CA_INT64:    proc_find_value(int64_t);   break;
  case CA_UINT64:   proc_find_value(uint64_t); break;
  case CA_FLOAT32:  proc_find_value_float(float32_t, FLT_EPSILON); break;
  case CA_FLOAT64:  proc_find_value_float(float64_t, DBL_EPSILON); break;
  case CA_FLOAT128: proc_find_value_float128(float128_t, DBL_EPSILON); break;
#ifdef HAVE_COMPLEX_H
  case CA_CMPLX64:  proc_find_value_cmplx(cmplx64_t, FLT_EPSILON); break;
  case CA_CMPLX128: proc_find_value_cmplx(cmplx128_t, DBL_EPSILON); break;
  case CA_CMPLX256: proc_find_value_cmplx(cmplx256_t, DBL_EPSILON); break;
#endif
  case CA_OBJECT:   proc_find_value_object(); break;
  default:
    rb_raise(rb_eCADataTypeError, "invalid data type");
  }

  ca_detach(ca);

  return ( addr == -1 ) ? Qnil : SIZE2NUM(addr);
}

#search_indexObject

[TBD].



746
747
748
749
750
751
# File 'ext/carray_order.c', line 746

static VALUE
rb_ca_linear_search_index (int argc, VALUE *argv, VALUE self)
{
  VALUE raddr = rb_ca_linear_search(argc, argv, self);
  return ( NIL_P(raddr) ) ? Qnil : rb_ca_addr2index(self, raddr);
}

#search_nearestObject

[TBD].



822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
# File 'ext/carray_order.c', line 822

static VALUE
rb_ca_linear_search_nearest (VALUE self, VALUE value)
{
  CArray *ca;
  ca_size_t addr;

  Data_Get_Struct(self, CArray, ca);

  ca_attach(ca);

  switch ( ca->data_type ) {
  case CA_BOOLEAN:
  case CA_INT8:    proc_nearest_addr(int8_t,      NUM2LONG,   fabs); break;
  case CA_UINT8:   proc_nearest_addr(uint8_t,    NUM2ULONG,  fabs); break;
  case CA_INT16:   proc_nearest_addr(int16_t,     NUM2LONG,   fabs); break;
  case CA_UINT16:  proc_nearest_addr(uint16_t,   NUM2ULONG,  fabs); break;
  case CA_INT32:   proc_nearest_addr(int32_t,     NUM2LONG,   fabs); break;
  case CA_UINT32:  proc_nearest_addr(uint32_t,   NUM2ULONG,  fabs); break;
  case CA_INT64:   proc_nearest_addr(int64_t,     NUM2LL,     fabs); break;
  case CA_UINT64:  proc_nearest_addr(uint64_t,   rb_num2ull, fabs); break;
  case CA_FLOAT32: proc_nearest_addr(float32_t,   NUM2DBL,    fabs); break;
  case CA_FLOAT64: proc_nearest_addr(float64_t,   NUM2DBL,    fabs); break;
  case CA_FLOAT128: proc_nearest_addr(float128_t, NUM2DBL,    fabs); break;
#ifdef HAVE_COMPLEX_H
  case CA_CMPLX64:  proc_nearest_addr(cmplx64_t,  NUM2CC, cabs); break;
  case CA_CMPLX128: proc_nearest_addr(cmplx128_t, NUM2CC, cabs); break;
  case CA_CMPLX256: proc_nearest_addr(cmplx256_t, NUM2CC, cabs); break;
#endif
  case CA_OBJECT:  proc_nearest_addr_VALUE(); break;
  default:
    rb_raise(rb_eCADataTypeError, "invalid data type for nearest_addr()");
  }

  ca_detach(ca);

  return ( addr == -1 ) ? Qnil : SIZE2NUM(addr);
}

#search_nearest_indexObject

[TBD].



865
866
867
868
869
870
# File 'ext/carray_order.c', line 865

static VALUE
rb_ca_linear_search_nearest_index (VALUE self, VALUE value)
{
  VALUE raddr = rb_ca_linear_search_nearest(self, value);
  return ( NIL_P(raddr) ) ? Qnil : rb_ca_addr2index(self, raddr);
}

#sectionObject



962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
# File 'ext/carray_order.c', line 962

static VALUE
rb_ca_binary_search_linear_index (volatile VALUE self, volatile VALUE vx)
{
  volatile VALUE out, out0;
  CArray *ca, *sc, *cx, *co0, *co;
  ca_size_t n;
  double *x;
  double *px;
  double *po;
  ca_size_t i;

  Data_Get_Struct(self, CArray, ca);

  if ( rb_ca_is_any_masked(self) ) {
    rb_raise(rb_eRuntimeError, "self should not have any masked elements");
  }

  sc = ca_wrap_readonly(self, CA_FLOAT64);
  cx = ca_wrap_readonly(vx, CA_FLOAT64);

  co0 = carray_new(ca->data_type, cx->ndim, cx->dim, 0, NULL);
  out = out0 = ca_wrap_struct(co0);
  co = ca_wrap_writable(out, CA_FLOAT64);

  ca_attach_n(3, sc, cx, co);

  n = sc->elements;
  x  = (double*) sc->ptr;
  px = (double*) cx->ptr;
  po = (double*) co->ptr;

  ca_update_mask(cx);
  if ( cx->mask ) {
    boolean8_t *mx, *mo;
    ca_create_mask(co);
    mx = (boolean8_t *) cx->mask->ptr;
    mo = (boolean8_t *) co->mask->ptr;
    for (i=0; i<cx->elements; i++) {
      if ( ! *mx ) {
        linear_index(n, x, *px, po);
      }
      else {
        *mo = 1;
      }
      mx++; mo++; px++, po++;
    }
  }
  else {
    for (i=0; i<cx->elements; i++) {
      linear_index(n, x, *px, po);
      px++; po++;
    }
  }

  ca_sync(co);
  ca_detach_n(3, sc, cx, co);

  if ( rb_ca_is_scalar(vx) ) {
    return rb_funcall(out0, rb_intern("[]"), 1, INT2NUM(0));
  }
  else {
    return out0;
  }
}

#seq(init_val = 0, step = 1{|elem| ... }) ⇒ Object

(Conversion) Generates sequential data with initial value init_val and step value step. For object array, if the second argument is Symbol object, it will be interpreted as stepping method and it is called for the last element in each step. # call-seq: # seq (init_val=0, step=1) # seq (init_val=0, step=1) {|x| ... } # seq (init_val=0, step=A_symbol) ### for object array # seq (init_val=0, step=A_symbol) {|x| ...} ### for object array # # Generates sequential data with initial value init_val # and step value step. For object array, if the second argument # is Symbol object, it will be interpreted as stepping method and # it is called for the last element in each step. #



358
359
360
361
362
363
# File 'ext/carray_generate.c', line 358

static VALUE
rb_ca_seq_method (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE out = rb_ca_template(self);
  return rb_ca_seq_bang_method(argc, argv, out);
}

#seq!(init_val = 0, step = 1{|elem| ... }) ⇒ Object

(Conversion, Destructive) Generates sequential data with initial value init_val and step value step. For object array, if the second argument is Symbol object, it will be interpreted as stepping method and it is called for the last element in each step. # call-seq: # seq (init_val=0, step=1) # seq (init_val=0, step=1) {|x| ... } # seq (init_val=0, step=A_symbol) ### for object array # seq (init_val=0, step=A_symbol) {|x| ...} ### for object array # # Generates sequential data with initial value init_val # and step value step. For object array, if the second argument # is Symbol object, it will be interpreted as stepping method and # it is called for the last element in each step. #



265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
# File 'ext/carray_generate.c', line 265

static VALUE
rb_ca_seq_bang_method (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE roffset, rstep;
  CArray *ca;

  rb_ca_modify(self);
  Data_Get_Struct(self, CArray, ca);

  /* delegate to rb_ca_seq_bang_object if data_type is object */
  if ( ca_is_object_type(ca) ) {
    return rb_ca_seq_bang_object(argc, argv, self);
  }

  rb_scan_args(argc, argv, "02", (VALUE *) &roffset, (VALUE *) &rstep);

  ca_allocate(ca);

  if ( ca_has_mask(ca) ) {
    ca_clear_mask(ca);              /* clear all mask */
  }

  if ( rb_block_given_p() ) {       /* with block */
    switch ( ca->data_type ) {
    case CA_INT8:     proc_seq_bang_with_block(int8_t,     NUM2LONG, );   break;
    case CA_UINT8:    proc_seq_bang_with_block(uint8_t,   NUM2ULONG, );  break;
    case CA_INT16:    proc_seq_bang_with_block(int16_t,    NUM2LONG, ) ;  break;
    case CA_UINT16:   proc_seq_bang_with_block(uint16_t,  NUM2ULONG, );  break;
    case CA_INT32:    proc_seq_bang_with_block(int32_t,    NUM2LONG, );   break;
    case CA_UINT32:   proc_seq_bang_with_block(uint32_t,  NUM2ULONG, );  break;
    case CA_INT64:    proc_seq_bang_with_block(int64_t,    NUM2LL, );     break;
    case CA_UINT64:   proc_seq_bang_with_block(uint64_t,  rb_num2ull, ); break;
    case CA_FLOAT32:  proc_seq_bang_with_block(float32_t,  NUM2DBL, );    break;
    case CA_FLOAT64:  proc_seq_bang_with_block(float64_t,  NUM2DBL, );    break;
    case CA_FLOAT128: proc_seq_bang_with_block(float128_t, NUM2DBL, );    break;
#ifdef HAVE_COMPLEX_H
    case CA_CMPLX64:  proc_seq_bang_with_block(cmplx64_t, (cmplx64_t) NUM2CC,); break;
    case CA_CMPLX128: proc_seq_bang_with_block(cmplx128_t, NUM2CC, );     break;
    case CA_CMPLX256: proc_seq_bang_with_block(cmplx256_t, (cmplx256_t) NUM2CC, ); break;
#endif
    default: rb_raise(rb_eCADataTypeError,
                      "invalid data type of receiver");
    }
  }
  else {                            /* without block */
    switch ( ca->data_type ) {
    case CA_INT8:     proc_seq_bang(int8_t,     NUM2LONG, );   break;
    case CA_UINT8:    proc_seq_bang(uint8_t,   NUM2ULONG, );  break;
    case CA_INT16:    proc_seq_bang(int16_t,    NUM2LONG, ) ;  break;
    case CA_UINT16:   proc_seq_bang(uint16_t,  NUM2ULONG, );  break;
    case CA_INT32:    proc_seq_bang(int32_t,    NUM2LONG, );   break;
    case CA_UINT32:   proc_seq_bang(uint32_t,  NUM2ULONG, );  break;
    case CA_INT64:    proc_seq_bang(int64_t,    NUM2LL, );     break;
    case CA_UINT64:   proc_seq_bang(uint64_t,  rb_num2ull, ); break;
    case CA_FLOAT32:  proc_seq_bang(float32_t,  NUM2DBL, );    break;
    case CA_FLOAT64:  proc_seq_bang(float64_t,  NUM2DBL, );    break;
    case CA_FLOAT128: proc_seq_bang(float128_t, NUM2DBL, );    break;
#ifdef HAVE_COMPLEX_H
    case CA_CMPLX64:  proc_seq_bang(cmplx64_t, (cmplx64_t) NUM2CC, );   break;
    case CA_CMPLX128: proc_seq_bang(cmplx128_t, NUM2CC, );              break;
    case CA_CMPLX256: proc_seq_bang(cmplx256_t, (cmplx256_t) NUM2CC, ); break;
#endif
    default: rb_raise(rb_eCADataTypeError,
                      "invalid data type of reciever");
    }
  }

  ca_sync(ca);
  ca_detach(ca);

  return self;
}

#set(*idx) ⇒ Object

(Boolean, Modification) Sets true at the given index for the boolean array and returns self. It accept the arguments same as for CArray#[].



23
24
25
26
27
28
29
30
31
32
33
# File 'ext/carray_generate.c', line 23

static VALUE
rb_ca_boolean_set (int argc, VALUE *argv, VALUE self)
{
  VALUE one = INT2NUM(1);
  rb_ca_modify(self);
  if ( ! rb_ca_is_boolean_type(self) ) {
    rb_raise(rb_eCADataTypeError, "reciever should be a boolean array");
  }
  rb_ca_store2(self, argc, argv, one);
  return self;
}

#dimObject

(Attribute) Returns the Array object contains the dimensional shape of array (e.g. [2,3] for 2D 2x3 array, ...).



98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'ext/carray_attribute.c', line 98

VALUE
rb_ca_dim (VALUE self)
{
  volatile VALUE dim;
  CArray *ca;
  int i;
  Data_Get_Struct(self, CArray, ca);
  dim = rb_ary_new2(ca->ndim);
  for (i=0; i<ca->ndim; i++) {
    rb_ary_store(dim, i, SIZE2NUM(ca->dim[i]));
  }
  return dim;
}

#elementsObject

(Attribute) Returns the number of elements



83
84
85
86
87
88
89
# File 'ext/carray_attribute.c', line 83

VALUE
rb_ca_elements (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return SIZE2NUM(ca->elements);
}

#sortObject

Returns a new CArray object containing ca's elements sorted.



428
429
430
431
432
433
434
# File 'ext/carray_order.c', line 428

static VALUE
rb_ca_sorted_copy (VALUE self)
{
  volatile VALUE out = rb_ca_copy(self);
  rb_ca_data_type_inherit(out, self);
  return rb_ca_sort_bang(out);
}

#sort!Object

Sorts ca's elements in place.



382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
# File 'ext/carray_order.c', line 382

static VALUE
rb_ca_sort_bang (VALUE self)
{
  CArray *ca;

  if ( rb_ca_is_any_masked(self) ) {
    rb_ca_sort_bang(rb_ca_value_not_masked(self));
    return self;
  }

  rb_ca_modify(self);

  Data_Get_Struct(self, CArray, ca);
  ca_attach(ca);

  if ( ca_is_fixlen_type(ca) ) {
    cmp_data *cmp_ptr, *p;
    char *ca_ptr, *q;
    ca_size_t i;
    cmp_ptr = malloc_with_check(sizeof(cmp_data)*ca->elements);
    ca_ptr  = malloc_with_check(ca_length(ca));
    for (i=0, p=cmp_ptr, q=ca->ptr; i<ca->elements; i++, p++, q+=ca->bytes) {
      p->bytes = ca->bytes;
      p->ptr   = q;
    }
    qsort(cmp_ptr, ca->elements, sizeof(cmp_data), ca_qsort_cmp[CA_FIXLEN]);
    for (i=0, p=cmp_ptr, q=ca_ptr; i<ca->elements; i++, p++, q+=ca->bytes) {
      memcpy(q, p->ptr, ca->bytes);
    }
    free(ca->ptr);
    ca->ptr = ca_ptr;
    free(cmp_ptr);
  }
  else {
    qsort(ca->ptr, ca->elements, ca->bytes, ca_qsort_cmp[ca->data_type]);
  }
  ca_sync(ca);
  ca_detach(ca);
  return self;
}

#sort_addr(*args) ⇒ Object

(Sort) Returns index table for index sort This method same as,

idx = CA.sort_addr(self, *args)


241
242
243
244
245
246
247
# File 'ext/carray_sort_addr.c', line 241

static VALUE
rb_ca_sort_addr (int argc, VALUE *argv, VALUE self)
{
  VALUE list = rb_ary_new4(argc, argv);
  rb_ary_unshift(list, self);
  return rb_apply(rb_mCA, rb_intern("sort_addr"), list);
}

#str_format(*fmts) ⇒ Object

(Conversion) Creates object type array consist of string using the "::format" method. The Multiple format strings are given, they are applied cyclic in turn.



299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
# File 'ext/carray_conversion.c', line 299

static VALUE
rb_ca_format (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE obj, elem, val;
  CArray *ca;
  ca_size_t i, j;
  ID id_format = rb_intern("format");

  Data_Get_Struct(self, CArray, ca);

  obj = rb_ca_template_with_type(self, INT2NUM(CA_OBJECT), INT2NUM(0));

  ca_attach(ca);
  if ( ca_has_mask(ca) ) {
    j = 0;
    for (i=0; i<ca->elements; i++) {
      val = CA_UNDEF;
      if ( ! ca->mask->ptr[i] ) {
        elem = rb_ca_fetch_addr(self, i);
        val = rb_funcall(elem, id_format, 2, argv[j], elem);
      }
      rb_ca_store_addr(obj, i, val);
      j++;
      j = j % argc; /* cyclic referencing of argv */
    }
  }
  else {
    j = 0;
    for (i=0; i<ca->elements; i++) {
      elem = rb_ca_fetch_addr(self, i);
      val = rb_funcall(elem, id_format, 2, argv[j], elem);
      rb_ca_store_addr(obj, i, val);
      j++;
      j = j % argc; /* cyclic referencing of argv */
    }
  }
  ca_detach(ca);

  return obj;
}

#str_strptime(fmt) ⇒ Object

(Conversion) Creates object type array consist of Time objects which are created by 'Time.strptime' applied to the elements of the object. This method assumes all the elements of the objetct to be String.



353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
# File 'ext/carray_conversion.c', line 353

static VALUE
rb_ca_strptime (VALUE self, VALUE rfmt)
{
  volatile VALUE obj, elem, val;
  CArray *ca;
  char *fmt;
  struct tm tmv;
  ca_size_t i;
  
  ca = ca_wrap_readonly(self, CA_OBJECT);

  if ( ! ca_is_object_type(ca) ) {
    rb_raise(rb_eRuntimeError, "strptime can be applied only to object type.");
  }

  Check_Type(rfmt, T_STRING);
  fmt = (char *) StringValuePtr(rfmt);

  obj = rb_ca_template(self);

  ca_attach(ca);
  if ( ca_has_mask(ca) ) {
    for (i=0; i<ca->elements; i++) {
      val = CA_UNDEF;
      if ( ! ca->mask->ptr[i] ) {
        elem = rb_ca_fetch_addr(self, i);
        if ( TYPE(elem) == T_STRING ) {
          memset(&tmv, 0, sizeof(struct tm));
          if ( strptime(StringValuePtr(elem), fmt, &tmv) ) {
            val = rb_time_new(mktime(&tmv), 0);
          }  
        }
      }
      rb_ca_store_addr(obj, i, val);      
    }
  }
  else {
    for (i=0; i<ca->elements; i++) {
      val = CA_UNDEF;
      elem = rb_ca_fetch_addr(self, i);
      if ( TYPE(elem) == T_STRING ) {
        memset(&tmv, 0, sizeof(struct tm));
        if ( strptime(StringValuePtr(elem), fmt, &tmv) ) {
          val = rb_time_new(mktime(&tmv), 0);
        }  
      }
      rb_ca_store_addr(obj, i, val);      
    }
  }
  ca_detach(ca);

  return obj;
}

#swap_bytesObject

(Conversion) Swaps the byte order of each element.



573
574
575
576
577
578
# File 'ext/carray_generate.c', line 573

VALUE
rb_ca_swap_bytes (VALUE self)
{
  volatile VALUE out = rb_ca_copy(self);
  return rb_ca_swap_bytes_bang(out);
}

#swap_bytes!Object

(Conversion, Destructive) Swaps the byte order of each element.



481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
# File 'ext/carray_generate.c', line 481

VALUE
rb_ca_swap_bytes_bang (VALUE self)
{
  CArray *ca;
  int i;

  rb_ca_modify(self);

  if ( rb_ca_is_object_type(self) ) {
    rb_raise(rb_eCADataTypeError, "object array can't swap bytes");
  }

  if ( rb_ca_is_fixlen_type(self) ) {
    if ( rb_ca_has_data_class(self) ) {
      volatile VALUE members = rb_ca_fields(self);
      Check_Type(members, T_ARRAY);
      for (i=0; i<RARRAY_LEN(members); i++) {
        volatile VALUE obj = rb_ary_entry(members, i);
        rb_ca_swap_bytes_bang(obj);
      }
    }
    else {
      Data_Get_Struct(self, CArray, ca);
      ca_attach(ca);
      ca_swap_bytes(ca->ptr, ca->bytes, ca->elements);
      ca_sync(ca);
      ca_detach(ca);
    }
    return self;
  }

  Data_Get_Struct(self, CArray, ca);

  switch ( ca->data_type ) {
  case CA_INT16:
  case CA_UINT16:
    ca_attach(ca);
    ca_swap_bytes(ca->ptr, 2, ca->elements);
    ca_sync(ca);
    ca_detach(ca);
    break;
  case CA_INT32:
  case CA_UINT32:
  case CA_FLOAT32:
    ca_attach(ca);
    ca_swap_bytes(ca->ptr, 4, ca->elements);
    ca_sync(ca);
    ca_detach(ca);
    break;
  case CA_INT64:
  case CA_UINT64:
  case CA_FLOAT64:
    ca_attach(ca);
    ca_swap_bytes(ca->ptr, 8, ca->elements);
    ca_sync(ca);
    ca_detach(ca);
    break;
  case CA_FLOAT128:
    ca_attach(ca);
    ca_swap_bytes(ca->ptr, 16, ca->elements);
    ca_sync(ca);
    ca_detach(ca);
    break;
  case CA_CMPLX64:
    ca_attach(ca);
    ca_swap_bytes(ca->ptr, 4, 2 * ca->elements);
    ca_sync(ca);
    ca_detach(ca);
    break;
  case CA_CMPLX128:
    ca_attach(ca);
    ca_swap_bytes(ca->ptr, 8, 2 * ca->elements);
    ca_sync(ca);
    ca_detach(ca);
    break;
  case CA_CMPLX256:
    ca_attach(ca);
    ca_swap_bytes(ca->ptr, 16, 2 * ca->elements);
    ca_sync(ca);
    ca_detach(ca);
    break;
  }

  return self;
}

#template(data_type = self.data_type, bytes: 0) ⇒ Object

(Copy) Returns CArray object with same dimension with self The data type of the new carray object can be specified by data_type. For fixlen data type, the option :bytes is used to specified the data length.



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
133
134
135
136
137
138
139
140
141
# File 'ext/carray_copy.c', line 107

static VALUE
rb_ca_template_method (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE ropt = rb_pop_options(&argc, &argv);
  volatile VALUE obj, rtype, rbytes = Qnil;
  CArray *ca, *co;
  int8_t data_type;
  ca_size_t bytes;

  rb_scan_args(argc, argv, "01", (VALUE *) &rtype);
  rb_scan_options(ropt, "bytes", &rbytes);

  Data_Get_Struct(self, CArray, ca);

  if ( NIL_P(rtype) ) {                  /* data_type not given */
    co  = ca_template_safe(ca);
    obj = ca_wrap_struct(co);
    rb_ca_data_type_inherit(obj, self);
  }
  else {
    rb_ca_guess_type_and_bytes(rtype, rbytes, &data_type, &bytes);
    co  = ca_template_safe2(ca, data_type, bytes);
    obj = ca_wrap_struct(co);
    rb_ca_data_type_import(obj, rtype);
  }

  if ( rb_block_given_p() ) {                   /* block given */
    volatile VALUE rval = rb_yield_values(0);
    if ( rval != self ) {
      rb_ca_store_all(obj, rval);
    }
  }

  return obj;
}

#time_strftime(fmt) ⇒ Object

(Conversion) Creates object type array consist of strings which are created by 'Time#strftime' applied to the elements of the object. This method assumes all the elements of the objetct to be Time or DateTime.



417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
# File 'ext/carray_conversion.c', line 417

static VALUE
rb_ca_strftime (VALUE self, VALUE rfmt)
{
  volatile VALUE obj, elem, val;
  CArray *ca;
  ca_size_t i;
  ID id_strftime = rb_intern("strftime");
  
  ca = ca_wrap_readonly(self, CA_OBJECT);

  if ( ! ca_is_object_type(ca) ) {
    rb_raise(rb_eRuntimeError, "strptime can be applied only to object type.");
  }

  obj = rb_ca_template(self);

  ca_attach(ca);
  if ( ca_has_mask(ca) ) {
    for (i=0; i<ca->elements; i++) {
      val = CA_UNDEF;
      if ( ! ca->mask->ptr[i] ) {
        elem = rb_ca_fetch_addr(self, i);
        val = rb_funcall(elem, id_strftime, 1, rfmt);
      }
      rb_ca_store_addr(obj, i, val);      
    }
  }
  else {
    for (i=0; i<ca->elements; i++) {
      elem = rb_ca_fetch_addr(self, i);
      val = rb_funcall(elem, id_strftime, 1, rfmt);
      rb_ca_store_addr(obj, i, val);      
    }
  }
  ca_detach(ca);

  return obj;
}

#to_aObject

(Conversion) Converts the array to Ruby's array. For higher dimension, the array is nested ndim-1 times.



52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'ext/carray_conversion.c', line 52

VALUE
rb_ca_to_a (VALUE self)
{
  volatile VALUE ary;
  CArray *ca;
  ca_size_t idx[CA_RANK_MAX];
  Data_Get_Struct(self, CArray, ca);
  ary = rb_ary_new2(ca->dim[0]);
  ca_attach(ca);
  rb_ca_to_a_loop(self, 0, idx, ary);
  ca_detach(ca);
  return ary;
}

#to_caObject

(Copy) Creates CArray object from self with same contents includes mask state.



49
50
51
52
53
54
55
56
57
58
# File 'ext/carray_copy.c', line 49

VALUE
rb_ca_copy (VALUE self)
{
  volatile VALUE obj;
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  obj = ca_wrap_struct(ca_copy(ca));
  rb_ca_data_type_inherit(obj, self);
  return obj;
}

#to_sObject

(Conversion) Dumps the value array to a string.



190
191
192
193
194
# File 'ext/carray_conversion.c', line 190

static VALUE
rb_ca_to_s (VALUE self)
{
  return rb_ca_dump_binary(0, NULL, self);
}

#to_type(data_type, bytes: nil) ⇒ Object

(Conversion) Returns an array of elements that are converted to the given data type from the object.



288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
# File 'ext/carray_cast.c', line 288

static VALUE
rb_ca_to_type_internal (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE obj, rtype = Qnil, ropt, rbytes = Qnil;
  CArray *ca, *cb;
  int8_t data_type;
  ca_size_t bytes;

  Data_Get_Struct(self, CArray, ca);

  rb_scan_args(argc, argv, "11", (VALUE *) &rtype, (VALUE *) &ropt);
  rb_scan_options(ropt, "bytes", &rbytes);

  rb_ca_guess_type_and_bytes(rtype, rbytes, &data_type, &bytes);

  if ( rb_ca_has_data_class(self) && data_type == CA_OBJECT ) {
    return rb_ca_data_class_to_object(self);
  }

  if ( rb_ca_is_object_type(self) && rb_obj_is_data_class(rtype) ) {
    return rb_ca_object_to_data_class(self, rtype, bytes);
  }

  ca_update_mask(ca);

  if ( ca_is_scalar(ca) ) {
    obj = rb_cscalar_new(data_type, bytes, ca->mask);
  }
  else {
    obj = rb_carray_new(data_type, ca->ndim, ca->dim, bytes, ca->mask);
  }

  rb_ca_data_type_import(obj, rtype);

  Data_Get_Struct(obj, CArray, cb);

  ca_attach(ca);
  if ( ca_has_mask(ca) ) {
    ca_cast_block_with_mask(cb->elements, ca, ca->ptr, cb, cb->ptr, 
                            (boolean8_t*)ca->mask->ptr);
  }
  else {
    ca_cast_block(cb->elements, ca, ca->ptr, cb, cb->ptr);
  }
  ca_detach(ca);

  return obj;
}

#trim(min, max, fill_value = nil) ⇒ Object

(Conversion) Trims the data into the range between min and max. If fill_value is given, the element out of the range between min and max is filled by fill_value



745
746
747
748
749
750
# File 'ext/carray_generate.c', line 745

static VALUE
rb_ca_trim (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE out = rb_ca_copy(self);
  return rb_ca_trim_bang(argc, argv, out);
}

#trim!(min, max, fill_value = nil) ⇒ Object

(Conversion) Trims the data into the range between min and max. If fill_value is given, the element out of the range between min and max is filled by fill_value



697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
# File 'ext/carray_generate.c', line 697

static VALUE
rb_ca_trim_bang (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE rmin, rmax, rfval;
  CArray *ca;

  rb_ca_modify(self);

  Data_Get_Struct(self, CArray, ca);

  rb_scan_args(argc, argv, "21", (VALUE *) &rmin, (VALUE *) &rmax, (VALUE *) &rfval);

  if ( rfval == CA_UNDEF ) {
    ca_create_mask(ca);
  }

  ca_attach(ca);

  switch ( ca->data_type ) {
  case CA_INT8:     proc_trim_bang(int8_t,    NUM2INT);  break;
  case CA_UINT8:    proc_trim_bang(uint8_t,   NUM2UINT); break;
  case CA_INT16:    proc_trim_bang(int16_t,    NUM2INT);  break;
  case CA_UINT16:   proc_trim_bang(uint16_t,  NUM2INT);  break;
  case CA_INT32:    proc_trim_bang(int32_t,    NUM2LONG);  break;
  case CA_UINT32:   proc_trim_bang(uint32_t,  NUM2LONG);  break;
  case CA_INT64:    proc_trim_bang(int64_t,    NUM2LONG);  break;
  case CA_UINT64:   proc_trim_bang(uint64_t,  NUM2LONG);  break;
  case CA_FLOAT32:  proc_trim_bang(float32_t,  NUM2DBL);   break;
  case CA_FLOAT64:  proc_trim_bang(float64_t,  NUM2DBL);   break;
  case CA_FLOAT128: proc_trim_bang(float128_t, NUM2DBL);   break;
  default:
    rb_raise(rb_eCADataTypeError,
             "can not trim for non-numeric or complex data type");
  }

  ca_detach(ca);

  return self;
}

#uint16Object

(Conversion) Short-Hand of "CArray#to_type(:uint16)"



408
409
410
411
# File 'ext/carray_cast.c', line 408

VALUE rb_ca_to_uint16 (VALUE self)
{
  rb_ca_to_type_method_body(CA_UINT16);
}

#uint32Object

(Conversion) Short-Hand of "CArray#to_type(:uint32)"



426
427
428
429
# File 'ext/carray_cast.c', line 426

VALUE rb_ca_to_uint32 (VALUE self)
{
  rb_ca_to_type_method_body(CA_UINT32);
}

#uint64Object

(Conversion) Short-Hand of "CArray#to_type(:uint64)"



444
445
446
447
# File 'ext/carray_cast.c', line 444

VALUE rb_ca_to_uint64 (VALUE self)
{
  rb_ca_to_type_method_body(CA_UINT64);
}

#uint8Object Also known as: byte

(Conversion) Short-Hand of "CArray#to_type(:uint8)"



390
391
392
393
# File 'ext/carray_cast.c', line 390

VALUE rb_ca_to_uint8 (VALUE self)
{
  rb_ca_to_type_method_body(CA_UINT8);
}

#unmask(fill_value = nil) ⇒ Object

(Masking, Destructive) Unmask all elements of the object. If the optional argument fill_value is given, the masked elements are filled by fill_value. The returned array doesn't have the mask array.



870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
# File 'ext/carray_mask.c', line 870

static VALUE
rb_ca_unmask_method (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE rfval = CA_NIL, rcs;
  CArray *ca;
  CScalar *cv;
  char *fval = NULL;

  rb_ca_modify(self);

  if ( argc >= 1 ) {
    rfval = argv[0];
  }

  Data_Get_Struct(self, CArray, ca);

  if ( rfval != CA_NIL ) {
    rcs = rb_cscalar_new_with_value(ca->data_type, ca->bytes, rfval);
    Data_Get_Struct(rcs, CScalar, cv);
    fval = cv->ptr;
  }

  ca_unmask(ca, fval);

  return self;
}

#unmask_copy(fill_value = nil) ⇒ Object

(Masking, Conversion) Returns new unmasked array. If the optional argument fill_value is given, the masked elements are filled by fill_value. The returned array doesn't have the mask array.



922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
# File 'ext/carray_mask.c', line 922

static VALUE
rb_ca_unmask_copy_method (int argc, VALUE *argv, VALUE self)
{
  volatile VALUE obj, rfval = CA_NIL, rcs;
  CArray *ca, *co;
  CScalar *cv;
  char *fval = NULL;

  if ( argc >= 1 ) {
    rfval = argv[0];
  }

  Data_Get_Struct(self, CArray, ca);

  if ( rfval != CA_NIL ) {
    rcs = rb_cscalar_new_with_value(ca->data_type, ca->bytes, rfval);
    Data_Get_Struct(rcs, CScalar, cv);
    fval = cv->ptr;
  }

  co = ca_unmask_copy(ca, fval);
  obj = ca_wrap_struct(co);
  rb_ca_data_type_inherit(obj, self);
  return obj;
}

#unset(*idx) ⇒ Object

(Boolean, Modification) Sets false at the given index for the boolean array and returns self. It accept the arguments same as for CArray#[].



42
43
44
45
46
47
48
49
50
51
52
# File 'ext/carray_generate.c', line 42

static VALUE
rb_ca_boolean_unset (int argc, VALUE *argv, VALUE self)
{
  VALUE zero = INT2NUM(0);
  rb_ca_modify(self);
  if ( ! rb_ca_is_boolean_type(self) ) {
    rb_raise(rb_eCADataTypeError, "reciever should be a boolean array");
  }
  rb_ca_store2(self, argc, argv, zero);
  return self;
}

#unsigned?Boolean

(Inquiry) Return true if self is unsigned integer type array

Returns:



498
499
500
501
502
503
504
# File 'ext/carray_attribute.c', line 498

VALUE
rb_ca_is_unsigned_type (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ca_is_unsigned_type(ca) ? Qtrue : Qfalse;
}

#valid_addr?(*addr) ⇒ Boolean

(Inquiry) Returns true if the given number is valid as array address for the object

Returns:



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'ext/carray_test.c', line 267

static VALUE
rb_ca_is_valid_addr (VALUE self, VALUE raddr)
{
  CArray *ca;
  ca_size_t addr;

  Data_Get_Struct(self, CArray, ca);
  addr = NUM2SIZE(raddr);
	/*
  if ( addr < 0 ) {
    addr += ca->elements;
  }
	*/
  if ( addr < 0 || addr >= ca->elements ) {
    return Qfalse;
  }
  else {
    return Qtrue;
  }
}

#valid_index?(*idx) ⇒ Boolean

(Inquiry) Returns true if the given number list is valid as array index for the object

Returns:



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'ext/carray_test.c', line 233

static VALUE
rb_ca_is_valid_index (int argc, VALUE *argv, VALUE self)
{
  CArray *ca;
  ca_size_t idx;
  int i;

  Data_Get_Struct(self, CArray, ca);

  if ( argc != ca->ndim ) {
    rb_raise(rb_eArgError,
             "invalid # of arguments (%i for %i)", argc, ca->ndim);
  }
  for (i=0; i<ca->ndim; i++) {
    idx = NUM2SIZE(argv[i]);
		/*
    if ( idx < 0 ) {
      idx += ca->dim[i];
    }
		*/
    if ( idx < 0 || idx >= ca->dim[i] ) {
      return Qfalse;
    }
  }

  return Qtrue;
}

#valueObject

(Masking, Inquiry) Returns new array which refers the data of self. The data of masked elements of self can be accessed via the returned array. The value array can't be set mask.



649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
# File 'ext/carray_mask.c', line 649

VALUE
rb_ca_value_array (VALUE self)
{
  VALUE obj;
  CArray *ca, *co;

  Data_Get_Struct(self, CArray, ca);

  obj = rb_ca_refer_new(self, ca->data_type, ca->ndim, ca->dim, ca->bytes, 0);
  Data_Get_Struct(obj, CArray, co);

  ca_set_flag(co, CA_FLAG_VALUE_ARRAY);

  return obj;
}

#value_array?Boolean

(Inquiry) Returns true if self is a value array

Returns:



378
379
380
381
382
383
384
# File 'ext/carray_attribute.c', line 378

VALUE
rb_ca_is_value_array (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ( ca_is_value_array(ca) ) ? Qtrue : Qfalse;
}

#vectorized_fetch_linear_addrObject



1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
# File 'ext/carray_order.c', line 1343

static VALUE
rb_ca_fetch_linear_addr_vectorized (volatile VALUE self, volatile VALUE vx)
{
  volatile VALUE out, out0;
  CArray *ca, *sc, *cx, *co0, *co;
  double *x;
  double *px;
  double *po;
  ca_size_t nseri, nlist, nreq, xnseri;
  ca_size_t i, k;
  boolean8_t *mx, *mo;

  Data_Get_Struct(self, CArray, ca);

  if ( rb_ca_is_any_masked(self) ) {
    rb_raise(rb_eRuntimeError, "self should not have any masked elements");
  }

  sc = ca_wrap_readonly(self, CA_FLOAT64);
  cx = ca_wrap_readonly(vx, CA_FLOAT64);

  if ( sc->ndim < 2 ) {
    rb_raise(rb_eRuntimeError, "ndim of self should be larger than 2");
  }

  nseri = 1;
  for (i=0; i<sc->ndim-1; i++) {
		nseri *= sc->dim[i];
	}
	nlist = sc->dim[sc->ndim-1];

  if ( cx->ndim < sc->ndim - 1 ) {
    rb_raise(rb_eRuntimeError, "ndim of first argument should be larger than (ndim - 1) of self");  	
  }

	xnseri = 1;
  for (i=0; i<sc->ndim-1; i++) {
		xnseri *= cx->dim[i];
	}
	
	if ( xnseri != nseri ) {
    rb_raise(rb_eRuntimeError, "1st dimension should be same between self and 1st argument");  			
	}

	if ( cx->ndim == sc->ndim - 1 ) {
		nreq = 1;
	}
	else {
	  nreq = cx->dim[cx->ndim-1];
	}

  co0 = carray_new(ca->data_type, cx->ndim, cx->dim, 0, NULL);
  out = out0 = ca_wrap_struct(co0);
  co = ca_wrap_writable(out, CA_FLOAT64);

  ca_attach_n(3, sc, cx, co);

  x  = (double*) sc->ptr;
  px = (double*) cx->ptr;
  po = (double*) co->ptr;

  ca_create_mask(co);
  ca_update_mask(cx);

  if ( cx->mask ) {
    mx = (boolean8_t *) cx->mask->ptr;
    mo = (boolean8_t *) co->mask->ptr;
		for (k=0; k<nseri; k++) {
	    for (i=0; i<nreq; i++) {
	      if ( ! *mx ) {
	        if ( fetch_linear_addr(nlist, x, *px, po) ) {
	        	*mo = 1;
	        }
	      }
	      else {
	        *mo = 1;
	      }
	      mx++; mo++; px++, po++;
	    }
			x += nlist;
    }		
  }
  else {
    mo = (boolean8_t *) co->mask->ptr;
		for (k=0; k<nseri; k++) {
	    for (i=0; i<nreq; i++) {
        if ( fetch_linear_addr(nlist, x, *px, po) ) {
        	*mo = 1;
        }
	      mo++; px++; po++; 
	    }
			x += nlist;
		}
  }

  ca_sync(co);
  ca_detach_n(3, sc, cx, co);

  return out0;		
}

#vectorized_find_linear_addrObject

self: ndim >= 2 0...ndim : prev dimensions are vectorized elements -1: last dimension is used for fetch_addr (as self)

vx: ndim >= 2 0...ndim : prev dimensions are vectorized elements should be equal to self's -1: last dimension is used for fetch_addr (as addr)



1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
# File 'ext/carray_order.c', line 1241

static VALUE
rb_ca_find_linear_addr_vectorized (volatile VALUE self, volatile VALUE vx)
{
  volatile VALUE out, out0;
  CArray *ca, *sc, *cx, *co0, *co;
  double *x;
  double *px;
  double *po;
  ca_size_t nseri, nlist, nreq, xnseri;
  ca_size_t i, k;
  boolean8_t *mx, *mo;

  Data_Get_Struct(self, CArray, ca);

  if ( rb_ca_is_any_masked(self) ) {
    rb_raise(rb_eRuntimeError, "self should not have any masked elements");
  }

  sc = ca_wrap_readonly(self, CA_FLOAT64);
  cx = ca_wrap_readonly(vx, CA_FLOAT64);

  if ( sc->ndim < 2 ) {
    rb_raise(rb_eRuntimeError, "ndim of self should be larger than 2");
  }

  nseri = 1;
  for (i=0; i<sc->ndim-1; i++) {
		nseri *= sc->dim[i];
	}
	nlist = sc->dim[sc->ndim-1];

  if ( cx->ndim < sc->ndim - 1 ) {
    rb_raise(rb_eRuntimeError, "ndim of first argument should be larger than (ndim - 1) of self");  	
  }

	xnseri = 1;
  for (i=0; i<sc->ndim-1; i++) {
		xnseri *= cx->dim[i];
	}
	
	if ( xnseri != nseri ) {
    rb_raise(rb_eRuntimeError, "1st dimension should be same between self and 1st argument");  			
	}

	if ( cx->ndim == sc->ndim - 1 ) {
		nreq = 1;
	}
	else {
	  nreq = cx->dim[cx->ndim-1];
	}

  co0 = carray_new(ca->data_type, cx->ndim, cx->dim, 0, NULL);
  out = out0 = ca_wrap_struct(co0);
  co = ca_wrap_writable(out, CA_FLOAT64);

  ca_attach_n(3, sc, cx, co);

  x  = (double*) sc->ptr;
  px = (double*) cx->ptr;
  po = (double*) co->ptr;

  ca_create_mask(co);
  ca_update_mask(cx);

  if ( cx->mask ) {
    mx = (boolean8_t *) cx->mask->ptr;
    mo = (boolean8_t *) co->mask->ptr;
		for (k=0; k<nseri; k++) {
	    for (i=0; i<nreq; i++) {
	      if ( ! *mx ) {
		      if ( linear_index(nlist, x, *px, po) ) {
	        	*mo = 1;
	        }
	      }
	      else {
	        *mo = 1;
	      }
	      mx++; mo++; px++, po++;
	    }
			x += nlist;
    }		
  }
  else {
    mo = (boolean8_t *) co->mask->ptr;
		for (k=0; k<nseri; k++) {
	    for (i=0; i<nreq; i++) {
	      if ( linear_index(nlist, x, *px, po) ) {
        	*mo = 1;
        }
	      mo++; px++; po++; 
	    }
			x += nlist;
		}
  }

  ca_sync(co);
  ca_detach_n(3, sc, cx, co);

  return out0;		
}

#vectorized_sectionObject



1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
# File 'ext/carray_order.c', line 1028

static VALUE
rb_ca_binary_search_linear_index_vectorized (volatile VALUE self, volatile VALUE vx)
{
  volatile VALUE out, out0;
  CArray *ca, *sc, *cx, *co0, *co;
  double *x;
  double *px;
  double *po;
  ca_size_t nseri, nlist;
  ca_size_t odim[CA_DIM_MAX];
  ca_size_t i, k;

  Data_Get_Struct(self, CArray, ca);

  if ( rb_ca_is_any_masked(self) ) {
    rb_raise(rb_eRuntimeError, "self should not have any masked elements");
  }

  sc = ca_wrap_readonly(self, CA_FLOAT64);
  cx = ca_wrap_readonly(vx, CA_FLOAT64);

  if ( sc->ndim < 2 ) {
    rb_raise(rb_eRuntimeError, "ndim of self should be larger than 2");
  }

  if ( cx->ndim > CA_DIM_MAX ) {
     rb_raise(rb_eRuntimeError, "2nd argument carray has too large dimension");  	
  }

  nseri = 1;
  for (i=0; i<sc->ndim-1; i++) {
		nseri *= sc->dim[i];
	}
	nlist = sc->dim[sc->ndim-1];

  if ( rb_ca_is_scalar(vx) ) {
	  for (i=0; i<sc->ndim-1; i++) {
	    odim[i] = sc->dim[i];
		}
    co0 = carray_new(ca->data_type, sc->ndim-1, odim, 0, NULL);
	}
	else {
	  for (i=0; i<sc->ndim-1; i++) {
	    odim[i] = sc->dim[i];
		}
    memcpy(&odim[sc->ndim], cx->dim, cx->ndim*sizeof(ca_size_t));
    co0 = carray_new(ca->data_type, sc->ndim-1 + cx->ndim, odim, 0, NULL);
	}
	
  out = out0 = ca_wrap_struct(co0);
  co = ca_wrap_writable(out, CA_FLOAT64);

  ca_attach_n(3, sc, cx, co);

  x  = (double*) sc->ptr;
  po = (double*) co->ptr;

  ca_update_mask(cx);
  if ( cx->mask ) {
    boolean8_t *mx, *mo;
    ca_create_mask(co);
    mx = (boolean8_t *) cx->mask->ptr;
    mo = (boolean8_t *) co->mask->ptr;
		for (k=0; k<nseri; k++) {
		  px = (double*) cx->ptr;
	    for (i=0; i<cx->elements; i++) {
	      if ( ! *mx ) {
	        linear_index(nlist, x, *px, po);
	      }
	      else {
	        *mo = 1;
	      }
	      mx++; mo++; px++, po++;
	    }
			x += nlist;
    }		
  }
  else {
		for (k=0; k<nseri; k++) {
		  px = (double*) cx->ptr;
	    for (i=0; i<cx->elements; i++) {
	      linear_index(nlist, x, *px, po);
	      px++; po++;
	    }
			x += nlist;
		}
  }

  ca_sync(co);
  ca_detach_n(3, sc, cx, co);

  return out0;
}

#virtual?Boolean

(Inquiry) Returns true if self is a virtural array (not an entity array).

Returns:



249
250
251
252
253
254
255
# File 'ext/carray_attribute.c', line 249

VALUE
rb_ca_is_virtual (VALUE self)
{
  CArray *ca;
  Data_Get_Struct(self, CArray, ca);
  return ( ca_is_virtual(ca) ) ? Qtrue : Qfalse;
}

#whereObject

(Conversion) Returns the 1d index array for non-zero elements of self



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'ext/carray_generate.c', line 62

VALUE
rb_ca_where (VALUE self)
{
  volatile VALUE bool0, obj;
  CArray *ca, *co;
  boolean8_t *p, *m;
  ca_size_t *q;
  ca_size_t i, count;

  bool0 = ( ! rb_ca_is_boolean_type(self) ) ? rb_ca_to_boolean(self) : self;

  Data_Get_Struct(bool0, CArray, ca);

  ca_attach(ca);

  /* calculate elements of output array */
  p = (boolean8_t *) ca->ptr;
  m = ca_mask_ptr(ca);
  count = 0;
  if ( m ) {
    for (i=0; i<ca->elements; i++) {
      if ( ( ! *m ) && ( *p ) ) { count++; }    /* not-masked && true */
      m++; p++;
    }
  }
  else {
    for (i=0; i<ca->elements; i++) {
      if ( *p ) { count++; }                    /* true */ 
      p++;
    }
  }

  /* create output array */
  obj = rb_carray_new(CA_SIZE, 1, &count, 0, NULL);
  Data_Get_Struct(obj, CArray, co);

  /* store address which elements is true to output array */
  p = (boolean8_t *) ca->ptr;
  q = (ca_size_t *) co->ptr;
  m = ca_mask_ptr(ca);
  if ( m )  {
    for (i=0; i<ca->elements; i++) {  /* not-masked && true */
      if ( ( ! *m ) && ( *p ) ) { *q = i; q++; }
      m++; p++; 
    }
  }
  else {                              /* true */
    for (i=0; i<ca->elements; i++) {
      if ( *p ) { *q = i; q++; }
      p++;
    }
  }

  ca_detach(ca);

  return obj;
}