nmatrix-fftw 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/ext/nmatrix/data/complex.h +388 -0
  3. data/ext/nmatrix/data/data.h +652 -0
  4. data/ext/nmatrix/data/meta.h +64 -0
  5. data/ext/nmatrix/data/ruby_object.h +389 -0
  6. data/ext/nmatrix/math/asum.h +120 -0
  7. data/ext/nmatrix/math/cblas_enums.h +36 -0
  8. data/ext/nmatrix/math/cblas_templates_core.h +507 -0
  9. data/ext/nmatrix/math/gemm.h +241 -0
  10. data/ext/nmatrix/math/gemv.h +178 -0
  11. data/ext/nmatrix/math/getrf.h +255 -0
  12. data/ext/nmatrix/math/getrs.h +121 -0
  13. data/ext/nmatrix/math/imax.h +79 -0
  14. data/ext/nmatrix/math/laswp.h +165 -0
  15. data/ext/nmatrix/math/long_dtype.h +49 -0
  16. data/ext/nmatrix/math/math.h +745 -0
  17. data/ext/nmatrix/math/nrm2.h +160 -0
  18. data/ext/nmatrix/math/rot.h +117 -0
  19. data/ext/nmatrix/math/rotg.h +106 -0
  20. data/ext/nmatrix/math/scal.h +71 -0
  21. data/ext/nmatrix/math/trsm.h +332 -0
  22. data/ext/nmatrix/math/util.h +148 -0
  23. data/ext/nmatrix/nm_memory.h +60 -0
  24. data/ext/nmatrix/nmatrix.h +438 -0
  25. data/ext/nmatrix/ruby_constants.h +106 -0
  26. data/ext/nmatrix/storage/common.h +177 -0
  27. data/ext/nmatrix/storage/dense/dense.h +129 -0
  28. data/ext/nmatrix/storage/list/list.h +138 -0
  29. data/ext/nmatrix/storage/storage.h +99 -0
  30. data/ext/nmatrix/storage/yale/class.h +1139 -0
  31. data/ext/nmatrix/storage/yale/iterators/base.h +143 -0
  32. data/ext/nmatrix/storage/yale/iterators/iterator.h +131 -0
  33. data/ext/nmatrix/storage/yale/iterators/row.h +450 -0
  34. data/ext/nmatrix/storage/yale/iterators/row_stored.h +140 -0
  35. data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +169 -0
  36. data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +124 -0
  37. data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
  38. data/ext/nmatrix/storage/yale/yale.h +203 -0
  39. data/ext/nmatrix/types.h +55 -0
  40. data/ext/nmatrix/util/io.h +115 -0
  41. data/ext/nmatrix/util/sl_list.h +144 -0
  42. data/ext/nmatrix/util/util.h +78 -0
  43. data/ext/nmatrix_fftw/extconf.rb +122 -0
  44. data/ext/nmatrix_fftw/nmatrix_fftw.cpp +274 -0
  45. data/lib/nmatrix/fftw.rb +343 -0
  46. data/spec/00_nmatrix_spec.rb +736 -0
  47. data/spec/01_enum_spec.rb +190 -0
  48. data/spec/02_slice_spec.rb +389 -0
  49. data/spec/03_nmatrix_monkeys_spec.rb +78 -0
  50. data/spec/2x2_dense_double.mat +0 -0
  51. data/spec/4x4_sparse.mat +0 -0
  52. data/spec/4x5_dense.mat +0 -0
  53. data/spec/blas_spec.rb +193 -0
  54. data/spec/elementwise_spec.rb +303 -0
  55. data/spec/homogeneous_spec.rb +99 -0
  56. data/spec/io/fortran_format_spec.rb +88 -0
  57. data/spec/io/harwell_boeing_spec.rb +98 -0
  58. data/spec/io/test.rua +9 -0
  59. data/spec/io_spec.rb +149 -0
  60. data/spec/lapack_core_spec.rb +482 -0
  61. data/spec/leakcheck.rb +16 -0
  62. data/spec/math_spec.rb +807 -0
  63. data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
  64. data/spec/nmatrix_yale_spec.rb +286 -0
  65. data/spec/plugins/fftw/fftw_spec.rb +348 -0
  66. data/spec/rspec_monkeys.rb +56 -0
  67. data/spec/rspec_spec.rb +34 -0
  68. data/spec/shortcuts_spec.rb +310 -0
  69. data/spec/slice_set_spec.rb +157 -0
  70. data/spec/spec_helper.rb +149 -0
  71. data/spec/stat_spec.rb +203 -0
  72. data/spec/test.pcd +20 -0
  73. data/spec/utm5940.mtx +83844 -0
  74. metadata +151 -0
@@ -0,0 +1,60 @@
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
+ // == nm_memory.h
25
+ //
26
+ // Macros for memory allocation and freeing
27
+
28
+ /**
29
+ * We define these macros, which just call the ruby ones, as this makes
30
+ * debugging memory issues (particularly those involving interaction with
31
+ * the ruby GC) easier, as it's posssible to add debugging code temporarily.
32
+ */
33
+ #ifndef __NM_MEMORY_H__
34
+ #define __NM_MEMORY_H__
35
+
36
+ #include <ruby.h>
37
+
38
+ #define NM_ALLOC(type) (ALLOC(type))
39
+
40
+ #define NM_ALLOC_N(type, n) (ALLOC_N(type, n))
41
+
42
+ #define NM_REALLOC_N(var, type, n) (REALLOC_N(var, type, n))
43
+
44
+ #define NM_ALLOCA_N(type, n) (ALLOCA_N(type, n))
45
+
46
+ #define NM_FREE(var) (xfree(var))
47
+
48
+ #define NM_ALLOC_NONRUBY(type) ((type*) malloc(sizeof(type)))
49
+
50
+ //Defines whether to do conservative gc registrations, i.e. those
51
+ //registrations that we're not that sure are necessary.
52
+ //#define NM_GC_CONSERVATIVE
53
+
54
+ #ifdef NM_GC_CONSERVATIVE
55
+ #define NM_CONSERVATIVE(statement) (statement)
56
+ #else
57
+ #define NM_CONSERVATIVE(statement)
58
+ #endif //NM_GC_CONSERVATIVE
59
+
60
+ #endif
@@ -0,0 +1,438 @@
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
+
37
+ #ifdef __cplusplus
38
+ #include <cmath>
39
+ #include <cstring>
40
+ #else
41
+ #include <math.h>
42
+ #include <string.h>
43
+ #endif
44
+
45
+ #ifdef BENCHMARK
46
+ // SOURCE: http://stackoverflow.com/questions/2349776/how-can-i-benchmark-a-c-program-easily
47
+ #ifdef __cplusplus
48
+ #include <sys/ctime>
49
+ #include <sys/cresource>
50
+ #else
51
+ #include <sys/time.h>
52
+ #include <sys/resource.h>
53
+ #endif
54
+ #endif
55
+
56
+ #ifdef __cplusplus
57
+ #include "nm_memory.h"
58
+ #endif
59
+
60
+ #ifndef FIX_CONST_VALUE_PTR
61
+ # if defined(__fcc__) || defined(__fcc_version) || \
62
+ defined(__FCC__) || defined(__FCC_VERSION)
63
+ /* workaround for old version of Fujitsu C Compiler (fcc) */
64
+ # define FIX_CONST_VALUE_PTR(x) ((const VALUE *)(x))
65
+ # else
66
+ # define FIX_CONST_VALUE_PTR(x) (x)
67
+ # endif
68
+ #endif
69
+
70
+ #ifndef HAVE_RB_ARRAY_CONST_PTR
71
+ static inline const VALUE *
72
+ rb_array_const_ptr(VALUE a)
73
+ {
74
+ return FIX_CONST_VALUE_PTR((RBASIC(a)->flags & RARRAY_EMBED_FLAG) ?
75
+ RARRAY(a)->as.ary : RARRAY(a)->as.heap.ptr);
76
+ }
77
+ #endif
78
+
79
+ #ifndef RARRAY_CONST_PTR
80
+ # define RARRAY_CONST_PTR(a) rb_array_const_ptr(a)
81
+ #endif
82
+
83
+ #ifndef RARRAY_AREF
84
+ # define RARRAY_AREF(a, i) (RARRAY_CONST_PTR(a)[i])
85
+ #endif
86
+
87
+ /*
88
+ * Macros
89
+ */
90
+
91
+ #define RUBY_ZERO INT2FIX(0)
92
+
93
+ #ifndef SIZEOF_INT
94
+ #error SIZEOF_INT undefined
95
+ #else
96
+ #if SIZEOF_INT == 8
97
+ #define DEFAULT_DTYPE INT64
98
+ #define SIZE_T INT64
99
+ #else
100
+ #if SIZEOF_INT == 4
101
+ #define DEFAULT_DTYPE INT32
102
+ #define SIZE_T INT32
103
+ #else
104
+ #if SIZEOF_INT == 2
105
+ #define DEFAULT_DTYPE INT16
106
+ #define SIZE_T INT16
107
+ #else
108
+ #error Unhandled SIZEOF_INT -- please #define SIZE_T and DEFAULT_DTYPE manually.
109
+ #endif
110
+ #endif
111
+ #endif
112
+ #endif
113
+
114
+ /*
115
+ * == Macros for Concurrent C and C++ Header Maintenance
116
+ *
117
+ * These macros look complicated, but they're really not so bad. They're also important: they ensure that whether our
118
+ * header file (nmatrix.h) is read by a C++ or a C compiler, all the same data structures and enumerators exist, albeit
119
+ * with slightly different names.
120
+ *
121
+ * "But wait," you say, "You use structs. Structs exist in C and C++. Why use a macro to set them up?"
122
+ *
123
+ * Well, in C, you have to be explicit about what a struct is. You can actually get around that requirement by using a
124
+ * typedef:
125
+ *
126
+ * typedef struct STORAGE { ... } STORAGE;
127
+ *
128
+ * Also, we use C++ inheritance, which is obviously not allowed in C. So we have to ensure that the base class's members
129
+ * are exposed properly to our child classes.
130
+ *
131
+ * The macros also allow us to put all of our C++ types into namespaces. For C, we prefix everything with either nm_ or
132
+ * NM_ to distinguish our declarations from those in other libraries.
133
+ */
134
+
135
+
136
+ #ifdef __cplusplus /* These are the C++ versions of the macros. */
137
+
138
+ /*
139
+ * If no block is given, return an enumerator. This copied straight out of ruby's include/ruby/intern.h.
140
+ *
141
+ * rb_enumeratorize is located in enumerator.c.
142
+ *
143
+ * VALUE rb_enumeratorize(VALUE obj, VALUE meth, int argc, VALUE *argv) {
144
+ * return enumerator_init(enumerator_allocate(rb_cEnumerator), obj, meth, argc, argv);
145
+ * }
146
+ */
147
+
148
+ //opening portion -- this allows unregistering any objects in use before returning
149
+ #define RETURN_SIZED_ENUMERATOR_PRE do { \
150
+ if (!rb_block_given_p()) {
151
+
152
+ //remaining portion
153
+ #ifdef RUBY_2
154
+ #ifndef RETURN_SIZED_ENUMERATOR
155
+ #undef RETURN_SIZED_ENUMERATOR
156
+ // Ruby 2.0 and higher has rb_enumeratorize_with_size instead of rb_enumeratorize.
157
+ // We want to support both in the simplest way possible.
158
+ #define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) \
159
+ return rb_enumeratorize_with_size((obj), ID2SYM(rb_frame_this_func()), (argc), (argv), (size_fn)); \
160
+ } \
161
+ } while (0)
162
+ #endif
163
+ #else
164
+ #undef RETURN_SIZED_ENUMERATOR
165
+ #define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) \
166
+ return rb_enumeratorize((obj), ID2SYM(rb_frame_this_func()), (argc), (argv)); \
167
+ } \
168
+ } while (0)
169
+ #endif
170
+
171
+ #define NM_DECL_ENUM(enum_type, name) nm::enum_type name
172
+ #define NM_DECL_STRUCT(type, name) type name;
173
+
174
+ #define NM_DEF_STORAGE_ELEMENTS \
175
+ NM_DECL_ENUM(dtype_t, dtype); \
176
+ size_t dim; \
177
+ size_t* shape; \
178
+ size_t* offset; \
179
+ int count; \
180
+ STORAGE* src;
181
+
182
+ #define NM_DEF_STORAGE_CHILD_STRUCT_PRE(name) struct name : STORAGE {
183
+ #define NM_DEF_STORAGE_STRUCT_POST(name) };
184
+
185
+ #define NM_DEF_STORAGE_STRUCT \
186
+ struct STORAGE { \
187
+ NM_DEF_STORAGE_ELEMENTS; \
188
+ };
189
+
190
+ #define NM_DEF_STRUCT_PRE(name) struct name {
191
+ #define NM_DEF_STRUCT_POST(name) };
192
+
193
+ #define NM_DEF_ENUM(name, ...) \
194
+ namespace nm { \
195
+ enum name { \
196
+ __VA_ARGS__ \
197
+ }; \
198
+ } // end of namespace nm
199
+
200
+ #else /* These are the C versions of the macros. */
201
+
202
+ #define NM_DECL_ENUM(enum_type, name) nm_ ## enum_type name
203
+ #define NM_DECL_STRUCT(type, name) struct NM_ ## type name;
204
+
205
+ #define NM_DEF_STORAGE_ELEMENTS \
206
+ NM_DECL_ENUM(dtype_t, dtype); \
207
+ size_t dim; \
208
+ size_t* shape; \
209
+ size_t* offset; \
210
+ int count; \
211
+ NM_DECL_STRUCT(STORAGE*, src);
212
+ #define NM_DEF_STORAGE_CHILD_STRUCT_PRE(name) typedef struct NM_ ## name { \
213
+ NM_DEF_STORAGE_ELEMENTS;
214
+
215
+ #define NM_DEF_STORAGE_STRUCT_POST(name) } NM_ ## name;
216
+
217
+ #define NM_DEF_STORAGE_STRUCT \
218
+ typedef struct NM_STORAGE { \
219
+ NM_DEF_STORAGE_ELEMENTS; \
220
+ } NM_STORAGE;
221
+
222
+ #define NM_DEF_STRUCT_PRE(name) typedef struct NM_ ## name {
223
+ #define NM_DEF_STRUCT_POST(name) } NM_ ## name;
224
+
225
+ #define NM_DEF_ENUM(name, ...) \
226
+ typedef enum nm_ ## name { \
227
+ __VA_ARGS__ \
228
+ } nm_ ## name;
229
+
230
+ #endif /* End of C/C++ Parallel Header Macro Definitions */
231
+
232
+
233
+ /*
234
+ * Types
235
+ */
236
+
237
+ #define NM_NUM_DTYPES 10 // data/data.h
238
+ #define NM_NUM_STYPES 3 // storage/storage.h
239
+
240
+ //#ifdef __cplusplus
241
+ //namespace nm {
242
+ //#endif
243
+
244
+ /* Storage Type -- Dense or Sparse */
245
+ NM_DEF_ENUM(stype_t, DENSE_STORE = 0,
246
+ LIST_STORE = 1,
247
+ YALE_STORE = 2);
248
+
249
+ /* Data Type */
250
+ NM_DEF_ENUM(dtype_t, BYTE = 0, // unsigned char
251
+ INT8 = 1, // char
252
+ INT16 = 2, // short
253
+ INT32 = 3, // int
254
+ INT64 = 4, // long
255
+ FLOAT32 = 5, // float
256
+ FLOAT64 = 6, // double
257
+ COMPLEX64 = 7, // Complex64 class
258
+ COMPLEX128 = 8, // Complex128 class
259
+ RUBYOBJ = 9); // Ruby VALUE type
260
+
261
+ NM_DEF_ENUM(symm_t, NONSYMM = 0,
262
+ SYMM = 1,
263
+ SKEW = 2,
264
+ HERM = 3,
265
+ UPPER = 4,
266
+ LOWER = 5);
267
+
268
+ //#ifdef __cplusplus
269
+ //}; // end of namespace nm
270
+ //#endif
271
+
272
+ /* struct STORAGE */
273
+ NM_DEF_STORAGE_STRUCT;
274
+
275
+ /* Dense Storage */
276
+ NM_DEF_STORAGE_CHILD_STRUCT_PRE(DENSE_STORAGE); // struct DENSE_STORAGE : STORAGE {
277
+ void* elements; // should go first to align with void* a in yale and NODE* first in list.
278
+ size_t* stride;
279
+ NM_DEF_STORAGE_STRUCT_POST(DENSE_STORAGE); // };
280
+
281
+ /* Yale Storage */
282
+ NM_DEF_STORAGE_CHILD_STRUCT_PRE(YALE_STORAGE);
283
+ void* a; // should go first
284
+ size_t ndnz; // Strictly non-diagonal non-zero count!
285
+ size_t capacity;
286
+ size_t* ija;
287
+ NM_DEF_STORAGE_STRUCT_POST(YALE_STORAGE);
288
+
289
+ // FIXME: NODE and LIST should be put in some kind of namespace or something, at least in C++.
290
+ NM_DEF_STRUCT_PRE(NODE); // struct NODE {
291
+ size_t key;
292
+ void* val;
293
+ NM_DECL_STRUCT(NODE*, next); // NODE* next;
294
+ NM_DEF_STRUCT_POST(NODE); // };
295
+
296
+ NM_DEF_STRUCT_PRE(LIST); // struct LIST {
297
+ NM_DECL_STRUCT(NODE*, first); // NODE* first;
298
+ NM_DEF_STRUCT_POST(LIST); // };
299
+
300
+ /* List-of-Lists Storage */
301
+ NM_DEF_STORAGE_CHILD_STRUCT_PRE(LIST_STORAGE); // struct LIST_STORAGE : STORAGE {
302
+ // List storage specific elements.
303
+ void* default_val;
304
+ NM_DECL_STRUCT(LIST*, rows); // LIST* rows;
305
+ NM_DEF_STORAGE_STRUCT_POST(LIST_STORAGE); // };
306
+
307
+
308
+
309
+ /* NMATRIX Object */
310
+ NM_DEF_STRUCT_PRE(NMATRIX); // struct NMATRIX {
311
+ NM_DECL_ENUM(stype_t, stype); // stype_t stype; // Method of storage (csc, dense, etc).
312
+ NM_DECL_STRUCT(STORAGE*, storage); // STORAGE* storage; // Pointer to storage struct.
313
+ NM_DEF_STRUCT_POST(NMATRIX); // };
314
+
315
+ /* Structs for dealing with VALUEs in use so that they don't get GC'd */
316
+
317
+ NM_DEF_STRUCT_PRE(NM_GC_LL_NODE); // struct NM_GC_LL_NODE {
318
+ VALUE* val; // VALUE* val;
319
+ size_t n; // size_t n;
320
+ NM_DECL_STRUCT(NM_GC_LL_NODE*, next); // NM_GC_LL_NODE* next;
321
+ NM_DEF_STRUCT_POST(NM_GC_LL_NODE); // };
322
+
323
+ NM_DEF_STRUCT_PRE(NM_GC_HOLDER); // struct NM_GC_HOLDER {
324
+ NM_DECL_STRUCT(NM_GC_LL_NODE*, start); // NM_GC_LL_NODE* start;
325
+ NM_DEF_STRUCT_POST(NM_GC_HOLDER); // };
326
+
327
+ #define NM_MAX_RANK 15
328
+
329
+ #define UnwrapNMatrix(obj,var) Data_Get_Struct(obj, NMATRIX, var)
330
+
331
+ #define NM_STORAGE(val) (NM_STRUCT(val)->storage)
332
+ #ifdef __cplusplus
333
+ #define NM_STRUCT(val) ((NMATRIX*)(DATA_PTR(val)))
334
+ #define NM_STORAGE_LIST(val) ((LIST_STORAGE*)(NM_STORAGE(val)))
335
+ #define NM_STORAGE_YALE(val) ((YALE_STORAGE*)(NM_STORAGE(val)))
336
+ #define NM_STORAGE_DENSE(val) ((DENSE_STORAGE*)(NM_STORAGE(val)))
337
+ #else
338
+ #define NM_STRUCT(val) ((struct NM_NMATRIX*)(DATA_PTR(val)))
339
+ #define NM_STORAGE_LIST(val) ((struct NM_LIST_STORAGE*)(NM_STORAGE(val)))
340
+ #define NM_STORAGE_YALE(val) ((struct NM_YALE_STORAGE*)(NM_STORAGE(val)))
341
+ #define NM_STORAGE_DENSE(val) ((struct NM_DENSE_STORAGE*)(NM_STORAGE(val)))
342
+ #endif
343
+
344
+ #define NM_SRC(val) (NM_STORAGE(val)->src)
345
+ #define NM_DIM(val) (NM_STORAGE(val)->dim)
346
+ #define NM_DTYPE(val) (NM_STORAGE(val)->dtype)
347
+ #define NM_STYPE(val) (NM_STRUCT(val)->stype)
348
+ #define NM_SHAPE(val,i) (NM_STORAGE(val)->shape[(i)])
349
+ #define NM_SHAPE0(val) (NM_STORAGE(val)->shape[0])
350
+ #define NM_SHAPE1(val) (NM_STORAGE(val)->shape[1])
351
+ #define NM_DEFAULT_VAL(val) (NM_STORAGE_LIST(val)->default_val)
352
+
353
+ // Number of elements in a dense nmatrix.
354
+ #define NM_DENSE_COUNT(val) (nm_storage_count_max_elements(NM_STORAGE_DENSE(val)))
355
+
356
+ // Get a pointer to the array that stores elements in a dense matrix.
357
+ #define NM_DENSE_ELEMENTS(val) (NM_STORAGE_DENSE(val)->elements)
358
+ #define NM_SIZEOF_DTYPE(val) (DTYPE_SIZES[NM_DTYPE(val)])
359
+ #define NM_REF(val,slice) (RefFuncs[NM_STYPE(val)]( NM_STORAGE(val), slice, NM_SIZEOF_DTYPE(val) ))
360
+
361
+ #define NM_MAX(a,b) (((a)>(b))?(a):(b))
362
+ #define NM_MIN(a,b) (((a)>(b))?(b):(a))
363
+ #define NM_SWAP(a,b,tmp) {(tmp)=(a);(a)=(b);(b)=(tmp);}
364
+
365
+ #define NM_CHECK_ALLOC(x) if (!x) rb_raise(rb_eNoMemError, "insufficient memory");
366
+
367
+ #define RB_FILE_EXISTS(fn) (rb_funcall(rb_const_get(rb_cObject, rb_intern("File")), rb_intern("exists?"), 1, (fn)) == Qtrue)
368
+
369
+ #define CheckNMatrixType(v) if (TYPE(v) != T_DATA || (RDATA(v)->dfree != (RUBY_DATA_FUNC)nm_delete && RDATA(v)->dfree != (RUBY_DATA_FUNC)nm_delete_ref)) rb_raise(rb_eTypeError, "expected NMatrix on left-hand side of operation");
370
+
371
+ #define NM_IsNMatrix(obj) \
372
+ (rb_obj_is_kind_of(obj, cNMatrix) == Qtrue)
373
+
374
+ #define NM_IsNVector(obj) \
375
+ (rb_obj_is_kind_of(obj, cNVector) == Qtrue)
376
+
377
+ #define RB_P(OBJ) \
378
+ rb_funcall(rb_stderr, rb_intern("print"), 1, rb_funcall(OBJ, rb_intern("object_id"), 0)); \
379
+ rb_funcall(rb_stderr, rb_intern("puts"), 1, rb_funcall(OBJ, rb_intern("inspect"), 0));
380
+
381
+
382
+ #ifdef __cplusplus
383
+ typedef VALUE (*METHOD)(...);
384
+
385
+ //}; // end of namespace nm
386
+ #endif
387
+
388
+ // In the init code below, we need to use NMATRIX for c++ and NM_NMATRIX for c
389
+ // this macro chooses the correct one:
390
+ #ifdef __cplusplus
391
+ #define _NMATRIX NMATRIX
392
+ #define _STORAGE STORAGE
393
+ #else
394
+ #define _NMATRIX NM_NMATRIX
395
+ #define _STORAGE NM_STORAGE
396
+ #endif
397
+
398
+ /*
399
+ * Functions
400
+ */
401
+
402
+ #ifdef __cplusplus
403
+ extern "C" {
404
+ #endif
405
+
406
+ void Init_nmatrix();
407
+ // External API
408
+ VALUE rb_nmatrix_dense_create(NM_DECL_ENUM(dtype_t, dtype), size_t* shape, size_t dim, void* elements, size_t length);
409
+ VALUE rb_nvector_dense_create(NM_DECL_ENUM(dtype_t, dtype), void* elements, size_t length);
410
+
411
+ NM_DECL_ENUM(dtype_t, nm_dtype_guess(VALUE)); // (This is a function)
412
+ NM_DECL_ENUM(dtype_t, nm_dtype_min(VALUE));
413
+
414
+ // Non-API functions needed by other cpp files.
415
+ _NMATRIX* nm_create(NM_DECL_ENUM(stype_t, stype), _STORAGE* storage);
416
+ _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);
417
+ VALUE nm_cast(VALUE self, VALUE new_stype_symbol, VALUE new_dtype_symbol, VALUE init);
418
+ void nm_mark(_NMATRIX* mat);
419
+ void nm_delete(_NMATRIX* mat);
420
+ void nm_delete_ref(_NMATRIX* mat);
421
+ void nm_register_values(VALUE* vals, size_t n);
422
+ void nm_register_value(VALUE* val);
423
+ void nm_unregister_value(VALUE* val);
424
+ void nm_unregister_values(VALUE* vals, size_t n);
425
+ void nm_register_storage(NM_DECL_ENUM(stype_t, stype), const _STORAGE* storage);
426
+ void nm_unregister_storage(NM_DECL_ENUM(stype_t, stype), const _STORAGE* storage);
427
+ void nm_register_nmatrix(_NMATRIX* nmatrix);
428
+ void nm_unregister_nmatrix(_NMATRIX* nmatrix);
429
+ void nm_completely_unregister_value(VALUE* val);
430
+
431
+ #ifdef __cplusplus
432
+ }
433
+ #endif
434
+
435
+ #undef _NMATRIX
436
+ #undef _STORAGE
437
+
438
+ #endif // NMATRIX_H