nmatrix 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/ext/nmatrix/data/complex.h +20 -55
  3. data/ext/nmatrix/data/data.cpp +11 -44
  4. data/ext/nmatrix/data/data.h +174 -311
  5. data/ext/nmatrix/data/meta.h +1 -7
  6. data/ext/nmatrix/data/ruby_object.h +3 -85
  7. data/ext/nmatrix/extconf.rb +2 -73
  8. data/ext/nmatrix/math.cpp +170 -813
  9. data/ext/nmatrix/math/asum.h +2 -25
  10. data/ext/nmatrix/math/{inc.h → cblas_enums.h} +11 -22
  11. data/ext/nmatrix/math/cblas_templates_core.h +507 -0
  12. data/ext/nmatrix/math/gemm.h +2 -32
  13. data/ext/nmatrix/math/gemv.h +1 -35
  14. data/ext/nmatrix/math/getrf.h +21 -6
  15. data/ext/nmatrix/math/getrs.h +0 -8
  16. data/ext/nmatrix/math/imax.h +0 -22
  17. data/ext/nmatrix/math/long_dtype.h +0 -3
  18. data/ext/nmatrix/math/math.h +11 -337
  19. data/ext/nmatrix/math/nrm2.h +2 -23
  20. data/ext/nmatrix/math/rot.h +1 -25
  21. data/ext/nmatrix/math/rotg.h +4 -13
  22. data/ext/nmatrix/math/scal.h +0 -22
  23. data/ext/nmatrix/math/trsm.h +0 -55
  24. data/ext/nmatrix/math/util.h +148 -0
  25. data/ext/nmatrix/nmatrix.cpp +0 -14
  26. data/ext/nmatrix/nmatrix.h +92 -84
  27. data/ext/nmatrix/ruby_constants.cpp +0 -2
  28. data/ext/nmatrix/ruby_constants.h +0 -2
  29. data/ext/nmatrix/ruby_nmatrix.c +86 -45
  30. data/ext/nmatrix/storage/dense/dense.cpp +1 -7
  31. data/ext/nmatrix/storage/storage.h +0 -1
  32. data/ext/nmatrix/ttable_helper.rb +0 -6
  33. data/ext/nmatrix/util/io.cpp +1 -1
  34. data/lib/nmatrix.rb +1 -19
  35. data/lib/nmatrix/blas.rb +33 -11
  36. data/lib/nmatrix/io/market.rb +3 -3
  37. data/lib/nmatrix/lapack_core.rb +181 -0
  38. data/lib/nmatrix/lapack_plugin.rb +44 -0
  39. data/lib/nmatrix/math.rb +382 -131
  40. data/lib/nmatrix/monkeys.rb +2 -3
  41. data/lib/nmatrix/nmatrix.rb +166 -13
  42. data/lib/nmatrix/shortcuts.rb +72 -7
  43. data/lib/nmatrix/version.rb +2 -2
  44. data/spec/00_nmatrix_spec.rb +154 -5
  45. data/spec/02_slice_spec.rb +2 -6
  46. data/spec/03_nmatrix_monkeys_spec.rb +7 -1
  47. data/spec/blas_spec.rb +60 -33
  48. data/spec/homogeneous_spec.rb +10 -10
  49. data/spec/lapack_core_spec.rb +482 -0
  50. data/spec/math_spec.rb +436 -52
  51. data/spec/shortcuts_spec.rb +28 -4
  52. data/spec/spec_helper.rb +14 -2
  53. data/spec/utm5940.mtx +83844 -0
  54. metadata +49 -76
  55. data/.gitignore +0 -27
  56. data/.rspec +0 -2
  57. data/.travis.yml +0 -15
  58. data/CONTRIBUTING.md +0 -82
  59. data/Gemfile +0 -2
  60. data/History.txt +0 -677
  61. data/LICENSE.txt +0 -23
  62. data/Manifest.txt +0 -92
  63. data/README.rdoc +0 -150
  64. data/Rakefile +0 -216
  65. data/ext/nmatrix/data/rational.h +0 -440
  66. data/ext/nmatrix/math/geev.h +0 -82
  67. data/ext/nmatrix/math/ger.h +0 -96
  68. data/ext/nmatrix/math/gesdd.h +0 -80
  69. data/ext/nmatrix/math/gesvd.h +0 -78
  70. data/ext/nmatrix/math/getf2.h +0 -86
  71. data/ext/nmatrix/math/getri.h +0 -108
  72. data/ext/nmatrix/math/potrs.h +0 -129
  73. data/ext/nmatrix/math/swap.h +0 -52
  74. data/lib/nmatrix/lapack.rb +0 -240
  75. data/nmatrix.gemspec +0 -55
  76. data/scripts/mac-brew-gcc.sh +0 -50
  77. data/scripts/mac-mavericks-brew-gcc.sh +0 -22
  78. data/spec/lapack_spec.rb +0 -459
@@ -59,6 +59,8 @@
59
59
  #ifndef NRM2_H
60
60
  # define NRM2_H
61
61
 
62
+ #include "math/long_dtype.h"
63
+
62
64
 
63
65
  namespace nm { namespace math {
64
66
 
@@ -71,7 +73,6 @@ namespace nm { namespace math {
71
73
  * double -> double
72
74
  * complex64 -> float or double
73
75
  * complex128 -> double
74
- * rational -> rational
75
76
  */
76
77
  template <typename ReturnDType, typename DType>
77
78
  ReturnDType nrm2(const int N, const DType* X, const int incX) {
@@ -98,27 +99,6 @@ ReturnDType nrm2(const int N, const DType* X, const int incX) {
98
99
  }
99
100
 
100
101
 
101
- #if defined HAVE_CBLAS_H || defined HAVE_ATLAS_CBLAS_H
102
- template <>
103
- inline float nrm2(const int N, const float* X, const int incX) {
104
- return cblas_snrm2(N, X, incX);
105
- }
106
-
107
- template <>
108
- inline double nrm2(const int N, const double* X, const int incX) {
109
- return cblas_dnrm2(N, X, incX);
110
- }
111
-
112
- template <>
113
- inline float nrm2(const int N, const Complex64* X, const int incX) {
114
- return cblas_scnrm2(N, X, incX);
115
- }
116
-
117
- template <>
118
- inline double nrm2(const int N, const Complex128* X, const int incX) {
119
- return cblas_dznrm2(N, X, incX);
120
- }
121
- #else
122
102
  template <typename FloatDType>
123
103
  static inline void nrm2_complex_helper(const FloatDType& xr, const FloatDType& xi, double& scale, double& ssq) {
124
104
  double absx = std::abs(xr);
@@ -167,7 +147,6 @@ double nrm2(const int N, const Complex128* X, const int incX) {
167
147
 
168
148
  return scale * std::sqrt( ssq );
169
149
  }
170
- #endif
171
150
 
172
151
  template <typename ReturnDType, typename DType>
173
152
  inline void cblas_nrm2(const int N, const void* X, const int incX, void* result) {
@@ -61,9 +61,6 @@
61
61
 
62
62
  namespace nm { namespace math {
63
63
 
64
- // FIXME: This is not working properly for rational numbers. Do we need some kind of symbolic
65
- // type to handle square roots?
66
-
67
64
 
68
65
  // TODO: Test this to see if it works properly on complex. ATLAS has a separate algorithm for complex, which looks like
69
66
  // TODO: it may actually be the same one.
@@ -108,27 +105,6 @@ inline void rot(const int N, DType* X, const int incX, DType* Y, const int incY,
108
105
  }
109
106
  }
110
107
 
111
- template <>
112
- inline void rot(const int N, float* X, const int incX, float* Y, const int incY, const float c, const float s) {
113
- cblas_srot(N, X, incX, Y, incY, (float)c, (float)s);
114
- }
115
-
116
- template <>
117
- inline void rot(const int N, double* X, const int incX, double* Y, const int incY, const double c, const double s) {
118
- cblas_drot(N, X, incX, Y, incY, c, s);
119
- }
120
-
121
- template <>
122
- inline void rot(const int N, Complex64* X, const int incX, Complex64* Y, const int incY, const float c, const float s) {
123
- cblas_csrot(N, X, incX, Y, incY, c, s);
124
- }
125
-
126
- template <>
127
- inline void rot(const int N, Complex128* X, const int incX, Complex128* Y, const int incY, const double c, const double s) {
128
- cblas_zdrot(N, X, incX, Y, incY, c, s);
129
- }
130
-
131
-
132
108
  template <typename DType, typename CSDType>
133
109
  inline void cblas_rot(const int N, void* X, const int incX, void* Y, const int incY, const void* c, const void* s) {
134
110
  rot<DType,CSDType>(N, reinterpret_cast<DType*>(X), incX, reinterpret_cast<DType*>(Y), incY,
@@ -138,4 +114,4 @@ inline void cblas_rot(const int N, void* X, const int incX, void* Y, const int i
138
114
 
139
115
  } } //nm::math
140
116
 
141
- #endif // ROT_H
117
+ #endif // ROT_H
@@ -84,26 +84,17 @@ inline void rotg(DType* a, DType* b, DType* c, DType* s) {
84
84
  }
85
85
  }
86
86
 
87
- template <>
88
- inline void rotg(float* a, float* b, float* c, float* s) {
89
- cblas_srotg(a, b, c, s);
90
- }
91
-
92
- template <>
93
- inline void rotg(double* a, double* b, double* c, double* s) {
94
- cblas_drotg(a, b, c, s);
95
- }
96
-
97
87
  template <>
98
88
  inline void rotg(Complex64* a, Complex64* b, Complex64* c, Complex64* s) {
99
- cblas_crotg(reinterpret_cast<void*>(a), reinterpret_cast<void*>(b), reinterpret_cast<void*>(c), reinterpret_cast<void*>(s));
89
+ rb_raise(rb_eNotImpError, "BLAS not available, and existing template requires modification for complex");
100
90
  }
101
91
 
102
92
  template <>
103
93
  inline void rotg(Complex128* a, Complex128* b, Complex128* c, Complex128* s) {
104
- cblas_zrotg(reinterpret_cast<void*>(a), reinterpret_cast<void*>(b), reinterpret_cast<void*>(c), reinterpret_cast<void*>(s));
94
+ rb_raise(rb_eNotImpError, "BLAS not available, and existing template requires modification for complex");
105
95
  }
106
96
 
97
+
107
98
  template <typename DType>
108
99
  inline void cblas_rotg(void* a, void* b, void* c, void* s) {
109
100
  rotg<DType>(reinterpret_cast<DType*>(a), reinterpret_cast<DType*>(b), reinterpret_cast<DType*>(c), reinterpret_cast<DType*>(s));
@@ -112,4 +103,4 @@ inline void cblas_rotg(void* a, void* b, void* c, void* s) {
112
103
 
113
104
  } } //nm::math
114
105
 
115
- #endif // ROTG_H
106
+ #endif // ROTG_H
@@ -58,28 +58,6 @@ inline void scal(const int n, const DType scalar, DType* x, const int incx) {
58
58
  }
59
59
  }
60
60
 
61
- #if defined HAVE_CBLAS_H || defined HAVE_ATLAS_CBLAS_H
62
- template <>
63
- inline void scal(const int n, const float scalar, float* x, const int incx) {
64
- cblas_sscal(n, scalar, x, incx);
65
- }
66
-
67
- template <>
68
- inline void scal(const int n, const double scalar, double* x, const int incx) {
69
- cblas_dscal(n, scalar, x, incx);
70
- }
71
-
72
- template <>
73
- inline void scal(const int n, const Complex64 scalar, Complex64* x, const int incx) {
74
- cblas_cscal(n, (const void*)(&scalar), (void*)(x), incx);
75
- }
76
-
77
- template <>
78
- inline void scal(const int n, const Complex128 scalar, Complex128* x, const int incx) {
79
- cblas_zscal(n, (const void*)(&scalar), (void*)(x), incx);
80
- }
81
- #endif
82
-
83
61
  /*
84
62
  * Function signature conversion for LAPACK's scal function.
85
63
  */
@@ -59,14 +59,6 @@
59
59
  #define TRSM_H
60
60
 
61
61
 
62
- extern "C" {
63
- #if defined HAVE_CBLAS_H
64
- #include <cblas.h>
65
- #elif defined HAVE_ATLAS_CBLAS_H
66
- #include <atlas/cblas.h>
67
- #endif
68
- }
69
-
70
62
  namespace nm { namespace math {
71
63
 
72
64
 
@@ -336,52 +328,5 @@ inline void trsm(const enum CBLAS_ORDER order,
336
328
 
337
329
  }
338
330
 
339
-
340
- template <>
341
- inline void trsm(const enum CBLAS_ORDER order, const enum CBLAS_SIDE side, const enum CBLAS_UPLO uplo,
342
- const enum CBLAS_TRANSPOSE trans_a, const enum CBLAS_DIAG diag,
343
- const int m, const int n, const float alpha, const float* a,
344
- const int lda, float* b, const int ldb)
345
- {
346
- cblas_strsm(order, side, uplo, trans_a, diag, m, n, alpha, a, lda, b, ldb);
347
- }
348
-
349
- template <>
350
- inline void trsm(const enum CBLAS_ORDER order, const enum CBLAS_SIDE side, const enum CBLAS_UPLO uplo,
351
- const enum CBLAS_TRANSPOSE trans_a, const enum CBLAS_DIAG diag,
352
- const int m, const int n, const double alpha, const double* a,
353
- const int lda, double* b, const int ldb)
354
- {
355
- /* using std::cerr;
356
- using std::endl;
357
- cerr << "(row-major) dtrsm: " << (side == CblasLeft ? "left " : "right ")
358
- << (uplo == CblasUpper ? "upper " : "lower ")
359
- << (trans_a == CblasTrans ? "trans " : "notrans ")
360
- << (diag == CblasNonUnit ? "nonunit " : "unit ")
361
- << m << " " << n << " " << alpha << " a " << lda << " b " << ldb << endl;
362
- */
363
- cblas_dtrsm(order, side, uplo, trans_a, diag, m, n, alpha, a, lda, b, ldb);
364
- }
365
-
366
-
367
- template <>
368
- inline void trsm(const enum CBLAS_ORDER order, const enum CBLAS_SIDE side, const enum CBLAS_UPLO uplo,
369
- const enum CBLAS_TRANSPOSE trans_a, const enum CBLAS_DIAG diag,
370
- const int m, const int n, const Complex64 alpha, const Complex64* a,
371
- const int lda, Complex64* b, const int ldb)
372
- {
373
- cblas_ctrsm(order, side, uplo, trans_a, diag, m, n, (const void*)(&alpha), (const void*)(a), lda, (void*)(b), ldb);
374
- }
375
-
376
- template <>
377
- inline void trsm(const enum CBLAS_ORDER order, const enum CBLAS_SIDE side, const enum CBLAS_UPLO uplo,
378
- const enum CBLAS_TRANSPOSE trans_a, const enum CBLAS_DIAG diag,
379
- const int m, const int n, const Complex128 alpha, const Complex128* a,
380
- const int lda, Complex128* b, const int ldb)
381
- {
382
- cblas_ztrsm(order, side, uplo, trans_a, diag, m, n, (const void*)(&alpha), (const void*)(a), lda, (void*)(b), ldb);
383
- }
384
-
385
-
386
331
  } } // namespace nm::math
387
332
  #endif // TRSM_H
@@ -0,0 +1,148 @@
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
+ // == util.h
25
+ //
26
+ // Collect a few utility functions which convert ruby symbols into arguments
27
+ // that CBLAS or LAPACK can understand: either enum's for CBLAS or char's
28
+ // for LAPACK.
29
+ //
30
+
31
+ #ifndef UTIL_H
32
+ #define UTIL_H
33
+
34
+ /* Interprets cblas argument which could be any of false/:no_transpose, :transpose, or :complex_conjugate,
35
+ * into an enum recognized by cblas.
36
+ *
37
+ * Called by nm_cblas_gemm -- basically inline.
38
+ *
39
+ */
40
+ static inline enum CBLAS_TRANSPOSE blas_transpose_sym(VALUE op) {
41
+ if (op == Qfalse || rb_to_id(op) == nm_rb_no_transpose) return CblasNoTrans;
42
+ else if (rb_to_id(op) == nm_rb_transpose) return CblasTrans;
43
+ else if (rb_to_id(op) == nm_rb_complex_conjugate) return CblasConjTrans;
44
+ else rb_raise(rb_eArgError, "Expected false, :transpose, or :complex_conjugate");
45
+ return CblasNoTrans;
46
+ }
47
+
48
+ /* Interprets transpose argument which could be any of false/:no_transpose, :transpose, or :complex_conjugate,
49
+ * into an character recognized by LAPACKE. LAPACKE uses a different system than CBLAS for this.
50
+ *
51
+ */
52
+ static inline char lapacke_transpose_sym(VALUE op) {
53
+ if (op == Qfalse || rb_to_id(op) == nm_rb_no_transpose) return 'N';
54
+ else if (rb_to_id(op) == nm_rb_transpose) return 'T';
55
+ else if (rb_to_id(op) == nm_rb_complex_conjugate) return 'C';
56
+ else rb_raise(rb_eArgError, "Expected false, :transpose, or :complex_conjugate");
57
+ return 'N';
58
+ }
59
+
60
+ /*
61
+ * Interprets cblas argument which could be :left or :right
62
+ *
63
+ * Called by nm_cblas_trsm -- basically inline
64
+ */
65
+ static inline enum CBLAS_SIDE blas_side_sym(VALUE op) {
66
+ ID op_id = rb_to_id(op);
67
+ if (op_id == nm_rb_left) return CblasLeft;
68
+ if (op_id == nm_rb_right) return CblasRight;
69
+ rb_raise(rb_eArgError, "Expected :left or :right for side argument");
70
+ return CblasLeft;
71
+ }
72
+
73
+ /*
74
+ * Interprets cblas argument which could be :upper or :lower
75
+ *
76
+ * Called by nm_cblas_trsm -- basically inline
77
+ */
78
+ static inline enum CBLAS_UPLO blas_uplo_sym(VALUE op) {
79
+ ID op_id = rb_to_id(op);
80
+ if (op_id == nm_rb_upper) return CblasUpper;
81
+ if (op_id == nm_rb_lower) return CblasLower;
82
+ rb_raise(rb_eArgError, "Expected :upper or :lower for uplo argument");
83
+ return CblasUpper;
84
+ }
85
+
86
+ /*
87
+ * Interprets argument which could be :upper or :lower for LAPACKE
88
+ *
89
+ * Called by nm_cblas_trsm -- basically inline
90
+ */
91
+ static inline char lapacke_uplo_sym(VALUE op) {
92
+ ID op_id = rb_to_id(op);
93
+ if (op_id == nm_rb_upper) return 'U';
94
+ if (op_id == nm_rb_lower) return 'L';
95
+ rb_raise(rb_eArgError, "Expected :upper or :lower for uplo argument");
96
+ return 'U';
97
+ }
98
+
99
+ /*
100
+ * Interprets cblas argument which could be :unit (true) or :nonunit (false or anything other than true/:unit)
101
+ *
102
+ * Called by nm_cblas_trsm -- basically inline
103
+ */
104
+ static inline enum CBLAS_DIAG blas_diag_sym(VALUE op) {
105
+ if (rb_to_id(op) == nm_rb_unit || op == Qtrue) return CblasUnit;
106
+ return CblasNonUnit;
107
+ }
108
+
109
+ /*
110
+ * Interprets cblas argument which could be :row or :col
111
+ *
112
+ * This function, unlike the other ones, works for LAPACKE as well as for CBLAS/CLAPACK.
113
+ * Although LAPACKE calls this an int instead of a enum, the magic values are the same
114
+ * (101 for row-major, 102 for column-major).
115
+ */
116
+ static inline enum CBLAS_ORDER blas_order_sym(VALUE op) {
117
+ if (rb_to_id(op) == rb_intern("row") || rb_to_id(op) == rb_intern("row_major")) return CblasRowMajor;
118
+ else if (rb_to_id(op) == rb_intern("col") || rb_to_id(op) == rb_intern("col_major") ||
119
+ rb_to_id(op) == rb_intern("column") || rb_to_id(op) == rb_intern("column_major")) return CblasColMajor;
120
+ rb_raise(rb_eArgError, "Expected :row or :col for order argument");
121
+ return CblasRowMajor;
122
+ }
123
+
124
+ /*
125
+ * Interprets lapack jobu and jobvt arguments, for which LAPACK needs character values A, S, O, or N.
126
+ *
127
+ * Called by lapack_gesvd -- basically inline. svd stands for singular value decomposition.
128
+ */
129
+ static inline char lapack_svd_job_sym(VALUE op) {
130
+ if (rb_to_id(op) == rb_intern("all") || rb_to_id(op) == rb_intern("a")) return 'A';
131
+ else if (rb_to_id(op) == rb_intern("return") || rb_to_id(op) == rb_intern("s")) return 'S';
132
+ else if (rb_to_id(op) == rb_intern("overwrite") || rb_to_id(op) == rb_intern("o")) return 'O';
133
+ else if (rb_to_id(op) == rb_intern("none") || rb_to_id(op) == rb_intern("n")) return 'N';
134
+ else rb_raise(rb_eArgError, "Expected :all, :return, :overwrite, :none (or :a, :s, :o, :n, respectively)");
135
+ return 'a';
136
+ }
137
+
138
+ /*
139
+ * Interprets lapack jobvl and jobvr arguments, for which LAPACK needs character values N or V.
140
+ *
141
+ * Called by lapack_geev -- basically inline. evd stands for eigenvalue decomposition.
142
+ */
143
+ static inline char lapack_evd_job_sym(VALUE op) {
144
+ if (op == Qfalse || op == Qnil || rb_to_id(op) == rb_intern("n")) return 'N';
145
+ else return 'V';
146
+ }
147
+
148
+ #endif
@@ -31,20 +31,6 @@
31
31
  * Standard Includes
32
32
  */
33
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
34
  #include <ruby.h>
49
35
  #include <algorithm> // std::min
50
36
  #include <fstream>
@@ -43,14 +43,14 @@
43
43
  #endif
44
44
 
45
45
  #ifdef BENCHMARK
46
- // SOURCE: http://stackoverflow.com/questions/2349776/how-can-i-benchmark-a-c-program-easily
46
+ // SOURCE: http://stackoverflow.com/questions/2349776/how-can-i-benchmark-a-c-program-easily
47
47
  #ifdef __cplusplus
48
48
  #include <sys/ctime>
49
49
  #include <sys/cresource>
50
50
  #else
51
51
  #include <sys/time.h>
52
52
  #include <sys/resource.h>
53
- #endif
53
+ #endif
54
54
  #endif
55
55
 
56
56
  #ifdef __cplusplus
@@ -64,24 +64,24 @@
64
64
  #define RUBY_ZERO INT2FIX(0)
65
65
 
66
66
  #ifndef SIZEOF_INT
67
- #error SIZEOF_INT undefined
67
+ #error SIZEOF_INT undefined
68
68
  #else
69
- #if SIZEOF_INT == 8
70
- #define DEFAULT_DTYPE INT64
71
- #define SIZE_T INT64
72
- #else
73
- #if SIZEOF_INT == 4
74
- #define DEFAULT_DTYPE INT32
75
- #define SIZE_T INT32
76
- #else
77
- #if SIZEOF_INT == 2
78
- #define DEFAULT_DTYPE INT16
79
- #define SIZE_T INT16
80
- #else
81
- #error Unhandled SIZEOF_INT -- please #define SIZE_T and DEFAULT_DTYPE manually.
82
- #endif
83
- #endif
84
- #endif
69
+ #if SIZEOF_INT == 8
70
+ #define DEFAULT_DTYPE INT64
71
+ #define SIZE_T INT64
72
+ #else
73
+ #if SIZEOF_INT == 4
74
+ #define DEFAULT_DTYPE INT32
75
+ #define SIZE_T INT32
76
+ #else
77
+ #if SIZEOF_INT == 2
78
+ #define DEFAULT_DTYPE INT16
79
+ #define SIZE_T INT16
80
+ #else
81
+ #error Unhandled SIZEOF_INT -- please #define SIZE_T and DEFAULT_DTYPE manually.
82
+ #endif
83
+ #endif
84
+ #endif
85
85
  #endif
86
86
 
87
87
  /*
@@ -119,27 +119,27 @@
119
119
  */
120
120
 
121
121
  //opening portion -- this allows unregistering any objects in use before returning
122
- #define RETURN_SIZED_ENUMERATOR_PRE do { \
123
- if (!rb_block_given_p()) {
122
+ #define RETURN_SIZED_ENUMERATOR_PRE do { \
123
+ if (!rb_block_given_p()) {
124
124
 
125
125
  //remaining portion
126
- #ifdef RUBY_2
127
- #ifndef RETURN_SIZED_ENUMERATOR
128
- #undef RETURN_SIZED_ENUMERATOR
129
- // Ruby 2.0 and higher has rb_enumeratorize_with_size instead of rb_enumeratorize.
130
- // We want to support both in the simplest way possible.
131
- #define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) \
126
+ #ifdef RUBY_2
127
+ #ifndef RETURN_SIZED_ENUMERATOR
128
+ #undef RETURN_SIZED_ENUMERATOR
129
+ // Ruby 2.0 and higher has rb_enumeratorize_with_size instead of rb_enumeratorize.
130
+ // We want to support both in the simplest way possible.
131
+ #define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) \
132
132
  return rb_enumeratorize_with_size((obj), ID2SYM(rb_frame_this_func()), (argc), (argv), (size_fn)); \
133
133
  } \
134
134
  } while (0)
135
- #endif
136
- #else
137
- #undef RETURN_SIZED_ENUMERATOR
138
- #define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) \
139
- return rb_enumeratorize((obj), ID2SYM(rb_frame_this_func()), (argc), (argv)); \
135
+ #endif
136
+ #else
137
+ #undef RETURN_SIZED_ENUMERATOR
138
+ #define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn) \
139
+ return rb_enumeratorize((obj), ID2SYM(rb_frame_this_func()), (argc), (argv)); \
140
140
  } \
141
141
  } while (0)
142
- #endif
142
+ #endif
143
143
 
144
144
  #define NM_DECL_ENUM(enum_type, name) nm::enum_type name
145
145
  #define NM_DECL_STRUCT(type, name) type name;
@@ -149,8 +149,8 @@
149
149
  size_t dim; \
150
150
  size_t* shape; \
151
151
  size_t* offset; \
152
- int count; \
153
- STORAGE* src;
152
+ int count; \
153
+ STORAGE* src;
154
154
 
155
155
  #define NM_DEF_STORAGE_CHILD_STRUCT_PRE(name) struct name : STORAGE {
156
156
  #define NM_DEF_STORAGE_STRUCT_POST(name) };
@@ -180,10 +180,10 @@
180
180
  size_t dim; \
181
181
  size_t* shape; \
182
182
  size_t* offset; \
183
- int count; \
184
- STORAGE* src;
183
+ int count; \
184
+ NM_DECL_STRUCT(STORAGE*, src);
185
185
  #define NM_DEF_STORAGE_CHILD_STRUCT_PRE(name) typedef struct NM_ ## name { \
186
- NM_DEF_STORAGE_ELEMENTS;
186
+ NM_DEF_STORAGE_ELEMENTS;
187
187
 
188
188
  #define NM_DEF_STORAGE_STRUCT_POST(name) } NM_ ## name;
189
189
 
@@ -207,7 +207,7 @@
207
207
  * Types
208
208
  */
209
209
 
210
- #define NM_NUM_DTYPES 13 // data/data.h
210
+ #define NM_NUM_DTYPES 10 // data/data.h
211
211
  #define NM_NUM_STYPES 3 // storage/storage.h
212
212
 
213
213
  //#ifdef __cplusplus
@@ -220,19 +220,16 @@ NM_DEF_ENUM(stype_t, DENSE_STORE = 0,
220
220
  YALE_STORE = 2);
221
221
 
222
222
  /* Data Type */
223
- NM_DEF_ENUM(dtype_t, BYTE = 0, // unsigned char
224
- INT8 = 1, // char
225
- INT16 = 2, // short
226
- INT32 = 3, // int
227
- INT64 = 4, // long
228
- FLOAT32 = 5, // float
229
- FLOAT64 = 6, // double
230
- COMPLEX64 = 7, // Complex64 class
231
- COMPLEX128 = 8, // Complex128 class
232
- RATIONAL32 = 9, // Rational32 class
233
- RATIONAL64 = 10, // Rational64 class
234
- RATIONAL128 = 11, // Rational128 class
235
- RUBYOBJ = 12); // Ruby VALUE type
223
+ NM_DEF_ENUM(dtype_t, BYTE = 0, // unsigned char
224
+ INT8 = 1, // char
225
+ INT16 = 2, // short
226
+ INT32 = 3, // int
227
+ INT64 = 4, // long
228
+ FLOAT32 = 5, // float
229
+ FLOAT64 = 6, // double
230
+ COMPLEX64 = 7, // Complex64 class
231
+ COMPLEX128 = 8, // Complex128 class
232
+ RUBYOBJ = 9); // Ruby VALUE type
236
233
 
237
234
  NM_DEF_ENUM(symm_t, NONSYMM = 0,
238
235
  SYMM = 1,
@@ -250,16 +247,16 @@ NM_DEF_STORAGE_STRUCT;
250
247
 
251
248
  /* Dense Storage */
252
249
  NM_DEF_STORAGE_CHILD_STRUCT_PRE(DENSE_STORAGE); // struct DENSE_STORAGE : STORAGE {
253
- void* elements; // should go first to align with void* a in yale and NODE* first in list.
254
- size_t* stride;
250
+ void* elements; // should go first to align with void* a in yale and NODE* first in list.
251
+ size_t* stride;
255
252
  NM_DEF_STORAGE_STRUCT_POST(DENSE_STORAGE); // };
256
253
 
257
254
  /* Yale Storage */
258
255
  NM_DEF_STORAGE_CHILD_STRUCT_PRE(YALE_STORAGE);
259
- void* a; // should go first
260
- size_t ndnz; // Strictly non-diagonal non-zero count!
261
- size_t capacity;
262
- size_t* ija;
256
+ void* a; // should go first
257
+ size_t ndnz; // Strictly non-diagonal non-zero count!
258
+ size_t capacity;
259
+ size_t* ija;
263
260
  NM_DEF_STORAGE_STRUCT_POST(YALE_STORAGE);
264
261
 
265
262
  // FIXME: NODE and LIST should be put in some kind of namespace or something, at least in C++.
@@ -275,9 +272,9 @@ NM_DEF_STRUCT_POST(LIST); // };
275
272
 
276
273
  /* List-of-Lists Storage */
277
274
  NM_DEF_STORAGE_CHILD_STRUCT_PRE(LIST_STORAGE); // struct LIST_STORAGE : STORAGE {
278
- // List storage specific elements.
279
- void* default_val;
280
- NM_DECL_STRUCT(LIST*, rows); // LIST* rows;
275
+ // List storage specific elements.
276
+ void* default_val;
277
+ NM_DECL_STRUCT(LIST*, rows); // LIST* rows;
281
278
  NM_DEF_STORAGE_STRUCT_POST(LIST_STORAGE); // };
282
279
 
283
280
 
@@ -329,7 +326,7 @@ NM_DEF_STRUCT_POST(NM_GC_HOLDER); // };
329
326
  #define NM_DENSE_COUNT(val) (nm_storage_count_max_elements(NM_STORAGE_DENSE(val)))
330
327
  #define NM_DENSE_ELEMENTS(val) (NM_STORAGE_DENSE(val)->elements)
331
328
  #define NM_SIZEOF_DTYPE(val) (DTYPE_SIZES[NM_DTYPE(val)])
332
- #define NM_REF(val,slice) (RefFuncs[NM_STYPE(val)]( NM_STORAGE(val), slice, NM_SIZEOF_DTYPE(val) ))
329
+ #define NM_REF(val,slice) (RefFuncs[NM_STYPE(val)]( NM_STORAGE(val), slice, NM_SIZEOF_DTYPE(val) ))
333
330
 
334
331
  #define NM_MAX(a,b) (((a)>(b))?(a):(b))
335
332
  #define NM_MIN(a,b) (((a)>(b))?(b):(a))
@@ -348,8 +345,8 @@ NM_DEF_STRUCT_POST(NM_GC_HOLDER); // };
348
345
  (rb_obj_is_kind_of(obj, cNVector) == Qtrue)
349
346
 
350
347
  #define RB_P(OBJ) \
351
- rb_funcall(rb_stderr, rb_intern("print"), 1, rb_funcall(OBJ, rb_intern("object_id"), 0)); \
352
- rb_funcall(rb_stderr, rb_intern("puts"), 1, rb_funcall(OBJ, rb_intern("inspect"), 0));
348
+ rb_funcall(rb_stderr, rb_intern("print"), 1, rb_funcall(OBJ, rb_intern("object_id"), 0)); \
349
+ rb_funcall(rb_stderr, rb_intern("puts"), 1, rb_funcall(OBJ, rb_intern("inspect"), 0));
353
350
 
354
351
 
355
352
  #ifdef __cplusplus
@@ -358,43 +355,54 @@ typedef VALUE (*METHOD)(...);
358
355
  //}; // end of namespace nm
359
356
  #endif
360
357
 
358
+ // In the init code below, we need to use NMATRIX for c++ and NM_NMATRIX for c
359
+ // this macro chooses the correct one:
360
+ #ifdef __cplusplus
361
+ #define _NMATRIX NMATRIX
362
+ #define _STORAGE STORAGE
363
+ #else
364
+ #define _NMATRIX NM_NMATRIX
365
+ #define _STORAGE NM_STORAGE
366
+ #endif
367
+
361
368
  /*
362
369
  * Functions
363
370
  */
364
371
 
365
372
  #ifdef __cplusplus
366
-
367
373
  extern "C" {
368
374
  #endif
369
375
 
370
- void Init_nmatrix();
371
-
372
- // External API
373
- VALUE rb_nmatrix_dense_create(NM_DECL_ENUM(dtype_t, dtype), size_t* shape, size_t dim, void* elements, size_t length);
374
- VALUE rb_nvector_dense_create(NM_DECL_ENUM(dtype_t, dtype), void* elements, size_t length);
376
+ void Init_nmatrix();
377
+ // External API
378
+ VALUE rb_nmatrix_dense_create(NM_DECL_ENUM(dtype_t, dtype), size_t* shape, size_t dim, void* elements, size_t length);
379
+ VALUE rb_nvector_dense_create(NM_DECL_ENUM(dtype_t, dtype), void* elements, size_t length);
375
380
 
376
- NM_DECL_ENUM(dtype_t, nm_dtype_guess(VALUE)); // (This is a function)
377
- NM_DECL_ENUM(dtype_t, nm_dtype_min(VALUE));
381
+ NM_DECL_ENUM(dtype_t, nm_dtype_guess(VALUE)); // (This is a function)
382
+ NM_DECL_ENUM(dtype_t, nm_dtype_min(VALUE));
378
383
 
379
384
  // Non-API functions needed by other cpp files.
380
- NMATRIX* nm_create(NM_DECL_ENUM(stype_t, stype), STORAGE* storage);
381
- 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);
382
- VALUE nm_cast(VALUE self, VALUE new_stype_symbol, VALUE new_dtype_symbol, VALUE init);
383
- void nm_mark(NMATRIX* mat);
384
- void nm_delete(NMATRIX* mat);
385
- void nm_delete_ref(NMATRIX* mat);
385
+ _NMATRIX* nm_create(NM_DECL_ENUM(stype_t, stype), _STORAGE* storage);
386
+ _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);
387
+ VALUE nm_cast(VALUE self, VALUE new_stype_symbol, VALUE new_dtype_symbol, VALUE init);
388
+ void nm_mark(_NMATRIX* mat);
389
+ void nm_delete(_NMATRIX* mat);
390
+ void nm_delete_ref(_NMATRIX* mat);
386
391
  void nm_register_values(VALUE* vals, size_t n);
387
392
  void nm_register_value(VALUE* val);
388
393
  void nm_unregister_value(VALUE* val);
389
394
  void nm_unregister_values(VALUE* vals, size_t n);
390
- void nm_register_storage(NM_DECL_ENUM(stype_t, stype), const STORAGE* storage);
391
- void nm_unregister_storage(NM_DECL_ENUM(stype_t, stype), const STORAGE* storage);
392
- void nm_register_nmatrix(NMATRIX* nmatrix);
393
- void nm_unregister_nmatrix(NMATRIX* nmatrix);
394
- void nm_completely_unregister_value(VALUE* val);
395
+ void nm_register_storage(NM_DECL_ENUM(stype_t, stype), const _STORAGE* storage);
396
+ void nm_unregister_storage(NM_DECL_ENUM(stype_t, stype), const _STORAGE* storage);
397
+ void nm_register_nmatrix(_NMATRIX* nmatrix);
398
+ void nm_unregister_nmatrix(_NMATRIX* nmatrix);
399
+ void nm_completely_unregister_value(VALUE* val);
400
+
395
401
  #ifdef __cplusplus
396
402
  }
397
-
398
403
  #endif
399
404
 
405
+ #undef _NMATRIX
406
+ #undef _STORAGE
407
+
400
408
  #endif // NMATRIX_H