nmatrix 0.0.1 → 0.0.2

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