stochastic_process 0.0.1a
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/.gitignore +20 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/Guardfile +24 -0
- data/LICENSE.txt +22 -0
- data/README.md +58 -0
- data/Rakefile +1 -0
- data/lib/stochastic_process/base.rb +51 -0
- data/lib/stochastic_process/brownian_motion.rb +29 -0
- data/lib/stochastic_process/version.rb +3 -0
- data/lib/stochastic_process.rb +8 -0
- data/spec/base_spec.rb +60 -0
- data/spec/brownian_motion_spec.rb +21 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/stochastic_process_spec.rb +7 -0
- data/stochastic_process.gemspec +26 -0
- metadata +130 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'rspec' do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
|
9
|
+
# Rails example
|
10
|
+
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
11
|
+
watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
12
|
+
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
13
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
14
|
+
watch('config/routes.rb') { "spec/routing" }
|
15
|
+
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
16
|
+
|
17
|
+
# Capybara features specs
|
18
|
+
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
|
19
|
+
|
20
|
+
# Turnip features and steps
|
21
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
22
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
23
|
+
end
|
24
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Alexander Potrykus
|
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,58 @@
|
|
1
|
+
# StochasticProcess
|
2
|
+
|
3
|
+
This gem defines a base class StochasticProcess::Base for the approximation of
|
4
|
+
stochastic processes. As an example, the class StochasticProcess:BrownianMotion
|
5
|
+
is included that defines a standard Brownian motion process.
|
6
|
+
|
7
|
+
Checkout the [sample app](http://stochasticprocess.herokuapp.com/)
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
*Note that this gem requires at least Ruby 2.0.0* because I decided to try out [keyword arguments](http://dev.af83.com/2013/02/18/ruby-2-0-keyword-arguments.html).
|
11
|
+
The linked article describes how to re-write the code to make it work for older Ruby versions.
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
gem 'stochastic_process'
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install stochastic_process
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
The base class is `StochasticProcess::Base` which takes as *optional* arguments:
|
28
|
+
- `initial_position`: default is 0. This is the point where the stochastic process
|
29
|
+
starts
|
30
|
+
- `start_time`: default is 0. This is the time at which the stochastic process starts
|
31
|
+
- `end_time`: default is 100. This is the time up to which the stochastic process is simulated.
|
32
|
+
- `evaluations`: default is 1000. This defines at how many points the stochastic process will be evaluated.
|
33
|
+
- `path_increment`: default is 0. This function returns the increment of the path from one time point to the next.
|
34
|
+
|
35
|
+
The most important part of the base class is the `path_increment` function. Inherting from `StochasticProcess::Base` one can easily define new stochastic processes by implementing the corresponding `path_increment` function.
|
36
|
+
|
37
|
+
So far only Brownian motion is implemented - the following creates a Brownian
|
38
|
+
motion and stores the path as pairs of `x` and `y` values in an array
|
39
|
+
|
40
|
+
b = StochasticProcess::BrownianMotion.new(initial_position, start_time, end_time, evaluations)
|
41
|
+
bm_path1 = b.graph # first sample path of Brownian motion
|
42
|
+
bm_path2 = b.graph # second sample path of Brownian motion
|
43
|
+
|
44
|
+
Creating a new class is easy once the function that constructs the path
|
45
|
+
increments is implemented: simply inherit from `StochasticProcess::Base` and
|
46
|
+
pass the new path increment function as the last parameter to the constructor, see `lib/brownian_motion.rb`
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
## Contributing
|
53
|
+
|
54
|
+
1. Fork it
|
55
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
56
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
57
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
58
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module StochasticProcess
|
2
|
+
class Base
|
3
|
+
DEFAULT_START_TIME = 0.0
|
4
|
+
DEFAULT_END_TIME = 100
|
5
|
+
DEFAULT_EVALUATIONS = 1000
|
6
|
+
|
7
|
+
attr_accessor :evaluations
|
8
|
+
|
9
|
+
def initialize(initial_position: 0.0,
|
10
|
+
start_time: DEFAULT_START_TIME,
|
11
|
+
end_time: DEFAULT_END_TIME,
|
12
|
+
evaluations: DEFAULT_EVALUATIONS,
|
13
|
+
path_increment: method(:default_path_increment))
|
14
|
+
@initial_position = initial_position
|
15
|
+
@start_time = start_time
|
16
|
+
@end_time = end_time
|
17
|
+
@evaluations = evaluations
|
18
|
+
@path_increment = path_increment
|
19
|
+
end
|
20
|
+
|
21
|
+
def default_path_increment
|
22
|
+
return 0
|
23
|
+
end
|
24
|
+
|
25
|
+
def interval_length
|
26
|
+
(@end_time - @start_time).abs.to_f
|
27
|
+
end
|
28
|
+
|
29
|
+
def mesh
|
30
|
+
interval_length / @evaluations
|
31
|
+
end
|
32
|
+
|
33
|
+
def mesh=(m)
|
34
|
+
if m <= 0
|
35
|
+
raise("Only positive numbers allowed!")
|
36
|
+
end
|
37
|
+
@evaluations = interval_length / m.to_f
|
38
|
+
end
|
39
|
+
|
40
|
+
def graph
|
41
|
+
a = []
|
42
|
+
m = mesh()
|
43
|
+
a.push({x: @start_time, y: @initial_position})
|
44
|
+
@evaluations.times do |i| # iterates from 0 to @evaluations - 1
|
45
|
+
a.push({x: @start_time + (i + 1) * m, y: a[i][:y] + @path_increment.call})
|
46
|
+
end
|
47
|
+
return a
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module StochasticProcess
|
2
|
+
|
3
|
+
class BrownianMotion < Base
|
4
|
+
|
5
|
+
def brownian_path_increment
|
6
|
+
return gaussian(0, 0.1)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(initial_position: 0.0,
|
10
|
+
start_time: DEFAULT_START_TIME,
|
11
|
+
end_time: DEFAULT_END_TIME,
|
12
|
+
evaluations: DEFAULT_EVALUATIONS)
|
13
|
+
super(initial_position: initial_position, start_time: start_time,
|
14
|
+
end_time: end_time, evaluations: evaluations,
|
15
|
+
path_increment: method(:brownian_path_increment))
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def gaussian(mean, stddev)
|
21
|
+
theta = 2 * Math::PI * rand
|
22
|
+
rho = Math.sqrt(-2 * Math.log(1 - rand))
|
23
|
+
scale = stddev * rho
|
24
|
+
x = mean + scale * Math.cos(theta)
|
25
|
+
#y = mean + scale * Math.sin(theta)
|
26
|
+
return x
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/spec/base_spec.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe StochasticProcess::Base do
|
4
|
+
|
5
|
+
it 'initalizes successfully' do
|
6
|
+
s = StochasticProcess::Base.new
|
7
|
+
s.should_not be_nil
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'has a default time interval and iteration settings' do
|
11
|
+
StochasticProcess::Base::DEFAULT_START_TIME.should_not be_nil
|
12
|
+
StochasticProcess::Base::DEFAULT_END_TIME.should_not be_nil
|
13
|
+
StochasticProcess::Base::DEFAULT_EVALUATIONS.should_not be_nil
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'sets default path increment to 0' do
|
17
|
+
s = StochasticProcess::Base.new
|
18
|
+
s.default_path_increment.should eq 0
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should calculate the interval length correctly' do
|
22
|
+
s = StochasticProcess::Base.new(start_time: -10.0, end_time: 10.0,
|
23
|
+
evaluations: 100)
|
24
|
+
s.interval_length.should eq 20.0
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should calculate a correct mesh given time interval and number of evaluations' do
|
28
|
+
s = StochasticProcess::Base.new(start_time: -10.0, end_time: 10.0,
|
29
|
+
evaluations: 100)
|
30
|
+
s.mesh.should eq 20.0 / 100
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should not allow a non-positive mesh' do
|
34
|
+
s = StochasticProcess::Base.new
|
35
|
+
expect {s.mesh = -0.1}.to raise_error
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should calculate the correct number of evaluations if a mesh is specified' do
|
39
|
+
s = StochasticProcess::Base.new(start_time: -10.0, end_time: 10.0,
|
40
|
+
evaluations: 100)
|
41
|
+
s.mesh = 0.1
|
42
|
+
s.evaluations.should eq 200
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should return a graph with the correct number of elements' do
|
46
|
+
s = StochasticProcess::Base.new(start_time: 0.0, end_time: 10.0,
|
47
|
+
evaluations: 100)
|
48
|
+
s.mesh.should eq 0.1
|
49
|
+
s.graph.count.should eq 101 # including starting point
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should return a graph with y coordinates constant to zero' do
|
53
|
+
s = StochasticProcess::Base.new(start_time: 0.0, end_time: 10.0,
|
54
|
+
evaluations: 100)
|
55
|
+
yc = s.graph.collect { |p| p[:y]}
|
56
|
+
sumy = yc.inject(0) {|y, res| res + y}
|
57
|
+
sumy.should eq 0
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe StochasticProcess::BrownianMotion do
|
4
|
+
|
5
|
+
it 'defines a function brownian_path_increment that returns a non-constant real number' do
|
6
|
+
s = StochasticProcess::BrownianMotion.new
|
7
|
+
a = s.brownian_path_increment
|
8
|
+
b = s.brownian_path_increment
|
9
|
+
a.should_not eq b
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should return a graph with y coordinates unequal to zero (almost surely)' do
|
13
|
+
s = StochasticProcess::BrownianMotion.new
|
14
|
+
n = s.graph.count
|
15
|
+
yc = s.graph.collect {|p| p[:y]}
|
16
|
+
yc[rand(n)].should_not eq 0.0
|
17
|
+
yc[rand(n)].should_not eq 0.0
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'stochastic_process/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "stochastic_process"
|
8
|
+
gem.version = StochasticProcess::VERSION
|
9
|
+
gem.authors = ["Alexander Potrykus"]
|
10
|
+
gem.email = ["apotry@gmail.com"]
|
11
|
+
gem.description = %q{Ruby library for simulating a variety of stochastic processes}
|
12
|
+
gem.summary = %q{Ruby library for simulating a variety of stochastic processes}
|
13
|
+
gem.homepage = ""
|
14
|
+
gem.license = "MIT"
|
15
|
+
|
16
|
+
gem.files = `git ls-files`.split($/)
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
|
+
gem.require_paths = ["lib"]
|
20
|
+
|
21
|
+
gem.add_development_dependency "rake"
|
22
|
+
gem.add_development_dependency "rspec", "~> 2.13.0"
|
23
|
+
gem.add_development_dependency 'rb-inotify', '~> 0.9'
|
24
|
+
gem.add_development_dependency "guard-rspec"
|
25
|
+
#gem.add_dependency "gsl", "~>1.15.3"
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: stochastic_process
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1a
|
5
|
+
prerelease: 5
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Alexander Potrykus
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-04-15 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
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
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 2.13.0
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.13.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rb-inotify
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.9'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.9'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: guard-rspec
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: Ruby library for simulating a variety of stochastic processes
|
79
|
+
email:
|
80
|
+
- apotry@gmail.com
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- .gitignore
|
86
|
+
- .rspec
|
87
|
+
- Gemfile
|
88
|
+
- Guardfile
|
89
|
+
- LICENSE.txt
|
90
|
+
- README.md
|
91
|
+
- Rakefile
|
92
|
+
- lib/stochastic_process.rb
|
93
|
+
- lib/stochastic_process/base.rb
|
94
|
+
- lib/stochastic_process/brownian_motion.rb
|
95
|
+
- lib/stochastic_process/version.rb
|
96
|
+
- spec/base_spec.rb
|
97
|
+
- spec/brownian_motion_spec.rb
|
98
|
+
- spec/spec_helper.rb
|
99
|
+
- spec/stochastic_process_spec.rb
|
100
|
+
- stochastic_process.gemspec
|
101
|
+
homepage: ''
|
102
|
+
licenses:
|
103
|
+
- MIT
|
104
|
+
post_install_message:
|
105
|
+
rdoc_options: []
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - '>='
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
117
|
+
- - '>'
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: 1.3.1
|
120
|
+
requirements: []
|
121
|
+
rubyforge_project:
|
122
|
+
rubygems_version: 1.8.25
|
123
|
+
signing_key:
|
124
|
+
specification_version: 3
|
125
|
+
summary: Ruby library for simulating a variety of stochastic processes
|
126
|
+
test_files:
|
127
|
+
- spec/base_spec.rb
|
128
|
+
- spec/brownian_motion_spec.rb
|
129
|
+
- spec/spec_helper.rb
|
130
|
+
- spec/stochastic_process_spec.rb
|