gsl4r 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/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
|