pnmatrix 1.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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