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,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
+ }