ruby-gsl-ng 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +11 -0
- data/Manifest +3 -2
- data/Rakefile +2 -2
- data/ext/extconf.rb +9 -1
- data/ext/gslng_extensions.cpp +29 -1
- data/ext/plotting.cpp +9 -0
- data/lib/gslng.rb +1 -1
- data/lib/gslng/backend.rb +1 -0
- data/lib/gslng/backend_components/matrix.rb +3 -0
- data/lib/gslng/backend_components/stats.rb +35 -0
- data/lib/gslng/backend_components/vector.rb +1 -0
- data/lib/gslng/matrix.rb +59 -52
- data/lib/gslng/matrix_view.rb +7 -2
- data/lib/gslng/plotter.rb +83 -0
- data/lib/gslng/rng/rng.rb +6 -5
- data/lib/gslng/vector.rb +123 -39
- data/lib/gslng/vector_view.rb +7 -3
- data/ruby-gsl-ng.gemspec +8 -8
- data/test/benchmark.rb +25 -12
- data/test/matrix_test.rb +6 -0
- data/test/vector_test.rb +3 -1
- metadata +16 -10
- data/TODO +0 -2
- data/lib/gslng/finalizer.rb +0 -9
data/History.txt
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
=== 0.2.4
|
2
|
+
* Features:
|
3
|
+
* Plotting support (using gnuplot) (Plotter class and associated methods on Matrix).
|
4
|
+
* Added Matrix#map_array (just like Vector#map_array)
|
5
|
+
* C version of operator []
|
6
|
+
* Support for some statistics operations in Vector
|
7
|
+
* Updated documentation to use YARD's @group feature
|
8
|
+
* Internal Changes:
|
9
|
+
* GSL memory is managed by FFI::AutoPointer now
|
10
|
+
* Fixes
|
11
|
+
* On some systems, with Ruby 1.8 the extension was missing libstdc++ support
|
1
12
|
=== 0.2.3
|
2
13
|
* FIXES:
|
3
14
|
* HUGE memory leak, no GSL object was ever freed.
|
data/Manifest
CHANGED
@@ -1,19 +1,20 @@
|
|
1
1
|
History.txt
|
2
2
|
README.rdoc
|
3
3
|
Rakefile
|
4
|
-
TODO
|
5
4
|
ext/extconf.rb
|
6
5
|
ext/gslng_extensions.cpp
|
6
|
+
ext/plotting.cpp
|
7
7
|
lib/gslng.rb
|
8
8
|
lib/gslng/backend.rb
|
9
9
|
lib/gslng/backend_components/error_handling.rb
|
10
10
|
lib/gslng/backend_components/matrix.rb
|
11
11
|
lib/gslng/backend_components/rng.rb
|
12
12
|
lib/gslng/backend_components/special.rb
|
13
|
+
lib/gslng/backend_components/stats.rb
|
13
14
|
lib/gslng/backend_components/vector.rb
|
14
|
-
lib/gslng/finalizer.rb
|
15
15
|
lib/gslng/matrix.rb
|
16
16
|
lib/gslng/matrix_view.rb
|
17
|
+
lib/gslng/plotter.rb
|
17
18
|
lib/gslng/rng/gaussian.rb
|
18
19
|
lib/gslng/rng/rng.rb
|
19
20
|
lib/gslng/rng/uniform.rb
|
data/Rakefile
CHANGED
@@ -6,9 +6,9 @@ require 'yard'
|
|
6
6
|
|
7
7
|
Echoe.new('ruby-gsl-ng') do |p|
|
8
8
|
p.author = 'v01d'
|
9
|
-
p.summary = "Ruby
|
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.4"
|
12
12
|
p.dependencies = ['yard', 'ffi']
|
13
13
|
# p.eval = proc { s.has_rdoc = 'yard' }
|
14
14
|
end
|
data/ext/extconf.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
require 'mkmf'
|
3
|
+
|
4
|
+
extra_flags='-O4 -DHAVE_INLINE=1'
|
5
|
+
|
6
|
+
## Check for GSL
|
3
7
|
gsl_vars = pkg_config('gsl') or raise 'GSL not found!'
|
4
|
-
|
8
|
+
|
9
|
+
# Configuration
|
10
|
+
if (RUBY_VERSION =~ /^1\.8/) then $libs << ' -lstdc++' end # Seems necessary in some cases
|
11
|
+
|
12
|
+
## Create Makefile
|
5
13
|
with_cppflags("#{extra_flags}") { true }
|
6
14
|
create_makefile('gslng_extensions')
|
data/ext/gslng_extensions.cpp
CHANGED
@@ -66,6 +66,13 @@ static VALUE gsl_vector_from_array(VALUE self, VALUE ptr, VALUE array) {
|
|
66
66
|
return self;
|
67
67
|
}
|
68
68
|
|
69
|
+
static VALUE gsl_vector_get_operator(VALUE self, VALUE ptr, VALUE element) {
|
70
|
+
gsl_vector* v = (gsl_vector*)FIX2ULONG(ptr);
|
71
|
+
long i = FIX2LONG(element);
|
72
|
+
if (i < 0) { i = v->size + i; }
|
73
|
+
return rb_float_new(gsl_vector_get(v, (size_t)i));
|
74
|
+
}
|
75
|
+
|
69
76
|
// Hide the view in a new vector (gsl_vector_subvector)
|
70
77
|
extern "C" gsl_vector* gsl_vector_subvector_with_stride2(gsl_vector* v, size_t offset, size_t stride, size_t n) {
|
71
78
|
gsl_vector_view view = gsl_vector_subvector_with_stride(v, offset, stride, n);
|
@@ -82,6 +89,10 @@ extern "C" gsl_vector* gsl_vector_subvector2(gsl_vector* v, size_t offset, size_
|
|
82
89
|
return vector_view;
|
83
90
|
}
|
84
91
|
|
92
|
+
extern "C" double* gsl_vector_as_array(gsl_vector* v) {
|
93
|
+
return v->data;
|
94
|
+
}
|
95
|
+
|
85
96
|
/************************* Matrix functions *****************************/
|
86
97
|
|
87
98
|
static VALUE gsl_matrix_map(VALUE self, VALUE ptr) {
|
@@ -96,6 +107,21 @@ static VALUE gsl_matrix_map(VALUE self, VALUE ptr) {
|
|
96
107
|
return self;
|
97
108
|
}
|
98
109
|
|
110
|
+
static VALUE gsl_matrix_map_array(VALUE self, VALUE ptr) {
|
111
|
+
gsl_matrix* m = (gsl_matrix*)FIX2ULONG(ptr);
|
112
|
+
|
113
|
+
VALUE array = rb_ary_new2(m->size1);
|
114
|
+
for (size_t i = 0; i < m->size1; i++) {
|
115
|
+
VALUE row = rb_ary_new2(m->size2);
|
116
|
+
for (size_t j = 0; j < m->size2; j++) {
|
117
|
+
rb_ary_store(row, j, rb_yield(rb_float_new(gsl_matrix_get(m, i, j))));
|
118
|
+
}
|
119
|
+
rb_ary_store(array, i, row);
|
120
|
+
}
|
121
|
+
|
122
|
+
return array;
|
123
|
+
}
|
124
|
+
|
99
125
|
static VALUE gsl_matrix_map_index(VALUE self, VALUE ptr) {
|
100
126
|
gsl_matrix* m = (gsl_matrix*)FIX2ULONG(ptr);
|
101
127
|
size_t size1 = m->size1;
|
@@ -206,6 +232,7 @@ extern "C" void Init_gslng_extensions(void) {
|
|
206
232
|
VALUE Backend_module = rb_funcall(GSLng_module, rb_intern("backend"), 0);
|
207
233
|
|
208
234
|
// vector
|
235
|
+
rb_define_module_function(Backend_module, "gsl_vector_get_operator", (VALUE(*)(ANYARGS))gsl_vector_get_operator, 2);
|
209
236
|
rb_define_module_function(Backend_module, "gsl_vector_map!", (VALUE(*)(ANYARGS))gsl_vector_map, 1);
|
210
237
|
rb_define_module_function(Backend_module, "gsl_vector_map_index!", (VALUE(*)(ANYARGS))gsl_vector_map_index, 1);
|
211
238
|
rb_define_module_function(Backend_module, "gsl_vector_each_with_index", (VALUE(*)(ANYARGS))gsl_vector_each_with_index, 1);
|
@@ -215,10 +242,11 @@ extern "C" void Init_gslng_extensions(void) {
|
|
215
242
|
|
216
243
|
// matrix
|
217
244
|
rb_define_module_function(Backend_module, "gsl_matrix_map!", (VALUE(*)(ANYARGS))gsl_matrix_map, 1);
|
245
|
+
rb_define_module_function(Backend_module, "gsl_matrix_map_array", (VALUE(*)(ANYARGS))gsl_matrix_map_array, 1);
|
218
246
|
rb_define_module_function(Backend_module, "gsl_matrix_map_index!", (VALUE(*)(ANYARGS))gsl_matrix_map_index, 1);
|
219
247
|
rb_define_module_function(Backend_module, "gsl_matrix_map_with_index!", (VALUE(*)(ANYARGS))gsl_matrix_map_with_index, 1);
|
220
248
|
rb_define_module_function(Backend_module, "gsl_matrix_each_with_index", (VALUE(*)(ANYARGS))gsl_matrix_each_with_index, 1);
|
221
249
|
rb_define_module_function(Backend_module, "gsl_matrix_each", (VALUE(*)(ANYARGS))gsl_matrix_each, 1);
|
222
250
|
rb_define_module_function(Backend_module, "gsl_matrix_to_a", (VALUE(*)(ANYARGS))gsl_matrix_to_a, 1);
|
223
251
|
rb_define_module_function(Backend_module, "gsl_matrix_from_array", (VALUE(*)(ANYARGS))gsl_matrix_from_array, 2);
|
224
|
-
}
|
252
|
+
}
|
data/ext/plotting.cpp
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
#include <gsl/gsl_matrix.h>
|
2
|
+
#include <unistd.h>
|
3
|
+
|
4
|
+
extern "C" int gsl_matrix_putdata(gsl_matrix* m, int fd) {
|
5
|
+
size_t bytes = m->size1 * m->size2 * sizeof(double);
|
6
|
+
long ret = write(fd, m->data, bytes);
|
7
|
+
if (ret == -1 || (ulong)ret < bytes) return errno;
|
8
|
+
else return 0;
|
9
|
+
}
|
data/lib/gslng.rb
CHANGED
data/lib/gslng/backend.rb
CHANGED
@@ -62,5 +62,8 @@ module GSLng
|
|
62
62
|
enum :cblas_transpose_t, [ :no_transpose, 111, :transpose, :conjugate_transpose ]
|
63
63
|
attach_function :gsl_blas_dgemv, [ :cblas_transpose_t, :double, :pointer, :pointer, :double, :pointer ], :int
|
64
64
|
attach_function :gsl_blas_dgemm, [ :cblas_transpose_t, :cblas_transpose_t, :double, :pointer, :pointer, :double, :pointer ], :int
|
65
|
+
|
66
|
+
# communication to gnuplot
|
67
|
+
attach_function :gsl_matrix_putdata, [ :pointer, :int ], :int
|
65
68
|
end
|
66
69
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module GSLng
|
2
|
+
backend.instance_eval do
|
3
|
+
# mean, sd and variance
|
4
|
+
attach_function :gsl_stats_mean, [ :pointer, :size_t, :size_t ], :double
|
5
|
+
attach_function :gsl_stats_variance, [ :pointer, :size_t, :size_t ], :double
|
6
|
+
attach_function :gsl_stats_variance_m, [ :pointer, :size_t, :size_t, :double ], :double
|
7
|
+
attach_function :gsl_stats_sd, [ :pointer, :size_t, :size_t ], :double
|
8
|
+
attach_function :gsl_stats_sd_m, [ :pointer, :size_t, :size_t, :double ], :double
|
9
|
+
attach_function :gsl_stats_tss, [ :pointer, :size_t, :size_t ], :double
|
10
|
+
attach_function :gsl_stats_tss_m, [ :pointer, :size_t, :size_t, :double ], :double
|
11
|
+
attach_function :gsl_stats_variance_with_fixed_mean, [ :pointer, :size_t, :size_t, :double ], :double
|
12
|
+
attach_function :gsl_stats_sd_with_fixed_mean, [ :pointer, :size_t, :size_t, :double ], :double
|
13
|
+
|
14
|
+
# absolute deviation
|
15
|
+
attach_function :gsl_stats_absdev, [ :pointer, :size_t, :size_t ], :double
|
16
|
+
attach_function :gsl_stats_absdev_m, [ :pointer, :size_t, :size_t, :double ], :double
|
17
|
+
|
18
|
+
# skewness and kurtosis
|
19
|
+
attach_function :gsl_stats_skew, [ :pointer, :size_t, :size_t ], :double
|
20
|
+
attach_function :gsl_stats_skew_m_sd, [ :pointer, :size_t, :size_t, :double, :double ], :double
|
21
|
+
attach_function :gsl_stats_kurtosis, [ :pointer, :size_t, :size_t ], :double
|
22
|
+
attach_function :gsl_stats_kurtosis_m_sd, [ :pointer, :size_t, :size_t, :double, :double ], :double
|
23
|
+
|
24
|
+
# autocorrelation
|
25
|
+
attach_function :gsl_stats_lag1_autocorrelation, [ :pointer, :size_t, :size_t ], :double
|
26
|
+
attach_function :gsl_stats_lag1_autocorrelation_m, [ :pointer, :size_t, :size_t, :double ], :double
|
27
|
+
|
28
|
+
# covariance
|
29
|
+
attach_function :gsl_stats_covariance, [ :pointer, :size_t, :pointer, :size_t, :size_t ], :double
|
30
|
+
attach_function :gsl_stats_covariance_m, [ :pointer, :size_t, :pointer, :size_t, :size_t, :double, :double ], :double
|
31
|
+
|
32
|
+
# correlation
|
33
|
+
attach_function :gsl_stats_correlation, [ :pointer, :size_t, :pointer, :size_t, :size_t ], :double
|
34
|
+
end
|
35
|
+
end
|
@@ -59,5 +59,6 @@ module GSLng
|
|
59
59
|
# views
|
60
60
|
attach_function :gsl_vector_subvector2, [ :pointer, :size_t, :size_t ], :pointer
|
61
61
|
attach_function :gsl_vector_subvector_with_stride2, [ :pointer, :size_t, :size_t, :size_t ], :pointer
|
62
|
+
attach_function :gsl_vector_as_array, [ :pointer ], :pointer
|
62
63
|
end
|
63
64
|
end
|
data/lib/gslng/matrix.rb
CHANGED
@@ -19,28 +19,30 @@ module GSLng
|
|
19
19
|
# Shorthand for [{#rows},{#columns}]
|
20
20
|
def size; [ @m, @n ] end
|
21
21
|
|
22
|
-
|
22
|
+
# @group Constructors
|
23
23
|
|
24
24
|
# Create a Matrix of m-by-n (rows and columns). If zero is true, the Matrix is initialized with zeros.
|
25
25
|
# Otherwise, the Matrix will contain garbage.
|
26
26
|
# You can optionally pass a block, in which case {#map_index!} will be called with it (i.e.: it works like Array.new).
|
27
27
|
def initialize(m, n, zero = false)
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
ptr = zero ? GSLng.backend::gsl_matrix_calloc(m, n) : GSLng.backend::gsl_matrix_alloc(m, n)
|
29
|
+
@ptr = FFI::AutoPointer.new(ptr, Matrix.method(:release))
|
31
30
|
@m,@n = m,n
|
32
31
|
if (block_given?) then self.map_index!(Proc.new) end
|
33
32
|
end
|
34
33
|
|
35
34
|
def initialize_copy(other) # @private
|
36
|
-
|
37
|
-
@ptr =
|
38
|
-
GSLng.define_finalizer(self, :gsl_matrix_free, @ptr)
|
35
|
+
ptr = GSLng.backend::gsl_matrix_alloc(other.m, other.n)
|
36
|
+
@ptr = FFI::AutoPointer.new(ptr, Matrix.method(:release))
|
39
37
|
|
40
38
|
@m,@n = other.size
|
41
39
|
GSLng.backend::gsl_matrix_memcpy(@ptr, other.ptr)
|
42
40
|
end
|
43
41
|
|
42
|
+
def Matrix.release(ptr) # @private
|
43
|
+
GSLng.backend.gsl_matrix_free(ptr)
|
44
|
+
end
|
45
|
+
|
44
46
|
# Same as Matrix.new(m, n, true)
|
45
47
|
def Matrix.zero(m, n); Matrix.new(m, n, true) end
|
46
48
|
|
@@ -79,20 +81,7 @@ module GSLng
|
|
79
81
|
end
|
80
82
|
class << self; alias_method :rand, :random end
|
81
83
|
|
82
|
-
|
83
|
-
|
84
|
-
# Set all values to _v_
|
85
|
-
def all!(v); GSLng.backend::gsl_matrix_set_all(@ptr, v); return self end
|
86
|
-
alias_method :set!, :all!
|
87
|
-
alias_method :fill!, :all!
|
88
|
-
|
89
|
-
# Set all values to zero
|
90
|
-
def zero!; GSLng.backend::gsl_matrix_set_zero(@ptr); return self end
|
91
|
-
|
92
|
-
# Set the identity matrix values
|
93
|
-
def identity; GSLng.backend::gsl_matrix_set_identity(@ptr); return self end
|
94
|
-
|
95
|
-
#--------------------- set/get -------------------------#
|
84
|
+
# @group Setting/getting values
|
96
85
|
|
97
86
|
# Access the element (i,j), which means (row,column).
|
98
87
|
# Symbols :* or :all can be used as wildcards for both dimensions.
|
@@ -104,17 +93,19 @@ module GSLng
|
|
104
93
|
# @raise [RuntimeError] if out-of-bounds
|
105
94
|
# @return [Numeric,Matrix] the element/sub-matrix
|
106
95
|
def [](i, j = :*)
|
107
|
-
if (
|
108
|
-
|
109
|
-
col = Vector.new(@m)
|
110
|
-
GSLng.backend::gsl_matrix_get_col(col.ptr, @ptr, j)
|
111
|
-
return col.to_matrix
|
112
|
-
elsif (Symbol === j)
|
113
|
-
row = Vector.new(@n)
|
114
|
-
GSLng.backend::gsl_matrix_get_row(row.ptr, @ptr, i)
|
115
|
-
return row.to_matrix
|
96
|
+
if (Integer === i && Integer === j)
|
97
|
+
GSLng.backend::gsl_matrix_get(self.ptr, i, j)
|
116
98
|
else
|
117
|
-
|
99
|
+
if (Symbol === i && Symbol === j) then return self
|
100
|
+
elsif (Symbol === i)
|
101
|
+
col = Vector.new(@m)
|
102
|
+
GSLng.backend::gsl_matrix_get_col(col.ptr, self.ptr, j)
|
103
|
+
return col.to_matrix
|
104
|
+
elsif (Symbol === j)
|
105
|
+
row = Vector.new(@n)
|
106
|
+
GSLng.backend::gsl_matrix_get_row(row.ptr, self.ptr, i)
|
107
|
+
return row.to_matrix
|
108
|
+
end
|
118
109
|
end
|
119
110
|
end
|
120
111
|
|
@@ -127,26 +118,37 @@ module GSLng
|
|
127
118
|
if (Numeric === value) then self.fill!(value)
|
128
119
|
else
|
129
120
|
x,y = self.coerce(value)
|
130
|
-
GSLng.backend::gsl_matrix_memcpy(
|
121
|
+
GSLng.backend::gsl_matrix_memcpy(self.ptr, x.ptr)
|
131
122
|
end
|
132
123
|
elsif (Symbol === i)
|
133
124
|
col = Vector.new(@m)
|
134
125
|
x,y = col.coerce(value)
|
135
|
-
GSLng.backend::gsl_matrix_set_col(
|
126
|
+
GSLng.backend::gsl_matrix_set_col(self.ptr, j, x.ptr)
|
136
127
|
return col
|
137
128
|
elsif (Symbol === j)
|
138
129
|
row = Vector.new(@n)
|
139
130
|
x,y = row.coerce(value)
|
140
|
-
GSLng.backend::gsl_matrix_set_row(
|
131
|
+
GSLng.backend::gsl_matrix_set_row(self.ptr, i, x.ptr)
|
141
132
|
return row
|
142
133
|
else
|
143
|
-
GSLng.backend::gsl_matrix_set(
|
134
|
+
GSLng.backend::gsl_matrix_set(self.ptr, i, j, value)
|
144
135
|
end
|
145
136
|
|
146
137
|
return self
|
147
138
|
end
|
148
139
|
|
149
|
-
|
140
|
+
# Set all values to _v_
|
141
|
+
def all!(v); GSLng.backend::gsl_matrix_set_all(self.ptr, v); return self end
|
142
|
+
alias_method :set!, :all!
|
143
|
+
alias_method :fill!, :all!
|
144
|
+
|
145
|
+
# Set all values to zero
|
146
|
+
def zero!; GSLng.backend::gsl_matrix_set_zero(self.ptr); return self end
|
147
|
+
|
148
|
+
# Set the identity matrix values
|
149
|
+
def identity; GSLng.backend::gsl_matrix_set_identity(self.ptr); return self end
|
150
|
+
|
151
|
+
# @group Views
|
150
152
|
|
151
153
|
# Create a {Matrix::View} from this Matrix.
|
152
154
|
# If either _m_ or _n_ are nil, they're computed from _x_, _y_ and the Matrix's {#size}
|
@@ -181,7 +183,7 @@ module GSLng
|
|
181
183
|
def row_vecview(i, offset = 0, size = nil)
|
182
184
|
size = (@n - offset) if size.nil?
|
183
185
|
ptr = GSLng.backend.gsl_matrix_row_view(self.ptr, i, offset, size)
|
184
|
-
Vector::View.new(ptr, self,
|
186
|
+
Vector::View.new(ptr, self, size)
|
185
187
|
end
|
186
188
|
|
187
189
|
# Same as {#column_view}, but returns a {Vector::View}
|
@@ -189,11 +191,11 @@ module GSLng
|
|
189
191
|
def column_vecview(i, offset = 0, size = nil)
|
190
192
|
size = (@m - offset) if size.nil?
|
191
193
|
ptr = GSLng.backend.gsl_matrix_column_view(self.ptr, i, offset, size)
|
192
|
-
Vector::View.new(ptr, self,
|
194
|
+
Vector::View.new(ptr, self, size)
|
193
195
|
end
|
194
196
|
|
195
197
|
|
196
|
-
|
198
|
+
# @group Operators
|
197
199
|
|
198
200
|
# Add other to self
|
199
201
|
# @return [Matrix] self
|
@@ -286,7 +288,7 @@ module GSLng
|
|
286
288
|
end
|
287
289
|
end
|
288
290
|
|
289
|
-
|
291
|
+
# @group Row/column swapping
|
290
292
|
|
291
293
|
# Transposes in-place. Only for square matrices
|
292
294
|
def transpose!; GSLng.backend::gsl_matrix_transpose(self.ptr); return self end
|
@@ -303,24 +305,24 @@ module GSLng
|
|
303
305
|
# Swap the i-th row with the j-th column. The Matrix must be square.
|
304
306
|
def swap_rowcol(i, j); GSLng.backend::gsl_matrix_swap_rowcol(self.ptr, i, j); return self end
|
305
307
|
|
306
|
-
|
308
|
+
# @group Predicate methods
|
307
309
|
|
308
310
|
# if all elements are zero
|
309
|
-
def zero?; GSLng.backend::gsl_matrix_isnull(
|
311
|
+
def zero?; GSLng.backend::gsl_matrix_isnull(self.ptr) == 1 ? true : false end
|
310
312
|
|
311
313
|
# if all elements are strictly positive (>0)
|
312
|
-
def positive?; GSLng.backend::gsl_matrix_ispos(
|
314
|
+
def positive?; GSLng.backend::gsl_matrix_ispos(self.ptr) == 1 ? true : false end
|
313
315
|
|
314
316
|
#if all elements are strictly negative (<0)
|
315
|
-
def negative?; GSLng.backend::gsl_matrix_isneg(
|
317
|
+
def negative?; GSLng.backend::gsl_matrix_isneg(self.ptr) == 1 ? true : false end
|
316
318
|
|
317
319
|
# if all elements are non-negative (>=0)
|
318
|
-
def nonnegative?; GSLng.backend::gsl_matrix_isnonneg(
|
320
|
+
def nonnegative?; GSLng.backend::gsl_matrix_isnonneg(self.ptr) == 1 ? true : false end
|
319
321
|
|
320
322
|
# If this is a column Matrix
|
321
323
|
def column?; self.columns == 1 end
|
322
324
|
|
323
|
-
|
325
|
+
# @group Minimum/maximum
|
324
326
|
|
325
327
|
# Maximum element of the Matrix
|
326
328
|
def max; GSLng.backend::gsl_matrix_max(self.ptr) end
|
@@ -363,7 +365,7 @@ module GSLng
|
|
363
365
|
return [i_max[0].get_ulong(0), j_max[0].get_ulong(0)]
|
364
366
|
end
|
365
367
|
|
366
|
-
|
368
|
+
# @group High-order methods
|
367
369
|
|
368
370
|
# Yields the specified block for each element going row-by-row
|
369
371
|
# @yield [elem]
|
@@ -408,22 +410,27 @@ module GSLng
|
|
408
410
|
|
409
411
|
# Efficient {#map!} implementation
|
410
412
|
# @yield [elem]
|
411
|
-
def map!(block = Proc.new); GSLng.backend::gsl_matrix_map!(
|
413
|
+
def map!(block = Proc.new); GSLng.backend::gsl_matrix_map!(self.ptr.to_i, &block); return self end
|
412
414
|
|
413
415
|
# Alternate version of {#map!}, in this case the block receives the index (row, column) as a parameter.
|
414
416
|
# @yield [i,j]
|
415
|
-
def map_index!(block = Proc.new); GSLng.backend::gsl_matrix_map_index!(
|
417
|
+
def map_index!(block = Proc.new); GSLng.backend::gsl_matrix_map_index!(self.ptr.to_i, &block); return self end
|
416
418
|
|
417
419
|
# Similar to {#map_index!}, in this case it receives both the element and the index to it
|
418
420
|
# @yield [elem,i,j]
|
419
|
-
def map_with_index!(block = Proc.new); GSLng.backend::gsl_matrix_map_with_index!(
|
421
|
+
def map_with_index!(block = Proc.new); GSLng.backend::gsl_matrix_map_with_index!(self.ptr.to_i, &block); return self end
|
420
422
|
|
421
423
|
# @see #map!
|
422
424
|
# @return [Matrix]
|
423
425
|
# @yield [elem]
|
424
426
|
def map(block = Proc.new); self.dup.map!(block) end
|
425
427
|
|
426
|
-
|
428
|
+
# @see #map
|
429
|
+
# @return [Array]
|
430
|
+
# @yield [elem]
|
431
|
+
def map_array(block = Proc.new); GSLng.backend.gsl_matrix_map_array(self.ptr.to_i, &block) end
|
432
|
+
|
433
|
+
# @group Type conversions
|
427
434
|
|
428
435
|
# Same as {Array#join}
|
429
436
|
# @example
|
@@ -479,7 +486,7 @@ module GSLng
|
|
479
486
|
end
|
480
487
|
end
|
481
488
|
|
482
|
-
|
489
|
+
# @group Equality
|
483
490
|
|
484
491
|
# Element-by-element comparison.
|
485
492
|
def ==(other)
|
data/lib/gslng/matrix_view.rb
CHANGED
@@ -13,8 +13,13 @@ module GSLng
|
|
13
13
|
def initialize(owner, x, y, m, n) # @private
|
14
14
|
@owner = owner
|
15
15
|
@m,@n = m,n
|
16
|
-
|
17
|
-
GSLng.
|
16
|
+
|
17
|
+
ptr = GSLng.backend::gsl_matrix_submatrix2(owner.ptr, x, y, m, n)
|
18
|
+
@ptr = FFI::AutoPointer.new(ptr, View.method(:release))
|
19
|
+
end
|
20
|
+
|
21
|
+
def View.release(ptr)
|
22
|
+
GSLng.backend.gsl_matrix_free(ptr)
|
18
23
|
end
|
19
24
|
|
20
25
|
# Returns a Matrix (*NOT* a View) copied from this view. In other words,
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'ffi'
|
3
|
+
|
4
|
+
module GSLng
|
5
|
+
# This class encapsulates the communication with the plotting backend: gnuplot.
|
6
|
+
#
|
7
|
+
# Plot data is always represented as a {Matrix}, so you can use {Matrix#plot} to do a single plot.
|
8
|
+
# Otherwise, you can use {Matrix#define_plot} (taking the same parameters as the previous method) which returns a {Plotter::Plot}
|
9
|
+
# object. By defining multiple plot objects you can then use {Plotter#plot} passing all plot objects as parameters effectively
|
10
|
+
# creating a single output of all plots.
|
11
|
+
#
|
12
|
+
# This class works as {Singleton}, so when you instantiate it the gnuplot process is started. You can also send arbitrary commands
|
13
|
+
# to the gnuplot process by using the {Plotter#<<} operator. Read the gnuplot documentation on what are the possible commands you can send.
|
14
|
+
#
|
15
|
+
class Plotter
|
16
|
+
include Singleton
|
17
|
+
|
18
|
+
attr_reader :io
|
19
|
+
|
20
|
+
# Creates the singleton Plotter object
|
21
|
+
def initialize
|
22
|
+
@io = IO.popen('gnuplot -', 'w')
|
23
|
+
@io.sync = true
|
24
|
+
self << "set datafile nofpe_trap"
|
25
|
+
end
|
26
|
+
|
27
|
+
# Close the pipe. It is desireable to call this in an "ensure" section, to avoid
|
28
|
+
# leaving the child gnuplot process there if the main ruby process dies
|
29
|
+
def close
|
30
|
+
@io.close; @io = nil
|
31
|
+
end
|
32
|
+
|
33
|
+
# Send a command to the gnuplot process
|
34
|
+
# @example Setting the xrange
|
35
|
+
# Plotter.instance << "set xrange [0:1]"
|
36
|
+
def <<(cmd)
|
37
|
+
@io.puts(cmd)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Expects a variable number of {Plot} objects and creates a single plot out of them
|
41
|
+
def plot(*plots)
|
42
|
+
self << 'plot ' + plots.map(&:command).join(', ')
|
43
|
+
plots.each {|p| self.put_data(p.matrix)}
|
44
|
+
end
|
45
|
+
|
46
|
+
def put_data(matrix) # @private
|
47
|
+
ret = GSLng.backend.gsl_matrix_putdata(matrix.ptr, @io.to_i)
|
48
|
+
if (ret != 0) then raise SystemCallError.new("Problem sending data to gnuplot", ret) end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Yields the given block enabling and disabling multiplot mode, before and after the yield respectively
|
52
|
+
def multiplot
|
53
|
+
self << 'set multiplot'
|
54
|
+
yield(self)
|
55
|
+
ensure
|
56
|
+
self << 'unset multiplot'
|
57
|
+
end
|
58
|
+
|
59
|
+
# This class holds a "plot" command and the associated matrix
|
60
|
+
class Plot < Struct.new(:command, :matrix); end
|
61
|
+
end
|
62
|
+
|
63
|
+
class Matrix
|
64
|
+
# Create a single plot out of the data contained in this Matrix
|
65
|
+
# @param [String] with The value of the 'with' option in gnuplot's plot command (i.e.: lines, linespoints, image, etc.)
|
66
|
+
# @param [String] extra_cmds Other variables/modifiers you can optionally pass to the "plot" command
|
67
|
+
def plot(with, extra_cmds = '')
|
68
|
+
Plotter.instance.plot(define_plot(with, extra_cmds))
|
69
|
+
end
|
70
|
+
|
71
|
+
# Works the same as {#plot} but returns a {Plotter::Plot} object you can store and then pass (along with other plot objects)
|
72
|
+
# to {Plotter#plot} and create a single plot out of them
|
73
|
+
# @return [Plot] The plot object you can pass to {Plotter#plot}
|
74
|
+
def define_plot(with, extra_cmds = '')
|
75
|
+
if (with == 'image')
|
76
|
+
cmd = "'-' binary array=(#{self.m},#{self.n}) format='%double' #{extra_cmds} with #{with}"
|
77
|
+
else
|
78
|
+
cmd = "'-' binary record=(#{self.m}) format=\"#{Array.new(self.n,'%double').join('')}\" #{extra_cmds} with #{with}"
|
79
|
+
end
|
80
|
+
Plotter::Plot.new(cmd, self)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/lib/gslng/rng/rng.rb
CHANGED
@@ -10,15 +10,16 @@ module GSLng
|
|
10
10
|
if (@type.nil?) then @type = :mt19937 end # update comment above if changed
|
11
11
|
|
12
12
|
type = GSLng.backend.send(:"gsl_rng_#{@type}")
|
13
|
-
@ptr = GSLng.backend.gsl_rng_alloc(type)
|
14
|
-
|
13
|
+
@ptr = FFI::AutoPointer.new(GSLng.backend.gsl_rng_alloc(type), RNG.method(:release))
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.release(ptr)
|
17
|
+
GSLng.backend.gsl_rng_free(ptr)
|
15
18
|
end
|
16
19
|
|
17
20
|
def initialize_copy
|
18
|
-
ObjectSpace.undefine_finalizer(self)
|
19
21
|
type = GSLng.backend.send(:"gsl_rng_#{@type}")
|
20
|
-
@ptr = GSLng.backend.gsl_rng_alloc(type)
|
21
|
-
GSLng.define_finalizer(self, :gsl_rng_free, @ptr)
|
22
|
+
@ptr = FFI::AutoPointer.new(GSLng.backend.gsl_rng_alloc(type), RNG.method(:release))
|
22
23
|
end
|
23
24
|
end
|
24
25
|
end
|
data/lib/gslng/vector.rb
CHANGED
@@ -14,31 +14,34 @@ module GSLng
|
|
14
14
|
class Vector
|
15
15
|
include Enumerable
|
16
16
|
|
17
|
-
attr_reader :size
|
17
|
+
attr_reader :size, :stride
|
18
18
|
attr_reader :ptr # @private
|
19
19
|
|
20
|
-
|
20
|
+
# @group Constructors
|
21
21
|
|
22
22
|
# Create a Vector of size n. If zero is true, the vector is initialized with zeros.
|
23
23
|
# Otherwise, the vector will contain garbage.
|
24
24
|
# You can optionally pass a block, in which case {#map_index!} will be called with it (i.e.: it works like {Array.new}).
|
25
25
|
def initialize(n, zero = false)
|
26
|
+
ptr = (zero ? GSLng.backend::gsl_vector_calloc(n) : GSLng.backend::gsl_vector_alloc(n))
|
27
|
+
@ptr = FFI::AutoPointer.new(ptr, Vector.method(:release))
|
26
28
|
@size = n
|
27
|
-
@
|
28
|
-
GSLng.define_finalizer(self, :gsl_vector_free, @ptr)
|
29
|
+
@stride = 1
|
29
30
|
if (block_given?) then self.map_index!(Proc.new) end
|
30
31
|
end
|
31
32
|
|
32
33
|
def initialize_copy(other) # @private
|
33
|
-
|
34
|
-
|
34
|
+
ptr = GSLng.backend::gsl_vector_alloc(other.size)
|
35
|
+
@ptr = FFI::AutoPointer.new(ptr, Vector.method(:release))
|
35
36
|
@size = other.size
|
36
|
-
@
|
37
|
-
GSLng.define_finalizer(self, :gsl_vector_free, @ptr)
|
38
|
-
|
37
|
+
@stride = 1
|
39
38
|
GSLng.backend::gsl_vector_memcpy(@ptr, other.ptr)
|
40
39
|
end
|
41
40
|
|
41
|
+
def Vector.release(ptr) # @private
|
42
|
+
GSLng.backend.gsl_vector_free(ptr)
|
43
|
+
end
|
44
|
+
|
42
45
|
# Same as Vector.new(n, true)
|
43
46
|
def Vector.zero(n); Vector.new(n, true) end
|
44
47
|
|
@@ -67,20 +70,7 @@ module GSLng
|
|
67
70
|
end
|
68
71
|
class << self; alias_method :rand, :random end
|
69
72
|
|
70
|
-
|
71
|
-
|
72
|
-
# Set all values to v
|
73
|
-
def all!(v); GSLng.backend::gsl_vector_set_all(self.ptr, v); return self end
|
74
|
-
alias_method :set!, :all!
|
75
|
-
alias_method :fill!, :all!
|
76
|
-
|
77
|
-
# Set all values to zero
|
78
|
-
def zero!; GSLng.backend::gsl_vector_set_zero(self.ptr); return self end
|
79
|
-
|
80
|
-
# Set all values to zero, except the i-th element, which is set to 1
|
81
|
-
def basis!(i); GSLng.backend::gsl_vector_set_basis(self.ptr, i); return self end
|
82
|
-
|
83
|
-
#--------------------- operators -------------------------#
|
73
|
+
# @group Operators
|
84
74
|
|
85
75
|
# Add (element-by-element) other to self
|
86
76
|
# @return [Vector] self
|
@@ -163,7 +153,7 @@ module GSLng
|
|
163
153
|
# Invert sign on all elements
|
164
154
|
def -@; self.map!(&:-@) end
|
165
155
|
|
166
|
-
|
156
|
+
# @group Other mathematical operations
|
167
157
|
|
168
158
|
# Dot product between self and other (uses BLAS's ddot)
|
169
159
|
# @return [Float]
|
@@ -186,7 +176,7 @@ module GSLng
|
|
186
176
|
# Optimized version of: self += other * alpha (where alpha is a Numeric). Uses BLAS's daxpy.
|
187
177
|
def mul_add(other, alpha); GSLng.backend::gsl_blas_daxpy(alpha, other.ptr, self.ptr); return self end
|
188
178
|
|
189
|
-
|
179
|
+
# @group Miscelaneous methods
|
190
180
|
|
191
181
|
# Reverse the order of elements
|
192
182
|
def reverse!; GSLng.backend::gsl_vector_reverse(self.ptr); return self end
|
@@ -223,14 +213,14 @@ module GSLng
|
|
223
213
|
return delta
|
224
214
|
end
|
225
215
|
|
226
|
-
|
216
|
+
# @group Setting/getting values
|
227
217
|
|
228
218
|
# Access the i-th element.
|
229
219
|
# If _index_ is negative, it counts from the end (-1 is the last element).
|
230
220
|
# @raise [RuntimeError] if out-of-bounds
|
231
|
-
# @todo support ranges
|
221
|
+
# @todo support ranges
|
232
222
|
def [](index)
|
233
|
-
GSLng.backend
|
223
|
+
GSLng.backend.gsl_vector_get_operator(self.ptr.to_i, index)
|
234
224
|
end
|
235
225
|
|
236
226
|
# Set the i-th element.
|
@@ -241,6 +231,8 @@ module GSLng
|
|
241
231
|
GSLng.backend::gsl_vector_set(self.ptr, (index < 0 ? @size + index : index), value.to_f)
|
242
232
|
end
|
243
233
|
|
234
|
+
# @group Views
|
235
|
+
|
244
236
|
# Create a {Vector::View} from this Vector.
|
245
237
|
# If _size_ is nil, it is computed automatically from _offset_ and _stride_
|
246
238
|
def view(offset = 0, size = nil, stride = 1)
|
@@ -254,14 +246,25 @@ module GSLng
|
|
254
246
|
|
255
247
|
if (stride == 1) then ptr = GSLng.backend::gsl_vector_subvector2(self.ptr, offset, size)
|
256
248
|
else ptr = GSLng.backend::gsl_vector_subvector_with_stride2(self.ptr, offset, stride, size) end
|
257
|
-
View.new(ptr, self,
|
249
|
+
View.new(ptr, self, size, stride)
|
258
250
|
end
|
259
251
|
alias_method :subvector_view, :view
|
260
252
|
|
261
253
|
# Shorthand for #subvector_view(..).to_vector.
|
262
254
|
def subvector(*args); subvector_view(*args).to_vector end
|
263
255
|
|
264
|
-
|
256
|
+
# Set all values to v
|
257
|
+
def all!(v); GSLng.backend::gsl_vector_set_all(self.ptr, v); return self end
|
258
|
+
alias_method :set!, :all!
|
259
|
+
alias_method :fill!, :all!
|
260
|
+
|
261
|
+
# Set all values to zero
|
262
|
+
def zero!; GSLng.backend::gsl_vector_set_zero(self.ptr); return self end
|
263
|
+
|
264
|
+
# Set all values to zero, except the i-th element, which is set to 1
|
265
|
+
def basis!(i); GSLng.backend::gsl_vector_set_basis(self.ptr, i); return self end
|
266
|
+
|
267
|
+
# @group 2D/3D/4D utility vectors
|
265
268
|
|
266
269
|
# Same as Vector#[0]
|
267
270
|
def x; GSLng.backend::gsl_vector_get(self.ptr, 0) end
|
@@ -281,7 +284,7 @@ module GSLng
|
|
281
284
|
# Same as Vector#[3]=
|
282
285
|
def w=(v); GSLng.backend::gsl_vector_set(self.ptr, 3, v.to_f) end
|
283
286
|
|
284
|
-
|
287
|
+
# @group Predicate methods
|
285
288
|
|
286
289
|
# if all elements are zero
|
287
290
|
def zero?; GSLng.backend::gsl_vector_isnull(self.ptr) == 1 ? true : false end
|
@@ -307,7 +310,7 @@ module GSLng
|
|
307
310
|
# If each element of self is less-or-equal than other's elements
|
308
311
|
def >=(other); (self - other).nonnegative? end
|
309
312
|
|
310
|
-
|
313
|
+
# @group Minimum/Maximum
|
311
314
|
|
312
315
|
# Return maximum element of vector
|
313
316
|
def max; GSLng.backend::gsl_vector_max(self.ptr) end
|
@@ -337,10 +340,81 @@ module GSLng
|
|
337
340
|
|
338
341
|
# Same as {#max}, but returns the index to the element
|
339
342
|
def max_index; GSLng.backend::gsl_vector_max_index(self.ptr) end
|
343
|
+
|
344
|
+
# @group Statistics
|
345
|
+
|
346
|
+
# Compute the mean of the vector
|
347
|
+
def mean; GSLng.backend.gsl_stats_mean(self.as_array, self.stride, self.size) end
|
348
|
+
|
349
|
+
# Compute the variance of the vector
|
350
|
+
# @param [Float] mean Optionally supply the mean if you already computed it previously with {self#mean}
|
351
|
+
# @param [Boolean] fixed_mean If true, the passed mean is taken to be known a priori (see GSL documentation)
|
352
|
+
def variance(mean = nil, fixed_mean = false)
|
353
|
+
if (mean.nil?) then GSLng.backend.gsl_stats_variance(self.as_array, self.stride, self.size)
|
354
|
+
else
|
355
|
+
if (fixed_mean) then GSLng.backend.gsl_stats_variance_with_fixed_mean(self.as_array, self.stride, self.size, mean)
|
356
|
+
else GSLng.backend.gsl_stats_variance_m(self.as_array, self.stride, self.size, mean) end
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
# Compute the standard deviation of the vector
|
361
|
+
# @see #variance
|
362
|
+
def standard_deviation(mean = nil, fixed_mean = false)
|
363
|
+
if (mean.nil?) then GSLng.backend.gsl_stats_sd(self.as_array, self.stride, self.size)
|
364
|
+
else
|
365
|
+
if (fixed_mean) then GSLng.backend.gsl_stats_sd_with_fixed_mean(self.as_array, self.stride, self.size, mean)
|
366
|
+
else GSLng.backend.gsl_stats_sd_m(self.as_array, self.stride, self.size, mean) end
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
# Compute the total sum of squares of the vector
|
371
|
+
# @see #variance
|
372
|
+
def total_sum_squares(mean = nil)
|
373
|
+
if (mean.nil?) then GSLng.backend.gsl_stats_tss(self.as_array, self.stride, self.size)
|
374
|
+
else GSLng.backend.gsl_stats_tss_m(self.as_array, self.stride, self.size, mean) end
|
375
|
+
end
|
376
|
+
|
377
|
+
# Compute the absolute deviation of the vector
|
378
|
+
# @see #variance
|
379
|
+
def absolute_deviation(mean = nil)
|
380
|
+
if (mean.nil?) then GSLng.backend.gsl_stats_absdev(self.as_array, self.stride, self.size)
|
381
|
+
else GSLng.backend.gsl_stats_absdev_m(self.as_array, self.stride, self.size, mean) end
|
382
|
+
end
|
383
|
+
|
384
|
+
# Compute the skew of the vector. You can optionally provide the mean *and* the standard deviation if you already computed them
|
385
|
+
def skew(mean = nil, sd = nil)
|
386
|
+
if (mean.nil? || sd.nil?) then GSLng.backend.gsl_stats_skew(self.as_array, self.stride, self.size)
|
387
|
+
else GSLng.backend.gsl_stats_skew_sd_m(self.as_array, self.stride, self.size, mean, sd) end
|
388
|
+
end
|
389
|
+
|
390
|
+
# Compute the kurtosis of the vector
|
391
|
+
# @see #skew
|
392
|
+
def kurtosis(mean = nil, sd = nil)
|
393
|
+
if (mean.nil? || sd.nil?) then GSLng.backend.gsl_stats_kurtosis(self.as_array, self.stride, self.size)
|
394
|
+
else GSLng.backend.gsl_stats_kurtosis_sd_m(self.as_array, self.stride, self.size, mean, sd) end
|
395
|
+
end
|
396
|
+
|
397
|
+
# Compute the autocorrelation of the vector
|
398
|
+
# @see #variance
|
399
|
+
def autocorrelation(mean = nil)
|
400
|
+
if (mean.nil?) then GSLng.backend.gsl_stats_lag1_autocorrelation(self.as_array, self.stride, self.size)
|
401
|
+
else GSLng.backend.gsl_stats_lag1_autocorrelation(self.as_array, self.stride, self.size, mean) end
|
402
|
+
end
|
403
|
+
|
404
|
+
# Compute the covariance between self and other. You can optionally pass the mean of both vectors if you already computed them
|
405
|
+
# @see #variance
|
406
|
+
def covariance(other, mean1 = nil, mean2 = nil)
|
407
|
+
if (mean1.nil? || mean2.nil?) then GSLng.backend.gsl_stats_covariance(self.as_array, self.stride, other.as_array, other.stride, self.size)
|
408
|
+
else GSLng.backend.gsl_stats_covariance(self.as_array, self.stride, other.as_array, other.stride, self.size, mean1, mean2) end
|
409
|
+
end
|
340
410
|
|
341
|
-
|
411
|
+
# Compute the correlation between self and other
|
412
|
+
def correlation(other)
|
413
|
+
GSLng.backend.gsl_stats_correlation(self.as_array, self.stride, other.as_array, other.stride, self.size)
|
414
|
+
end
|
415
|
+
|
416
|
+
# @group High-order methods
|
342
417
|
|
343
|
-
# Same as {#each}, but faster. The catch is that this method returns nothing.
|
344
418
|
# @yield [elem]
|
345
419
|
def each(block = Proc.new)
|
346
420
|
GSLng.backend::gsl_vector_each(self.ptr.to_i, &block)
|
@@ -352,7 +426,7 @@ module GSLng
|
|
352
426
|
GSLng.backend::gsl_vector_each_with_index(self.ptr.to_i, &block)
|
353
427
|
end
|
354
428
|
|
355
|
-
#
|
429
|
+
# @see #map
|
356
430
|
def map!(block = Proc.new); GSLng.backend::gsl_vector_map!(self.ptr.to_i, &block); return self end
|
357
431
|
|
358
432
|
# Similar to {#map!}, but passes the index to the element instead.
|
@@ -360,17 +434,23 @@ module GSLng
|
|
360
434
|
def map_index!(block = Proc.new); GSLng.backend::gsl_vector_map_index!(self.ptr.to_i, &block); return self end
|
361
435
|
|
362
436
|
# @return [Vector]
|
363
|
-
# @see map_index!
|
437
|
+
# @see #map_index!
|
364
438
|
# @yield [i]
|
365
439
|
def map_index(block = Proc.new); self.dup.map_index!(block) end
|
366
440
|
|
367
|
-
alias_method :
|
441
|
+
alias_method :map_old, :map
|
442
|
+
|
443
|
+
# Acts like the normal 'map' method from Enumerator
|
444
|
+
# @return [Array]
|
445
|
+
# @see #map
|
446
|
+
# @yield [i]
|
447
|
+
def map_array(block = Proc.new); self.map_old(&block); end
|
368
448
|
|
369
449
|
# @return [Vector]
|
370
450
|
# @yield [elem]
|
371
451
|
def map(block = Proc.new); self.dup.map!(block) end
|
372
452
|
|
373
|
-
|
453
|
+
# @group Type conversions
|
374
454
|
|
375
455
|
# @see Array#join
|
376
456
|
# @return [String]
|
@@ -411,6 +491,10 @@ module GSLng
|
|
411
491
|
def to_a
|
412
492
|
GSLng.backend.gsl_vector_to_a(self.ptr.to_i)
|
413
493
|
end
|
494
|
+
|
495
|
+
def as_array # @private
|
496
|
+
GSLng.backend.gsl_vector_as_array(self.ptr)
|
497
|
+
end
|
414
498
|
|
415
499
|
# Create a row matrix from this vector
|
416
500
|
# @return [Matrix]
|
@@ -430,7 +514,7 @@ module GSLng
|
|
430
514
|
end
|
431
515
|
alias_method :to_column, :transpose
|
432
516
|
|
433
|
-
|
517
|
+
# @group Equality test
|
434
518
|
|
435
519
|
# Element-by-element comparison. Admits comparing to Array.
|
436
520
|
def ==(other)
|
data/lib/gslng/vector_view.rb
CHANGED
@@ -10,9 +10,13 @@ module GSLng
|
|
10
10
|
# @return [Vector,Matrix] The owner of the data this view accesses
|
11
11
|
attr_reader :owner
|
12
12
|
|
13
|
-
def initialize(ptr, owner,
|
14
|
-
@owner,@size,@
|
15
|
-
|
13
|
+
def initialize(ptr, owner, size, stride = 1) # @private
|
14
|
+
@owner,@size,@stride = owner,size,stride
|
15
|
+
@ptr = FFI::AutoPointer.new(ptr, View.method(:release))
|
16
|
+
end
|
17
|
+
|
18
|
+
def View.release(ptr)
|
19
|
+
GSLng.backend.gsl_vector_free(ptr)
|
16
20
|
end
|
17
21
|
|
18
22
|
# Returns a Vector (*NOT* a View) copied from this view. In other words,
|
data/ruby-gsl-ng.gemspec
CHANGED
@@ -2,29 +2,29 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{ruby-gsl-ng}
|
5
|
-
s.version = "0.2.
|
5
|
+
s.version = "0.2.4"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["v01d"]
|
9
|
-
s.date = %q{2010-
|
10
|
-
s.description = %q{Ruby
|
9
|
+
s.date = %q{2010-09-21}
|
10
|
+
s.description = %q{Ruby/GSL new-generation wrapper}
|
11
11
|
s.email = %q{}
|
12
12
|
s.extensions = ["ext/extconf.rb"]
|
13
|
-
s.extra_rdoc_files = ["README.rdoc", "
|
14
|
-
s.files = ["History.txt", "README.rdoc", "Rakefile", "
|
13
|
+
s.extra_rdoc_files = ["README.rdoc", "ext/extconf.rb", "ext/gslng_extensions.cpp", "ext/plotting.cpp", "lib/gslng.rb", "lib/gslng/backend.rb", "lib/gslng/backend_components/error_handling.rb", "lib/gslng/backend_components/matrix.rb", "lib/gslng/backend_components/rng.rb", "lib/gslng/backend_components/special.rb", "lib/gslng/backend_components/stats.rb", "lib/gslng/backend_components/vector.rb", "lib/gslng/matrix.rb", "lib/gslng/matrix_view.rb", "lib/gslng/plotter.rb", "lib/gslng/rng/gaussian.rb", "lib/gslng/rng/rng.rb", "lib/gslng/rng/uniform.rb", "lib/gslng/special.rb", "lib/gslng/vector.rb", "lib/gslng/vector_view.rb"]
|
14
|
+
s.files = ["History.txt", "README.rdoc", "Rakefile", "ext/extconf.rb", "ext/gslng_extensions.cpp", "ext/plotting.cpp", "lib/gslng.rb", "lib/gslng/backend.rb", "lib/gslng/backend_components/error_handling.rb", "lib/gslng/backend_components/matrix.rb", "lib/gslng/backend_components/rng.rb", "lib/gslng/backend_components/special.rb", "lib/gslng/backend_components/stats.rb", "lib/gslng/backend_components/vector.rb", "lib/gslng/matrix.rb", "lib/gslng/matrix_view.rb", "lib/gslng/plotter.rb", "lib/gslng/rng/gaussian.rb", "lib/gslng/rng/rng.rb", "lib/gslng/rng/uniform.rb", "lib/gslng/special.rb", "lib/gslng/vector.rb", "lib/gslng/vector_view.rb", "ruby-gsl-ng.gemspec", "test/benchmark.rb", "test/benchmark_results", "test/matrix_test.rb", "test/rng_test.rb", "test/test_gsl.rb", "test/test_special.rb", "test/vector_test.rb", "Manifest"]
|
15
15
|
s.homepage = %q{http://github.com/v01d/ruby-gsl-ng}
|
16
16
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Ruby-gsl-ng", "--main", "README.rdoc"]
|
17
17
|
s.require_paths = ["lib", "ext"]
|
18
18
|
s.rubyforge_project = %q{ruby-gsl-ng}
|
19
|
-
s.rubygems_version = %q{1.3.
|
20
|
-
s.summary = %q{Ruby
|
19
|
+
s.rubygems_version = %q{1.3.7}
|
20
|
+
s.summary = %q{Ruby/GSL new-generation wrapper}
|
21
21
|
s.test_files = ["test/test_special.rb", "test/vector_test.rb", "test/test_gsl.rb", "test/matrix_test.rb", "test/rng_test.rb"]
|
22
22
|
|
23
23
|
if s.respond_to? :specification_version then
|
24
24
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
25
25
|
s.specification_version = 3
|
26
26
|
|
27
|
-
if Gem::Version.new(Gem::
|
27
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
28
28
|
s.add_runtime_dependency(%q<yard>, [">= 0"])
|
29
29
|
s.add_runtime_dependency(%q<ffi>, [">= 0"])
|
30
30
|
else
|
data/test/benchmark.rb
CHANGED
@@ -7,14 +7,27 @@ require 'rbgsl'
|
|
7
7
|
require 'narray'
|
8
8
|
include Benchmark
|
9
9
|
|
10
|
+
puts '#################################### Vector ####################################'
|
11
|
+
|
12
|
+
n=500000
|
13
|
+
size = 50000
|
14
|
+
puts "Vector#[]"
|
15
|
+
bmbm do |x|
|
16
|
+
v = GSLng::Vector.random(size)
|
17
|
+
gv = GSL::Vector.alloc(v.to_a)
|
18
|
+
x.report("rb-gsl :") {n.times {i=rand(size); gv[i]}}
|
19
|
+
x.report("GSLng :") {n.times {i=rand(size); v[i]}}
|
20
|
+
end
|
21
|
+
puts
|
22
|
+
|
10
23
|
n = 100
|
11
24
|
size = 5000
|
12
25
|
puts "Vector#each - vector of #{size} elements"
|
13
26
|
bmbm do |x|
|
14
27
|
v = GSLng::Vector.zero(size)
|
15
28
|
gv = GSL::Vector.alloc(v.to_a)
|
16
|
-
x.report("rb-gsl
|
17
|
-
x.report("
|
29
|
+
x.report("rb-gsl :") {n.times {s = 0; gv.each do |e| s += e end}}
|
30
|
+
x.report("GSLng :") {n.times {s = 0; v.each do |e| s += e end}}
|
18
31
|
end
|
19
32
|
puts
|
20
33
|
|
@@ -77,7 +90,7 @@ end
|
|
77
90
|
puts
|
78
91
|
|
79
92
|
n=500
|
80
|
-
size =
|
93
|
+
size = 50000
|
81
94
|
puts "Vector::from_array"
|
82
95
|
bmbm do |x|
|
83
96
|
a = Array.new(size) { rand }
|
@@ -86,15 +99,15 @@ bmbm do |x|
|
|
86
99
|
end
|
87
100
|
puts
|
88
101
|
|
102
|
+
puts '#################################### Matrix ####################################'
|
103
|
+
|
89
104
|
n=500000
|
90
|
-
size =
|
91
|
-
puts "
|
105
|
+
size = 50
|
106
|
+
puts "Matrix#[] - 50 x 50"
|
92
107
|
bmbm do |x|
|
93
|
-
v = GSLng::
|
94
|
-
gv = GSL::
|
95
|
-
i
|
96
|
-
x.report("
|
97
|
-
x.report("GSLng :") {n.times {v[i]}}
|
108
|
+
v = GSLng::Matrix.random(size, size)
|
109
|
+
gv = GSL::Matrix.alloc(size, size)
|
110
|
+
x.report("rb-gsl :") {n.times {i,j=rand(size),rand(size); gv[i,j]}}
|
111
|
+
x.report("GSLng :") {n.times {i,j=rand(size),rand(size); v[i,j]}}
|
98
112
|
end
|
99
|
-
puts
|
100
|
-
|
113
|
+
puts
|
data/test/matrix_test.rb
CHANGED
@@ -127,4 +127,10 @@ class TestMatrix < Test::Unit::TestCase
|
|
127
127
|
assert_equal(Matrix[[3],[2]], m.column_view(0))
|
128
128
|
assert_equal(Matrix[3,2,3], m.row_view(0))
|
129
129
|
end
|
130
|
+
|
131
|
+
def test_map
|
132
|
+
m = Matrix[[1,2,3],[2,3,4]]
|
133
|
+
assert_equal([['1.0','2.0','3.0'],['2.0','3.0','4.0']], m.map_array {|e| e.to_s})
|
134
|
+
assert_equal(Matrix[[2,3,4],[3,4,5]], m.map {|e| e+1})
|
135
|
+
end
|
130
136
|
end
|
data/test/vector_test.rb
CHANGED
@@ -35,7 +35,9 @@ class VectorTest < Test::Unit::TestCase
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def test_each
|
38
|
-
|
38
|
+
a = Vector[1.1,2.1,3.8].map_array(&:round)
|
39
|
+
assert_kind_of(Array, a)
|
40
|
+
assert_equal([1,2,4], a)
|
39
41
|
assert_equal(Vector[1,2,4],Vector[1.1,2.1,3.8].map!(&:round))
|
40
42
|
end
|
41
43
|
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 0.2.
|
8
|
+
- 4
|
9
|
+
version: 0.2.4
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- v01d
|
@@ -14,13 +14,14 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-09-21 00:00:00 -03:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: yard
|
22
22
|
prerelease: false
|
23
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
24
25
|
requirements:
|
25
26
|
- - ">="
|
26
27
|
- !ruby/object:Gem::Version
|
@@ -33,6 +34,7 @@ dependencies:
|
|
33
34
|
name: ffi
|
34
35
|
prerelease: false
|
35
36
|
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
36
38
|
requirements:
|
37
39
|
- - ">="
|
38
40
|
- !ruby/object:Gem::Version
|
@@ -41,7 +43,7 @@ dependencies:
|
|
41
43
|
version: "0"
|
42
44
|
type: :runtime
|
43
45
|
version_requirements: *id002
|
44
|
-
description: Ruby
|
46
|
+
description: Ruby/GSL new-generation wrapper
|
45
47
|
email: ""
|
46
48
|
executables: []
|
47
49
|
|
@@ -49,19 +51,20 @@ extensions:
|
|
49
51
|
- ext/extconf.rb
|
50
52
|
extra_rdoc_files:
|
51
53
|
- README.rdoc
|
52
|
-
- TODO
|
53
54
|
- ext/extconf.rb
|
54
55
|
- ext/gslng_extensions.cpp
|
56
|
+
- ext/plotting.cpp
|
55
57
|
- lib/gslng.rb
|
56
58
|
- lib/gslng/backend.rb
|
57
59
|
- lib/gslng/backend_components/error_handling.rb
|
58
60
|
- lib/gslng/backend_components/matrix.rb
|
59
61
|
- lib/gslng/backend_components/rng.rb
|
60
62
|
- lib/gslng/backend_components/special.rb
|
63
|
+
- lib/gslng/backend_components/stats.rb
|
61
64
|
- lib/gslng/backend_components/vector.rb
|
62
|
-
- lib/gslng/finalizer.rb
|
63
65
|
- lib/gslng/matrix.rb
|
64
66
|
- lib/gslng/matrix_view.rb
|
67
|
+
- lib/gslng/plotter.rb
|
65
68
|
- lib/gslng/rng/gaussian.rb
|
66
69
|
- lib/gslng/rng/rng.rb
|
67
70
|
- lib/gslng/rng/uniform.rb
|
@@ -72,19 +75,20 @@ files:
|
|
72
75
|
- History.txt
|
73
76
|
- README.rdoc
|
74
77
|
- Rakefile
|
75
|
-
- TODO
|
76
78
|
- ext/extconf.rb
|
77
79
|
- ext/gslng_extensions.cpp
|
80
|
+
- ext/plotting.cpp
|
78
81
|
- lib/gslng.rb
|
79
82
|
- lib/gslng/backend.rb
|
80
83
|
- lib/gslng/backend_components/error_handling.rb
|
81
84
|
- lib/gslng/backend_components/matrix.rb
|
82
85
|
- lib/gslng/backend_components/rng.rb
|
83
86
|
- lib/gslng/backend_components/special.rb
|
87
|
+
- lib/gslng/backend_components/stats.rb
|
84
88
|
- lib/gslng/backend_components/vector.rb
|
85
|
-
- lib/gslng/finalizer.rb
|
86
89
|
- lib/gslng/matrix.rb
|
87
90
|
- lib/gslng/matrix_view.rb
|
91
|
+
- lib/gslng/plotter.rb
|
88
92
|
- lib/gslng/rng/gaussian.rb
|
89
93
|
- lib/gslng/rng/rng.rb
|
90
94
|
- lib/gslng/rng/uniform.rb
|
@@ -116,6 +120,7 @@ require_paths:
|
|
116
120
|
- lib
|
117
121
|
- ext
|
118
122
|
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
none: false
|
119
124
|
requirements:
|
120
125
|
- - ">="
|
121
126
|
- !ruby/object:Gem::Version
|
@@ -123,6 +128,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
123
128
|
- 0
|
124
129
|
version: "0"
|
125
130
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
126
132
|
requirements:
|
127
133
|
- - ">="
|
128
134
|
- !ruby/object:Gem::Version
|
@@ -133,10 +139,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
139
|
requirements: []
|
134
140
|
|
135
141
|
rubyforge_project: ruby-gsl-ng
|
136
|
-
rubygems_version: 1.3.
|
142
|
+
rubygems_version: 1.3.7
|
137
143
|
signing_key:
|
138
144
|
specification_version: 3
|
139
|
-
summary: Ruby
|
145
|
+
summary: Ruby/GSL new-generation wrapper
|
140
146
|
test_files:
|
141
147
|
- test/test_special.rb
|
142
148
|
- test/vector_test.rb
|
data/lib/gslng/finalizer.rb
DELETED