gsl4r 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/INSTALL +3 -8
- data/README +20 -3
- data/Rakefile +6 -0
- data/changelog +2 -0
- data/lib/b_t.rb +16 -0
- data/lib/gsl4r.rb +1 -1
- data/lib/gsl4r/block.rb +64 -21
- data/lib/gsl4r/complex.rb +20 -0
- data/lib/gsl4r/harness.rb +2 -2
- data/lib/gsl4r/util.rb +56 -21
- data/lib/gsl4r/vector.rb +328 -12
- data/lib/t.rb +19 -10
- data/test/README +6 -2
- data/test/block_class_test.rb +104 -0
- data/test/complex_test.rb +210 -210
- data/test/gsl_complex_tests_gen +0 -0
- data/test/gsl_complex_tests_gen.c +613 -613
- data/test/gsl_vector_tests_gen +0 -0
- data/test/gsl_vector_tests_gen.c +203 -0
- data/test/vector_class_test.rb +128 -0
- data/test/vector_test.rb +104 -0
- metadata +18 -5
data/INSTALL
CHANGED
@@ -11,12 +11,7 @@ System wide gem install using rake
|
|
11
11
|
|
12
12
|
sudo rake install
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
export LD_LIBRARY_PATH=/opt/local/lib:$LD_LIBRARY_PATH
|
18
|
-
|
19
|
-
Under linux, it might look something like,
|
20
|
-
|
21
|
-
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
|
14
|
+
GSL4r uses gsl-config to dynamically determine the location
|
15
|
+
of the gsl libraries. You must have gsl-config in your
|
16
|
+
execution path for GSL4r to operate.
|
22
17
|
|
data/README
CHANGED
@@ -11,7 +11,7 @@ This avoids the complications with implementation specific C extensions or Java
|
|
11
11
|
|
12
12
|
== Documentation
|
13
13
|
|
14
|
-
This project is currently in its alpha stages and as of
|
14
|
+
This project is currently in its alpha stages and as of 22 Mar 2010, I have only pushed a library for using Complex functions in GSL, all constants are defined, and handling pointers to blocks and vectors and basic vector functions.
|
15
15
|
|
16
16
|
== Getting Started
|
17
17
|
|
@@ -25,10 +25,12 @@ gem install -r gsl4r
|
|
25
25
|
|
26
26
|
== Examples
|
27
27
|
|
28
|
+
Also see the examples directory in the gem.
|
29
|
+
|
28
30
|
cd gsl4r/lib
|
29
31
|
irb -r rubygems -r gsl4r -r gsl4r/complex
|
30
32
|
irb(main):001:0> include GSL4r::Complex
|
31
|
-
|
33
|
+
=> Object
|
32
34
|
irb(main):004:0> a=GSL_Complex.create(1,1)
|
33
35
|
=> (1.0,1.0)
|
34
36
|
irb(main):005:0> b=GSL_Complex.create(2,2)
|
@@ -53,7 +55,22 @@ irb(main):013:0> p CGS::JOULE
|
|
53
55
|
10000000.0
|
54
56
|
irb(main):014:0> p MKS::ERG
|
55
57
|
1.0e-07
|
56
|
-
|
58
|
+
...
|
59
|
+
irb -r rubygems -r gsl4r -r gsl4r/vector
|
60
|
+
irb(main):001:0> include GSL4r::Vector
|
61
|
+
=> Object
|
62
|
+
irb(main):002:0> a=GSL_Vector.create(3)
|
63
|
+
=> #<GSL4r::Vector::GSL_Vector:0x5ea038>
|
64
|
+
irb(main):003:0> b=GSL_Vector.create(3)
|
65
|
+
=> #<GSL4r::Vector::GSL_Vector:0x5e66f4>
|
66
|
+
irb(main):004:0> a.set_with_array([1,2,3])
|
67
|
+
=> #<FFI::Pointer address=0x2db2e0>
|
68
|
+
irb(main):005:0> b.set_with_array([4,5,6])
|
69
|
+
=> #<FFI::Pointer address=0x4f8260>
|
70
|
+
irb(main):006:0> a.mul(b)
|
71
|
+
=> 0
|
72
|
+
irb(main):012:0> a.values
|
73
|
+
=> [4.0, 10.0, 18.0]
|
57
74
|
...
|
58
75
|
|
59
76
|
== Questions and/or Comments
|
data/Rakefile
CHANGED
@@ -63,12 +63,18 @@ task :test => [:gsl_config] do
|
|
63
63
|
|
64
64
|
require 'gsl4r'
|
65
65
|
require 'gsl4r/complex'
|
66
|
+
require 'gsl4r/vector'
|
66
67
|
|
67
68
|
complextests = GSL4r::Complex::Harness.new
|
68
69
|
complextests.write_c_tests
|
69
70
|
complextests.compile_c_tests
|
70
71
|
complextests.run_c_tests "complex_test.rb"
|
71
72
|
|
73
|
+
vectortests = GSL4r::Vector::Harness.new
|
74
|
+
vectortests.write_c_tests
|
75
|
+
vectortests.compile_c_tests
|
76
|
+
vectortests.run_c_tests "vector_test.rb"
|
77
|
+
|
72
78
|
runner = Test::Unit::AutoRunner.new(true)
|
73
79
|
runner.to_run << 'test'
|
74
80
|
runner.pattern = [/_test.rb$/]
|
data/changelog
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
0.0.2
|
2
2
|
|
3
|
+
* Uses gsl-config at runtime
|
3
4
|
* Added all GSL constants
|
4
5
|
* Block and Vector memory handling
|
5
6
|
* Moved method_missing definition into generic AutoPrefix
|
6
7
|
* class, so that this code is not duplicated amongst many
|
7
8
|
* classes.
|
9
|
+
* Added tools in bin/ for generating wrapper stubs and constants
|
8
10
|
|
9
11
|
0.0.1
|
10
12
|
|
data/lib/b_t.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'gsl4r'
|
3
|
+
require 'gsl4r/block'
|
4
|
+
include FFI
|
5
|
+
op1 = MemoryPointer.new :pointer
|
6
|
+
op1 = GSL4r::Block::Methods::gsl_block_alloc(50)
|
7
|
+
puts op1.get_ulong(0)
|
8
|
+
ob1=GSL4r::Block::GSL_Block.new(op1)
|
9
|
+
ob2=GSL4r::Block::GSL_Block_Cast.new(op1)
|
10
|
+
#puts ob1.length
|
11
|
+
#op1.put_array_of_double(1, (1..50).to_a.collect { |i| i=i*5.0 } )
|
12
|
+
#ob1[:data].put_array_of_double(0, (1..50).to_a.collect { |i| i=i*5.0 } )
|
13
|
+
puts ob2.set( (1..50).to_a.collect { |i| i=i*5.0 } )
|
14
|
+
v = ob2.values
|
15
|
+
v[1] = 3000.0
|
16
|
+
puts v
|
data/lib/gsl4r.rb
CHANGED
@@ -10,7 +10,7 @@ require 'rubygems'
|
|
10
10
|
require 'ffi'
|
11
11
|
|
12
12
|
module GSL4r
|
13
|
-
Version = '0.0.
|
13
|
+
Version = '0.0.3';
|
14
14
|
GSL_LIB_PATH = File.join([`gsl-config --prefix`.chomp,
|
15
15
|
"lib","libgsl.#{FFI::Platform::LIBSUFFIX}"])
|
16
16
|
GSLCBLAS_LIB_PATH = File.join([`gsl-config --prefix`.chomp,
|
data/lib/gsl4r/block.rb
CHANGED
@@ -19,29 +19,71 @@ module GSL4r
|
|
19
19
|
|
20
20
|
extend ::FFI::Library
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
# lifted from
|
23
|
+
# http://wiki.github.com/ffi/ffi/examples
|
24
|
+
module BlockLayout
|
25
|
+
def self.included(base)
|
26
|
+
base.class_eval do
|
27
|
+
layout :size, :size_t,
|
28
|
+
:data, :pointer
|
28
29
|
end
|
30
|
+
end
|
31
|
+
end
|
29
32
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
+
def get_block_size( a_block )
|
34
|
+
return a_block.get_ulong(0)
|
35
|
+
end
|
36
|
+
module_function :get_block_size
|
33
37
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
38
|
+
def get_block_data( a_block )
|
39
|
+
return a_block.get_array_of_double(0,get_block_size(a_block))
|
40
|
+
end
|
41
|
+
module_function :get_block_data
|
42
|
+
|
43
|
+
def set_block_data( a_block, some_data )
|
44
|
+
if ( some_data.length > get_block_size(a_block) )
|
45
|
+
raise "data exceeds size of block"
|
46
|
+
end
|
47
|
+
a_block.put_array_of_double(1,some_data)
|
48
|
+
return some_data
|
49
|
+
end
|
50
|
+
module_function :set_block_data
|
51
|
+
|
52
|
+
class GSL_Block < FFI::ManagedStruct
|
53
|
+
include ::GSL4r::Block::BlockLayout
|
54
|
+
|
55
|
+
def self.release(ptr)
|
56
|
+
::GSL4r::Block::Methods::gsl_block_free(ptr)
|
57
|
+
end
|
40
58
|
|
41
|
-
|
59
|
+
def length
|
60
|
+
return self[:size]
|
61
|
+
end
|
42
62
|
|
43
|
-
|
44
|
-
|
63
|
+
def values
|
64
|
+
return self[:data].get_array_of_double(0,length)
|
65
|
+
end
|
66
|
+
|
67
|
+
def set( a )
|
68
|
+
self[:data].put_array_of_double(0,a)
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
class GSL_Block_Cast < FFI::Struct
|
74
|
+
include ::GSL4r::Block::BlockLayout
|
75
|
+
|
76
|
+
def length
|
77
|
+
return self[:size]
|
78
|
+
end
|
79
|
+
|
80
|
+
def values
|
81
|
+
return self[:data].get_array_of_double(0,length)
|
82
|
+
end
|
83
|
+
|
84
|
+
def set( a )
|
85
|
+
self[:data].put_array_of_double(0,a)
|
86
|
+
end
|
45
87
|
|
46
88
|
end # class GSL_Block
|
47
89
|
|
@@ -51,9 +93,10 @@ module GSL4r
|
|
51
93
|
|
52
94
|
ffi_lib ::GSL4r::GSL_LIB_PATH
|
53
95
|
|
54
|
-
|
55
|
-
|
56
|
-
|
96
|
+
attach_function :gsl_block_alloc, [:size_t], :pointer
|
97
|
+
attach_function :gsl_block_calloc, [:size_t], :pointer
|
98
|
+
attach_function :gsl_block_free, [:pointer], :void
|
99
|
+
|
57
100
|
end
|
58
101
|
end # module Block
|
59
102
|
end # module GSL4r
|
data/lib/gsl4r/complex.rb
CHANGED
@@ -72,6 +72,10 @@ module GSL4r
|
|
72
72
|
"GSL_Complex"
|
73
73
|
end
|
74
74
|
|
75
|
+
def r_initializer()
|
76
|
+
r_type + ".create"
|
77
|
+
end
|
78
|
+
|
75
79
|
def r_equals(v1,v2)
|
76
80
|
"#{v1.to_s}.equals(#{v2.to_s})"
|
77
81
|
end
|
@@ -104,6 +108,22 @@ module GSL4r
|
|
104
108
|
end
|
105
109
|
end
|
106
110
|
|
111
|
+
def +(other)
|
112
|
+
self.add(other)
|
113
|
+
end
|
114
|
+
|
115
|
+
def -(other)
|
116
|
+
self.sub(other)
|
117
|
+
end
|
118
|
+
|
119
|
+
def *(other)
|
120
|
+
self.mul(other)
|
121
|
+
end
|
122
|
+
|
123
|
+
def /(other)
|
124
|
+
self.div(other)
|
125
|
+
end
|
126
|
+
|
107
127
|
# Play nice and have these methods show up in case someone
|
108
128
|
# is digging around for them using these reflection routines
|
109
129
|
# Note: this won't show the shortened named forms that
|
data/lib/gsl4r/harness.rb
CHANGED
@@ -44,8 +44,8 @@ module GSL4r
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def compile_c_tests
|
47
|
-
compile_s = "#{@c_compiler} #{@
|
48
|
-
|
47
|
+
compile_s = "#{@c_compiler} -o #{TEST_DIR}/#{@c_binary} " +
|
48
|
+
"#{TEST_DIR}/#{@c_src_name} #{@c_flags.join(" ")} "
|
49
49
|
p compile_s
|
50
50
|
`#{compile_s}`
|
51
51
|
end
|
data/lib/gsl4r/util.rb
CHANGED
@@ -14,8 +14,10 @@ module GSL4r
|
|
14
14
|
|
15
15
|
$c_var_num = 0
|
16
16
|
|
17
|
+
# TODO: The automated test writing is kindof klunky and probably
|
18
|
+
# ought to be re-thought out...
|
17
19
|
def attach_gsl_function( method_name, args, return_var, args_type=nil, return_type=nil,
|
18
|
-
add_self=true )
|
20
|
+
add_self=true, answerat=0 )
|
19
21
|
|
20
22
|
# This function is attached to the extended ::FFI::Library
|
21
23
|
# module from the calling namespace, e.g. ::GSL4r::Complex::Methods
|
@@ -31,32 +33,53 @@ module GSL4r
|
|
31
33
|
# prepare c and ruby args code
|
32
34
|
c_src = ""
|
33
35
|
c_call_vars = []
|
34
|
-
|
36
|
+
|
37
|
+
c_return_name = ( answerat == 0 ? "c_r#{$c_var_num}" : "" )
|
38
|
+
|
35
39
|
r_src = []
|
36
40
|
if ( ! args_type.is_a?(Array) )
|
37
41
|
args_type = Array.new([args_type])
|
38
42
|
end
|
39
43
|
args_type.each { |a_t|
|
40
44
|
c_var_name = "v#{$c_var_num += 1}"
|
45
|
+
|
46
|
+
# This tracks if the answer to check against is in a variable
|
47
|
+
# *other than* the return value. For example:
|
48
|
+
# sprintf( char *ans, char *format, ... ), the answer is
|
49
|
+
# in *ans (aka 1). answerat == 0 is the return value
|
50
|
+
if ( answerat == $c_var_num )
|
51
|
+
c_return_name = c_var_name
|
52
|
+
end
|
53
|
+
|
41
54
|
c_src << (a_t.respond_to?("c_type") ?
|
42
55
|
" #{a_t.c_type} #{c_var_name};\n" : "#{a_t.to_s} #{c_var_name} ")
|
56
|
+
c_src << (a_t.respond_to?("c_initializer") ?
|
57
|
+
" #{a_t.c_initializer("#{c_var_name}")}\n" : "")
|
43
58
|
c_src << (a_t.respond_to?("c_assignment") ?
|
44
59
|
" #{a_t.c_assignment("#{c_var_name}")}\n" : "= (#{a_t.to_s})2.0;\n")
|
45
60
|
c_call_vars << "#{c_var_name}"
|
46
61
|
|
47
|
-
r_src << (a_t.respond_to?("
|
48
|
-
" #{c_var_name} = #{a_t.
|
62
|
+
r_src << (a_t.respond_to?("r_initializer") ?
|
63
|
+
" #{c_var_name} = #{a_t.r_initializer}" : "")
|
49
64
|
r_src << (a_t.respond_to?("r_assignment") ?
|
50
65
|
" #{a_t.r_assignment("#{c_var_name}")}" : " #{c_var_name} = 2.0")
|
51
66
|
} # args_type.each
|
52
67
|
|
53
68
|
# prepare c return type
|
54
|
-
|
55
|
-
|
56
|
-
|
69
|
+
# if the answer is coming back not from the return value,
|
70
|
+
# then don't bother adding this
|
71
|
+
if ( answerat == 0 )
|
72
|
+
c_src << (return_type.respond_to?("c_type") ?
|
73
|
+
" #{return_type.c_type} #{c_return_name};\n" :
|
74
|
+
" #{return_type.to_s} #{c_return_name};\n")
|
75
|
+
c_src << " #{c_return_name} = "
|
76
|
+
else
|
77
|
+
c_src << " "
|
78
|
+
end
|
57
79
|
|
58
80
|
# prepare c call
|
59
|
-
|
81
|
+
|
82
|
+
c_src << "#{method_name}(#{c_call_vars.join(",")});\n"
|
60
83
|
|
61
84
|
# now generate the ruby code for the unit test
|
62
85
|
c_src << " puts(" << %Q{\\"def test_#{method_name}()\\"} << ");\n"
|
@@ -69,24 +92,36 @@ module GSL4r
|
|
69
92
|
|
70
93
|
r_r1 = "r_r1" # ruby result
|
71
94
|
c_src << " puts(" << %Q{\\" #{r_r1} = ::#{self.to_s}::#{method_name}(#{c_call_vars.join(",")})\\"} << ");\n"
|
72
|
-
if (
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
95
|
+
if ( answerat == 0 )
|
96
|
+
if ( return_type.respond_to?("c_to_r_assignment") )
|
97
|
+
r_r2 = "r_r2" # ruby result comparitor
|
98
|
+
c_src << " puts(" << %Q{\\" #{r_r2} = #{return_type.r_type}.new\\"} << ");\n"
|
99
|
+
c_src << " #{return_type.c_to_r_assignment(r_r2,c_return_name)}"
|
100
|
+
c_src << " printf(" << %Q{\\" assert r_r1.equals(r_r2)\\\\n\\"} << ");\n"
|
101
|
+
else # return_type.respond_to
|
102
|
+
# TODO: this will have to be expanded to handle more types..
|
103
|
+
# A good default fall back is unsigned long though, for size_t or int returns
|
104
|
+
# but this could lead to submit errors that aren't really errors...
|
105
|
+
c_src << " printf(" << %Q{\\" assert_in_delta r_r1, #{(return_type == :double ? "%.15g" : "%lu")}, EPSILON\\\\n\\"} << ", #{c_return_name});\n"
|
106
|
+
end
|
107
|
+
else # answerat == 0
|
108
|
+
c_src << " printf(" << %Q{\\" assert }
|
109
|
+
# I'd rather this fail at run-time so, don't check if r_answer is there
|
110
|
+
c_src << args_type[answerat-1].r_answer("#{c_call_vars[answerat-1]}")
|
111
|
+
c_src << args_type[answerat-1].r_equals << %Q{\\");\n}
|
112
|
+
c_src << " " << args_type[answerat-1].c_answer("#{c_call_vars[answerat-1]}")
|
79
113
|
end
|
80
114
|
|
81
115
|
c_src << " puts(" << %Q{\\"end\\"} << ");"
|
82
116
|
|
83
117
|
# TODO, create unit test for aliased/shorthand versions of methods
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
118
|
+
|
119
|
+
self.module_eval <<-end_eval
|
120
|
+
def c_test_#{method_name}
|
121
|
+
# Build list of arguments and their values
|
122
|
+
"#{c_src}"
|
123
|
+
end
|
124
|
+
module_function :c_test_#{method_name}
|
90
125
|
end_eval
|
91
126
|
end
|
92
127
|
end # attach_gsl_function
|
data/lib/gsl4r/vector.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
|
2
1
|
#
|
3
2
|
# == Other Info
|
4
3
|
#
|
4
|
+
#
|
5
5
|
# Author:: Colby Gutierrez-Kraybill
|
6
6
|
# Version:: $Id$
|
7
7
|
#
|
@@ -9,26 +9,342 @@
|
|
9
9
|
require 'rubygems'
|
10
10
|
require 'ffi'
|
11
11
|
|
12
|
+
require 'gsl4r/util'
|
13
|
+
require 'gsl4r/harness'
|
14
|
+
require 'gsl4r/block'
|
15
|
+
|
12
16
|
module GSL4r
|
13
17
|
module Vector
|
14
18
|
|
15
19
|
extend ::FFI::Library
|
16
20
|
|
17
|
-
|
21
|
+
# layout/cast/struct pattern /lifted from
|
22
|
+
# http://wiki.github.com/ffi/ffi/examples
|
23
|
+
module VectorLayout
|
24
|
+
def self.included(base)
|
25
|
+
base.class_eval do
|
26
|
+
layout :size, :size_t,
|
27
|
+
:stride, :size_t,
|
28
|
+
:data, :pointer,
|
29
|
+
:block, :pointer,
|
30
|
+
:owner, :int
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_vector_size( a_vector )
|
36
|
+
return a_vector.get_ulong(0)
|
37
|
+
end
|
38
|
+
module_function :get_vector_size
|
39
|
+
|
40
|
+
def get_vector_stride( a_vector )
|
41
|
+
return a_vector.get_ulong(1)
|
42
|
+
end
|
43
|
+
module_function :get_vector_stride
|
44
|
+
|
45
|
+
# TODO fix me
|
46
|
+
def get_vector_data( a_vector )
|
47
|
+
return a_vector.values
|
48
|
+
end
|
49
|
+
module_function :get_vector_data
|
50
|
+
|
51
|
+
def set_vector_data( a_block, some_data )
|
52
|
+
if ( some_data.length > ::GSL4r::Block::get_block_size(a_block) )
|
53
|
+
raise "data exceeds size of block"
|
54
|
+
end
|
55
|
+
a_block.put_array_of_double(1,some_data)
|
56
|
+
return some_data
|
57
|
+
end
|
58
|
+
module_function :set_vector_data
|
59
|
+
|
60
|
+
class GSL_Vector < FFI::ManagedStruct
|
61
|
+
include ::GSL4r::Vector::VectorLayout
|
18
62
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
:block, :pointer,
|
24
|
-
:owner, :int
|
63
|
+
attr_accessor :vecptr
|
64
|
+
|
65
|
+
GSL_PREFIX = "gsl_vector_"
|
66
|
+
GSL_MODULE = ::GSL4r::Vector
|
25
67
|
|
26
68
|
include ::GSL4r::Util::AutoPrefix
|
27
|
-
|
28
|
-
|
29
|
-
|
69
|
+
|
70
|
+
def self.create( size )
|
71
|
+
@vecptr = ::FFI::MemoryPointer.new :pointer
|
72
|
+
@vecptr = ::GSL4r::Vector::Methods::gsl_vector_alloc( size )
|
73
|
+
|
74
|
+
GSL_Vector.new( @vecptr )
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.release(ptr)
|
78
|
+
::GSL4r::Vector::Methods::gsl_vector_free(ptr)
|
79
|
+
end
|
80
|
+
|
81
|
+
def length
|
82
|
+
return self[:size]
|
83
|
+
end
|
84
|
+
|
85
|
+
def values
|
86
|
+
return self[:data].get_array_of_double(0,self.length)
|
87
|
+
end
|
88
|
+
|
89
|
+
def set_with_array( a )
|
90
|
+
self[:data].put_array_of_double(0,a)
|
91
|
+
end
|
92
|
+
|
93
|
+
def minmax
|
94
|
+
min = ::FFI::MemoryPointer.new :double
|
95
|
+
max = ::FFI::MemoryPointer.new :double
|
96
|
+
|
97
|
+
::GSL4r::Vector::Methods::gsl_vector_minmax( self, min, max )
|
98
|
+
|
99
|
+
rmin = min.get_double(0)
|
100
|
+
rmax = max.get_double(0)
|
101
|
+
min = nil
|
102
|
+
max = nil
|
103
|
+
|
104
|
+
return rmin, rmax
|
105
|
+
end
|
106
|
+
|
107
|
+
def minmax_index
|
108
|
+
min = ::FFI::MemoryPointer.new :size_t
|
109
|
+
max = ::FFI::MemoryPointer.new :size_t
|
110
|
+
|
111
|
+
::GSL4r::Vector::Methods::gsl_vector_minmax_index( self, min, max )
|
112
|
+
|
113
|
+
# TODO: Submit request that get_size_t be added to FFI?
|
114
|
+
if min.size > FFI::type_size( :ulong )
|
115
|
+
raise RuntimeError, "unsigned long < size_t on this platform!"
|
116
|
+
end
|
117
|
+
|
118
|
+
rmin = min.get_ulong(0)
|
119
|
+
rmax = max.get_ulong(0)
|
120
|
+
min = nil
|
121
|
+
max = nil
|
122
|
+
|
123
|
+
return rmin, rmax
|
124
|
+
end
|
125
|
+
|
126
|
+
# Play nice and have these methods show up in case someone
|
127
|
+
# is digging around for them using these reflection routines
|
128
|
+
# Note: this won't show the shortened named forms that
|
129
|
+
# will automatically be generated when called.
|
130
|
+
def methods
|
131
|
+
a = super
|
132
|
+
a + GSL_MODULE::Methods.methods.grep(/^#{GSL_PREFIX}/)
|
133
|
+
end
|
134
|
+
|
135
|
+
class << self
|
136
|
+
def r_type()
|
137
|
+
"GSL_Vector"
|
138
|
+
end
|
139
|
+
def r_initializer()
|
140
|
+
r_type + ".create(3)"
|
141
|
+
end
|
142
|
+
def r_equals()
|
143
|
+
" == "
|
144
|
+
end
|
145
|
+
def r_answer( name )
|
146
|
+
"#{name}.values"
|
147
|
+
end
|
148
|
+
def r_assignment( name )
|
149
|
+
"#{name}.set( [1.0,2.0,3.0] )" # these numbers should make c_assignment ...
|
150
|
+
end
|
151
|
+
def c_to_r_assignment(v1,v2)
|
152
|
+
"printf(\\\" #{v1}.set([%.15g,%.15g,%.15g])\\\\n\\\",gsl_vector_get(#{v2},0),gsl_vector_get(#{v2},1),gsl_vector_get(#{v2},2));\\n"
|
153
|
+
end
|
154
|
+
def c_type()
|
155
|
+
"gsl_vector *"
|
156
|
+
end
|
157
|
+
def c_assignment( name )
|
158
|
+
"gsl_vector_set(#{name}, 0, 1.0 ); gsl_vector_set(#{name}, 1, 2.0 ); gsl_vector_set(#{name}, 2, 3.0 );"
|
159
|
+
end
|
160
|
+
def c_answer( name )
|
161
|
+
"printf(\\\"[%.15g,%.15g,%.15g]\\\\n\\\",gsl_vector_get(#{name},0),gsl_vector_get(#{name},1),gsl_vector_get(#{name},2));\\n"
|
162
|
+
end
|
163
|
+
def c_equals()
|
164
|
+
end
|
165
|
+
def c_initializer( name )
|
166
|
+
"#{name} = gsl_vector_alloc(3); "
|
167
|
+
end
|
168
|
+
end # class << self
|
169
|
+
|
170
|
+
end # GSL_Vector
|
171
|
+
|
172
|
+
class GSL_Vector_Cast < FFI::Struct
|
173
|
+
include ::GSL4r::Vector::VectorLayout
|
174
|
+
|
175
|
+
GSL_PREFIX = "gsl_vector_"
|
176
|
+
GSL_MODULE = ::GSL4r::Vector
|
177
|
+
|
178
|
+
include ::GSL4r::Util::AutoPrefix
|
179
|
+
|
180
|
+
def length
|
181
|
+
return self[:size]
|
182
|
+
end
|
183
|
+
|
184
|
+
def values
|
185
|
+
return self[:data].get_array_of_double(0,length)
|
186
|
+
end
|
187
|
+
|
188
|
+
def set_with_array( a )
|
189
|
+
self[:data].put_array_of_double(0,a)
|
190
|
+
end
|
191
|
+
|
192
|
+
def minmax
|
193
|
+
min = ::FFI::MemoryPointer.new :double
|
194
|
+
max = ::FFI::MemoryPointer.new :double
|
195
|
+
|
196
|
+
::GSL4r::Vector::Methods::gsl_vector_minmax( self, min, max )
|
197
|
+
|
198
|
+
rmin = min.get_double(0)
|
199
|
+
rmax = max.get_double(0)
|
200
|
+
min = nil
|
201
|
+
max = nil
|
202
|
+
|
203
|
+
return rmin, rmax
|
204
|
+
end
|
205
|
+
|
206
|
+
def minmax_index
|
207
|
+
min = ::FFI::MemoryPointer.new :size_t
|
208
|
+
max = ::FFI::MemoryPointer.new :size_t
|
209
|
+
|
210
|
+
::GSL4r::Vector::Methods::gsl_vector_minmax_index( self, min, max )
|
211
|
+
|
212
|
+
# TODO: Submit request that get_size_t be added to FFI?
|
213
|
+
if min.size > FFI::type_size( :ulong )
|
214
|
+
raise RuntimeError, "unsigned long < size_t on this platform!"
|
215
|
+
end
|
216
|
+
|
217
|
+
rmin = min.get_ulong(0)
|
218
|
+
rmax = max.get_ulong(0)
|
219
|
+
min = nil
|
220
|
+
max = nil
|
221
|
+
|
222
|
+
return rmin, rmax
|
223
|
+
end
|
224
|
+
|
225
|
+
# Play nice and have these methods show up in case someone
|
226
|
+
# is digging around for them using these reflection routines
|
227
|
+
# Note: this won't show the shortened named forms that
|
228
|
+
# will automatically be generated when called.
|
229
|
+
def methods
|
230
|
+
a = super
|
231
|
+
a + GSL_MODULE::Methods.methods.grep(/^#{GSL_PREFIX}/)
|
232
|
+
end
|
233
|
+
|
234
|
+
end # class GSL_Vector_Cast
|
235
|
+
|
236
|
+
module Methods
|
237
|
+
extend ::GSL4r::Util
|
238
|
+
extend ::FFI::Library
|
239
|
+
|
240
|
+
ffi_lib ::GSL4r::GSL_LIB_PATH
|
241
|
+
|
242
|
+
# Utility routines related to handling vectors
|
243
|
+
#
|
244
|
+
# Creating vectors
|
245
|
+
attach_function :gsl_vector_alloc, [:size_t], :pointer
|
246
|
+
attach_function :gsl_vector_calloc, [:size_t], :pointer
|
247
|
+
attach_function :gsl_vector_free, [:pointer], :void
|
248
|
+
|
249
|
+
# set/get individual values
|
250
|
+
attach_gsl_function :gsl_vector_get, [:pointer, :size_t], :double
|
251
|
+
attach_gsl_function :gsl_vector_set, [:pointer, :size_t, :double], :void
|
252
|
+
|
253
|
+
# set values across entire vector
|
254
|
+
attach_gsl_function :gsl_vector_set_all, [:pointer, :double], :void
|
255
|
+
attach_gsl_function :gsl_vector_set_zero, [:pointer], :void
|
256
|
+
attach_gsl_function :gsl_vector_set_basis, [:pointer, :size_t], :int
|
257
|
+
|
258
|
+
# Vector views
|
259
|
+
#
|
260
|
+
# These return a GSL_Vector_Cast to avoid inappropriate garbage
|
261
|
+
# collection on the returned structure
|
262
|
+
attach_gsl_function :gsl_vector_subvector, [:pointer, :size_t, :size_t],
|
263
|
+
GSL_Vector_Cast.by_value
|
264
|
+
|
265
|
+
attach_gsl_function :gsl_vector_subvector_with_stride,
|
266
|
+
[:pointer, :size_t, :size_t, :size_t],
|
267
|
+
GSL_Vector_Cast.by_value
|
268
|
+
|
269
|
+
# Copying vectors
|
270
|
+
attach_gsl_function :gsl_vector_memcpy, [:pointer, :pointer], :int
|
271
|
+
attach_gsl_function :gsl_vector_swap, [:pointer, :pointer], :int
|
272
|
+
|
273
|
+
# Exchanging elements
|
274
|
+
attach_gsl_function :gsl_vector_swap_elements, [:pointer, :size_t, :size_t], :int
|
275
|
+
attach_gsl_function :gsl_vector_reverse, [:pointer], :int
|
276
|
+
|
277
|
+
# basic arithmetic
|
278
|
+
# a'i = ai + bi
|
279
|
+
attach_gsl_function :gsl_vector_add, [:pointer, :pointer], :int,
|
280
|
+
[GSL_Vector, GSL_Vector], :double, true, 1
|
281
|
+
# a'i = ai - bi
|
282
|
+
attach_gsl_function :gsl_vector_sub, [:pointer, :pointer], :int,
|
283
|
+
[GSL_Vector, GSL_Vector], :double, true, 1
|
284
|
+
# a'i = ai * bi
|
285
|
+
attach_gsl_function :gsl_vector_mul, [:pointer, :pointer], :int,
|
286
|
+
[GSL_Vector, GSL_Vector], :double, true, 1
|
287
|
+
# a'i = ai / bi
|
288
|
+
attach_gsl_function :gsl_vector_div, [:pointer, :pointer], :int,
|
289
|
+
[GSL_Vector, GSL_Vector], :double, true, 1
|
290
|
+
# a'i = x * ai
|
291
|
+
attach_gsl_function :gsl_vector_scale, [:pointer, :double], :int,
|
292
|
+
[GSL_Vector, :double], :double, true, 1
|
293
|
+
# a'i = x + ai
|
294
|
+
attach_gsl_function :gsl_vector_add_constant, [:pointer, :double], :int,
|
295
|
+
[GSL_Vector, :double], :double, true, 1
|
296
|
+
# return max value
|
297
|
+
attach_gsl_function :gsl_vector_max, [:pointer], :double,
|
298
|
+
[GSL_Vector], :double
|
299
|
+
# return max value index
|
300
|
+
attach_gsl_function :gsl_vector_max_index, [:pointer], :size_t,
|
301
|
+
[GSL_Vector], :size_t
|
302
|
+
# return min value
|
303
|
+
attach_gsl_function :gsl_vector_min, [:pointer], :double,
|
304
|
+
[GSL_Vector], :double
|
305
|
+
# return min value index
|
306
|
+
attach_gsl_function :gsl_vector_min_index, [:pointer], :size_t,
|
307
|
+
[GSL_Vector], :size_t
|
308
|
+
|
309
|
+
# minmax routines have special wrappers to make them easier to use
|
310
|
+
# return min and max values
|
311
|
+
# TODO: increase answer checking sophistication in util to compare
|
312
|
+
# results that arrive in mulitple arguments, like minmax...
|
313
|
+
attach_function :gsl_vector_minmax, [:pointer, :pointer, :pointer], :void
|
314
|
+
attach_function :gsl_vector_minmax_index, [:pointer, :pointer, :pointer], :void
|
315
|
+
|
316
|
+
# Vector properties
|
317
|
+
|
318
|
+
# returns 1 if vector is null, 0 otherwise
|
319
|
+
attach_gsl_function :gsl_vector_isnull, [:pointer], :int,
|
320
|
+
[GSL_Vector], :int
|
321
|
+
# returns 1 if vector is all positive, 0 otherwise
|
322
|
+
attach_gsl_function :gsl_vector_ispos, [:pointer], :int,
|
323
|
+
[GSL_Vector], :int
|
324
|
+
# returns 1 if vector is all negative, 0 otherwise
|
325
|
+
attach_gsl_function :gsl_vector_isneg, [:pointer], :int,
|
326
|
+
[GSL_Vector], :int
|
327
|
+
# returns 1 if vector is all non-negative, 0 otherwise
|
328
|
+
attach_gsl_function :gsl_vector_isnonneg, [:pointer], :int,
|
329
|
+
[GSL_Vector], :int
|
330
|
+
|
331
|
+
end
|
332
|
+
|
333
|
+
class Harness
|
334
|
+
include ::GSL4r::Harness
|
335
|
+
|
336
|
+
def initialize
|
337
|
+
@c_compiler = "gcc"
|
338
|
+
@c_src_name = "gsl_vector_tests_gen.c"
|
339
|
+
@c_binary = "gsl_vector_tests_gen"
|
340
|
+
@c_includes = ["gsl/gsl_vector.h"]
|
341
|
+
@c_flags = [`gsl-config --libs`.chomp,`gsl-config --cflags`.chomp]
|
342
|
+
@c_tests = ::GSL4r::Vector::Methods.methods.grep(/^c_test/)
|
343
|
+
@r_header = %Q{$: << File.join('..','lib')\\nrequire 'test/unit'\\nrequire 'test/unit/autorunner'\\nrequire 'gsl4r/vector'\\ninclude GSL4r::Vector\\nclass VectorTests < Test::Unit::TestCase\\n EPSILON = 5.0e-15}
|
344
|
+
|
345
|
+
@r_footer = %Q{end}
|
30
346
|
end
|
347
|
+
end
|
31
348
|
|
32
|
-
end # class GSL_Vector
|
33
349
|
end # module Vector
|
34
350
|
end # module GSL4r
|