nmatrix-gemv 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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