ruby-gsl-ng 0.2.4.1 → 0.2.6
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.
- data/History.txt +13 -0
- data/Manifest +2 -1
- data/Rakefile +1 -1
- data/ext/extconf.rb +6 -0
- data/ext/gslng_extensions.cpp +70 -15
- data/ext/plotting.cpp +14 -1
- data/lib/core_extensions/array.rb +14 -0
- data/lib/gslng.rb +2 -0
- data/lib/gslng/backend_components/matrix.rb +3 -0
- data/lib/gslng/backend_components/stats.rb +1 -0
- data/lib/gslng/matrix.rb +65 -50
- data/lib/gslng/matrix_view.rb +2 -0
- data/lib/gslng/plotter.rb +6 -2
- data/lib/gslng/vector.rb +112 -87
- data/lib/gslng/vector_view.rb +3 -1
- data/ruby-gsl-ng.gemspec +4 -4
- data/test/benchmark_results +53 -41
- data/test/matrix_test.rb +9 -0
- data/test/test_gsl.rb +2 -1
- data/test/vector_test.rb +17 -4
- metadata +6 -5
data/History.txt
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
=== 0.2.6
|
2
|
+
* Features:
|
3
|
+
* Improved Vector#wrap
|
4
|
+
* Performance improvements
|
5
|
+
* Check for pkg-config, to avoid problems
|
6
|
+
* Vector#median (bdigital)
|
7
|
+
* Added Vector.linspace, Vector#hash, Matrix#set, Vector#eql?, Matrix#slide, Vector#quantile
|
8
|
+
* Extend Array to include #to_v and #to_m (bdigital)
|
9
|
+
* Fixes:
|
10
|
+
* Better plotter process closing
|
11
|
+
* Clear C/CXXFLAGS
|
12
|
+
* Pointer conversion bug causing random segfaults
|
13
|
+
* Problem while trying to free GSL memory
|
1
14
|
=== 0.2.4.1
|
2
15
|
* Fixes:
|
3
16
|
* Gnuplot not being correctly executed
|
data/Manifest
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
History.txt
|
2
|
+
Manifest
|
2
3
|
README.rdoc
|
3
4
|
Rakefile
|
4
5
|
ext/extconf.rb
|
5
6
|
ext/gslng_extensions.cpp
|
6
7
|
ext/plotting.cpp
|
8
|
+
lib/core_extensions/array.rb
|
7
9
|
lib/gslng.rb
|
8
10
|
lib/gslng/backend.rb
|
9
11
|
lib/gslng/backend_components/error_handling.rb
|
@@ -29,4 +31,3 @@ test/rng_test.rb
|
|
29
31
|
test/test_gsl.rb
|
30
32
|
test/test_special.rb
|
31
33
|
test/vector_test.rb
|
32
|
-
Manifest
|
data/Rakefile
CHANGED
@@ -8,7 +8,7 @@ Echoe.new('ruby-gsl-ng') do |p|
|
|
8
8
|
p.author = 'v01d'
|
9
9
|
p.summary = "Ruby/GSL new-generation wrapper"
|
10
10
|
p.url = "http://github.com/v01d/ruby-gsl-ng"
|
11
|
-
p.version = "0.2.
|
11
|
+
p.version = "0.2.6"
|
12
12
|
p.dependencies = ['yard', 'ffi']
|
13
13
|
# p.eval = proc { s.has_rdoc = 'yard' }
|
14
14
|
end
|
data/ext/extconf.rb
CHANGED
@@ -4,6 +4,7 @@ require 'mkmf'
|
|
4
4
|
extra_flags='-O4 -DHAVE_INLINE=1'
|
5
5
|
|
6
6
|
## Check for GSL
|
7
|
+
find_executable('pkg-config') or raise 'pkg-config should be installed'
|
7
8
|
gsl_vars = pkg_config('gsl') or raise 'GSL not found!'
|
8
9
|
|
9
10
|
# Configuration
|
@@ -11,4 +12,9 @@ if (RUBY_VERSION =~ /^1\.8/) then $libs << ' -lstdc++' end # Seems necessary in
|
|
11
12
|
|
12
13
|
## Create Makefile
|
13
14
|
with_cppflags("#{extra_flags}") { true }
|
15
|
+
with_cflags('') { true }
|
16
|
+
CONFIG['CXXFLAGS']=''
|
17
|
+
|
14
18
|
create_makefile('gslng_extensions')
|
19
|
+
|
20
|
+
|
data/ext/gslng_extensions.cpp
CHANGED
@@ -7,11 +7,13 @@
|
|
7
7
|
#include <ruby.h>
|
8
8
|
#include <gsl/gsl_vector.h>
|
9
9
|
#include <gsl/gsl_matrix.h>
|
10
|
+
#include <iostream>
|
11
|
+
using namespace std;
|
10
12
|
|
11
13
|
/************************* Vector functions *****************************/
|
12
14
|
|
13
15
|
static VALUE gsl_vector_map(VALUE self, VALUE ptr) {
|
14
|
-
gsl_vector* v = (gsl_vector*)
|
16
|
+
gsl_vector* v = (gsl_vector*)NUM2ULONG(ptr);
|
15
17
|
for (size_t i = 0; i < v->size; i++)
|
16
18
|
gsl_vector_set(v, i, NUM2DBL(rb_yield(rb_float_new(gsl_vector_get(v, i)))));
|
17
19
|
|
@@ -19,7 +21,7 @@ static VALUE gsl_vector_map(VALUE self, VALUE ptr) {
|
|
19
21
|
}
|
20
22
|
|
21
23
|
static VALUE gsl_vector_map_index(VALUE self, VALUE ptr) {
|
22
|
-
gsl_vector* v = (gsl_vector*)
|
24
|
+
gsl_vector* v = (gsl_vector*)NUM2ULONG(ptr);
|
23
25
|
for (size_t i = 0; i < v->size; i++) {
|
24
26
|
VALUE vi = ULONG2NUM(i);
|
25
27
|
gsl_vector_set(v, i, NUM2DBL(rb_yield(vi)));
|
@@ -29,7 +31,7 @@ static VALUE gsl_vector_map_index(VALUE self, VALUE ptr) {
|
|
29
31
|
}
|
30
32
|
|
31
33
|
static VALUE gsl_vector_each_with_index(VALUE self, VALUE ptr) {
|
32
|
-
gsl_vector* v = (gsl_vector*)
|
34
|
+
gsl_vector* v = (gsl_vector*)NUM2ULONG(ptr);
|
33
35
|
for (size_t i = 0; i < v->size; i++) {
|
34
36
|
VALUE vi = ULONG2NUM(i);
|
35
37
|
rb_yield_values(2, rb_float_new(gsl_vector_get(v, i)), vi);
|
@@ -39,7 +41,7 @@ static VALUE gsl_vector_each_with_index(VALUE self, VALUE ptr) {
|
|
39
41
|
}
|
40
42
|
|
41
43
|
static VALUE gsl_vector_each(VALUE self, VALUE ptr) {
|
42
|
-
gsl_vector* v = (gsl_vector*)
|
44
|
+
gsl_vector* v = (gsl_vector*)NUM2ULONG(ptr);
|
43
45
|
for (size_t i = 0; i < v->size; i++)
|
44
46
|
rb_yield(rb_float_new(gsl_vector_get(v, i)));
|
45
47
|
|
@@ -47,7 +49,7 @@ static VALUE gsl_vector_each(VALUE self, VALUE ptr) {
|
|
47
49
|
}
|
48
50
|
|
49
51
|
static VALUE gsl_vector_to_a(VALUE self, VALUE ptr) {
|
50
|
-
gsl_vector* v = (gsl_vector*)
|
52
|
+
gsl_vector* v = (gsl_vector*)NUM2ULONG(ptr);
|
51
53
|
|
52
54
|
VALUE array = rb_ary_new2(v->size);
|
53
55
|
for (size_t i = 0; i < v->size; i++)
|
@@ -57,7 +59,7 @@ static VALUE gsl_vector_to_a(VALUE self, VALUE ptr) {
|
|
57
59
|
}
|
58
60
|
|
59
61
|
static VALUE gsl_vector_from_array(VALUE self, VALUE ptr, VALUE array) {
|
60
|
-
gsl_vector* v = (gsl_vector*)
|
62
|
+
gsl_vector* v = (gsl_vector*)NUM2ULONG(ptr);
|
61
63
|
if (v->size != RARRAY_LEN(array)) rb_raise(rb_eRuntimeError, "Sizes differ!");
|
62
64
|
|
63
65
|
for (size_t i = 0; i < v->size; i++)
|
@@ -67,12 +69,30 @@ static VALUE gsl_vector_from_array(VALUE self, VALUE ptr, VALUE array) {
|
|
67
69
|
}
|
68
70
|
|
69
71
|
static VALUE gsl_vector_get_operator(VALUE self, VALUE ptr, VALUE element) {
|
70
|
-
gsl_vector* v = (gsl_vector*)
|
72
|
+
gsl_vector* v = (gsl_vector*)NUM2ULONG(ptr);
|
71
73
|
long i = FIX2LONG(element);
|
72
74
|
if (i < 0) { i = v->size + i; }
|
73
75
|
return rb_float_new(gsl_vector_get(v, (size_t)i));
|
74
76
|
}
|
75
77
|
|
78
|
+
static VALUE gsl_vector_set_operator(VALUE self, VALUE ptr, VALUE element, VALUE value) {
|
79
|
+
gsl_vector* v = (gsl_vector*)NUM2ULONG(ptr);
|
80
|
+
long i = FIX2LONG(element);
|
81
|
+
if (i < 0) { i = v->size + i; }
|
82
|
+
gsl_vector_set(v, (size_t)i, NUM2DBL(value));
|
83
|
+
return Qnil;
|
84
|
+
}
|
85
|
+
|
86
|
+
static VALUE gsl_vector_eql(VALUE self, VALUE ptr, VALUE other_ptr) {
|
87
|
+
gsl_vector* v1 = (gsl_vector*)NUM2ULONG(ptr);
|
88
|
+
gsl_vector* v2 = (gsl_vector*)NUM2ULONG(other_ptr);
|
89
|
+
if (v1->size != v2->size) return Qfalse;
|
90
|
+
for (size_t i = 0; i < v1->size; i++) {
|
91
|
+
if (gsl_vector_get(v1, i) != gsl_vector_get(v2, i)) return Qfalse;
|
92
|
+
}
|
93
|
+
return Qtrue;
|
94
|
+
}
|
95
|
+
|
76
96
|
// Hide the view in a new vector (gsl_vector_subvector)
|
77
97
|
extern "C" gsl_vector* gsl_vector_subvector_with_stride2(gsl_vector* v, size_t offset, size_t stride, size_t n) {
|
78
98
|
gsl_vector_view view = gsl_vector_subvector_with_stride(v, offset, stride, n);
|
@@ -96,7 +116,7 @@ extern "C" double* gsl_vector_as_array(gsl_vector* v) {
|
|
96
116
|
/************************* Matrix functions *****************************/
|
97
117
|
|
98
118
|
static VALUE gsl_matrix_map(VALUE self, VALUE ptr) {
|
99
|
-
gsl_matrix* m = (gsl_matrix*)
|
119
|
+
gsl_matrix* m = (gsl_matrix*)NUM2ULONG(ptr);
|
100
120
|
size_t size1 = m->size1;
|
101
121
|
size_t size2 = m->size2;
|
102
122
|
|
@@ -108,7 +128,7 @@ static VALUE gsl_matrix_map(VALUE self, VALUE ptr) {
|
|
108
128
|
}
|
109
129
|
|
110
130
|
static VALUE gsl_matrix_map_array(VALUE self, VALUE ptr) {
|
111
|
-
gsl_matrix* m = (gsl_matrix*)
|
131
|
+
gsl_matrix* m = (gsl_matrix*)NUM2ULONG(ptr);
|
112
132
|
|
113
133
|
VALUE array = rb_ary_new2(m->size1);
|
114
134
|
for (size_t i = 0; i < m->size1; i++) {
|
@@ -123,7 +143,7 @@ static VALUE gsl_matrix_map_array(VALUE self, VALUE ptr) {
|
|
123
143
|
}
|
124
144
|
|
125
145
|
static VALUE gsl_matrix_map_index(VALUE self, VALUE ptr) {
|
126
|
-
gsl_matrix* m = (gsl_matrix*)
|
146
|
+
gsl_matrix* m = (gsl_matrix*)NUM2ULONG(ptr);
|
127
147
|
size_t size1 = m->size1;
|
128
148
|
size_t size2 = m->size2;
|
129
149
|
|
@@ -135,7 +155,7 @@ static VALUE gsl_matrix_map_index(VALUE self, VALUE ptr) {
|
|
135
155
|
}
|
136
156
|
|
137
157
|
static VALUE gsl_matrix_map_with_index(VALUE self, VALUE ptr) {
|
138
|
-
gsl_matrix* m = (gsl_matrix*)
|
158
|
+
gsl_matrix* m = (gsl_matrix*)NUM2ULONG(ptr);
|
139
159
|
size_t size1 = m->size1;
|
140
160
|
size_t size2 = m->size2;
|
141
161
|
|
@@ -147,7 +167,7 @@ static VALUE gsl_matrix_map_with_index(VALUE self, VALUE ptr) {
|
|
147
167
|
}
|
148
168
|
|
149
169
|
static VALUE gsl_matrix_each(VALUE self, VALUE ptr) {
|
150
|
-
gsl_matrix* m = (gsl_matrix*)
|
170
|
+
gsl_matrix* m = (gsl_matrix*)NUM2ULONG(ptr);
|
151
171
|
size_t size1 = m->size1;
|
152
172
|
size_t size2 = m->size2;
|
153
173
|
|
@@ -159,7 +179,7 @@ static VALUE gsl_matrix_each(VALUE self, VALUE ptr) {
|
|
159
179
|
}
|
160
180
|
|
161
181
|
static VALUE gsl_matrix_each_with_index(VALUE self, VALUE ptr) {
|
162
|
-
gsl_matrix* m = (gsl_matrix*)
|
182
|
+
gsl_matrix* m = (gsl_matrix*)NUM2ULONG(ptr);
|
163
183
|
size_t size1 = m->size1;
|
164
184
|
size_t size2 = m->size2;
|
165
185
|
|
@@ -173,7 +193,7 @@ static VALUE gsl_matrix_each_with_index(VALUE self, VALUE ptr) {
|
|
173
193
|
}
|
174
194
|
|
175
195
|
static VALUE gsl_matrix_to_a(VALUE self, VALUE ptr) {
|
176
|
-
gsl_matrix* m = (gsl_matrix*)
|
196
|
+
gsl_matrix* m = (gsl_matrix*)NUM2ULONG(ptr);
|
177
197
|
|
178
198
|
VALUE array = rb_ary_new2(m->size1);
|
179
199
|
for (size_t i = 0; i < m->size1; i++) {
|
@@ -188,7 +208,7 @@ static VALUE gsl_matrix_to_a(VALUE self, VALUE ptr) {
|
|
188
208
|
}
|
189
209
|
|
190
210
|
static VALUE gsl_matrix_from_array(VALUE self, VALUE ptr, VALUE array) {
|
191
|
-
gsl_matrix* m = (gsl_matrix*)
|
211
|
+
gsl_matrix* m = (gsl_matrix*)NUM2ULONG(ptr);
|
192
212
|
if (m->size1 != RARRAY_LEN(array)) rb_raise(rb_eRuntimeError, "Sizes differ!");
|
193
213
|
|
194
214
|
for (size_t i = 0; i < m->size1; i++) {
|
@@ -202,6 +222,21 @@ static VALUE gsl_matrix_from_array(VALUE self, VALUE ptr, VALUE array) {
|
|
202
222
|
return self;
|
203
223
|
}
|
204
224
|
|
225
|
+
static VALUE gsl_matrix_get_operator(VALUE self, VALUE ptr, VALUE element_i, VALUE element_j) {
|
226
|
+
gsl_matrix* m = (gsl_matrix*)NUM2ULONG(ptr);
|
227
|
+
size_t i = NUM2ULONG(element_i);
|
228
|
+
size_t j = NUM2ULONG(element_j);
|
229
|
+
return rb_float_new(gsl_matrix_get(m, i, j));
|
230
|
+
}
|
231
|
+
|
232
|
+
static VALUE gsl_matrix_set_operator(VALUE self, VALUE ptr, VALUE element_i, VALUE element_j, VALUE value) {
|
233
|
+
gsl_matrix* m = (gsl_matrix*)NUM2ULONG(ptr);
|
234
|
+
size_t i = NUM2ULONG(element_i);
|
235
|
+
size_t j = NUM2ULONG(element_j);
|
236
|
+
gsl_matrix_set(m, i, j, NUM2DBL(value));
|
237
|
+
return Qnil;
|
238
|
+
}
|
239
|
+
|
205
240
|
// Hide the view in a new matrix (gsl_matrix_submatrix)
|
206
241
|
extern "C" gsl_matrix* gsl_matrix_submatrix2(gsl_matrix* m_ptr, size_t x, size_t y, size_t n, size_t m) {
|
207
242
|
gsl_matrix_view view = gsl_matrix_submatrix(m_ptr, x, y, n, m);
|
@@ -224,6 +259,22 @@ extern "C" gsl_vector* gsl_matrix_column_view(gsl_matrix* m_ptr, size_t column,
|
|
224
259
|
return vector_view;
|
225
260
|
}
|
226
261
|
|
262
|
+
extern "C" void gsl_matrix_slide(gsl_matrix* m, ssize_t slide_i, ssize_t slide_j)
|
263
|
+
{
|
264
|
+
gsl_matrix* m2 = gsl_matrix_calloc(m->size1, m->size2);
|
265
|
+
|
266
|
+
for (ssize_t i = 0; (size_t)i < m->size1; i++) {
|
267
|
+
for (ssize_t j = 0; (size_t)j < m->size2; j++) {
|
268
|
+
if (i - slide_i >= 0 && (size_t)(i - slide_i) < m->size1 && j - slide_j >= 0 && (size_t)(j - slide_j) < m->size2) {
|
269
|
+
double v = gsl_matrix_get(m, (size_t)(i - slide_i), (size_t)(j - slide_j));
|
270
|
+
gsl_matrix_set(m2, (size_t)i, (size_t)j, v);
|
271
|
+
}
|
272
|
+
}
|
273
|
+
}
|
274
|
+
|
275
|
+
gsl_matrix_memcpy(m, m2);
|
276
|
+
gsl_matrix_free(m2);
|
277
|
+
}
|
227
278
|
|
228
279
|
/************************* Module initialization *****************************/
|
229
280
|
|
@@ -233,12 +284,14 @@ extern "C" void Init_gslng_extensions(void) {
|
|
233
284
|
|
234
285
|
// vector
|
235
286
|
rb_define_module_function(Backend_module, "gsl_vector_get_operator", (VALUE(*)(ANYARGS))gsl_vector_get_operator, 2);
|
287
|
+
rb_define_module_function(Backend_module, "gsl_vector_set_operator", (VALUE(*)(ANYARGS))gsl_vector_set_operator, 3);
|
236
288
|
rb_define_module_function(Backend_module, "gsl_vector_map!", (VALUE(*)(ANYARGS))gsl_vector_map, 1);
|
237
289
|
rb_define_module_function(Backend_module, "gsl_vector_map_index!", (VALUE(*)(ANYARGS))gsl_vector_map_index, 1);
|
238
290
|
rb_define_module_function(Backend_module, "gsl_vector_each_with_index", (VALUE(*)(ANYARGS))gsl_vector_each_with_index, 1);
|
239
291
|
rb_define_module_function(Backend_module, "gsl_vector_each", (VALUE(*)(ANYARGS))gsl_vector_each, 1);
|
240
292
|
rb_define_module_function(Backend_module, "gsl_vector_to_a", (VALUE(*)(ANYARGS))gsl_vector_to_a, 1);
|
241
293
|
rb_define_module_function(Backend_module, "gsl_vector_from_array", (VALUE(*)(ANYARGS))gsl_vector_from_array, 2);
|
294
|
+
rb_define_module_function(Backend_module, "gsl_vector_eql?", (VALUE(*)(ANYARGS))gsl_vector_eql, 2);
|
242
295
|
|
243
296
|
// matrix
|
244
297
|
rb_define_module_function(Backend_module, "gsl_matrix_map!", (VALUE(*)(ANYARGS))gsl_matrix_map, 1);
|
@@ -249,4 +302,6 @@ extern "C" void Init_gslng_extensions(void) {
|
|
249
302
|
rb_define_module_function(Backend_module, "gsl_matrix_each", (VALUE(*)(ANYARGS))gsl_matrix_each, 1);
|
250
303
|
rb_define_module_function(Backend_module, "gsl_matrix_to_a", (VALUE(*)(ANYARGS))gsl_matrix_to_a, 1);
|
251
304
|
rb_define_module_function(Backend_module, "gsl_matrix_from_array", (VALUE(*)(ANYARGS))gsl_matrix_from_array, 2);
|
305
|
+
rb_define_module_function(Backend_module, "gsl_matrix_get_operator", (VALUE(*)(ANYARGS))gsl_matrix_get_operator, 3);
|
306
|
+
rb_define_module_function(Backend_module, "gsl_matrix_set_operator", (VALUE(*)(ANYARGS))gsl_matrix_set_operator, 4);
|
252
307
|
}
|
data/ext/plotting.cpp
CHANGED
@@ -1,9 +1,22 @@
|
|
1
1
|
#include <gsl/gsl_matrix.h>
|
2
2
|
#include <unistd.h>
|
3
|
+
#include <iostream>
|
4
|
+
using namespace std;
|
3
5
|
|
4
6
|
extern "C" int gsl_matrix_putdata(gsl_matrix* m, int fd) {
|
5
7
|
size_t bytes = m->size1 * m->size2 * sizeof(double);
|
6
8
|
long ret = write(fd, m->data, bytes);
|
7
|
-
if (ret == -1 || (unsigned long)ret < bytes)
|
9
|
+
if (ret == -1 || (unsigned long)ret < bytes) {
|
10
|
+
if (errno == EINTR) {
|
11
|
+
cout << "retrying write" << endl;
|
12
|
+
long written;
|
13
|
+
if (ret == -1) written = 0;
|
14
|
+
else written = ret;
|
15
|
+
|
16
|
+
ret = write(fd, m->data + written, bytes - written);
|
17
|
+
if (ret == -1 || (unsigned long)ret < (bytes - written)) return errno;
|
18
|
+
else return 0;
|
19
|
+
}
|
20
|
+
}
|
8
21
|
else return 0;
|
9
22
|
}
|
data/lib/gslng.rb
CHANGED
@@ -58,6 +58,9 @@ module GSLng
|
|
58
58
|
attach_function :gsl_matrix_row_view, [ :pointer, :size_t, :size_t, :size_t ], :pointer
|
59
59
|
attach_function :gsl_matrix_column_view, [ :pointer, :size_t, :size_t, :size_t ], :pointer
|
60
60
|
|
61
|
+
# slide
|
62
|
+
attach_function :gsl_matrix_slide, [ :pointer, :ssize_t, :ssize_t ], :void
|
63
|
+
|
61
64
|
# BLAS interface
|
62
65
|
enum :cblas_transpose_t, [ :no_transpose, 111, :transpose, :conjugate_transpose ]
|
63
66
|
attach_function :gsl_blas_dgemv, [ :cblas_transpose_t, :double, :pointer, :pointer, :double, :pointer ], :int
|
@@ -2,6 +2,7 @@ module GSLng
|
|
2
2
|
backend.instance_eval do
|
3
3
|
# mean, sd and variance
|
4
4
|
attach_function :gsl_stats_mean, [ :pointer, :size_t, :size_t ], :double
|
5
|
+
attach_function :gsl_stats_median_from_sorted_data, [ :pointer, :size_t, :size_t ], :double
|
5
6
|
attach_function :gsl_stats_variance, [ :pointer, :size_t, :size_t ], :double
|
6
7
|
attach_function :gsl_stats_variance_m, [ :pointer, :size_t, :size_t, :double ], :double
|
7
8
|
attach_function :gsl_stats_sd, [ :pointer, :size_t, :size_t ], :double
|
data/lib/gslng/matrix.rb
CHANGED
@@ -10,6 +10,7 @@ module GSLng
|
|
10
10
|
class Matrix
|
11
11
|
attr_reader :m, :n
|
12
12
|
attr_reader :ptr # @private
|
13
|
+
attr_reader :ptr_value # @private
|
13
14
|
|
14
15
|
alias_method :height, :m
|
15
16
|
alias_method :width, :n
|
@@ -25,18 +26,22 @@ module GSLng
|
|
25
26
|
# Otherwise, the Matrix will contain garbage.
|
26
27
|
# You can optionally pass a block, in which case {#map_index!} will be called with it (i.e.: it works like Array.new).
|
27
28
|
def initialize(m, n, zero = false)
|
28
|
-
|
29
|
+
@backend = GSLng.backend
|
30
|
+
ptr = zero ? @backend.gsl_matrix_calloc(m, n) : @backend.gsl_matrix_alloc(m, n)
|
29
31
|
@ptr = FFI::AutoPointer.new(ptr, Matrix.method(:release))
|
32
|
+
@ptr_value = @ptr.to_i
|
30
33
|
@m,@n = m,n
|
31
34
|
if (block_given?) then self.map_index!(Proc.new) end
|
32
35
|
end
|
33
36
|
|
34
37
|
def initialize_copy(other) # @private
|
35
|
-
|
38
|
+
@backend = GSLng.backend
|
39
|
+
ptr = @backend.gsl_matrix_alloc(other.m, other.n)
|
36
40
|
@ptr = FFI::AutoPointer.new(ptr, Matrix.method(:release))
|
41
|
+
@ptr_value = @ptr.to_i
|
37
42
|
|
38
43
|
@m,@n = other.size
|
39
|
-
|
44
|
+
@backend.gsl_matrix_memcpy(@ptr, other.ptr)
|
40
45
|
end
|
41
46
|
|
42
47
|
def Matrix.release(ptr) # @private
|
@@ -53,11 +58,11 @@ module GSLng
|
|
53
58
|
|
54
59
|
if (Numeric === array[0])
|
55
60
|
m = Matrix.new(1, array.size)
|
56
|
-
GSLng.backend.gsl_matrix_from_array(m.
|
61
|
+
GSLng.backend.gsl_matrix_from_array(m.ptr_value, [ array ])
|
57
62
|
return m
|
58
63
|
elsif (Array === array[0])
|
59
64
|
m = Matrix.new(array.size, array[0].size)
|
60
|
-
GSLng.backend.gsl_matrix_from_array(m.
|
65
|
+
GSLng.backend.gsl_matrix_from_array(m.ptr_value, array)
|
61
66
|
return m
|
62
67
|
else
|
63
68
|
Matrix.new(array.size, array[0].to_a.size) {|i,j| array[i].to_a[j]}
|
@@ -94,16 +99,16 @@ module GSLng
|
|
94
99
|
# @return [Numeric,Matrix] the element/sub-matrix
|
95
100
|
def [](i, j = :*)
|
96
101
|
if (Integer === i && Integer === j)
|
97
|
-
|
102
|
+
@backend.gsl_matrix_get_operator(@ptr_value, i, j)
|
98
103
|
else
|
99
104
|
if (Symbol === i && Symbol === j) then return self
|
100
105
|
elsif (Symbol === i)
|
101
106
|
col = Vector.new(@m)
|
102
|
-
|
107
|
+
@backend.gsl_matrix_get_col(col.ptr, @ptr, j)
|
103
108
|
return col.to_matrix
|
104
109
|
elsif (Symbol === j)
|
105
110
|
row = Vector.new(@n)
|
106
|
-
|
111
|
+
@backend.gsl_matrix_get_row(row.ptr, @ptr, i)
|
107
112
|
return row.to_matrix
|
108
113
|
end
|
109
114
|
end
|
@@ -118,35 +123,38 @@ module GSLng
|
|
118
123
|
if (Numeric === value) then self.fill!(value)
|
119
124
|
else
|
120
125
|
x,y = self.coerce(value)
|
121
|
-
|
126
|
+
@backend.gsl_matrix_memcpy(@ptr, x.ptr)
|
122
127
|
end
|
123
128
|
elsif (Symbol === i)
|
124
129
|
col = Vector.new(@m)
|
125
130
|
x,y = col.coerce(value)
|
126
|
-
|
131
|
+
@backend.gsl_matrix_set_col(@ptr, j, x.ptr)
|
127
132
|
return col
|
128
133
|
elsif (Symbol === j)
|
129
134
|
row = Vector.new(@n)
|
130
135
|
x,y = row.coerce(value)
|
131
|
-
|
136
|
+
@backend.gsl_matrix_set_row(@ptr, i, x.ptr)
|
132
137
|
return row
|
133
138
|
else
|
134
|
-
|
139
|
+
@backend.gsl_matrix_set_operator(@ptr_value, i, j, value)
|
135
140
|
end
|
136
141
|
|
137
142
|
return self
|
138
143
|
end
|
139
144
|
|
140
145
|
# Set all values to _v_
|
141
|
-
def all!(v);
|
146
|
+
def all!(v); @backend.gsl_matrix_set_all(@ptr, v); return self end
|
142
147
|
alias_method :set!, :all!
|
143
148
|
alias_method :fill!, :all!
|
144
149
|
|
145
150
|
# Set all values to zero
|
146
|
-
def zero!;
|
151
|
+
def zero!; @backend.gsl_matrix_set_zero(@ptr); return self end
|
147
152
|
|
148
153
|
# Set the identity matrix values
|
149
|
-
def identity;
|
154
|
+
def identity; @backend.gsl_matrix_set_identity(@ptr); return self end
|
155
|
+
|
156
|
+
# Copy matrix values from +other+ to +self+
|
157
|
+
def set(other); @backend.gsl_matrix_memcpy(@ptr, other.ptr); return self end
|
150
158
|
|
151
159
|
# @group Views
|
152
160
|
|
@@ -182,7 +190,7 @@ module GSLng
|
|
182
190
|
# @return [Vector::View]
|
183
191
|
def row_vecview(i, offset = 0, size = nil)
|
184
192
|
size = (@n - offset) if size.nil?
|
185
|
-
ptr =
|
193
|
+
ptr = @backend.gsl_matrix_row_view(@ptr, i, offset, size)
|
186
194
|
Vector::View.new(ptr, self, size)
|
187
195
|
end
|
188
196
|
|
@@ -190,8 +198,8 @@ module GSLng
|
|
190
198
|
# @return [Vector::View]
|
191
199
|
def column_vecview(i, offset = 0, size = nil)
|
192
200
|
size = (@m - offset) if size.nil?
|
193
|
-
ptr =
|
194
|
-
Vector::View.new(ptr, self, size)
|
201
|
+
ptr = @backend.gsl_matrix_column_view(@ptr, i, offset, size)
|
202
|
+
Vector::View.new(ptr, self, size, self.columns)
|
195
203
|
end
|
196
204
|
|
197
205
|
|
@@ -201,8 +209,8 @@ module GSLng
|
|
201
209
|
# @return [Matrix] self
|
202
210
|
def add!(other)
|
203
211
|
case other
|
204
|
-
when Numeric;
|
205
|
-
when Matrix;
|
212
|
+
when Numeric; @backend.gsl_matrix_add_constant(@ptr, other.to_f)
|
213
|
+
when Matrix; @backend.gsl_matrix_add(@ptr, other.ptr)
|
206
214
|
else
|
207
215
|
x,y = other.coerce(self)
|
208
216
|
x.add!(y)
|
@@ -214,8 +222,8 @@ module GSLng
|
|
214
222
|
# @return [Matrix] self
|
215
223
|
def substract!(other)
|
216
224
|
case other
|
217
|
-
when Numeric;
|
218
|
-
when Matrix;
|
225
|
+
when Numeric; @backend.gsl_matrix_add_constant(@ptr, -other.to_f)
|
226
|
+
when Matrix; @backend.gsl_matrix_sub(@ptr, other.ptr)
|
219
227
|
else
|
220
228
|
x,y = other.coerce(self)
|
221
229
|
x.substract!(y)
|
@@ -228,8 +236,8 @@ module GSLng
|
|
228
236
|
# @return [Matrix] self
|
229
237
|
def multiply!(other)
|
230
238
|
case other
|
231
|
-
when Numeric;
|
232
|
-
when Matrix;
|
239
|
+
when Numeric; @backend.gsl_matrix_scale(@ptr, other.to_f)
|
240
|
+
when Matrix; @backend.gsl_matrix_mul_elements(@ptr, other.ptr)
|
233
241
|
else
|
234
242
|
x,y = other.coerce(self)
|
235
243
|
x.multiply!(y)
|
@@ -242,8 +250,8 @@ module GSLng
|
|
242
250
|
# @return [Matrix] self
|
243
251
|
def divide!(other)
|
244
252
|
case other
|
245
|
-
when Numeric;
|
246
|
-
when Matrix;
|
253
|
+
when Numeric; @backend.gsl_matrix_scale(@ptr, 1.0 / other)
|
254
|
+
when Matrix; @backend.gsl_matrix_div_elements(@ptr, other.ptr)
|
247
255
|
else
|
248
256
|
x,y = other.coerce(self)
|
249
257
|
x.divide!(y)
|
@@ -276,11 +284,11 @@ module GSLng
|
|
276
284
|
self.multiply(other)
|
277
285
|
when Vector
|
278
286
|
matrix = Matrix.new(self.m, other.size)
|
279
|
-
|
287
|
+
@backend.gsl_blas_dgemm(:no_transpose, :no_transpose, 1, @ptr, other.to_matrix.ptr, 0, matrix.ptr)
|
280
288
|
return matrix
|
281
289
|
when Matrix
|
282
290
|
matrix = Matrix.new(self.m, other.n)
|
283
|
-
|
291
|
+
@backend.gsl_blas_dgemm(:no_transpose, :no_transpose, 1, @ptr, other.ptr, 0, matrix.ptr)
|
284
292
|
return matrix
|
285
293
|
else
|
286
294
|
x,y = other.coerce(self)
|
@@ -291,33 +299,40 @@ module GSLng
|
|
291
299
|
# @group Row/column swapping
|
292
300
|
|
293
301
|
# Transposes in-place. Only for square matrices
|
294
|
-
def transpose!;
|
302
|
+
def transpose!; @backend.gsl_matrix_transpose(@ptr); return self end
|
295
303
|
|
296
304
|
# Returns the transpose of self, in a new matrix
|
297
|
-
def transpose; matrix = Matrix.new(@n, @m);
|
305
|
+
def transpose; matrix = Matrix.new(@n, @m); @backend.gsl_matrix_transpose_memcpy(matrix.ptr, @ptr); return matrix end
|
298
306
|
|
299
307
|
# Swap the i-th and j-th columnos
|
300
|
-
def swap_columns(i, j);
|
308
|
+
def swap_columns(i, j); @backend.gsl_matrix_swap_columns(@ptr, i, j); return self end
|
301
309
|
|
302
310
|
# Swap the i-th and j-th rows
|
303
|
-
def swap_rows(i, j);
|
311
|
+
def swap_rows(i, j); @backend.gsl_matrix_swap_rows(@ptr, i, j); return self end
|
304
312
|
|
305
313
|
# Swap the i-th row with the j-th column. The Matrix must be square.
|
306
|
-
def swap_rowcol(i, j);
|
314
|
+
def swap_rowcol(i, j); @backend.gsl_matrix_swap_rowcol(@ptr, i, j); return self end
|
315
|
+
|
316
|
+
# Discards rows and columns as necessary (fill them with zero), to "slide" the values of the matrix
|
317
|
+
# @param [Integer] i If > 0, slides all values to the bottom (adds +i+ rows of zeros at the top). If < 0,
|
318
|
+
# slides all values to the top and adds zeros in the bottom.
|
319
|
+
# @param [Integer] j Analogous to parameter +i+, in this case a value < 0 adds zeros to the right (slides to the left),
|
320
|
+
# and a value > 0 adds zeros to the left (slides to the right).
|
321
|
+
def slide(i, j); @backend.gsl_matrix_slide(@ptr, i, j); return self end
|
307
322
|
|
308
323
|
# @group Predicate methods
|
309
324
|
|
310
325
|
# if all elements are zero
|
311
|
-
def zero?;
|
326
|
+
def zero?; @backend.gsl_matrix_isnull(@ptr) == 1 ? true : false end
|
312
327
|
|
313
328
|
# if all elements are strictly positive (>0)
|
314
|
-
def positive?;
|
329
|
+
def positive?; @backend.gsl_matrix_ispos(@ptr) == 1 ? true : false end
|
315
330
|
|
316
331
|
#if all elements are strictly negative (<0)
|
317
|
-
def negative?;
|
332
|
+
def negative?; @backend.gsl_matrix_isneg(@ptr) == 1 ? true : false end
|
318
333
|
|
319
334
|
# if all elements are non-negative (>=0)
|
320
|
-
def nonnegative?;
|
335
|
+
def nonnegative?; @backend.gsl_matrix_isnonneg(@ptr) == 1 ? true : false end
|
321
336
|
|
322
337
|
# If this is a column Matrix
|
323
338
|
def column?; self.columns == 1 end
|
@@ -325,16 +340,16 @@ module GSLng
|
|
325
340
|
# @group Minimum/maximum
|
326
341
|
|
327
342
|
# Maximum element of the Matrix
|
328
|
-
def max;
|
343
|
+
def max; @backend.gsl_matrix_max(@ptr) end
|
329
344
|
|
330
345
|
# Minimum element of the Matrix
|
331
|
-
def min;
|
346
|
+
def min; @backend.gsl_matrix_min(@ptr) end
|
332
347
|
|
333
348
|
# Same as {Array#minmax}
|
334
349
|
def minmax
|
335
350
|
min = FFI::Buffer.new(:double)
|
336
351
|
max = FFI::Buffer.new(:double)
|
337
|
-
|
352
|
+
@backend.gsl_matrix_minmax(@ptr, min, max)
|
338
353
|
return [min[0].get_float64(0),max[0].get_float64(0)]
|
339
354
|
end
|
340
355
|
|
@@ -344,7 +359,7 @@ module GSLng
|
|
344
359
|
j_min = FFI::Buffer.new(:size_t)
|
345
360
|
i_max = FFI::Buffer.new(:size_t)
|
346
361
|
j_max = FFI::Buffer.new(:size_t)
|
347
|
-
|
362
|
+
@backend.gsl_matrix_minmax_index(@ptr, i_min, j_min, i_max, j_max)
|
348
363
|
#return [min[0].get_size_t(0),max[0].get_size_t(0)]
|
349
364
|
return [i_min[0].get_ulong(0),j_min[0].get_ulong(0),i_max[0].get_ulong(0),j_max[0].get_ulong(0)]
|
350
365
|
end
|
@@ -353,7 +368,7 @@ module GSLng
|
|
353
368
|
def min_index
|
354
369
|
i_min = FFI::Buffer.new(:size_t)
|
355
370
|
j_min = FFI::Buffer.new(:size_t)
|
356
|
-
|
371
|
+
@backend.gsl_matrix_min_index(@ptr, i_min, j_min)
|
357
372
|
return [i_min[0].get_ulong(0), j_min[0].get_ulong(0)]
|
358
373
|
end
|
359
374
|
|
@@ -361,7 +376,7 @@ module GSLng
|
|
361
376
|
def max_index
|
362
377
|
i_max = FFI::Buffer.new(:size_t)
|
363
378
|
j_max = FFI::Buffer.new(:size_t)
|
364
|
-
|
379
|
+
@backend.gsl_matrix_max_index(@ptr, i_max, j_max)
|
365
380
|
return [i_max[0].get_ulong(0), j_max[0].get_ulong(0)]
|
366
381
|
end
|
367
382
|
|
@@ -383,13 +398,13 @@ module GSLng
|
|
383
398
|
# @yield [elem]
|
384
399
|
# @return [void]
|
385
400
|
def each(block = Proc.new)
|
386
|
-
|
401
|
+
@backend.gsl_matrix_each(@ptr_value, &block)
|
387
402
|
end
|
388
403
|
|
389
404
|
# @see #each
|
390
405
|
# @yield [elem,i,j]
|
391
406
|
def each_with_index(block = Proc.new)
|
392
|
-
|
407
|
+
@backend.gsl_matrix_each_with_index(@ptr_value, &block)
|
393
408
|
end
|
394
409
|
|
395
410
|
# Yields the block for each row *view* ({Matrix::View}).
|
@@ -410,15 +425,15 @@ module GSLng
|
|
410
425
|
|
411
426
|
# Efficient {#map!} implementation
|
412
427
|
# @yield [elem]
|
413
|
-
def map!(block = Proc.new);
|
428
|
+
def map!(block = Proc.new); @backend.gsl_matrix_map!(@ptr_value, &block); return self end
|
414
429
|
|
415
430
|
# Alternate version of {#map!}, in this case the block receives the index (row, column) as a parameter.
|
416
431
|
# @yield [i,j]
|
417
|
-
def map_index!(block = Proc.new);
|
432
|
+
def map_index!(block = Proc.new); @backend.gsl_matrix_map_index!(@ptr_value, &block); return self end
|
418
433
|
|
419
434
|
# Similar to {#map_index!}, in this case it receives both the element and the index to it
|
420
435
|
# @yield [elem,i,j]
|
421
|
-
def map_with_index!(block = Proc.new);
|
436
|
+
def map_with_index!(block = Proc.new); @backend.gsl_matrix_map_with_index!(@ptr_value, &block); return self end
|
422
437
|
|
423
438
|
# @see #map!
|
424
439
|
# @return [Matrix]
|
@@ -428,7 +443,7 @@ module GSLng
|
|
428
443
|
# @see #map
|
429
444
|
# @return [Array]
|
430
445
|
# @yield [elem]
|
431
|
-
def map_array(block = Proc.new);
|
446
|
+
def map_array(block = Proc.new); @backend.gsl_matrix_map_array(@ptr_value, &block) end
|
432
447
|
|
433
448
|
# @group Type conversions
|
434
449
|
|
@@ -463,7 +478,7 @@ module GSLng
|
|
463
478
|
# @example
|
464
479
|
# Matrix[[1,2],[2,3]] => [[1.0,2.0],[2.0,3.0]]
|
465
480
|
def to_a
|
466
|
-
|
481
|
+
@backend.gsl_matrix_to_a(@ptr_value)
|
467
482
|
end
|
468
483
|
|
469
484
|
def inspect # @private
|