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,476 @@
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
+ // == nmatrix.h
25
+ //
26
+ // C and C++ API for NMatrix, and main header file.
27
+
28
+ #ifndef NMATRIX_H
29
+ #define NMATRIX_H
30
+
31
+ /*
32
+ * Standard Includes
33
+ */
34
+
35
+ #include <ruby.h>
36
+ #include "ruby_constants.h"
37
+
38
+ #ifdef __cplusplus
39
+ #include <cmath>
40
+ #include <cstring>
41
+ #else
42
+ #include <math.h>
43
+ #include <string.h>
44
+ #endif
45
+
46
+ #ifdef BENCHMARK
47
+ // SOURCE: http://stackoverflow.com/questions/2349776/how-can-i-benchmark-a-c-program-easily
48
+ #ifdef __cplusplus
49
+ #include <sys/ctime>
50
+ #include <sys/cresource>
51
+ #else
52
+ #include <sys/time.h>
53
+ #include <sys/resource.h>
54
+ #endif
55
+ #endif
56
+
57
+ #ifdef __cplusplus
58
+ #include "nm_memory.h"
59
+ #endif
60
+
61
+ #ifndef RB_BUILTIN_TYPE
62
+ # define RB_BUILTIN_TYPE(obj) BUILTIN_TYPE(obj)
63
+ #endif
64
+
65
+ #ifndef RB_FLOAT_TYPE_P
66
+ /* NOTE: assume flonum doesn't exist */
67
+ # define RB_FLOAT_TYPE_P(obj) ( \
68
+ (!SPECIAL_CONST_P(obj) && BUILTIN_TYPE(obj) == T_FLOAT))
69
+ #endif
70
+
71
+ #ifndef RB_TYPE_P
72
+ # define RB_TYPE_P(obj, type) ( \
73
+ ((type) == T_FIXNUM) ? FIXNUM_P(obj) : \
74
+ ((type) == T_TRUE) ? ((obj) == Qtrue) : \
75
+ ((type) == T_FALSE) ? ((obj) == Qfalse) : \
76
+ ((type) == T_NIL) ? ((obj) == Qnil) : \
77
+ ((type) == T_UNDEF) ? ((obj) == Qundef) : \
78
+ ((type) == T_SYMBOL) ? SYMBOL_P(obj) : \
79
+ ((type) == T_FLOAT) ? RB_FLOAT_TYPE_P(obj) : \
80
+ (!SPECIAL_CONST_P(obj) && BUILTIN_TYPE(obj) == (type)))
81
+ #endif
82
+
83
+ #ifndef FIX_CONST_VALUE_PTR
84
+ # if defined(__fcc__) || defined(__fcc_version) || \
85
+ defined(__FCC__) || defined(__FCC_VERSION)
86
+ /* workaround for old version of Fujitsu C Compiler (fcc) */
87
+ # define FIX_CONST_VALUE_PTR(x) ((const VALUE *)(x))
88
+ # else
89
+ # define FIX_CONST_VALUE_PTR(x) (x)
90
+ # endif
91
+ #endif
92
+
93
+ #ifndef HAVE_RB_ARRAY_CONST_PTR
94
+ static inline const VALUE *
95
+ rb_array_const_ptr(VALUE a)
96
+ {
97
+ return FIX_CONST_VALUE_PTR((RBASIC(a)->flags & RARRAY_EMBED_FLAG) ?
98
+ RARRAY(a)->as.ary : RARRAY(a)->as.heap.ptr);
99
+ }
100
+ #endif
101
+
102
+ #ifndef RARRAY_CONST_PTR
103
+ # define RARRAY_CONST_PTR(a) rb_array_const_ptr(a)
104
+ #endif
105
+
106
+ #ifndef RARRAY_AREF
107
+ # define RARRAY_AREF(a, i) (RARRAY_CONST_PTR(a)[i])
108
+ #endif
109
+
110
+ /*
111
+ * Macros
112
+ */
113
+
114
+ #define RUBY_ZERO INT2FIX(0)
115
+
116
+ #ifndef SIZEOF_INT
117
+ #error SIZEOF_INT undefined
118
+ #else
119
+ #if SIZEOF_INT == 8
120
+ #define DEFAULT_DTYPE INT64
121
+ #define SIZE_T INT64
122
+ #else
123
+ #if SIZEOF_INT == 4
124
+ #define DEFAULT_DTYPE INT32
125
+ #define SIZE_T INT32
126
+ #else
127
+ #if SIZEOF_INT == 2
128
+ #define DEFAULT_DTYPE INT16
129
+ #define SIZE_T INT16
130
+ #else
131
+ #error Unhandled SIZEOF_INT -- please #define SIZE_T and DEFAULT_DTYPE manually.
132
+ #endif
133
+ #endif
134
+ #endif
135
+ #endif
136
+
137
+ /*
138
+ * == Macros for Concurrent C and C++ Header Maintenance
139
+ *
140
+ * These macros look complicated, but they're really not so bad. They're also important: they ensure that whether our
141
+ * header file (nmatrix.h) is read by a C++ or a C compiler, all the same data structures and enumerators exist, albeit
142
+ * with slightly different names.
143
+ *
144
+ * "But wait," you say, "You use structs. Structs exist in C and C++. Why use a macro to set them up?"
145
+ *
146
+ * Well, in C, you have to be explicit about what a struct is. You can actually get around that requirement by using a
147
+ * typedef:
148
+ *
149
+ * typedef struct STORAGE { ... } STORAGE;
150
+ *
151
+ * Also, we use C++ inheritance, which is obviously not allowed in C. So we have to ensure that the base class's members
152
+ * are exposed properly to our child classes.
153
+ *
154
+ * The macros also allow us to put all of our C++ types into namespaces. For C, we prefix everything with either nm_ or
155
+ * NM_ to distinguish our declarations from those in other libraries.
156
+ */
157
+
158
+
159
+ #ifdef __cplusplus /* These are the C++ versions of the macros. */
160
+
161
+ /*
162
+ * If no block is given, return an enumerator. This copied straight out of ruby's include/ruby/intern.h.
163
+ *
164
+ * rb_enumeratorize is located in enumerator.c.
165
+ *
166
+ * VALUE rb_enumeratorize(VALUE obj, VALUE meth, int argc, VALUE *argv) {
167
+ * return enumerator_init(enumerator_allocate(rb_cEnumerator), obj, meth, argc, argv);
168
+ * }
169
+ */
170
+
171
+ //opening portion -- this allows unregistering any objects in use before returning
172
+ #define RETURN_SIZED_ENUMERATOR_PRE do { \
173
+ if (!rb_block_given_p()) {
174
+
175
+ //remaining portion
176
+ #ifdef RUBY_2
177
+ #ifndef RETURN_SIZED_ENUMERATOR
178
+ #undef RETURN_SIZED_ENUMERATOR
179
+ // Ruby 2.0 and higher has rb_enumeratorize_with_size instead of rb_enumeratorize.
180
+ // We want to support both in the simplest way possible.
181
+ #define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) \
182
+ return rb_enumeratorize_with_size((obj), ID2SYM(rb_frame_this_func()), (argc), (argv), (size_fn)); \
183
+ } \
184
+ } while (0)
185
+ #endif
186
+ #else
187
+ #undef RETURN_SIZED_ENUMERATOR
188
+ #define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) \
189
+ return rb_enumeratorize((obj), ID2SYM(rb_frame_this_func()), (argc), (argv)); \
190
+ } \
191
+ } while (0)
192
+ #endif
193
+
194
+ #define NM_DECL_ENUM(enum_type, name) nm::enum_type name
195
+ #define NM_DECL_STRUCT(type, name) type name;
196
+
197
+ #define NM_DEF_STORAGE_ELEMENTS \
198
+ NM_DECL_ENUM(dtype_t, dtype); \
199
+ size_t dim; \
200
+ size_t* shape; \
201
+ size_t* offset; \
202
+ int count; \
203
+ STORAGE* src;
204
+
205
+ #define NM_DEF_STORAGE_CHILD_STRUCT_PRE(name) struct name : STORAGE {
206
+ #define NM_DEF_STORAGE_STRUCT_POST(name) };
207
+
208
+ #define NM_DEF_STORAGE_STRUCT \
209
+ struct STORAGE { \
210
+ NM_DEF_STORAGE_ELEMENTS; \
211
+ };
212
+
213
+ #define NM_DEF_STRUCT_PRE(name) struct name {
214
+ #define NM_DEF_STRUCT_POST(name) };
215
+
216
+ #define NM_DEF_ENUM(name, ...) \
217
+ namespace nm { \
218
+ enum name { \
219
+ __VA_ARGS__ \
220
+ }; \
221
+ } // end of namespace nm
222
+
223
+ #else /* These are the C versions of the macros. */
224
+
225
+ #define NM_DECL_ENUM(enum_type, name) nm_ ## enum_type name
226
+ #define NM_DECL_STRUCT(type, name) struct NM_ ## type name;
227
+
228
+ #define NM_DEF_STORAGE_ELEMENTS \
229
+ NM_DECL_ENUM(dtype_t, dtype); \
230
+ size_t dim; \
231
+ size_t* shape; \
232
+ size_t* offset; \
233
+ int count; \
234
+ NM_DECL_STRUCT(STORAGE*, src);
235
+ #define NM_DEF_STORAGE_CHILD_STRUCT_PRE(name) typedef struct NM_ ## name { \
236
+ NM_DEF_STORAGE_ELEMENTS;
237
+
238
+ #define NM_DEF_STORAGE_STRUCT_POST(name) } NM_ ## name;
239
+
240
+ #define NM_DEF_STORAGE_STRUCT \
241
+ typedef struct NM_STORAGE { \
242
+ NM_DEF_STORAGE_ELEMENTS; \
243
+ } NM_STORAGE;
244
+
245
+ #define NM_DEF_STRUCT_PRE(name) typedef struct NM_ ## name {
246
+ #define NM_DEF_STRUCT_POST(name) } NM_ ## name;
247
+
248
+ #define NM_DEF_ENUM(name, ...) \
249
+ typedef enum nm_ ## name { \
250
+ __VA_ARGS__ \
251
+ } nm_ ## name;
252
+
253
+ #endif /* End of C/C++ Parallel Header Macro Definitions */
254
+
255
+
256
+ /*
257
+ * Types
258
+ */
259
+
260
+ #define NM_NUM_DTYPES 10 // data/data.h
261
+ #define NM_NUM_STYPES 3 // storage/storage.h
262
+
263
+ //#ifdef __cplusplus
264
+ //namespace nm {
265
+ //#endif
266
+
267
+ /* Storage Type -- Dense or Sparse */
268
+ NM_DEF_ENUM(stype_t, DENSE_STORE = 0,
269
+ LIST_STORE = 1,
270
+ YALE_STORE = 2);
271
+
272
+ /* Data Type */
273
+ NM_DEF_ENUM(dtype_t, BYTE = 0, // unsigned char
274
+ INT8 = 1, // char
275
+ INT16 = 2, // short
276
+ INT32 = 3, // int
277
+ INT64 = 4, // long
278
+ FLOAT32 = 5, // float
279
+ FLOAT64 = 6, // double
280
+ COMPLEX64 = 7, // Complex64 class
281
+ COMPLEX128 = 8, // Complex128 class
282
+ RUBYOBJ = 9); // Ruby VALUE type
283
+
284
+ NM_DEF_ENUM(symm_t, NONSYMM = 0,
285
+ SYMM = 1,
286
+ SKEW = 2,
287
+ HERM = 3,
288
+ UPPER = 4,
289
+ LOWER = 5);
290
+
291
+ //#ifdef __cplusplus
292
+ //}; // end of namespace nm
293
+ //#endif
294
+
295
+ /* struct STORAGE */
296
+ NM_DEF_STORAGE_STRUCT;
297
+
298
+ /* Dense Storage */
299
+ NM_DEF_STORAGE_CHILD_STRUCT_PRE(DENSE_STORAGE); // struct DENSE_STORAGE : STORAGE {
300
+ void* elements; // should go first to align with void* a in yale and NODE* first in list.
301
+ size_t* stride;
302
+ NM_DEF_STORAGE_STRUCT_POST(DENSE_STORAGE); // };
303
+
304
+ /* Yale Storage */
305
+ NM_DEF_STORAGE_CHILD_STRUCT_PRE(YALE_STORAGE);
306
+ void* a; // should go first
307
+ size_t ndnz; // Strictly non-diagonal non-zero count!
308
+ size_t capacity;
309
+ size_t* ija;
310
+ NM_DEF_STORAGE_STRUCT_POST(YALE_STORAGE);
311
+
312
+ // FIXME: NODE and LIST should be put in some kind of namespace or something, at least in C++.
313
+ NM_DEF_STRUCT_PRE(NODE); // struct NODE {
314
+ size_t key;
315
+ void* val;
316
+ NM_DECL_STRUCT(NODE*, next); // NODE* next;
317
+ NM_DEF_STRUCT_POST(NODE); // };
318
+
319
+ NM_DEF_STRUCT_PRE(LIST); // struct LIST {
320
+ NM_DECL_STRUCT(NODE*, first); // NODE* first;
321
+ NM_DEF_STRUCT_POST(LIST); // };
322
+
323
+ /* List-of-Lists Storage */
324
+ NM_DEF_STORAGE_CHILD_STRUCT_PRE(LIST_STORAGE); // struct LIST_STORAGE : STORAGE {
325
+ // List storage specific elements.
326
+ void* default_val;
327
+ NM_DECL_STRUCT(LIST*, rows); // LIST* rows;
328
+ NM_DEF_STORAGE_STRUCT_POST(LIST_STORAGE); // };
329
+
330
+
331
+
332
+ /* NMATRIX Object */
333
+ NM_DEF_STRUCT_PRE(NMATRIX); // struct NMATRIX {
334
+ NM_DECL_ENUM(stype_t, stype); // stype_t stype; // Method of storage (csc, dense, etc).
335
+ NM_DECL_STRUCT(STORAGE*, storage); // STORAGE* storage; // Pointer to storage struct.
336
+ NM_DEF_STRUCT_POST(NMATRIX); // };
337
+
338
+ /* Structs for dealing with VALUEs in use so that they don't get GC'd */
339
+
340
+ NM_DEF_STRUCT_PRE(NM_GC_LL_NODE); // struct NM_GC_LL_NODE {
341
+ VALUE* val; // VALUE* val;
342
+ size_t n; // size_t n;
343
+ NM_DECL_STRUCT(NM_GC_LL_NODE*, next); // NM_GC_LL_NODE* next;
344
+ NM_DEF_STRUCT_POST(NM_GC_LL_NODE); // };
345
+
346
+ NM_DEF_STRUCT_PRE(NM_GC_HOLDER); // struct NM_GC_HOLDER {
347
+ NM_DECL_STRUCT(NM_GC_LL_NODE*, start); // NM_GC_LL_NODE* start;
348
+ NM_DEF_STRUCT_POST(NM_GC_HOLDER); // };
349
+
350
+ #define NM_MAX_RANK 15
351
+
352
+ #define UnwrapNMatrix(obj,var) Data_Get_Struct(obj, NMATRIX, var)
353
+
354
+ #define NM_STORAGE(val) (NM_STRUCT(val)->storage)
355
+ #ifdef __cplusplus
356
+ #define NM_STRUCT(val) ((NMATRIX*)(DATA_PTR(val)))
357
+ #define NM_STORAGE_LIST(val) ((LIST_STORAGE*)(NM_STORAGE(val)))
358
+ #define NM_STORAGE_YALE(val) ((YALE_STORAGE*)(NM_STORAGE(val)))
359
+ #define NM_STORAGE_DENSE(val) ((DENSE_STORAGE*)(NM_STORAGE(val)))
360
+ #else
361
+ #define NM_STRUCT(val) ((struct NM_NMATRIX*)(DATA_PTR(val)))
362
+ #define NM_STORAGE_LIST(val) ((struct NM_LIST_STORAGE*)(NM_STORAGE(val)))
363
+ #define NM_STORAGE_YALE(val) ((struct NM_YALE_STORAGE*)(NM_STORAGE(val)))
364
+ #define NM_STORAGE_DENSE(val) ((struct NM_DENSE_STORAGE*)(NM_STORAGE(val)))
365
+ #endif
366
+
367
+ #define NM_SRC(val) (NM_STORAGE(val)->src)
368
+ #define NM_DIM(val) (NM_STORAGE(val)->dim)
369
+
370
+ // Returns an int corresponding the data type of the nmatrix. See the dtype_t
371
+ // enum for a list of possible data types.
372
+ #define NM_DTYPE(val) (NM_STORAGE(val)->dtype)
373
+
374
+ // Returns a number corresponding the storage type of the nmatrix. See the stype_t
375
+ // enum for a list of possible storage types.
376
+ #define NM_STYPE(val) (NM_STRUCT(val)->stype)
377
+
378
+ // Get the shape of the ith dimension (int)
379
+ #define NM_SHAPE(val,i) (NM_STORAGE(val)->shape[(i)])
380
+
381
+ // Get the shape of the 0th dimension (int)
382
+ #define NM_SHAPE0(val) (NM_STORAGE(val)->shape[0])
383
+
384
+ // Get the shape of the 1st dimenension (int)
385
+ #define NM_SHAPE1(val) (NM_STORAGE(val)->shape[1])
386
+
387
+ // Get the default value assigned to the nmatrix.
388
+ #define NM_DEFAULT_VAL(val) (NM_STORAGE_LIST(val)->default_val)
389
+
390
+ // Number of elements in a dense nmatrix.
391
+ #define NM_DENSE_COUNT(val) (nm_storage_count_max_elements(NM_STORAGE_DENSE(val)))
392
+
393
+ // Get a pointer to the array that stores elements in a dense matrix.
394
+ #define NM_DENSE_ELEMENTS(val) (NM_STORAGE_DENSE(val)->elements)
395
+ #define NM_SIZEOF_DTYPE(val) (DTYPE_SIZES[NM_DTYPE(val)])
396
+ #define NM_REF(val,slice) (RefFuncs[NM_STYPE(val)]( NM_STORAGE(val), slice, NM_SIZEOF_DTYPE(val) ))
397
+
398
+ #define NM_MAX(a,b) (((a)>(b))?(a):(b))
399
+ #define NM_MIN(a,b) (((a)>(b))?(b):(a))
400
+ #define NM_SWAP(a,b,tmp) {(tmp)=(a);(a)=(b);(b)=(tmp);}
401
+
402
+ #define NM_CHECK_ALLOC(x) if (!x) rb_raise(rb_eNoMemError, "insufficient memory");
403
+
404
+ #define RB_FILE_EXISTS(fn) (rb_funcall(rb_const_get(rb_cObject, rb_intern("File")), rb_intern("exists?"), 1, (fn)) == Qtrue)
405
+
406
+ #define IsNMatrixType(v) (RB_TYPE_P(v, T_DATA) && (RDATA(v)->dfree == (RUBY_DATA_FUNC)nm_delete || RDATA(v)->dfree == (RUBY_DATA_FUNC)nm_delete_ref))
407
+ #define CheckNMatrixType(v) if (!IsNMatrixType(v)) rb_raise(rb_eTypeError, "expected NMatrix on left-hand side of operation");
408
+
409
+ #define NM_IsNMatrix(obj) \
410
+ (rb_obj_is_kind_of(obj, cNMatrix) == Qtrue)
411
+
412
+ #define NM_IsNVector(obj) \
413
+ (rb_obj_is_kind_of(obj, cNVector) == Qtrue)
414
+
415
+ #define RB_P(OBJ) \
416
+ rb_funcall(rb_stderr, rb_intern("print"), 1, rb_funcall(OBJ, rb_intern("object_id"), 0)); \
417
+ rb_funcall(rb_stderr, rb_intern("puts"), 1, rb_funcall(OBJ, rb_intern("inspect"), 0));
418
+
419
+
420
+ #ifdef __cplusplus
421
+ typedef VALUE (*METHOD)(...);
422
+
423
+ //}; // end of namespace nm
424
+ #endif
425
+
426
+ // In the init code below, we need to use NMATRIX for c++ and NM_NMATRIX for c
427
+ // this macro chooses the correct one:
428
+ #ifdef __cplusplus
429
+ #define _NMATRIX NMATRIX
430
+ #define _STORAGE STORAGE
431
+ #else
432
+ #define _NMATRIX NM_NMATRIX
433
+ #define _STORAGE NM_STORAGE
434
+ #endif
435
+
436
+ /*
437
+ * Functions
438
+ */
439
+
440
+ #ifdef __cplusplus
441
+ extern "C" {
442
+ #endif
443
+
444
+ void Init_nmatrix();
445
+ // External API
446
+ VALUE rb_nmatrix_dense_create(NM_DECL_ENUM(dtype_t, dtype), size_t* shape, size_t dim, void* elements, size_t length);
447
+ VALUE rb_nvector_dense_create(NM_DECL_ENUM(dtype_t, dtype), void* elements, size_t length);
448
+
449
+ NM_DECL_ENUM(dtype_t, nm_dtype_guess(VALUE)); // (This is a function)
450
+ NM_DECL_ENUM(dtype_t, nm_dtype_min(VALUE));
451
+
452
+ // Non-API functions needed by other cpp files.
453
+ _NMATRIX* nm_create(NM_DECL_ENUM(stype_t, stype), _STORAGE* storage);
454
+ _NMATRIX* nm_cast_with_ctype_args(_NMATRIX* self, NM_DECL_ENUM(stype_t, new_stype), NM_DECL_ENUM(dtype_t, new_dtype), void* init_ptr);
455
+ VALUE nm_cast(VALUE self, VALUE new_stype_symbol, VALUE new_dtype_symbol, VALUE init);
456
+ void nm_mark(_NMATRIX* mat);
457
+ void nm_delete(_NMATRIX* mat);
458
+ void nm_delete_ref(_NMATRIX* mat);
459
+ void nm_register_values(VALUE* vals, size_t n);
460
+ void nm_register_value(VALUE* val);
461
+ void nm_unregister_value(VALUE* val);
462
+ void nm_unregister_values(VALUE* vals, size_t n);
463
+ void nm_register_storage(NM_DECL_ENUM(stype_t, stype), const _STORAGE* storage);
464
+ void nm_unregister_storage(NM_DECL_ENUM(stype_t, stype), const _STORAGE* storage);
465
+ void nm_register_nmatrix(_NMATRIX* nmatrix);
466
+ void nm_unregister_nmatrix(_NMATRIX* nmatrix);
467
+ void nm_completely_unregister_value(VALUE* val);
468
+
469
+ #ifdef __cplusplus
470
+ }
471
+ #endif
472
+
473
+ #undef _NMATRIX
474
+ #undef _STORAGE
475
+
476
+ #endif // NMATRIX_H
@@ -0,0 +1,151 @@
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
+ // == ruby_symbols.cpp
25
+ //
26
+ // Ruby symbols used throught the NMatrix project.
27
+
28
+ /*
29
+ * Standard Includes
30
+ */
31
+
32
+ #include <ruby.h>
33
+
34
+ /*
35
+ * Global Variables
36
+ */
37
+
38
+ ID nm_rb_dtype,
39
+ nm_rb_stype,
40
+
41
+ nm_rb_capacity,
42
+ nm_rb_default,
43
+
44
+ nm_rb_real,
45
+ nm_rb_imag,
46
+
47
+ nm_rb_numer,
48
+ nm_rb_denom,
49
+
50
+ nm_rb_complex_conjugate,
51
+ nm_rb_transpose,
52
+ nm_rb_no_transpose,
53
+ nm_rb_left,
54
+ nm_rb_right,
55
+ nm_rb_upper,
56
+ nm_rb_lower,
57
+ nm_rb_unit,
58
+ nm_rb_nonunit,
59
+
60
+ nm_rb_dense,
61
+ nm_rb_list,
62
+ nm_rb_yale,
63
+
64
+ nm_rb_row,
65
+ nm_rb_column,
66
+ nm_rb_add,
67
+ nm_rb_sub,
68
+ nm_rb_mul,
69
+ nm_rb_div,
70
+ nm_rb_both,
71
+ nm_rb_none,
72
+
73
+ nm_rb_negate,
74
+
75
+ nm_rb_percent,
76
+ nm_rb_gt,
77
+ nm_rb_lt,
78
+ nm_rb_eql,
79
+ nm_rb_neql,
80
+ nm_rb_gte,
81
+ nm_rb_lte,
82
+
83
+ nm_rb_hash;
84
+
85
+ VALUE cNMatrix,
86
+ cNMatrix_IO,
87
+ cNMatrix_IO_Matlab,
88
+ cNMatrix_YaleFunctions,
89
+
90
+ cNMatrix_GC_holder,
91
+
92
+ nm_eDataTypeError,
93
+ nm_eConvergenceError,
94
+ nm_eStorageTypeError,
95
+ nm_eShapeError,
96
+ nm_eNotInvertibleError;
97
+
98
+ /*
99
+ * Functions
100
+ */
101
+
102
+ void nm_init_ruby_constants(void) {
103
+ nm_rb_dtype = rb_intern("dtype");
104
+ nm_rb_stype = rb_intern("stype");
105
+
106
+ nm_rb_capacity = rb_intern("capacity");
107
+ nm_rb_default = rb_intern("default");
108
+
109
+ nm_rb_real = rb_intern("real");
110
+ nm_rb_imag = rb_intern("imag");
111
+
112
+ nm_rb_numer = rb_intern("numerator");
113
+ nm_rb_denom = rb_intern("denominator");
114
+
115
+ nm_rb_complex_conjugate = rb_intern("complex_conjugate");
116
+ nm_rb_transpose = rb_intern("transpose");
117
+ nm_rb_no_transpose = rb_intern("no_transpose");
118
+
119
+ nm_rb_dense = rb_intern("dense");
120
+ nm_rb_list = rb_intern("list");
121
+ nm_rb_yale = rb_intern("yale");
122
+
123
+ nm_rb_add = rb_intern("+");
124
+ nm_rb_sub = rb_intern("-");
125
+ nm_rb_mul = rb_intern("*");
126
+ nm_rb_div = rb_intern("/");
127
+
128
+ nm_rb_negate = rb_intern("-@");
129
+
130
+ nm_rb_percent = rb_intern("%");
131
+ nm_rb_gt = rb_intern(">");
132
+ nm_rb_lt = rb_intern("<");
133
+ nm_rb_eql = rb_intern("==");
134
+ nm_rb_neql = rb_intern("!=");
135
+ nm_rb_gte = rb_intern(">=");
136
+ nm_rb_lte = rb_intern("<=");
137
+
138
+ nm_rb_left = rb_intern("left");
139
+ nm_rb_right = rb_intern("right");
140
+ nm_rb_upper = rb_intern("upper");
141
+ nm_rb_lower = rb_intern("lower");
142
+ nm_rb_unit = rb_intern("unit");
143
+ nm_rb_nonunit = rb_intern("nonunit");
144
+ nm_rb_hash = rb_intern("hash");
145
+
146
+ nm_rb_column = rb_intern("column");
147
+ nm_rb_row = rb_intern("row");
148
+
149
+ nm_rb_both = rb_intern("both");
150
+ nm_rb_none = rb_intern("none");
151
+ }