nmatrix-fftw 0.2.1

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 (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