pretty_gsl 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in minimize.gemspec
4
+ gemspec
data/LICENCE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Ben Doyle
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # PrettyGLS
2
+
3
+ This gem provides a nice interface to the GNU scientific library through the Ruby/GSL wrapper. I've simply attempted to update the interface to use more idiomatic ruby.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'pretty_gsl'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install pretty_gsl
18
+
19
+ ## Usage
20
+
21
+ function = Proc.new{ |variables, constants| ...}
22
+ optional_gradient = Proc.new{ |variables, constants, gradient_components| ...}
23
+ constants = [1,2,3, ...]
24
+ guess = [1,2,3, ...]
25
+ m = Minimizer.new(function, constants, function_gradient: optional_gradient)
26
+ m.minimize(*guess)
27
+ => {:success=>true, :minimum_x=>[1, 2], :iterations=>50, :minimum_f=>30.0, :simplex_size=>0.0008 ... }
28
+
29
+ ## Contributing
30
+
31
+ 1. Fork it
32
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
33
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
34
+ 4. Push to the branch (`git push origin my-new-feature`)
35
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require "rake/testtask"
4
+
5
+ Rake::TestTask.new(:test) do |t|
6
+ t.libs << 'lib'
7
+ t.libs << 'test'
8
+ t.pattern = 'test/*_test.rb'
9
+ t.verbose = false
10
+ end
11
+
12
+ task :default => :test
@@ -0,0 +1,49 @@
1
+ # RUBY
2
+ # ruby 1.9.2p320 (2012-04-20 revision 35421) [x86_64-darwin11.3.0]
3
+
4
+ # GEM
5
+ # gsl (1.14.7)
6
+
7
+ # LIB
8
+ # gsl-1.15
9
+
10
+
11
+ require 'gsl'
12
+ include GSL
13
+ include GSL::MultiMin
14
+
15
+ my_f = Proc.new do |v, params|
16
+ x = v[0]
17
+ y = v[1]
18
+ p0 = params[0]
19
+ p1 = params[1]
20
+ 10.0 * (x - p0) * (x - p0) + 20.0 * (y - p1) * (y - p1) + 30.0
21
+ end
22
+
23
+ my_df = Proc.new do |v, params, df|
24
+ x = v[0]
25
+ y = v[1]
26
+ p0 = params[0]
27
+ p1 = params[1]
28
+ df[0] = 20.0*(x-p0)
29
+ df[1] = 40.0*(y-p1)
30
+ end
31
+
32
+ my_func = Function_fdf.alloc(my_f, my_df, 2)
33
+ my_func.set_params([1.0, 2.0]) # parameters
34
+
35
+ x = Vector.alloc(5.0, 7.0) # starting point
36
+
37
+ minimizer = FdfMinimizer.alloc("conjugate_fr", 2)
38
+ minimizer.set(my_func, x, 0.01, 1e-4)
39
+
40
+ iter = 0
41
+ begin
42
+ iter += 1
43
+ status = minimizer.iterate()
44
+ status = minimizer.test_gradient(1e-3)
45
+ puts("Minimum found at") if status == GSL::SUCCESS
46
+ x = minimizer.x
47
+ f = minimizer.f
48
+ printf("%5d %.5f %.5f %10.5f\n", iter, x[0], x[1], f)
49
+ end while status == GSL::CONTINUE and iter < 100
@@ -0,0 +1,78 @@
1
+ module PrettyGSL
2
+ class Minimizer
3
+ include GSL
4
+ include GSL::MultiMin
5
+
6
+ attr_reader :result
7
+
8
+ def initialize(function, constants, options = {})
9
+ @function = function
10
+ @constants = constants
11
+ @params = {
12
+ max_iterations: 100, # the maximum number of iterations to carry out the minimization
13
+ step_size: 0.01, # initial guess of the length scale of the minimiztion steps
14
+ direction_tolerance: 1e-4, # the tolerance for errors in the direction of line minimization
15
+ absolute_gradient_tolerance: 1e-3, # halt if the magnetude of the gradient falls below this value
16
+ }.merge(options)
17
+ @result = nil
18
+ self
19
+ end
20
+
21
+ def minimize(*guess)
22
+ minimizer = get_gsl_minimizer(guess)
23
+ @params[:max_iterations].times do |iter|
24
+ status = minimizer.iterate
25
+ status = test_gsl_convergence(minimizer)
26
+ if status != CONTINUE
27
+ @result = {
28
+ success: status == SUCCESS,
29
+ minimum_x: minimizer.x.to_a,
30
+ iterations: iter
31
+ }.merge(get_gsl_result(minimizer))
32
+ break
33
+ end
34
+ end
35
+ @result
36
+ end
37
+
38
+ protected
39
+ def test_gsl_convergence(minimizer)
40
+ if @params[:function_gradient]
41
+ minimizer.test_gradient @params[:absolute_gradient_tolerance]
42
+ else
43
+ minimizer.test_size @params[:absolute_gradient_tolerance]
44
+ end
45
+ end
46
+
47
+ def get_gsl_minimizer(guess)
48
+ minimizer = nil
49
+ if @params[:function_gradient]
50
+ function = Function_fdf.alloc(@function, @params[:function_gradient], guess.size)
51
+ function.set_params(@constants)
52
+ minimizer = FdfMinimizer.alloc("conjugate_fr", guess.size)
53
+ minimizer.set(function, Vector.alloc(*guess), @params[:step_size], @params[:direction_tolerance])
54
+ else
55
+ function = Function.alloc(@function, guess.size)
56
+ function.set_params(@constants)
57
+ minimizer = FMinimizer.alloc("nmsimplex", guess.size)
58
+ ss = Vector.alloc(guess.size)
59
+ ss.set_all(@params[:step_size])
60
+ minimizer.set(function, Vector.alloc(*guess), ss)
61
+ end
62
+ minimizer
63
+ end
64
+
65
+ def get_gsl_result(minimizer)
66
+ if @params[:function_gradient]
67
+ {
68
+ minimum_f: minimizer.f,
69
+ }
70
+ else
71
+ {
72
+ minimum_f: minimizer.fval,
73
+ simplex_size: minimizer.size,
74
+ }
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,3 @@
1
+ module PrettyGSL
2
+ VERSION = "0.0.1"
3
+ end
data/lib/pretty_gsl.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'gsl'
2
+ require "pretty_gsl/version"
3
+ require "pretty_gsl/minimizer"
4
+
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/pretty_gsl/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Ben Doyle"]
6
+ gem.email = ["doyle.ben@gmail.com"]
7
+ gem.description = "prettify ruby/gsl with more idiomatic ruby"
8
+ gem.summary = "GSL wrapper wrapper"
9
+ gem.homepage = "https://github.com/BenDoyle/pretty_gsl"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "pretty_gsl"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = PrettyGSL::VERSION
17
+
18
+ gem.add_runtime_dependency "gsl"
19
+ end
@@ -0,0 +1,35 @@
1
+ require 'test_helper'
2
+
3
+ class MinimizerTest < Test::Unit::TestCase
4
+ include PrettyGSL
5
+ def setup
6
+ @function = Proc.new do |variables, constants|
7
+ x = variables[0]
8
+ y = variables[1]
9
+ p0 = constants[0]
10
+ p1 = constants[1]
11
+ 10.0 * (x - p0) * (x - p0) + 20.0 * (y - p1) * (y - p1) + 30.0
12
+ end
13
+
14
+ @function_gradient = Proc.new do |variables, constants, gradient_components|
15
+ x = variables[0]
16
+ y = variables[1]
17
+ p0 = constants[0]
18
+ p1 = constants[1]
19
+ gradient_components[0] = 20.0*(x-p0)
20
+ gradient_components[1] = 40.0*(y-p1)
21
+ end
22
+
23
+ @constants = [1.0, 2.0]
24
+ @guess = [5.0, 7.0]
25
+ end
26
+
27
+ def test_with_gradient
28
+ assert_not_nil Minimizer.new(@function, @constants, function_gradient: @function_gradient).minimize(*@guess)
29
+ end
30
+
31
+ def test_without_gradient
32
+ assert_not_nil Minimizer.new(@function, @constants).minimize(*@guess)
33
+ end
34
+
35
+ end
@@ -0,0 +1,2 @@
1
+ require 'test/unit'
2
+ require 'pretty_gsl'
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pretty_gsl
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ben Doyle
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: gsl
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: prettify ruby/gsl with more idiomatic ruby
31
+ email:
32
+ - doyle.ben@gmail.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - Gemfile
38
+ - LICENCE
39
+ - README.md
40
+ - Rakefile
41
+ - examples/ruby_gsl_example.rb
42
+ - lib/pretty_gsl.rb
43
+ - lib/pretty_gsl/minimizer.rb
44
+ - lib/pretty_gsl/version.rb
45
+ - pretty_gsl.gemspec
46
+ - test/minimizer_test.rb
47
+ - test/test_helper.rb
48
+ homepage: https://github.com/BenDoyle/pretty_gsl
49
+ licenses: []
50
+ post_install_message:
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 1.8.23
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: GSL wrapper wrapper
72
+ test_files:
73
+ - test/minimizer_test.rb
74
+ - test/test_helper.rb