nmatrix-gemv 0.0.3

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 (56) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +29 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +14 -0
  5. data/Gemfile +7 -0
  6. data/README.md +29 -0
  7. data/Rakefile +225 -0
  8. data/ext/nmatrix_gemv/binary_format.txt +53 -0
  9. data/ext/nmatrix_gemv/data/complex.h +399 -0
  10. data/ext/nmatrix_gemv/data/data.cpp +298 -0
  11. data/ext/nmatrix_gemv/data/data.h +771 -0
  12. data/ext/nmatrix_gemv/data/meta.h +70 -0
  13. data/ext/nmatrix_gemv/data/rational.h +436 -0
  14. data/ext/nmatrix_gemv/data/ruby_object.h +471 -0
  15. data/ext/nmatrix_gemv/extconf.rb +254 -0
  16. data/ext/nmatrix_gemv/math.cpp +1639 -0
  17. data/ext/nmatrix_gemv/math/asum.h +143 -0
  18. data/ext/nmatrix_gemv/math/geev.h +82 -0
  19. data/ext/nmatrix_gemv/math/gemm.h +271 -0
  20. data/ext/nmatrix_gemv/math/gemv.h +212 -0
  21. data/ext/nmatrix_gemv/math/ger.h +96 -0
  22. data/ext/nmatrix_gemv/math/gesdd.h +80 -0
  23. data/ext/nmatrix_gemv/math/gesvd.h +78 -0
  24. data/ext/nmatrix_gemv/math/getf2.h +86 -0
  25. data/ext/nmatrix_gemv/math/getrf.h +240 -0
  26. data/ext/nmatrix_gemv/math/getri.h +108 -0
  27. data/ext/nmatrix_gemv/math/getrs.h +129 -0
  28. data/ext/nmatrix_gemv/math/idamax.h +86 -0
  29. data/ext/nmatrix_gemv/math/inc.h +47 -0
  30. data/ext/nmatrix_gemv/math/laswp.h +165 -0
  31. data/ext/nmatrix_gemv/math/long_dtype.h +52 -0
  32. data/ext/nmatrix_gemv/math/math.h +1069 -0
  33. data/ext/nmatrix_gemv/math/nrm2.h +181 -0
  34. data/ext/nmatrix_gemv/math/potrs.h +129 -0
  35. data/ext/nmatrix_gemv/math/rot.h +141 -0
  36. data/ext/nmatrix_gemv/math/rotg.h +115 -0
  37. data/ext/nmatrix_gemv/math/scal.h +73 -0
  38. data/ext/nmatrix_gemv/math/swap.h +73 -0
  39. data/ext/nmatrix_gemv/math/trsm.h +387 -0
  40. data/ext/nmatrix_gemv/nm_memory.h +60 -0
  41. data/ext/nmatrix_gemv/nmatrix_gemv.cpp +90 -0
  42. data/ext/nmatrix_gemv/nmatrix_gemv.h +374 -0
  43. data/ext/nmatrix_gemv/ruby_constants.cpp +153 -0
  44. data/ext/nmatrix_gemv/ruby_constants.h +107 -0
  45. data/ext/nmatrix_gemv/ruby_nmatrix.c +84 -0
  46. data/ext/nmatrix_gemv/ttable_helper.rb +122 -0
  47. data/ext/nmatrix_gemv/types.h +54 -0
  48. data/ext/nmatrix_gemv/util/util.h +78 -0
  49. data/lib/nmatrix-gemv.rb +43 -0
  50. data/lib/nmatrix_gemv/blas.rb +85 -0
  51. data/lib/nmatrix_gemv/nmatrix_gemv.rb +35 -0
  52. data/lib/nmatrix_gemv/rspec.rb +75 -0
  53. data/nmatrix-gemv.gemspec +31 -0
  54. data/spec/blas_spec.rb +154 -0
  55. data/spec/spec_helper.rb +128 -0
  56. metadata +186 -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,90 @@
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.cpp
25
+ //
26
+ // Main C++ source file for NMatrix. Contains Init_nmatrix and most Ruby
27
+ // instance and class methods for NMatrix. Also responsible for calling Init
28
+ // methods on related modules.
29
+
30
+ /*
31
+ * Standard Includes
32
+ */
33
+
34
+ extern "C" {
35
+ #if defined HAVE_CBLAS_H
36
+ #include <cblas.h>
37
+ #elif defined HAVE_ATLAS_CBLAS_H
38
+ #include <atlas/cblas.h>
39
+ #endif
40
+
41
+ #if defined HAVE_CLAPACK_H
42
+ #include <clapack.h>
43
+ #elif defined HAVE_ATLAS_CLAPACK_H
44
+ #include <atlas/clapack.h>
45
+ #endif
46
+ }
47
+
48
+ #include <ruby.h>
49
+ #include <algorithm> // std::min
50
+ #include <fstream>
51
+
52
+ /*
53
+ * Project Includes
54
+ */
55
+ #include "nmatrix_gemv_config.h"
56
+
57
+ #include "types.h"
58
+ #include "data/data.h"
59
+ #include "math/math.h"
60
+ //#include "util/io.h"
61
+ //#include "storage/storage.h"
62
+ //#include "storage/list/list.h"
63
+ //#include "storage/yale/yale.h"
64
+
65
+ #include "nmatrix_gemv.h"
66
+
67
+ #include "ruby_constants.h"
68
+
69
+ /*
70
+ * Ruby internals
71
+ */
72
+
73
+
74
+ /*
75
+ * Macros
76
+ */
77
+
78
+
79
+ /*
80
+ * Global Variables
81
+ */
82
+
83
+ namespace nm {
84
+
85
+
86
+ } // end of namespace nm
87
+
88
+ extern "C" {
89
+ #include "ruby_nmatrix.c"
90
+ } // end of extern "C"
@@ -0,0 +1,374 @@
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
+ #include "nm_memory.h"
57
+
58
+ /*
59
+ * Macros
60
+ */
61
+
62
+ #define RUBY_ZERO INT2FIX(0)
63
+
64
+ #ifndef SIZEOF_INT
65
+ #error SIZEOF_INT undefined
66
+ #else
67
+ #if SIZEOF_INT == 8
68
+ #define DEFAULT_DTYPE INT64
69
+ #define SIZE_T INT64
70
+ #else
71
+ #if SIZEOF_INT == 4
72
+ #define DEFAULT_DTYPE INT32
73
+ #define SIZE_T INT32
74
+ #else
75
+ #if SIZEOF_INT == 2
76
+ #define DEFAULT_DTYPE INT16
77
+ #define SIZE_T INT16
78
+ #else
79
+ #error Unhandled SIZEOF_INT -- please #define SIZE_T and DEFAULT_DTYPE manually.
80
+ #endif
81
+ #endif
82
+ #endif
83
+ #endif
84
+
85
+ /*
86
+ * == Macros for Concurrent C and C++ Header Maintenance
87
+ *
88
+ * These macros look complicated, but they're really not so bad. They're also important: they ensure that whether our
89
+ * header file (nmatrix.h) is read by a C++ or a C compiler, all the same data structures and enumerators exist, albeit
90
+ * with slightly different names.
91
+ *
92
+ * "But wait," you say, "You use structs. Structs exist in C and C++. Why use a macro to set them up?"
93
+ *
94
+ * Well, in C, you have to be explicit about what a struct is. You can actually get around that requirement by using a
95
+ * typedef:
96
+ *
97
+ * typedef struct STORAGE { ... } STORAGE;
98
+ *
99
+ * Also, we use C++ inheritance, which is obviously not allowed in C. So we have to ensure that the base class's members
100
+ * are exposed properly to our child classes.
101
+ *
102
+ * The macros also allow us to put all of our C++ types into namespaces. For C, we prefix everything with either nm_ or
103
+ * NM_ to distinguish our declarations from those in other libraries.
104
+ */
105
+
106
+
107
+ #ifdef __cplusplus /* These are the C++ versions of the macros. */
108
+
109
+ /*
110
+ * If no block is given, return an enumerator. This copied straight out of ruby's include/ruby/intern.h.
111
+ *
112
+ * rb_enumeratorize is located in enumerator.c.
113
+ *
114
+ * VALUE rb_enumeratorize(VALUE obj, VALUE meth, int argc, VALUE *argv) {
115
+ * return enumerator_init(enumerator_allocate(rb_cEnumerator), obj, meth, argc, argv);
116
+ * }
117
+ */
118
+
119
+ //opening portion -- this allows unregistering any objects in use before returning
120
+ #define RETURN_SIZED_ENUMERATOR_PRE do { \
121
+ if (!rb_block_given_p()) {
122
+
123
+ //remaining portion
124
+ #ifdef RUBY_2
125
+ #ifndef RETURN_SIZED_ENUMERATOR
126
+ #undef RETURN_SIZED_ENUMERATOR
127
+ // Ruby 2.0 and higher has rb_enumeratorize_with_size instead of rb_enumeratorize.
128
+ // We want to support both in the simplest way possible.
129
+ #define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) \
130
+ return rb_enumeratorize_with_size((obj), ID2SYM(rb_frame_this_func()), (argc), (argv), (size_fn)); \
131
+ } \
132
+ } while (0)
133
+ #endif
134
+ #else
135
+ #undef RETURN_SIZED_ENUMERATOR
136
+ #define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) \
137
+ return rb_enumeratorize((obj), ID2SYM(rb_frame_this_func()), (argc), (argv)); \
138
+ } \
139
+ } while (0)
140
+ #endif
141
+
142
+ #define NM_DECL_ENUM(enum_type, name) nm::enum_type name
143
+ #define NM_DECL_STRUCT(type, name) type name;
144
+
145
+ #define NM_DEF_STORAGE_ELEMENTS \
146
+ NM_DECL_ENUM(dtype_t, dtype); \
147
+ size_t dim; \
148
+ size_t* shape; \
149
+ size_t* offset; \
150
+ int count; \
151
+ STORAGE* src;
152
+
153
+ #define NM_DEF_STORAGE_CHILD_STRUCT_PRE(name) struct name : STORAGE {
154
+ #define NM_DEF_STORAGE_STRUCT_POST(name) };
155
+
156
+ #define NM_DEF_STORAGE_STRUCT \
157
+ struct STORAGE { \
158
+ NM_DEF_STORAGE_ELEMENTS; \
159
+ };
160
+
161
+ #define NM_DEF_STRUCT_PRE(name) struct name {
162
+ #define NM_DEF_STRUCT_POST(name) };
163
+
164
+ #define NM_DEF_ENUM(name, ...) \
165
+ namespace nm { \
166
+ enum name { \
167
+ __VA_ARGS__ \
168
+ }; \
169
+ } // end of namespace nm
170
+
171
+ #else /* These are the C versions of the macros. */
172
+
173
+ #define NM_DECL_ENUM(enum_type, name) nm_ ## enum_type name
174
+ #define NM_DECL_STRUCT(type, name) struct NM_ ## type name;
175
+
176
+ #define NM_DEF_STORAGE_ELEMENTS \
177
+ NM_DECL_ENUM(dtype_t, dtype); \
178
+ size_t dim; \
179
+ size_t* shape; \
180
+ size_t* offset; \
181
+ int count; \
182
+ STORAGE* src;
183
+ #define NM_DEF_STORAGE_CHILD_STRUCT_PRE(name) typedef struct NM_ ## name { \
184
+ NM_DEF_STORAGE_ELEMENTS;
185
+
186
+ #define NM_DEF_STORAGE_STRUCT_POST(name) } NM_ ## name;
187
+
188
+ #define NM_DEF_STORAGE_STRUCT \
189
+ typedef struct NM_STORAGE { \
190
+ NM_DEF_STORAGE_ELEMENTS; \
191
+ } NM_STORAGE;
192
+
193
+ #define NM_DEF_STRUCT_PRE(name) typedef struct NM_ ## name {
194
+ #define NM_DEF_STRUCT_POST(name) } NM_ ## name;
195
+
196
+ #define NM_DEF_ENUM(name, ...) \
197
+ typedef enum nm_ ## name { \
198
+ __VA_ARGS__ \
199
+ } nm_ ## name;
200
+
201
+ #endif /* End of C/C++ Parallel Header Macro Definitions */
202
+
203
+
204
+ /*
205
+ * Types
206
+ */
207
+
208
+ #define NM_NUM_DTYPES 13 // data/data.h
209
+ #define NM_NUM_STYPES 3 // storage/storage.h
210
+
211
+ //#ifdef __cplusplus
212
+ //namespace nm {
213
+ //#endif
214
+
215
+ /* Storage Type -- Dense or Sparse */
216
+ NM_DEF_ENUM(stype_t, DENSE_STORE = 0,
217
+ LIST_STORE = 1,
218
+ YALE_STORE = 2);
219
+
220
+ /* Data Type */
221
+ NM_DEF_ENUM(dtype_t, BYTE = 0, // unsigned char
222
+ INT8 = 1, // char
223
+ INT16 = 2, // short
224
+ INT32 = 3, // int
225
+ INT64 = 4, // long
226
+ FLOAT32 = 5, // float
227
+ FLOAT64 = 6, // double
228
+ COMPLEX64 = 7, // Complex64 class
229
+ COMPLEX128 = 8, // Complex128 class
230
+ RATIONAL32 = 9, // Rational32 class
231
+ RATIONAL64 = 10, // Rational64 class
232
+ RATIONAL128 = 11, // Rational128 class
233
+ RUBYOBJ = 12); // Ruby VALUE type
234
+
235
+ NM_DEF_ENUM(symm_t, NONSYMM = 0,
236
+ SYMM = 1,
237
+ SKEW = 2,
238
+ HERM = 3,
239
+ UPPER = 4,
240
+ LOWER = 5);
241
+
242
+ //#ifdef __cplusplus
243
+ //}; // end of namespace nm
244
+ //#endif
245
+
246
+ /* struct STORAGE */
247
+ NM_DEF_STORAGE_STRUCT;
248
+
249
+ /* Dense Storage */
250
+ NM_DEF_STORAGE_CHILD_STRUCT_PRE(DENSE_STORAGE); // struct DENSE_STORAGE : STORAGE {
251
+ size_t* stride;
252
+ void* elements;
253
+ NM_DEF_STORAGE_STRUCT_POST(DENSE_STORAGE); // };
254
+
255
+ /* Yale Storage */
256
+ NM_DEF_STORAGE_CHILD_STRUCT_PRE(YALE_STORAGE);
257
+ void* a; // should go first
258
+ size_t ndnz; // Strictly non-diagonal non-zero count!
259
+ size_t capacity;
260
+ size_t* ija;
261
+ NM_DEF_STORAGE_STRUCT_POST(YALE_STORAGE);
262
+
263
+ // FIXME: NODE and LIST should be put in some kind of namespace or something, at least in C++.
264
+ NM_DEF_STRUCT_PRE(NODE); // struct NODE {
265
+ size_t key;
266
+ void* val;
267
+ NM_DECL_STRUCT(NODE*, next); // NODE* next;
268
+ NM_DEF_STRUCT_POST(NODE); // };
269
+
270
+ NM_DEF_STRUCT_PRE(LIST); // struct LIST {
271
+ NM_DECL_STRUCT(NODE*, first); // NODE* first;
272
+ NM_DEF_STRUCT_POST(LIST); // };
273
+
274
+ /* List-of-Lists Storage */
275
+ NM_DEF_STORAGE_CHILD_STRUCT_PRE(LIST_STORAGE); // struct LIST_STORAGE : STORAGE {
276
+ // List storage specific elements.
277
+ void* default_val;
278
+ NM_DECL_STRUCT(LIST*, rows); // LIST* rows;
279
+ NM_DEF_STORAGE_STRUCT_POST(LIST_STORAGE); // };
280
+
281
+
282
+
283
+ /* NMATRIX Object */
284
+ NM_DEF_STRUCT_PRE(NMATRIX); // struct NMATRIX {
285
+ NM_DECL_ENUM(stype_t, stype); // stype_t stype; // Method of storage (csc, dense, etc).
286
+ NM_DECL_STRUCT(STORAGE*, storage); // STORAGE* storage; // Pointer to storage struct.
287
+ NM_DEF_STRUCT_POST(NMATRIX); // };
288
+
289
+ /* Structs for dealing with VALUEs in use so that they don't get GC'd */
290
+
291
+ typedef struct __NM_GC_LL_NODE {
292
+ VALUE* val;
293
+ size_t n;
294
+ __NM_GC_LL_NODE* next;
295
+ } nm_gc_ll_node;
296
+
297
+ typedef struct __NM_GC_HOLDER {
298
+ __NM_GC_LL_NODE* start;
299
+ } nm_gc_holder;
300
+
301
+ #define NM_MAX_RANK 15
302
+
303
+ #define UnwrapNMatrix(obj,var) Data_Get_Struct(obj, NMATRIX, var)
304
+
305
+ #define NM_STORAGE(val) (NM_STRUCT(val)->storage)
306
+ #ifdef __cplusplus
307
+ #define NM_STRUCT(val) ((NMATRIX*)(DATA_PTR(val)))
308
+ #define NM_STORAGE_LIST(val) ((LIST_STORAGE*)(NM_STORAGE(val)))
309
+ #define NM_STORAGE_YALE(val) ((YALE_STORAGE*)(NM_STORAGE(val)))
310
+ #define NM_STORAGE_DENSE(val) ((DENSE_STORAGE*)(NM_STORAGE(val)))
311
+ #else
312
+ #define NM_STRUCT(val) ((struct NM_NMATRIX*)(DATA_PTR(val)))
313
+ #define NM_STORAGE_LIST(val) ((struct NM_LIST_STORAGE*)(NM_STORAGE(val)))
314
+ #define NM_STORAGE_YALE(val) ((struct NM_YALE_STORAGE*)(NM_STORAGE(val)))
315
+ #define NM_STORAGE_DENSE(val) ((struct NM_DENSE_STORAGE*)(NM_STORAGE(val)))
316
+ #endif
317
+
318
+ #define NM_SRC(val) (NM_STORAGE(val)->src)
319
+ #define NM_DIM(val) (NM_STORAGE(val)->dim)
320
+ #define NM_DTYPE(val) (NM_STORAGE(val)->dtype)
321
+ #define NM_STYPE(val) (NM_STRUCT(val)->stype)
322
+ #define NM_SHAPE(val,i) (NM_STORAGE(val)->shape[(i)])
323
+ #define NM_SHAPE0(val) (NM_STORAGE(val)->shape[0])
324
+ #define NM_SHAPE1(val) (NM_STORAGE(val)->shape[1])
325
+ #define NM_DEFAULT_VAL(val) (NM_STORAGE_LIST(val)->default_val)
326
+
327
+ #define NM_DENSE_COUNT(val) (nm_storage_count_max_elements(NM_STORAGE_DENSE(val)))
328
+ #define NM_DENSE_ELEMENTS(val) (NM_STORAGE_DENSE(val)->elements)
329
+ #define NM_SIZEOF_DTYPE(val) (DTYPE_SIZES[NM_DTYPE(val)])
330
+ #define NM_REF(val,slice) (RefFuncs[NM_STYPE(val)]( NM_STORAGE(val), slice, NM_SIZEOF_DTYPE(val) ))
331
+
332
+ #define NM_MAX(a,b) (((a)>(b))?(a):(b))
333
+ #define NM_MIN(a,b) (((a)>(b))?(b):(a))
334
+ #define NM_SWAP(a,b,tmp) {(tmp)=(a);(a)=(b);(b)=(tmp);}
335
+
336
+ #define NM_CHECK_ALLOC(x) if (!x) rb_raise(rb_eNoMemError, "insufficient memory");
337
+
338
+ #define RB_FILE_EXISTS(fn) (rb_funcall(rb_const_get(rb_cObject, rb_intern("File")), rb_intern("exists?"), 1, (fn)) == Qtrue)
339
+
340
+ #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");
341
+
342
+ #define NM_IsNMatrix(obj) \
343
+ (rb_obj_is_kind_of(obj, cNMatrix) == Qtrue)
344
+
345
+ #define NM_IsNVector(obj) \
346
+ (rb_obj_is_kind_of(obj, cNVector) == Qtrue)
347
+
348
+ #define RB_P(OBJ) \
349
+ rb_funcall(rb_stderr, rb_intern("print"), 1, rb_funcall(OBJ, rb_intern("object_id"), 0)); \
350
+ rb_funcall(rb_stderr, rb_intern("puts"), 1, rb_funcall(OBJ, rb_intern("inspect"), 0));
351
+
352
+
353
+ #ifdef __cplusplus
354
+ typedef VALUE (*METHOD)(...);
355
+
356
+ //}; // end of namespace nm
357
+ #endif
358
+
359
+ /*
360
+ * Functions
361
+ */
362
+
363
+ #ifdef __cplusplus
364
+
365
+ extern "C" {
366
+ #endif
367
+
368
+ void Init_nmatrix_gemv();
369
+
370
+ #ifdef __cplusplus
371
+ }
372
+ #endif
373
+
374
+ #endif // NMATRIX_H