ruby-gsl-ng 0.2.4.1 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|