pnmatrix 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/ext/nmatrix/binary_format.txt +53 -0
  3. data/ext/nmatrix/data/complex.h +388 -0
  4. data/ext/nmatrix/data/data.cpp +274 -0
  5. data/ext/nmatrix/data/data.h +651 -0
  6. data/ext/nmatrix/data/meta.h +64 -0
  7. data/ext/nmatrix/data/ruby_object.h +386 -0
  8. data/ext/nmatrix/extconf.rb +70 -0
  9. data/ext/nmatrix/math/asum.h +99 -0
  10. data/ext/nmatrix/math/cblas_enums.h +36 -0
  11. data/ext/nmatrix/math/cblas_templates_core.h +507 -0
  12. data/ext/nmatrix/math/gemm.h +241 -0
  13. data/ext/nmatrix/math/gemv.h +178 -0
  14. data/ext/nmatrix/math/getrf.h +255 -0
  15. data/ext/nmatrix/math/getrs.h +121 -0
  16. data/ext/nmatrix/math/imax.h +82 -0
  17. data/ext/nmatrix/math/laswp.h +165 -0
  18. data/ext/nmatrix/math/long_dtype.h +62 -0
  19. data/ext/nmatrix/math/magnitude.h +54 -0
  20. data/ext/nmatrix/math/math.h +751 -0
  21. data/ext/nmatrix/math/nrm2.h +165 -0
  22. data/ext/nmatrix/math/rot.h +117 -0
  23. data/ext/nmatrix/math/rotg.h +106 -0
  24. data/ext/nmatrix/math/scal.h +71 -0
  25. data/ext/nmatrix/math/trsm.h +336 -0
  26. data/ext/nmatrix/math/util.h +162 -0
  27. data/ext/nmatrix/math.cpp +1368 -0
  28. data/ext/nmatrix/nm_memory.h +60 -0
  29. data/ext/nmatrix/nmatrix.cpp +285 -0
  30. data/ext/nmatrix/nmatrix.h +476 -0
  31. data/ext/nmatrix/ruby_constants.cpp +151 -0
  32. data/ext/nmatrix/ruby_constants.h +106 -0
  33. data/ext/nmatrix/ruby_nmatrix.c +3130 -0
  34. data/ext/nmatrix/storage/common.cpp +77 -0
  35. data/ext/nmatrix/storage/common.h +183 -0
  36. data/ext/nmatrix/storage/dense/dense.cpp +1096 -0
  37. data/ext/nmatrix/storage/dense/dense.h +129 -0
  38. data/ext/nmatrix/storage/list/list.cpp +1628 -0
  39. data/ext/nmatrix/storage/list/list.h +138 -0
  40. data/ext/nmatrix/storage/storage.cpp +730 -0
  41. data/ext/nmatrix/storage/storage.h +99 -0
  42. data/ext/nmatrix/storage/yale/class.h +1139 -0
  43. data/ext/nmatrix/storage/yale/iterators/base.h +143 -0
  44. data/ext/nmatrix/storage/yale/iterators/iterator.h +131 -0
  45. data/ext/nmatrix/storage/yale/iterators/row.h +450 -0
  46. data/ext/nmatrix/storage/yale/iterators/row_stored.h +140 -0
  47. data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +169 -0
  48. data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +124 -0
  49. data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
  50. data/ext/nmatrix/storage/yale/yale.cpp +2074 -0
  51. data/ext/nmatrix/storage/yale/yale.h +203 -0
  52. data/ext/nmatrix/types.h +55 -0
  53. data/ext/nmatrix/util/io.cpp +279 -0
  54. data/ext/nmatrix/util/io.h +115 -0
  55. data/ext/nmatrix/util/sl_list.cpp +627 -0
  56. data/ext/nmatrix/util/sl_list.h +144 -0
  57. data/ext/nmatrix/util/util.h +78 -0
  58. data/lib/nmatrix/blas.rb +378 -0
  59. data/lib/nmatrix/cruby/math.rb +744 -0
  60. data/lib/nmatrix/enumerate.rb +253 -0
  61. data/lib/nmatrix/homogeneous.rb +241 -0
  62. data/lib/nmatrix/io/fortran_format.rb +138 -0
  63. data/lib/nmatrix/io/harwell_boeing.rb +221 -0
  64. data/lib/nmatrix/io/market.rb +263 -0
  65. data/lib/nmatrix/io/point_cloud.rb +189 -0
  66. data/lib/nmatrix/jruby/decomposition.rb +24 -0
  67. data/lib/nmatrix/jruby/enumerable.rb +13 -0
  68. data/lib/nmatrix/jruby/error.rb +4 -0
  69. data/lib/nmatrix/jruby/math.rb +501 -0
  70. data/lib/nmatrix/jruby/nmatrix_java.rb +840 -0
  71. data/lib/nmatrix/jruby/operators.rb +283 -0
  72. data/lib/nmatrix/jruby/slice.rb +264 -0
  73. data/lib/nmatrix/lapack_core.rb +181 -0
  74. data/lib/nmatrix/lapack_plugin.rb +44 -0
  75. data/lib/nmatrix/math.rb +953 -0
  76. data/lib/nmatrix/mkmf.rb +100 -0
  77. data/lib/nmatrix/monkeys.rb +137 -0
  78. data/lib/nmatrix/nmatrix.rb +1172 -0
  79. data/lib/nmatrix/rspec.rb +75 -0
  80. data/lib/nmatrix/shortcuts.rb +1163 -0
  81. data/lib/nmatrix/version.rb +39 -0
  82. data/lib/nmatrix/yale_functions.rb +118 -0
  83. data/lib/nmatrix.rb +28 -0
  84. data/spec/00_nmatrix_spec.rb +892 -0
  85. data/spec/01_enum_spec.rb +196 -0
  86. data/spec/02_slice_spec.rb +407 -0
  87. data/spec/03_nmatrix_monkeys_spec.rb +80 -0
  88. data/spec/2x2_dense_double.mat +0 -0
  89. data/spec/4x4_sparse.mat +0 -0
  90. data/spec/4x5_dense.mat +0 -0
  91. data/spec/blas_spec.rb +215 -0
  92. data/spec/elementwise_spec.rb +311 -0
  93. data/spec/homogeneous_spec.rb +100 -0
  94. data/spec/io/fortran_format_spec.rb +88 -0
  95. data/spec/io/harwell_boeing_spec.rb +98 -0
  96. data/spec/io/test.rua +9 -0
  97. data/spec/io_spec.rb +159 -0
  98. data/spec/lapack_core_spec.rb +482 -0
  99. data/spec/leakcheck.rb +16 -0
  100. data/spec/math_spec.rb +1363 -0
  101. data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
  102. data/spec/nmatrix_yale_spec.rb +286 -0
  103. data/spec/rspec_monkeys.rb +56 -0
  104. data/spec/rspec_spec.rb +35 -0
  105. data/spec/shortcuts_spec.rb +474 -0
  106. data/spec/slice_set_spec.rb +162 -0
  107. data/spec/spec_helper.rb +172 -0
  108. data/spec/stat_spec.rb +214 -0
  109. data/spec/test.pcd +20 -0
  110. data/spec/utm5940.mtx +83844 -0
  111. metadata +295 -0
@@ -0,0 +1,203 @@
1
+ /////////////////////////////////////////////////////////////////////
2
+ // = NMatrix
3
+ //
4
+ // A linear algebra library for scientific computation in Ruby.
5
+ // NMatrix is part of SciRuby.
6
+ //
7
+ // NMatrix was originally inspired by and derived from NArray, by
8
+ // Masahiro Tanaka: http://narray.rubyforge.org
9
+ //
10
+ // == Copyright Information
11
+ //
12
+ // SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
13
+ // NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
14
+ //
15
+ // Please see LICENSE.txt for additional copyright notices.
16
+ //
17
+ // == Contributing
18
+ //
19
+ // By contributing source code to SciRuby, you agree to be bound by
20
+ // our Contributor Agreement:
21
+ //
22
+ // * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
23
+ //
24
+ // == yale.h
25
+ //
26
+ // "new yale" storage format for 2D matrices (like yale, but with
27
+ // the diagonal pulled out for O(1) access).
28
+ //
29
+ // Specifications:
30
+ // * dtype and index dtype must necessarily differ
31
+ // * index dtype is defined by whatever unsigned type can store
32
+ // max(rows,cols)
33
+ // * that means vector ija stores only index dtype, but a stores
34
+ // dtype
35
+ // * vectors must be able to grow as necessary
36
+ // * maximum size is rows*cols+1
37
+
38
+ #ifndef YALE_H
39
+ #define YALE_H
40
+
41
+ /*
42
+ * Standard Includes
43
+ */
44
+
45
+ #include <ruby.h>
46
+ #include <limits> // for std::numeric_limits<T>::max()
47
+ #include <stdexcept>
48
+
49
+ /*
50
+ * Project Includes
51
+ */
52
+
53
+ #include "../../types.h"
54
+ #include "../../data/data.h"
55
+ #include "../common.h"
56
+ #include "../../nmatrix.h"
57
+
58
+ extern "C" {
59
+
60
+ /*
61
+ * Macros
62
+ */
63
+
64
+ #ifndef NM_CHECK_ALLOC
65
+ #define NM_CHECK_ALLOC(x) if (!x) rb_raise(rb_eNoMemError, "insufficient memory");
66
+ #endif
67
+
68
+ /*
69
+ * Types
70
+ */
71
+
72
+
73
+ /*
74
+ * Data
75
+ */
76
+
77
+
78
+ /*
79
+ * Functions
80
+ */
81
+
82
+ ///////////////
83
+ // Lifecycle //
84
+ ///////////////
85
+
86
+ YALE_STORAGE* nm_yale_storage_create(nm::dtype_t dtype, size_t* shape, size_t dim, size_t init_capacity);
87
+ YALE_STORAGE* nm_yale_storage_create_from_old_yale(nm::dtype_t dtype, size_t* shape, char* ia, char* ja, char* a, nm::dtype_t from_dtype);
88
+ YALE_STORAGE* nm_yale_storage_create_merged(const YALE_STORAGE* merge_template, const YALE_STORAGE* other);
89
+ void nm_yale_storage_delete(STORAGE* s);
90
+ void nm_yale_storage_delete_ref(STORAGE* s);
91
+ void nm_yale_storage_init(YALE_STORAGE* s, void* default_val);
92
+ void nm_yale_storage_mark(STORAGE*);
93
+ void nm_yale_storage_register(const STORAGE* s);
94
+ void nm_yale_storage_unregister(const STORAGE* s);
95
+ void nm_yale_storage_register_a(void* a, size_t size);
96
+ void nm_yale_storage_unregister_a(void* a, size_t size);
97
+
98
+ ///////////////
99
+ // Accessors //
100
+ ///////////////
101
+
102
+ VALUE nm_yale_each_with_indices(VALUE nmatrix);
103
+ VALUE nm_yale_each_stored_with_indices(VALUE nmatrix);
104
+ VALUE nm_yale_stored_diagonal_each_with_indices(VALUE nmatrix);
105
+ VALUE nm_yale_stored_nondiagonal_each_with_indices(VALUE nmatrix);
106
+ VALUE nm_yale_each_ordered_stored_with_indices(VALUE nmatrix);
107
+ void* nm_yale_storage_get(const STORAGE* s, SLICE* slice);
108
+ void* nm_yale_storage_ref(const STORAGE* s, SLICE* slice);
109
+ void nm_yale_storage_set(VALUE left, SLICE* slice, VALUE right);
110
+
111
+ //char nm_yale_storage_vector_insert(YALE_STORAGE* s, size_t pos, size_t* js, void* vals, size_t n, bool struct_only, nm::dtype_t dtype, nm::itype_t itype);
112
+ //void nm_yale_storage_increment_ia_after(YALE_STORAGE* s, size_t ija_size, size_t i, size_t n);
113
+
114
+ size_t nm_yale_storage_get_size(const YALE_STORAGE* storage);
115
+ VALUE nm_yale_default_value(VALUE self);
116
+ VALUE nm_yale_map_stored(VALUE self);
117
+ VALUE nm_yale_map_merged_stored(VALUE left, VALUE right, VALUE init);
118
+
119
+ ///////////
120
+ // Tests //
121
+ ///////////
122
+
123
+ bool nm_yale_storage_eqeq(const STORAGE* left, const STORAGE* right);
124
+
125
+ //////////
126
+ // Math //
127
+ //////////
128
+
129
+ STORAGE* nm_yale_storage_matrix_multiply(const STORAGE_PAIR& casted_storage, size_t* resulting_shape, bool vector);
130
+
131
+ /////////////
132
+ // Utility //
133
+ /////////////
134
+
135
+
136
+
137
+ /////////////////////////
138
+ // Copying and Casting //
139
+ /////////////////////////
140
+
141
+ STORAGE* nm_yale_storage_cast_copy(const STORAGE* rhs, nm::dtype_t new_dtype, void*);
142
+ STORAGE* nm_yale_storage_copy_transposed(const STORAGE* rhs_base);
143
+
144
+
145
+
146
+ void nm_init_yale_functions(void);
147
+
148
+ VALUE nm_vector_set(int argc, VALUE* argv, VALUE self);
149
+
150
+
151
+ } // end of extern "C" block
152
+
153
+ namespace nm {
154
+
155
+ namespace yale_storage {
156
+
157
+ /*
158
+ * Typedefs
159
+ */
160
+
161
+ typedef size_t IType;
162
+
163
+
164
+ /*
165
+ * Templated Functions
166
+ */
167
+
168
+ int binary_search(YALE_STORAGE* s, IType left, IType right, IType key);
169
+
170
+ /*
171
+ * Clear out the D portion of the A vector (clearing the diagonal and setting
172
+ * the zero value).
173
+ *
174
+ * Note: This sets a literal 0 value. If your dtype is RUBYOBJ (a Ruby object),
175
+ * it'll actually be INT2FIX(0) instead of a string of NULLs. You can actually
176
+ * set a default for Ruby objects other than zero -- you generally want it to
177
+ * be Qfalse, Qnil, or INT2FIX(0). The last is the default.
178
+ */
179
+ template <typename DType>
180
+ inline void clear_diagonal_and_zero(YALE_STORAGE* s, void* init_val) {
181
+ DType* a = reinterpret_cast<DType*>(s->a);
182
+
183
+ // Clear out the diagonal + one extra entry
184
+ if (init_val) {
185
+ for (size_t i = 0; i <= s->shape[0]; ++i) // insert Ruby zeros, falses, or whatever else.
186
+ a[i] = *reinterpret_cast<DType*>(init_val);
187
+ } else {
188
+ for (size_t i = 0; i <= s->shape[0]; ++i) // insert zeros.
189
+ a[i] = 0;
190
+ }
191
+ }
192
+
193
+ template <typename DType>
194
+ void init(YALE_STORAGE* s, void* init_val);
195
+
196
+ size_t get_size(const YALE_STORAGE* storage);
197
+
198
+ IType binary_search_left_boundary(const YALE_STORAGE* s, IType left, IType right, IType bound);
199
+
200
+
201
+ }} // end of namespace nm::yale_storage
202
+
203
+ #endif // YALE_H
@@ -0,0 +1,55 @@
1
+ /////////////////////////////////////////////////////////////////////
2
+ // = NMatrix
3
+ //
4
+ // A linear algebra library for scientific computation in Ruby.
5
+ // NMatrix is part of SciRuby.
6
+ //
7
+ // NMatrix was originally inspired by and derived from NArray, by
8
+ // Masahiro Tanaka: http://narray.rubyforge.org
9
+ //
10
+ // == Copyright Information
11
+ //
12
+ // SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
13
+ // NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
14
+ //
15
+ // Please see LICENSE.txt for additional copyright notices.
16
+ //
17
+ // == Contributing
18
+ //
19
+ // By contributing source code to SciRuby, you agree to be bound by
20
+ // our Contributor Agreement:
21
+ //
22
+ // * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
23
+ //
24
+ // == types.h
25
+ //
26
+ // Definition of simple types used throughout NMatrix.
27
+
28
+ #ifndef NMATRIX_TYPES_H
29
+ #define NMATRIX_TYPES_H
30
+
31
+ /*
32
+ * Standard Includes
33
+ */
34
+
35
+ #include <ruby.h>
36
+ #include <cstdint>
37
+
38
+ /*
39
+ * Macros
40
+ */
41
+
42
+ #define EPSILON 1E-10
43
+ #define FP_IS_ZERO(n) (-EPSILON < n && n < EPSILON)
44
+ #define FP_EQUAL(a, b) FP_IS_ZERO((a - b))
45
+
46
+ /*
47
+ * Types
48
+ */
49
+
50
+ typedef float float32_t;
51
+ typedef double float64_t;
52
+
53
+ typedef size_t IType;
54
+
55
+ #endif
@@ -0,0 +1,279 @@
1
+ /////////////////////////////////////////////////////////////////////
2
+ // = NMatrix
3
+ //
4
+ // A linear algebra library for scientific computation in Ruby.
5
+ // NMatrix is part of SciRuby.
6
+ //
7
+ // NMatrix was originally inspired by and derived from NArray, by
8
+ // Masahiro Tanaka: http://narray.rubyforge.org
9
+ //
10
+ // == Copyright Information
11
+ //
12
+ // SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
13
+ // NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
14
+ //
15
+ // Please see LICENSE.txt for additional copyright notices.
16
+ //
17
+ // == Contributing
18
+ //
19
+ // By contributing source code to SciRuby, you agree to be bound by
20
+ // our Contributor Agreement:
21
+ //
22
+ // * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
23
+ //
24
+ // == io.cpp
25
+ //
26
+ // Input/output support functions.
27
+
28
+ #include "io.h"
29
+
30
+ #include <ruby.h>
31
+
32
+ namespace nm { namespace io {
33
+
34
+ const char* const MATLAB_DTYPE_NAMES[NUM_MATLAB_DTYPES] = {
35
+ "miUNDEFINED0",
36
+ "miINT8",
37
+ "miUINT8",
38
+ "miINT16",
39
+ "miUINT16",
40
+ "miINT32",
41
+ "miUINT32",
42
+ "miSINGLE",
43
+ "miRESERVED8",
44
+ "miDOUBLE",
45
+ "miRESERVED10",
46
+ "miRESERVED11",
47
+ "miINT64",
48
+ "miUINT64",
49
+ "miMATRIX"
50
+ };
51
+
52
+ const size_t MATLAB_DTYPE_SIZES[NUM_MATLAB_DTYPES] = {
53
+ 1, // undefined
54
+ 1, // int8
55
+ 1, // uint8
56
+ 2, // int16
57
+ 2, // uint16
58
+ 4, // int32
59
+ 4, // uint32
60
+ sizeof(float),
61
+ 1, // reserved
62
+ sizeof(double),
63
+ 1, // reserved
64
+ 1, // reserved
65
+ 8, // int64
66
+ 8, // uint64
67
+ 1 // matlab array?
68
+ };
69
+
70
+
71
+ /*
72
+ * Templated function for converting from MATLAB dtypes to NMatrix dtypes.
73
+ */
74
+ template <typename DType, typename MDType>
75
+ char* matlab_cstring_to_dtype_string(size_t& result_len, const char* str, size_t bytes) {
76
+
77
+ result_len = sizeof(DType) * bytes / sizeof(MDType);
78
+ char* result = NM_ALLOC_N(char, result_len);
79
+
80
+ if (bytes % sizeof(MDType) != 0) {
81
+ rb_raise(rb_eArgError, "the given string does not divide evenly for the given MATLAB dtype");
82
+ }
83
+
84
+ for (size_t i = 0, j = 0; i < bytes; i += sizeof(MDType), j += sizeof(DType)) {
85
+ *reinterpret_cast<DType*>(result+j) = (DType)(*reinterpret_cast<const MDType*>(str + i));
86
+ }
87
+
88
+ return result;
89
+ }
90
+
91
+
92
+
93
+ }} // end of namespace nm::io
94
+
95
+ extern "C" {
96
+
97
+ ///////////////////////
98
+ // Utility Functions //
99
+ ///////////////////////
100
+
101
+ /*
102
+ * Converts a string to a data type.
103
+ */
104
+ nm::dtype_t nm_dtype_from_rbstring(VALUE str) {
105
+
106
+ for (size_t index = 0; index < NM_NUM_DTYPES; ++index) {
107
+ if (!std::strncmp(RSTRING_PTR(str), DTYPE_NAMES[index], RSTRING_LEN(str))) {
108
+ return static_cast<nm::dtype_t>(index);
109
+ }
110
+ }
111
+
112
+ rb_raise(rb_eArgError, "invalid data type string (%s) specified", RSTRING_PTR(str));
113
+ }
114
+
115
+
116
+ /*
117
+ * Converts a symbol to a data type.
118
+ */
119
+ nm::dtype_t nm_dtype_from_rbsymbol(VALUE sym) {
120
+ ID sym_id = SYM2ID(sym);
121
+
122
+ for (size_t index = 0; index < NM_NUM_DTYPES; ++index) {
123
+ if (sym_id == rb_intern(DTYPE_NAMES[index])) {
124
+ return static_cast<nm::dtype_t>(index);
125
+ }
126
+ }
127
+
128
+ VALUE str = rb_any_to_s(sym);
129
+ rb_raise(rb_eArgError, "invalid data type symbol (:%s) specified", RSTRING_PTR(str));
130
+ }
131
+
132
+
133
+ /*
134
+ * Converts a string to a storage type. Only looks at the first three
135
+ * characters.
136
+ */
137
+ nm::stype_t nm_stype_from_rbstring(VALUE str) {
138
+
139
+ for (size_t index = 0; index < NM_NUM_STYPES; ++index) {
140
+ if (!std::strncmp(RSTRING_PTR(str), STYPE_NAMES[index], 3)) {
141
+ return static_cast<nm::stype_t>(index);
142
+ }
143
+ }
144
+
145
+ rb_raise(rb_eArgError, "Invalid storage type string specified");
146
+ return nm::DENSE_STORE;
147
+ }
148
+
149
+ /*
150
+ * Converts a symbol to a storage type.
151
+ */
152
+ nm::stype_t nm_stype_from_rbsymbol(VALUE sym) {
153
+
154
+ for (size_t index = 0; index < NM_NUM_STYPES; ++index) {
155
+ if (SYM2ID(sym) == rb_intern(STYPE_NAMES[index])) {
156
+ return static_cast<nm::stype_t>(index);
157
+ }
158
+ }
159
+
160
+ VALUE str = rb_any_to_s(sym);
161
+ rb_raise(rb_eArgError, "invalid storage type symbol (:%s) specified", RSTRING_PTR(str));
162
+ return nm::DENSE_STORE;
163
+ }
164
+
165
+
166
+ /*
167
+ * Converts a MATLAB data-type symbol to an enum.
168
+ */
169
+ static nm::io::matlab_dtype_t matlab_dtype_from_rbsymbol(VALUE sym) {
170
+ for (size_t index = 0; index < nm::io::NUM_MATLAB_DTYPES; ++index) {
171
+ if (SYM2ID(sym) == rb_intern(nm::io::MATLAB_DTYPE_NAMES[index])) {
172
+ return static_cast<nm::io::matlab_dtype_t>(index);
173
+ }
174
+ }
175
+
176
+ rb_raise(rb_eArgError, "Invalid matlab type specified.");
177
+ }
178
+
179
+
180
+ /*
181
+ * Take a string of bytes which represent MATLAB data type values and repack them into a string
182
+ * of bytes representing values of an NMatrix dtype (or itype).
183
+ *
184
+ * Returns what appears to be a Ruby String.
185
+ *
186
+ * Arguments:
187
+ * * str :: the data
188
+ * * from :: symbol representing MATLAB data type (e.g., :miINT8)
189
+ * * type :: either :itype or some dtype symbol (:byte, :uint32, etc)
190
+ */
191
+ static VALUE nm_rbstring_matlab_repack(VALUE self, VALUE str, VALUE from, VALUE type) {
192
+ nm::io::matlab_dtype_t from_type = matlab_dtype_from_rbsymbol(from);
193
+ uint8_t to_type;
194
+
195
+ if (SYMBOL_P(type)) {
196
+ if (rb_to_id(type) == rb_intern("itype")) {
197
+ if (sizeof(size_t) == sizeof(int64_t)) {
198
+ to_type = static_cast<int8_t>(nm::INT64);
199
+ } else if (sizeof(size_t) == sizeof(int32_t)) {
200
+ to_type = static_cast<int8_t>(nm::INT32);
201
+ } else if (sizeof(size_t) == sizeof(int16_t)) {
202
+ to_type = static_cast<int8_t>(nm::INT16);
203
+ } else {
204
+ rb_raise(rb_eStandardError, "unhandled size_t definition");
205
+ }
206
+ } else {
207
+ to_type = static_cast<uint8_t>(nm_dtype_from_rbsymbol(type));
208
+ }
209
+ } else {
210
+ rb_raise(rb_eArgError, "expected symbol for third argument");
211
+ }
212
+
213
+ // For next few lines, see explanation above NM_MATLAB_DTYPE_TEMPLATE_TABLE definition in io.h.
214
+ if (to_type >= static_cast<uint8_t>(nm::COMPLEX64)) {
215
+ rb_raise(rb_eArgError, "can only repack into a simple dtype, no complex/VALUE");
216
+ }
217
+
218
+ // Do the actual repacking -- really simple!
219
+ NM_MATLAB_DTYPE_TEMPLATE_TABLE(ttable, nm::io::matlab_cstring_to_dtype_string, char*, size_t& result_len, const char* str, size_t bytes);
220
+
221
+ size_t repacked_data_length;
222
+ char* repacked_data = ttable[to_type][from_type](repacked_data_length, RSTRING_PTR(str), RSTRING_LEN(str));
223
+
224
+ // Encode as 8-bit ASCII with a length -- don't want to hiccup on \0
225
+ VALUE result = rb_str_new(repacked_data, repacked_data_length);
226
+ NM_FREE(repacked_data); // Don't forget to free what we allocated!
227
+
228
+ return result;
229
+ }
230
+
231
+
232
+ /*
233
+ * Take two byte-strings (real and imaginary) and treat them as if they contain
234
+ * a sequence of data of type dtype. Merge them together and return a new string.
235
+ */
236
+ static VALUE nm_rbstring_merge(VALUE self, VALUE rb_real, VALUE rb_imaginary, VALUE rb_dtype) {
237
+
238
+ // Sanity check.
239
+ if (RSTRING_LEN(rb_real) != RSTRING_LEN(rb_imaginary)) {
240
+ rb_raise(rb_eArgError, "real and imaginary components do not have same length");
241
+ }
242
+
243
+ nm::dtype_t dtype = nm_dtype_from_rbsymbol(rb_dtype);
244
+ size_t len = DTYPE_SIZES[dtype];
245
+
246
+ char *real = RSTRING_PTR(rb_real),
247
+ *imag = RSTRING_PTR(rb_imaginary);
248
+
249
+ char* merge = NM_ALLOCA_N(char, RSTRING_LEN(rb_real)*2);
250
+
251
+ size_t merge_pos = 0;
252
+
253
+ // Merge the two sequences
254
+ for (size_t i = 0; i < (size_t)RSTRING_LEN(rb_real); i += len) {
255
+
256
+ // Copy real number
257
+ memcpy(merge + merge_pos, real + i, len);
258
+ merge_pos += len;
259
+
260
+ // Copy imaginary number
261
+ memcpy(merge + merge_pos, imag + i, len);
262
+ merge_pos += len;
263
+ }
264
+
265
+ return rb_str_new(merge, merge_pos);
266
+ }
267
+
268
+
269
+ void nm_init_io() {
270
+ cNMatrix_IO = rb_define_module_under(cNMatrix, "IO");
271
+ cNMatrix_IO_Matlab = rb_define_module_under(cNMatrix_IO, "Matlab");
272
+
273
+ rb_define_singleton_method(cNMatrix_IO_Matlab, "repack", (METHOD)nm_rbstring_matlab_repack, 3);
274
+ rb_define_singleton_method(cNMatrix_IO_Matlab, "complex_merge", (METHOD)nm_rbstring_merge, 3);
275
+ }
276
+
277
+
278
+
279
+ }
@@ -0,0 +1,115 @@
1
+ /////////////////////////////////////////////////////////////////////
2
+ // = NMatrix
3
+ //
4
+ // A linear algebra library for scientific computation in Ruby.
5
+ // NMatrix is part of SciRuby.
6
+ //
7
+ // NMatrix was originally inspired by and derived from NArray, by
8
+ // Masahiro Tanaka: http://narray.rubyforge.org
9
+ //
10
+ // == Copyright Information
11
+ //
12
+ // SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
13
+ // NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
14
+ //
15
+ // Please see LICENSE.txt for additional copyright notices.
16
+ //
17
+ // == Contributing
18
+ //
19
+ // By contributing source code to SciRuby, you agree to be bound by
20
+ // our Contributor Agreement:
21
+ //
22
+ // * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
23
+ //
24
+ // == io.h
25
+ //
26
+ // Header file for input/output support functions.
27
+
28
+ #ifndef NMATRIX_IO_H
29
+ #define NMATRIX_IO_H
30
+
31
+ /*
32
+ * Project Includes
33
+ */
34
+
35
+ #include "nmatrix.h"
36
+
37
+ #include "data/data.h"
38
+ #include "storage/storage.h"
39
+
40
+ /*
41
+ * Extern Types
42
+ */
43
+ extern const char* const DTYPE_NAMES[nm::NUM_DTYPES];
44
+
45
+ namespace nm { namespace io {
46
+ /*
47
+ * Types
48
+ */
49
+ enum matlab_dtype_t {
50
+ miINT8 = 1,
51
+ miUINT8 = 2,
52
+ miINT16 = 3,
53
+ miUINT16 = 4,
54
+ miINT32 = 5,
55
+ miUINT32 = 6,
56
+ miSINGLE = 7,
57
+ miDOUBLE = 9,
58
+ miINT64 = 12,
59
+ miUINT64 = 13,
60
+ miMATRIX = 14
61
+ };
62
+
63
+ /*
64
+ * Constants
65
+ */
66
+
67
+ const size_t NUM_MATLAB_DTYPES = 15;
68
+ }} // end of namespace nm::io
69
+
70
+ extern "C" {
71
+
72
+ /*
73
+ * C accessors.
74
+ */
75
+ nm::dtype_t nm_dtype_from_rbsymbol(VALUE sym);
76
+ nm::dtype_t nm_dtype_from_rbstring(VALUE str);
77
+ nm::stype_t nm_stype_from_rbsymbol(VALUE sym);
78
+ nm::stype_t nm_stype_from_rbstring(VALUE str);
79
+
80
+ void nm_init_io(void);
81
+
82
+
83
+ /*
84
+ * Macros.
85
+ */
86
+
87
+ /*
88
+ * Macro for a function pointer table between NMatrix dtypes and MATLAB dtypes.
89
+ *
90
+ * You can't convert as freely between these two as you can between NMatrix dtypes, but there's no reason to. MATLAB
91
+ * stores its complex numbers in two separate arrays, for example, not as a single unit of data. If you want to convert
92
+ * to a VALUE, convert first to an appropriate integer or float type.
93
+ *
94
+ * FIXME: Maybe be a little more selective about which conversions we DO allow. This is really just for loading an
95
+ * already-constructed MATLAB matrix into memory, and most of these functions will never get called.
96
+ */
97
+ #define NM_MATLAB_DTYPE_TEMPLATE_TABLE(name,fun,ret,...) \
98
+ static ret (*(name)[7][nm::io::NUM_MATLAB_DTYPES])(__VA_ARGS__) = { \
99
+ { NULL, fun<uint8_t,int8_t>, fun<uint8_t,uint8_t>, fun<uint8_t,int16_t>, fun<uint8_t,uint16_t>, fun<uint8_t,int32_t>, fun<uint8_t,uint32_t>, fun<uint8_t,float>, NULL, fun<uint8_t,double>, NULL, NULL, fun<uint8_t,int64_t>, fun<uint8_t,uint64_t>, NULL }, \
100
+ { NULL, fun<int8_t,int8_t>, fun<int8_t,uint8_t>, fun<int8_t,int16_t>, fun<int8_t,uint16_t>, fun<int8_t,int32_t>, fun<int8_t,uint32_t>, fun<int8_t,float>, NULL, fun<int8_t,double>, NULL, NULL, fun<int8_t,int64_t>, fun<int8_t,uint64_t>, NULL }, \
101
+ { NULL, fun<int16_t,int8_t>, fun<int16_t,uint8_t>, fun<int16_t,int16_t>, fun<int16_t,uint16_t>, fun<int16_t,int32_t>, fun<int16_t,uint32_t>, fun<int16_t,float>, NULL, fun<int16_t,double>, NULL, NULL, fun<int16_t,int64_t>, fun<int16_t,uint64_t>, NULL }, \
102
+ { NULL, fun<int32_t,int8_t>, fun<int32_t,uint8_t>, fun<int32_t,int16_t>, fun<int32_t,uint16_t>, fun<int32_t,int32_t>, fun<int32_t,uint32_t>, fun<int32_t,float>, NULL, fun<int32_t,double>, NULL, NULL, fun<int32_t,int64_t>, fun<int32_t,uint64_t>, NULL }, \
103
+ { NULL, fun<int64_t,int8_t>, fun<int64_t,uint8_t>, fun<int64_t,int16_t>, fun<int64_t,uint16_t>, fun<int64_t,int32_t>, fun<int64_t,uint32_t>, fun<int64_t,float>, NULL, fun<int64_t,double>, NULL, NULL, fun<int64_t,int64_t>, fun<int64_t,uint64_t>, NULL }, \
104
+ { NULL, fun<float,int8_t>, fun<float,uint8_t>, fun<float,int16_t>, fun<float,uint16_t>, fun<float,int32_t>, fun<float,uint32_t>, fun<float,float>, NULL, fun<float,double>, NULL, NULL, fun<float,int64_t>, fun<float,uint64_t>, NULL }, \
105
+ { NULL, fun<double,int8_t>, fun<double,uint8_t>, fun<double,int16_t>, fun<double,uint16_t>, fun<double,int32_t>, fun<double,uint32_t>, fun<double,float>, NULL, fun<double,double>, NULL, NULL, fun<double,int64_t>, fun<double,uint64_t>, NULL } \
106
+ };
107
+
108
+ /*
109
+ * Hash#has_key? for symbols. Arguments are: hash (VALUE), string (char*).
110
+ */
111
+ #define RB_HASH_HAS_SYMBOL_KEY(hash, str) (rb_funcall((hash), rb_intern("has_key?"), 1, ID2SYM(rb_intern(str))) == Qtrue)
112
+ }
113
+
114
+
115
+ #endif