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 CHANGED
@@ -11,12 +11,7 @@ System wide gem install using rake
11
11
 
12
12
  sudo rake install
13
13
 
14
-
15
- You must also update your environment so that GSL4r can find the gsl shared library, under Mac OS X, and using macports, this is something along the lines of:
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 01 Mar 2010, I have only pushed a library for using Complex functions in GSL, all constants are defined, and some functions for handling blocks and vectors containing blocks.
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
- => Object
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
 
@@ -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
@@ -10,7 +10,7 @@ require 'rubygems'
10
10
  require 'ffi'
11
11
 
12
12
  module GSL4r
13
- Version = '0.0.1';
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,
@@ -19,29 +19,71 @@ module GSL4r
19
19
 
20
20
  extend ::FFI::Library
21
21
 
22
- class GSL_Block < FFI::Struct
23
- layout :size, :size_t,
24
- :data, :pointer
25
-
26
- def get_size( a_block )
27
- return a_block.get_ulong(0)
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
- def get_data( a_block )
31
- return a_block.get_array_of_double(1,get_size(a_block))
32
- end
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
- def set_data( a_block, some_data )
35
- if ( some_data.length >= get_size(a_block) )
36
- raise "data exceeds size of block"
37
- end
38
- a_block.put_array_of_double(1,some_data)
39
- end
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
- include ::GSL4r::Util::AutoPrefix
59
+ def length
60
+ return self[:size]
61
+ end
42
62
 
43
- GSL_PREFIX = "gsl_block_"
44
- GSL_MODULE = ::GSL4r::Block
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
- attach_gsl_function :gsl_block_alloc, [:size_t], :pointer, [:size_t], :pointer, false
55
- attach_gsl_function :gsl_block_calloc, [:size_t], :pointer, [:size_t], :pointer, false
56
- attach_gsl_function :gsl_block_free, [:pointer], :void, [:pointer], :void, false
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
@@ -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
@@ -44,8 +44,8 @@ module GSL4r
44
44
  end
45
45
 
46
46
  def compile_c_tests
47
- compile_s = "#{@c_compiler} #{@c_flags.join(" ")} " +
48
- "-o #{TEST_DIR}/#{@c_binary} #{TEST_DIR}/#{@c_src_name}"
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
@@ -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
- c_return_name = "c_r#{$c_var_num}"
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?("r_type") ?
48
- " #{c_var_name} = #{a_t.r_type}.create" : "")
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
- c_src << (return_type.respond_to?("c_type") ?
55
- " #{return_type.c_type} #{c_return_name};\n" :
56
- " #{return_type.to_s} #{c_return_name};\n")
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
- c_src << " #{c_return_name} = #{method_name}(#{c_call_vars.join(",")});\n"
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 ( return_type.respond_to?("c_to_r_assignment") )
73
- r_r2 = "r_r2" # ruby result comparitor
74
- c_src << " puts(" << %Q{\\" #{r_r2} = #{return_type.r_type}.new\\"} << ");\n"
75
- c_src << " #{return_type.c_to_r_assignment(r_r2,c_return_name)}"
76
- c_src << " printf(" << %Q{\\" assert r_r1.equals(r_r2)\\\\n\\"} << ");\n"
77
- else
78
- c_src << " printf(" << %Q{\\" assert_in_delta r_r1, %.15g, EPSILON\\\\n\\"} << ", #{c_return_name});\n"
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
- eval <<-end_eval
86
- def c_test_#{method_name}
87
- # Build list of arguments and their values
88
- "#{c_src}"
89
- end
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
@@ -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
- ffi_lib ::GSL4r::GSL_LIB_PATH
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
- class GSL_Vector < ::FFI::Struct
20
- layout :size, :size_t,
21
- :stride, :size_t,
22
- :data, :pointer,
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
- module ::GSL4r::Util::AutoPrefix
28
- GSL_PREFIX = "gsl_vector_"
29
- GSL_MODULE = ::GSL4r::Vector
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