nmatrix 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/.gitignore +27 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +3 -5
  4. data/Guardfile +6 -0
  5. data/History.txt +33 -0
  6. data/Manifest.txt +41 -38
  7. data/README.rdoc +88 -11
  8. data/Rakefile +35 -53
  9. data/ext/nmatrix/data/complex.h +372 -0
  10. data/ext/nmatrix/data/data.cpp +275 -0
  11. data/ext/nmatrix/data/data.h +707 -0
  12. data/ext/nmatrix/data/rational.h +421 -0
  13. data/ext/nmatrix/data/ruby_object.h +446 -0
  14. data/ext/nmatrix/extconf.rb +101 -51
  15. data/ext/nmatrix/new_extconf.rb +56 -0
  16. data/ext/nmatrix/nmatrix.cpp +1609 -0
  17. data/ext/nmatrix/nmatrix.h +265 -849
  18. data/ext/nmatrix/ruby_constants.cpp +134 -0
  19. data/ext/nmatrix/ruby_constants.h +103 -0
  20. data/ext/nmatrix/storage/common.cpp +70 -0
  21. data/ext/nmatrix/storage/common.h +170 -0
  22. data/ext/nmatrix/storage/dense.cpp +665 -0
  23. data/ext/nmatrix/storage/dense.h +116 -0
  24. data/ext/nmatrix/storage/list.cpp +1088 -0
  25. data/ext/nmatrix/storage/list.h +129 -0
  26. data/ext/nmatrix/storage/storage.cpp +658 -0
  27. data/ext/nmatrix/storage/storage.h +99 -0
  28. data/ext/nmatrix/storage/yale.cpp +1601 -0
  29. data/ext/nmatrix/storage/yale.h +208 -0
  30. data/ext/nmatrix/ttable_helper.rb +126 -0
  31. data/ext/nmatrix/{yale/smmp1_header.template.c → types.h} +36 -9
  32. data/ext/nmatrix/util/io.cpp +295 -0
  33. data/ext/nmatrix/util/io.h +117 -0
  34. data/ext/nmatrix/util/lapack.h +1175 -0
  35. data/ext/nmatrix/util/math.cpp +557 -0
  36. data/ext/nmatrix/util/math.h +1363 -0
  37. data/ext/nmatrix/util/sl_list.cpp +475 -0
  38. data/ext/nmatrix/util/sl_list.h +255 -0
  39. data/ext/nmatrix/util/util.h +78 -0
  40. data/lib/nmatrix/blas.rb +70 -0
  41. data/lib/nmatrix/io/mat5_reader.rb +567 -0
  42. data/lib/nmatrix/io/mat_reader.rb +162 -0
  43. data/lib/{string.rb → nmatrix/monkeys.rb} +49 -2
  44. data/lib/nmatrix/nmatrix.rb +199 -0
  45. data/lib/nmatrix/nvector.rb +103 -0
  46. data/lib/nmatrix/version.rb +27 -0
  47. data/lib/nmatrix.rb +22 -230
  48. data/nmatrix.gemspec +59 -0
  49. data/scripts/mac-brew-gcc.sh +47 -0
  50. data/spec/4x4_sparse.mat +0 -0
  51. data/spec/4x5_dense.mat +0 -0
  52. data/spec/blas_spec.rb +47 -0
  53. data/spec/elementwise_spec.rb +164 -0
  54. data/spec/io_spec.rb +60 -0
  55. data/spec/lapack_spec.rb +52 -0
  56. data/spec/math_spec.rb +96 -0
  57. data/spec/nmatrix_spec.rb +93 -89
  58. data/spec/nmatrix_yale_spec.rb +52 -36
  59. data/spec/nvector_spec.rb +1 -1
  60. data/spec/slice_spec.rb +257 -0
  61. data/spec/spec_helper.rb +51 -0
  62. data/spec/utm5940.mtx +83844 -0
  63. metadata +113 -71
  64. data/.autotest +0 -23
  65. data/.gemtest +0 -0
  66. data/ext/nmatrix/cblas.c +0 -150
  67. data/ext/nmatrix/dense/blas_header.template.c +0 -52
  68. data/ext/nmatrix/dense/elementwise.template.c +0 -107
  69. data/ext/nmatrix/dense/gemm.template.c +0 -159
  70. data/ext/nmatrix/dense/gemv.template.c +0 -130
  71. data/ext/nmatrix/dense/rationalmath.template.c +0 -68
  72. data/ext/nmatrix/dense.c +0 -307
  73. data/ext/nmatrix/depend +0 -18
  74. data/ext/nmatrix/generator/syntax_tree.rb +0 -481
  75. data/ext/nmatrix/generator.rb +0 -594
  76. data/ext/nmatrix/list.c +0 -774
  77. data/ext/nmatrix/nmatrix.c +0 -1977
  78. data/ext/nmatrix/rational.c +0 -98
  79. data/ext/nmatrix/yale/complexmath.template.c +0 -71
  80. data/ext/nmatrix/yale/elementwise.template.c +0 -46
  81. data/ext/nmatrix/yale/elementwise_op.template.c +0 -73
  82. data/ext/nmatrix/yale/numbmm.template.c +0 -94
  83. data/ext/nmatrix/yale/smmp1.template.c +0 -21
  84. data/ext/nmatrix/yale/smmp2.template.c +0 -43
  85. data/ext/nmatrix/yale/smmp2_header.template.c +0 -46
  86. data/ext/nmatrix/yale/sort_columns.template.c +0 -56
  87. data/ext/nmatrix/yale/symbmm.template.c +0 -54
  88. data/ext/nmatrix/yale/transp.template.c +0 -68
  89. data/ext/nmatrix/yale.c +0 -726
  90. data/lib/array.rb +0 -67
  91. data/spec/syntax_tree_spec.rb +0 -46
@@ -1,159 +0,0 @@
1
-
2
- int %%TYPE_ABBREV%%gemm(enum CBLAS_TRANSPOSE TransA, enum CBLAS_TRANSPOSE TransB,
3
- const int M, const int N, const int K, const %%TYPE%% alpha,
4
- const %%TYPE%%* A, const int lda,
5
- const %%TYPE%%* B, const int ldb, const %%TYPE%% beta,
6
- %%TYPE%%* C, const int ldc)
7
- {
8
- int num_rows_a, /*num_cols_a,*/ num_rows_b; // nrowa, ncola, nrowb
9
-
10
- // use longest possible type for intermediate value storage:
11
- %%TYPE_LONG%% temp;
12
- %%= if [:rational,:complex,:value].include?(dtype.type); "#{dtype.long_dtype.sizeof} temp1, temp2;"; end%%
13
- int i, j, l;
14
-
15
- if (TransA == CblasNoTrans) num_rows_a = M;
16
- else num_rows_a = K;
17
-
18
- if (TransB == CblasNoTrans) num_rows_b = K;
19
- else num_rows_b = N;
20
-
21
- // Test the input parameters
22
- if (TransA < 111 || TransA > 113) {
23
- fprintf(stderr, "GEMM: TransA must be CblasNoTrans, CblasTrans, or CblasConjTrans\n");
24
- return 0;
25
- } else if (TransB < 111 || TransB > 113) {
26
- fprintf(stderr, "GEMM: TransB must be CblasNoTrans, CblasTrans, or CblasConjTrans\n");
27
- return 0;
28
- } else if (M < 0) {
29
- fprintf(stderr, "GEMM: Expected M >= 0\n");
30
- return 0;
31
- } else if (N < 0) {
32
- fprintf(stderr, "GEMM: Expected N >= 0\n");
33
- return 0;
34
- } else if (K < 0) {
35
- fprintf(stderr, "GEMM: Expected K >= 0\n");
36
- return 0;
37
- } else if (lda < NM_MAX(1, num_rows_a)) {
38
- fprintf(stderr, "GEMM: Expected lda >= max(1, num_rows_a), with num_rows_a = %d; got lda=%d\n", num_rows_a, lda);
39
- return 0;
40
- } else if (ldb < NM_MAX(1, num_rows_b)) {
41
- fprintf(stderr, "GEMM: Expected ldb >= max(1, num_rows_b), with num_rows_b = %d; got ldb=%d\n", num_rows_b, ldb);
42
- return 0;
43
- } else if (ldc < NM_MAX(1,M)) {
44
- fprintf(stderr, "GEMM: Expected ldc >= max(1,M) with M=%d; got ldc=%d\n", M, ldc);
45
- return 0;
46
- }
47
-
48
- // Quick return if possible
49
- if (!M || !N || (%%TYPE alpha == 0%% || !K) && %%TYPE beta == 1%%) return 0;
50
-
51
- // For alpha = 0
52
- if (%%TYPE alpha == 0%%) {
53
- if (%%TYPE beta == 0%%) {
54
- for (j = 0; j < N; ++j)
55
- for (i = 0; i < M; ++i) {
56
- %%TYPE C[i+j*ldc] = 0%%
57
- }
58
- } else {
59
- for (j = 0; j < N; ++j)
60
- for (i = 0; i < M; ++i) {
61
- %%TYPE C[i+j*ldc] *= beta%%
62
- }
63
- }
64
- return 0;
65
- }
66
-
67
- // Start the operations
68
- if (TransB == CblasNoTrans) {
69
- if (TransA == CblasNoTrans) {
70
- // C = alpha*A*B+beta*C
71
- for (j = 0; j < N; ++j) {
72
- if (%%TYPE beta == 0%%) {
73
- for (i = 0; i < M; ++i) {
74
- %%TYPE C[i+j*ldc] = 0%%
75
- }
76
- } else if (%%TYPE beta != 1%%) {
77
- for (i = 0; i < M; ++i) {
78
- %%TYPE C[i+j*ldc] *= beta%%
79
- }
80
- }
81
-
82
- for (l = 0; l < K; ++l) {
83
- if (%%TYPE B[l+j*ldb] != 0%%) {
84
- %%TYPE_LONG temp = alpha * B[l+j*ldb]%%
85
- for (i = 0; i < M; ++i) {
86
- %%TYPE C[i+j*ldc] += A[i+l*lda] * temp%%
87
- }
88
- }
89
- }
90
- }
91
-
92
- } else {
93
-
94
- // C = alpha*A**T*B + beta*C
95
- for (j = 0; j < N; ++j) {
96
- for (i = 0; i < M; ++i) {
97
- %%TYPE temp = 0%%
98
- for (l = 0; l < K; ++l) {
99
- %%TYPE_LONG temp += A[l+i*lda] * B[l+j*ldb]%%
100
- }
101
-
102
- if (%%TYPE beta == 0%%) {
103
- %%TYPE C[i+j*ldc] = alpha*temp%%
104
- } else {
105
- %%TYPE C[i+j*ldc] = alpha*temp + beta*C[i+j*ldc]%%
106
- }
107
- }
108
- }
109
-
110
- }
111
-
112
- } else if (TransA == CblasNoTrans) {
113
-
114
- // C = alpha*A*B**T + beta*C
115
- for (j = 0; j < N; ++j) {
116
- if (%%TYPE beta == 0%%) {
117
- for (i = 0; i < M; ++i) {
118
- %%TYPE C[i+j*ldc] = 0%%
119
- }
120
- } else if (%%TYPE beta != 1%%) {
121
- for (i = 0; i < M; ++i) {
122
- %%TYPE C[i+j*ldc] *= beta%%
123
- }
124
- }
125
-
126
- for (l = 0; l < K; ++l) {
127
- if (%%TYPE B[j+l*ldb] != 0%%) {
128
- %%TYPE_LONG temp = alpha * B[j+l*ldb]%%
129
- for (i = 0; i < M; ++i) {
130
- %%TYPE C[i+j*ldc] += A[i+l*lda] * temp%%
131
- }
132
- }
133
- }
134
-
135
- }
136
-
137
- } else {
138
-
139
- // C = alpha*A**T*B**T + beta*C
140
- for (j = 0; j < N; ++j) {
141
- for (i = 0; i < M; ++i) {
142
- %%TYPE temp = 0%%
143
- for (l = 0; l < K; ++l) {
144
- %%TYPE_LONG temp += A[l+i*lda] * B[j+l*ldb]%%
145
- }
146
-
147
- if (%%TYPE beta == 0%%) {
148
- %%TYPE C[i+j*ldc] = alpha*temp%%
149
- } else {
150
- %%TYPE C[i+j*ldc] = alpha*temp + beta*C[i+j*ldc]%%
151
- }
152
- }
153
- }
154
-
155
- }
156
-
157
- return 0;
158
- }
159
-
@@ -1,130 +0,0 @@
1
-
2
- int %%TYPE_ABBREV%%gemv(enum CBLAS_TRANSPOSE Trans, const size_t M, const size_t N, const %%TYPE%% alpha,
3
- const %%TYPE%%* A, const size_t lda, const %%TYPE%%* X, const int incX, const %%TYPE%% beta, %%TYPE%%* Y, const int incY)
4
- {
5
- size_t lenX, lenY, i, j;
6
- int kx, ky, iy, jx, jy, ix;
7
- %%TYPE_LONG%% temp;
8
- %%= if [:rational,:complex,:value].include?(dtype.type); "#{dtype.long_dtype.sizeof} temp1;"; end%%
9
-
10
- // Test the input parameters
11
- if (Trans < 111 || Trans > 113) {
12
- fprintf(stderr, "IGEMV: TransA must be CblasNoTrans, CblasTrans, or CblasConjTrans\n");
13
- return 0;
14
- } else if (lda < NM_MAX(1, N)) {
15
- fprintf(stderr, "IGEMV: Expected lda >= max(1, N), with N = %d; got lda=%d\n", N, lda);
16
- return 0;
17
- } else if (incX == 0) {
18
- fprintf(stderr, "IGEMV: Expected incX != 0\n");
19
- return 0;
20
- } else if (incY == 0) {
21
- fprintf(stderr, "IGEMV: Expected incY != 0\n");
22
- return 0;
23
- }
24
-
25
- // Quick return if possible
26
- if (!M || !N || %%TYPE alpha == 0%% && %%TYPE beta == 1%%) return 0;
27
-
28
- if (Trans == CblasNoTrans) {
29
- lenX = N;
30
- lenY = M;
31
- } else {
32
- lenX = M;
33
- lenY = N;
34
- }
35
-
36
- if (incX > 0) kx = 0;
37
- else kx = (lenX - 1) * -incX;
38
-
39
- if (incY > 0) ky = 0;
40
- else ky = (lenY - 1) * -incY;
41
-
42
- // Start the operations. In this version, the elements of A are accessed sequentially with one pass through A.
43
- if (%%TYPE beta != 1%%) {
44
- if (incY == 1) {
45
- if (%%TYPE beta == 0%%) {
46
- for (i = 0; i < lenY; ++i) {
47
- %%TYPE Y[i] = 0%%
48
- }
49
- } else {
50
- for (i = 0; i < lenY; ++i) {
51
- %%TYPE Y[i] *= beta%%
52
- }
53
- }
54
- } else {
55
- iy = ky;
56
- if (%%TYPE beta == 0%%) {
57
- for (i = 0; i < lenY; ++i) {
58
- %%TYPE Y[iy] = 0%%
59
- iy += incY;
60
- }
61
- } else {
62
- for (i = 0; i < lenY; ++i) {
63
- %%TYPE Y[iy] *= beta%%
64
- iy += incY;
65
- }
66
- }
67
- }
68
- }
69
-
70
- if (%%TYPE alpha == 0%%) return 0;
71
-
72
- if (Trans == CblasNoTrans) {
73
-
74
- // Form y := alpha*A*x + y.
75
- jx = kx;
76
- if (incY == 1) {
77
- for (j = 0; j < N; ++j) {
78
- if (%%TYPE X[jx] != 0%%) {
79
- %%TYPE_LONG temp = alpha * X[jx]%%
80
- for (i = 0; i < M; ++i) {
81
- %%TYPE Y[i] += A[j+i*lda] * temp%%
82
- }
83
- }
84
- jx += incX;
85
- }
86
- } else {
87
- for (j = 0; j < N; ++j) {
88
- if (%%TYPE X[jx] != 0%%) {
89
- %%TYPE_LONG temp = alpha * X[jx]%%
90
- iy = ky;
91
- for (i = 0; i < M; ++i) {
92
- %%TYPE Y[iy] += A[j+i*lda] * temp%%
93
- iy += incY;
94
- }
95
- }
96
- jx += incX;
97
- }
98
- }
99
-
100
- } else { // TODO: Check that indices are correct! They're switched for C.
101
-
102
- // Form y := alpha*A**T*x + y.
103
- jy = ky;
104
-
105
- if (incX == 1) {
106
- for (j = 0; j < N; ++j) {
107
- %%TYPE temp = 0%%
108
- for (i = 0; i < M; ++i) {
109
- %%TYPE_LONG temp += A[j+i*lda]*X[j]%%
110
- }
111
- %%TYPE Y[jy] += alpha * temp%%
112
- jy += incY;
113
- }
114
- } else {
115
- for (j = 0; j < N; ++j) {
116
- %%TYPE temp = 0%%
117
- ix = kx;
118
- for (i = 0; i < M; ++i) {
119
- %%TYPE_LONG temp += A[j+i*lda] * X[ix]%%
120
- ix += incX;
121
- }
122
-
123
- %%TYPE Y[jy] += alpha * temp%%
124
- jy += incY;
125
- }
126
- }
127
- }
128
-
129
- return 0;
130
- } // end of GEMV
@@ -1,68 +0,0 @@
1
-
2
- inline %%TYPE%% BOOL2%%= dtype.id.to_s.upcase%%(bool expr) {
3
- %%TYPE%% result;
4
- result.n = expr;
5
- result.d = 1;
6
- return result;
7
- }
8
-
9
- inline %%TYPE%% %%TYPE_ABBREV%%_bang(%%= dtype.sym == :rational128 ? "int64_t n, int64_t d" : (dtype.sym == :rational64 ? "int32_t n, int32_t d" : "int16_t n, int16_t d")%%)
10
- {
11
- %%TYPE%% result = {!n, 1};
12
- return result;
13
- }
14
-
15
- inline %%TYPE%% %%TYPE_ABBREV%%_negate(%%= dtype.sym == :rational128 ? "int64_t n, int64_t d" : (dtype.sym == :rational64 ? "int32_t n, int32_t d" : "int16_t n, int16_t d")%%)
16
- {
17
- %%TYPE%% result = {-n, -d};
18
- return result;
19
- }
20
-
21
- inline %%TYPE%% %%TYPE_ABBREV%%_muldiv(int64_t anum, int64_t aden, int64_t bnum, int64_t bden, char k) {
22
- %%TYPE%% result;
23
- int64_t t, g1, g2;
24
-
25
- if (k == '/') { // Switch numerator and denominator for division (and move sign)
26
- if (bnum < 0) {
27
- anum = -anum;
28
- bnum = -bnum;
29
- }
30
- t = bnum;
31
- bnum = bden;
32
- bden = t;
33
- }
34
-
35
- g1 = nmrb_gcd(anum, bden);
36
- g2 = nmrb_gcd(aden, bnum);
37
-
38
- result.n = (anum / g1) * (bnum / g2);
39
- result.d = (aden / g2) * (bden / g1);
40
-
41
- return result;
42
- }
43
-
44
- inline %%TYPE%% %%TYPE_ABBREV%%_addsub(int64_t anum, int64_t aden, int64_t bnum, int64_t bden, char k) {
45
- %%TYPE%% result;
46
-
47
- int64_t ig = nmrb_gcd(aden, bden);
48
- int64_t a = anum * (bden / ig);
49
- int64_t b = bnum * (aden / ig);
50
- int64_t c;
51
-
52
- if (k == '+') c=a+b;
53
- else c=a-b;
54
-
55
- b = aden / ig;
56
- ig = nmrb_gcd(aden, ig);
57
- result.n = c / ig;
58
- a = bden / ig;
59
- result.d = a*b;
60
-
61
- return result;
62
- }
63
-
64
- inline %%TYPE%% %%TYPE_ABBREV%%_mod(%%= dtype.sym == :rational128 ? "int64_t anum, int64_t aden, int64_t bnum, int64_t bden" : (dtype.sym == :rational64 ? "int32_t anum, int32_t aden, int32_t bnum, int32_t bden" : "int16_t anum, int16_t aden, int16_t bnum, int16_t bden")%%)
65
- {
66
- // a - (b * int(a/b))
67
- return %%TYPE_ABBREV%%_addsub(anum, aden, bnum*((int64_t)((anum * bden) / (aden * bnum))), bden, '-');
68
- }
data/ext/nmatrix/dense.c DELETED
@@ -1,307 +0,0 @@
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 - 2012, Ruby Science Foundation
13
- // NMatrix is Copyright (c) 2012, 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
- // == dense.c
25
- //
26
- // Dense n-dimensional matrix storage.
27
-
28
- #ifndef DENSE_C
29
- #define DENSE_C
30
-
31
- #include <ruby.h>
32
-
33
- #include "nmatrix.h"
34
-
35
-
36
- /* Calculate the number of elements in the dense storage structure, based on shape and rank */
37
- size_t count_dense_storage_elements(const DENSE_STORAGE* s) {
38
- size_t i;
39
- size_t count = 1;
40
- for (i = 0; i < s->rank; ++i) count *= s->shape[i];
41
- return count;
42
- }
43
-
44
-
45
- // Do these two dense matrices of the same dtype have exactly the same contents?
46
- bool dense_storage_eqeq(const DENSE_STORAGE* left, const DENSE_STORAGE* right) {
47
- return !memcmp(left->elements, right->elements, count_dense_storage_elements(left) / nm_sizeof[left->dtype]);
48
- }
49
-
50
-
51
- size_t dense_storage_pos(DENSE_STORAGE* s, size_t* coords) {
52
- size_t k, l;
53
- size_t inner, outer = 0;
54
- for (k = 0; k < s->rank; ++k) {
55
- inner = coords[k];
56
- for (l = k+1; l < s->rank; ++l) {
57
- inner *= s->shape[l];
58
- }
59
- outer += inner;
60
- }
61
- return outer;
62
- }
63
-
64
-
65
-
66
- void* dense_storage_get(DENSE_STORAGE* s, size_t* coords) {
67
- return (char*)(s->elements) + dense_storage_pos(s, coords) * nm_sizeof[s->dtype];
68
- }
69
-
70
-
71
- /* Does not free passed-in value! Different from list_storage_insert. */
72
- void dense_storage_set(DENSE_STORAGE* s, size_t* coords, void* val) {
73
- memcpy((char*)(s->elements) + dense_storage_pos(s, coords) * nm_sizeof[s->dtype], val, nm_sizeof[s->dtype]);
74
- }
75
-
76
-
77
- DENSE_STORAGE* copy_dense_storage(DENSE_STORAGE* rhs) {
78
- DENSE_STORAGE* lhs;
79
- size_t count = count_dense_storage_elements(rhs), p;
80
- size_t* shape = ALLOC_N(size_t, rhs->rank);
81
- if (!shape) return NULL;
82
-
83
- // copy shape array
84
- for (p = 0; p < rhs->rank; ++p)
85
- shape[p] = rhs->shape[p];
86
-
87
- lhs = create_dense_storage(rhs->dtype, shape, rhs->rank, NULL, 0);
88
-
89
- if (lhs && count) // ensure that allocation worked before copying
90
- memcpy(lhs->elements, rhs->elements, nm_sizeof[rhs->dtype] * count);
91
-
92
- return lhs;
93
- }
94
-
95
-
96
- DENSE_STORAGE* cast_copy_dense_storage(DENSE_STORAGE* rhs, int8_t new_dtype) {
97
- DENSE_STORAGE* lhs;
98
- size_t count = count_dense_storage_elements(rhs), p;
99
- size_t* shape = ALLOC_N(size_t, rhs->rank);
100
- if (!shape) return NULL;
101
-
102
- // copy shape array
103
- for (p = 0; p < rhs->rank; ++p) shape[p] = rhs->shape[p];
104
-
105
- lhs = create_dense_storage(new_dtype, shape, rhs->rank, NULL, 0);
106
-
107
- if (lhs && count) // ensure that allocation worked before copying
108
- if (lhs->dtype == rhs->dtype)
109
- memcpy(lhs->elements, rhs->elements, nm_sizeof[rhs->dtype] * count);
110
- else
111
- SetFuncs[lhs->dtype][rhs->dtype](count, lhs->elements, nm_sizeof[lhs->dtype], rhs->elements, nm_sizeof[rhs->dtype]);
112
-
113
-
114
- return lhs;
115
- }
116
-
117
-
118
-
119
- // Copy a set of default values into dense
120
- static inline void cast_copy_dense_list_default(void* lhs, void* default_val, int8_t l_dtype, int8_t r_dtype, size_t* pos, const size_t* shape, size_t rank, size_t max_elements, size_t recursions) {
121
- size_t i;
122
-
123
- for (i = 0; i < shape[rank-1-recursions]; ++i, ++(*pos)) {
124
- //fprintf(stderr, "default: pos = %u, dim = %u\t", *pos, shape[rank-1-recursions]);
125
-
126
- if (recursions == 0) { cast_copy_value_single((char*)lhs + (*pos)*nm_sizeof[l_dtype], default_val, l_dtype, r_dtype); fprintf(stderr, "zero\n"); }
127
- else { cast_copy_dense_list_default(lhs, default_val, l_dtype, r_dtype, pos, shape, rank, max_elements, recursions-1); fprintf(stderr, "column of zeros\n"); }
128
- }
129
- --(*pos);
130
- }
131
-
132
-
133
- // Copy list contents into dense recursively
134
- static void cast_copy_dense_list_contents(void* lhs, const LIST* rhs, void* default_val, int8_t l_dtype, int8_t r_dtype, size_t* pos, const size_t* shape, size_t rank, size_t max_elements, size_t recursions) {
135
- NODE *curr = rhs->first;
136
- int last_key = -1;
137
- size_t i = 0;
138
-
139
- for (i = 0; i < shape[rank-1-recursions]; ++i, ++(*pos)) {
140
-
141
- if (!curr || (curr->key > (size_t)(last_key+1))) {
142
- //fprintf(stderr, "pos = %u, dim = %u, curr->key XX, last_key+1 = %d\t", *pos, shape[rank-1-recursions], last_key+1);
143
- if (recursions == 0) cast_copy_value_single((char*)lhs + (*pos)*nm_sizeof[l_dtype], default_val, l_dtype, r_dtype); //fprintf(stderr, "zero\n"); }
144
- else cast_copy_dense_list_default(lhs, default_val, l_dtype, r_dtype, pos, shape, rank, max_elements, recursions-1); //fprintf(stderr, "column of zeros\n"); }
145
-
146
- ++last_key;
147
- } else {
148
- //fprintf(stderr, "pos = %u, dim = %u, curr->key = %u, last_key+1 = %d\t", *pos, shape[rank-1-recursions], curr->key, last_key+1);
149
- if (recursions == 0) cast_copy_value_single((char*)lhs + (*pos)*nm_sizeof[l_dtype], curr->val, l_dtype, r_dtype); //fprintf(stderr, "value\n"); }
150
- else cast_copy_dense_list_contents(lhs, curr->val, default_val, l_dtype, r_dtype, pos, shape, rank, max_elements, recursions-1); //fprintf(stderr, "column of values\n"); }
151
-
152
- last_key = curr->key;
153
- curr = curr->next;
154
- }
155
- }
156
- --(*pos);
157
- }
158
-
159
-
160
- // Convert (by creating a copy) from list storage to dense storage.
161
- DENSE_STORAGE* scast_copy_dense_list(const LIST_STORAGE* rhs, int8_t l_dtype) {
162
- DENSE_STORAGE* lhs;
163
- size_t pos = 0; // position in lhs->elements
164
-
165
- // allocate and copy shape
166
- size_t* shape = ALLOC_N(size_t, rhs->rank);
167
- memcpy(shape, rhs->shape, rhs->rank * sizeof(size_t));
168
-
169
- lhs = create_dense_storage(l_dtype, shape, rhs->rank, NULL, 0);
170
-
171
- // recursively copy the contents
172
- cast_copy_dense_list_contents(lhs->elements, rhs->rows, rhs->default_val, l_dtype, rhs->dtype, &pos, shape, lhs->rank, count_storage_max_elements((STORAGE*)rhs), rhs->rank-1);
173
-
174
- return lhs;
175
- }
176
-
177
-
178
- DENSE_STORAGE* scast_copy_dense_yale(const YALE_STORAGE* rhs, int8_t l_dtype) {
179
- DENSE_STORAGE* lhs;
180
- y_size_t i, j, // position in lhs->elements
181
- ija, ija_next, jj; // position in rhs->elements
182
- y_size_t pos = 0; // position in dense to write to
183
- void* R_ZERO = (char*)(rhs->a) + rhs->shape[0] * nm_sizeof[rhs->dtype]; // determine zero representation
184
-
185
- // allocate and set shape
186
- size_t* shape = ALLOC_N(size_t, rhs->rank);
187
- memcpy(shape, rhs->shape, rhs->rank * sizeof(size_t));
188
-
189
- lhs = create_dense_storage(l_dtype, shape, rhs->rank, NULL, 0);
190
-
191
- // Walk through rows. For each entry we set in dense, increment pos.
192
- for (i = 0; i < rhs->shape[0]; ++i) {
193
-
194
- // get boundaries of this row, store in ija and ija_next
195
- YaleGetIJA(ija, rhs, i);
196
- YaleGetIJA(ija_next, rhs, i+1);
197
-
198
- if (ija == ija_next) { // row is empty?
199
-
200
- for (j = 0; j < rhs->shape[1]; ++j) { // write zeros in each column
201
-
202
- // Fill in zeros (except for diagonal)
203
- if (i == j) cast_copy_value_single((char*)(lhs->elements) + pos*nm_sizeof[l_dtype], (char*)(rhs->a) + i*nm_sizeof[rhs->dtype], l_dtype, rhs->dtype);
204
- else cast_copy_value_single((char*)(lhs->elements) + pos*nm_sizeof[l_dtype], R_ZERO, l_dtype, rhs->dtype);
205
-
206
- ++pos; // move to next dense position
207
- }
208
-
209
- } else {
210
- // row contains entries: write those in each column, interspersed with zeros
211
- YaleGetIJA(jj, rhs, ija);
212
-
213
- for (j = 0; j < rhs->shape[1]; ++j) {
214
- if (i == j) {
215
-
216
- cast_copy_value_single((char*)(lhs->elements) + pos*nm_sizeof[l_dtype], (char*)(rhs->a) + i*nm_sizeof[rhs->dtype], l_dtype, rhs->dtype);
217
-
218
- } else if (j == jj) {
219
-
220
- // copy from rhs
221
- cast_copy_value_single((char*)(lhs->elements) + pos*nm_sizeof[l_dtype], (char*)(rhs->a) + ija*nm_sizeof[rhs->dtype], l_dtype, rhs->dtype);
222
-
223
- // get next
224
- ++ija;
225
-
226
- // increment to next column ID (or go off the end)
227
- if (ija < ija_next) YaleGetIJA(jj, rhs, ija);
228
- else jj = rhs->shape[1];
229
-
230
- } else { // j < jj
231
-
232
- // insert zero
233
- cast_copy_value_single((char*)(lhs->elements) + pos*nm_sizeof[l_dtype], R_ZERO, l_dtype, rhs->dtype);
234
- }
235
- ++pos; // move to next dense position
236
- }
237
- }
238
- }
239
-
240
- return lhs;
241
- }
242
-
243
-
244
- // Note that elements and elements_length are for initial value(s) passed in. If they are the correct length, they will
245
- // be used directly. If not, they will be concatenated over and over again into a new elements array. If elements is NULL,
246
- // the new elements array will not be initialized.
247
- DENSE_STORAGE* create_dense_storage(int8_t dtype, size_t* shape, size_t rank, void* elements, size_t elements_length) {
248
- DENSE_STORAGE* s;
249
- size_t count, i, copy_length = elements_length;
250
-
251
- s = ALLOC( DENSE_STORAGE );
252
- //if (!(s = malloc(sizeof(DENSE_STORAGE)))) return NULL;
253
-
254
- s->rank = rank;
255
- s->shape = shape;
256
- s->dtype = dtype;
257
-
258
- //fprintf(stderr, "create_dense_storage: %p\n", s);
259
-
260
- count = count_dense_storage_elements(s);
261
- //fprintf(stderr, "count_dense_storage_elements: %d\n", count);
262
-
263
- if (elements_length == count) s->elements = elements;
264
- else {
265
- s->elements = ALLOC_N(char, nm_sizeof[dtype]*count);
266
-
267
- if (elements_length > 0) {
268
- // repeat elements over and over again until the end of the matrix
269
- for (i = 0; i < count; i += elements_length) {
270
- if (i + elements_length > count) copy_length = count - i;
271
- memcpy((char*)(s->elements)+i*nm_sizeof[dtype], (char*)(elements)+(i % elements_length)*nm_sizeof[dtype], copy_length*nm_sizeof[dtype]);
272
- }
273
-
274
- // get rid of the init_val
275
- free(elements);
276
- }
277
- }
278
-
279
- return s;
280
- }
281
-
282
-
283
- void delete_dense_storage(DENSE_STORAGE* s) {
284
- if (s) { // sometimes Ruby passes in NULL storage for some reason (probably on copy construction failure)
285
- free(s->shape);
286
- free(s->elements);
287
- free(s);
288
- }
289
- }
290
-
291
-
292
- void mark_dense_storage(void* m) {
293
- size_t i;
294
- DENSE_STORAGE* storage;
295
-
296
- if (m) {
297
- storage = (DENSE_STORAGE*)(((NMATRIX*)m)->storage);
298
- //fprintf(stderr, "mark_dense_storage\n");
299
- if (storage && storage->dtype == NM_ROBJ)
300
- for (i = 0; i < count_dense_storage_elements(storage); ++i)
301
- rb_gc_mark(*((VALUE*)((char*)(storage->elements) + i*nm_sizeof[NM_ROBJ])));
302
- }
303
- }
304
-
305
-
306
-
307
- #endif
data/ext/nmatrix/depend DELETED
@@ -1,18 +0,0 @@
1
- dtypes.h dtypes.c smmp1.c smmp2.c blas.c: generator.rb
2
- $(RUBY) -I$(srcdir) $(srcdir)/generator.rb
3
-
4
- blas.o: blas.c
5
-
6
- smmp2.o: smmp1.c smmp2.c nmatrix.h yale/smmp2_header.template.c yale/symbmm.template.c yale/transp.template.c yale/numbmm.template.c
7
-
8
- smmp1.o: smmp1.c nmatrix_config.h nmatrix.h yale/smmp1_header.template.c
9
-
10
- dfuncs.o: dfuncs.c $(hdrdir)/ruby.h
11
-
12
- $(DLLIB): dtypes.h dtypes.c dfuncs.c $(OBJS) Makefile
13
- # $(ECHO) linking shared-object $(DLLIB)
14
- @-$(RM) $(@)
15
- $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
16
-
17
- soclean:
18
- @-$(RM) *.so *.o *.bundle