monte_carlo 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +2 -0
- data/Gemfile +10 -2
- data/README.md +10 -38
- data/lib/monte_carlo/errors.rb +1 -0
- data/lib/monte_carlo/experiment.rb +44 -0
- data/lib/monte_carlo/experiment_dsl.rb +27 -0
- data/lib/monte_carlo/experiment_results.rb +24 -0
- data/lib/monte_carlo/result.rb +7 -0
- data/lib/monte_carlo/version.rb +5 -1
- data/monte_carlo.gemspec +1 -4
- metadata +6 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1045401a068ca8ca900b000ca47c36a2d3b9aaf
|
4
|
+
data.tar.gz: 529e4a6ac17cd14dbba9a41b672202e23b83fabf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f5ee56b4e2a2df819767c25e681de4d0103783aaf800922ea14680c119d2fd49d421128cb28038fcbd47d878e695770dc119d68c854e5a1868df51050883e37
|
7
|
+
data.tar.gz: 0b4eac19c056cebc1efdf5e101654d591b443bb2ab4243013a2fa84cdbefa54ec43dfcd28d83418ad1277ed9d637e7dcec231427fc3d56619be706c7536b36bc
|
data/.yardopts
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -20,56 +20,28 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
- `sample_method`: the method with which to generate a sample each iteration
|
26
|
-
- `computation`: an optional coputation method to run on each sample to obtain a result
|
27
|
-
- `setup` & `reset`: optional methods to run before and after each iteration
|
28
|
-
|
29
|
-
For example;
|
30
|
-
|
31
|
-
```ruby
|
32
|
-
# Create an experiment with an optional number of times
|
33
|
-
experiment = MonteCarlo::Experiment.new(100000)
|
34
|
-
|
35
|
-
# Set your smaple method
|
36
|
-
experiment.sample_method = -> { rand }
|
37
|
-
|
38
|
-
# Set your optional computation method
|
39
|
-
experiment.computation = -> (sample) { sample > 0.5 }
|
40
|
-
|
41
|
-
# Run your experiment and get your results
|
42
|
-
results = experiment.run
|
43
|
-
```
|
44
|
-
|
45
|
-
Another option is to use the configuration DSL, like so:
|
23
|
+
Every `MonteCarlo::Experiment` must have a sample method to generate random samples. The samples generated when the experiment is run will be collected into a `MonteCarlo::ExperimentResults` object after an optional computation method to turn the random sample into a meaningful value.
|
24
|
+
For example, the sample method may draw a random number between 1 and 10 and the computation method will test whether the number is greater than 5, returning `true` or `false` results.
|
46
25
|
|
47
26
|
```ruby
|
48
|
-
# Create an
|
27
|
+
# Create an instance and configure it with the DSL
|
49
28
|
experiment = MonteCarlo::Experiment.new do
|
50
29
|
times 1000000
|
51
|
-
sample_method { rand }
|
52
|
-
computation { |sample| sample
|
30
|
+
sample_method { rand(10) }
|
31
|
+
computation { |sample| sample >= 5 }
|
53
32
|
end
|
54
33
|
|
55
|
-
# And run it normally
|
56
34
|
results = experiment.run
|
57
|
-
```
|
58
|
-
|
59
|
-
Alternatively, you can write your sample and computation method as one with the shorthand block syntax and get the restults straight away:
|
60
35
|
|
61
|
-
|
62
|
-
|
36
|
+
results.probability_distribution
|
37
|
+
# => {true=>0.499443, false=>0.500557}
|
63
38
|
```
|
64
39
|
|
65
|
-
|
40
|
+
Or run it with the shorthand class method syntax:
|
66
41
|
|
67
|
-
|
68
|
-
- `index`: the index of the sample
|
69
|
-
- `value`: the final value returned from sampling, after computation
|
70
|
-
- `sample_value`: the value returned from the sample method, before computation
|
42
|
+
## Docs
|
71
43
|
|
72
|
-
|
44
|
+
[Can be found here](http://www.rubydoc.info/gems/monte_carlo)
|
73
45
|
|
74
46
|
## Contributing
|
75
47
|
|
data/lib/monte_carlo/errors.rb
CHANGED
@@ -1,21 +1,65 @@
|
|
1
1
|
module MonteCarlo
|
2
|
+
# Class to run your Monte Carlo experiments
|
3
|
+
#
|
4
|
+
# @example
|
5
|
+
# experiment = MonteCarlo::Experiment.new
|
6
|
+
# experiment.sample_method = -> { rand(10) }
|
7
|
+
# results = experiment.run
|
2
8
|
class Experiment
|
3
9
|
|
10
|
+
# The default number of sample methods to generate
|
4
11
|
DEFAULT_TIMES = 10000
|
5
12
|
|
13
|
+
# @!attribute times
|
14
|
+
# @return [#times] the number of samples to generate
|
15
|
+
# @!attribute sample_method
|
16
|
+
# @return [#call] a method to generate a sample each time
|
17
|
+
# @!attribute computation
|
18
|
+
# @return [#call] a method to turn a random sample to a meaningful result
|
19
|
+
# @!attribute setup
|
20
|
+
# @return [#call] a method to run before each iteration
|
21
|
+
# @!attribute reset
|
22
|
+
# @return [#call] a method to run after each iteration
|
6
23
|
attr_accessor :times, :sample_method, :computation, :setup, :reset
|
7
24
|
|
25
|
+
# Shorthand syntax to run a simple experiment
|
26
|
+
#
|
27
|
+
# @example
|
28
|
+
# results = MonteCarlo::Experiment.run(100000) { rand(10) }
|
29
|
+
#
|
30
|
+
# @param times [optional, #times] the number of samples to generate
|
31
|
+
# @param block [Block] the method to generate one sample each iteration
|
32
|
+
# @raise [MonteCarlo::Errors::NoSampleMethodError] if no block is given
|
33
|
+
# @return [MonteCarlo::ExperimentResults]
|
8
34
|
def self.run(times = DEFAULT_TIMES, &block)
|
9
35
|
experiment = MonteCarlo::Experiment.new(times)
|
10
36
|
experiment.sample_method = block
|
11
37
|
experiment.run
|
12
38
|
end
|
13
39
|
|
40
|
+
# Initialize a new experiment
|
41
|
+
#
|
42
|
+
# @example
|
43
|
+
# experiment = MonteCarlo::Experiment.new do
|
44
|
+
# times 100000
|
45
|
+
# sample_method { rand(10) }
|
46
|
+
# computation { |sample| sample >= 5 }
|
47
|
+
# end
|
48
|
+
#
|
49
|
+
# results = experiment.run
|
50
|
+
#
|
51
|
+
# @param times [optional, #times] the number of samples to generate
|
52
|
+
# @param block [optional, Block] a block to configure the experiment using the {MonteCarlo::ExperimentDSL}
|
53
|
+
# @return [MonteCarlo::Experiment]
|
14
54
|
def initialize(times = DEFAULT_TIMES, &block)
|
15
55
|
@times = times
|
16
56
|
MonteCarlo::ExperimentDSL.new(self).instance_eval(&block) if block_given?
|
17
57
|
end
|
18
58
|
|
59
|
+
# Run the experiment
|
60
|
+
#
|
61
|
+
# @raise [MonteCarlo::Errors::NoSampleMethodError] if the experiment has no sample method set
|
62
|
+
# @return [MonteCarlo::ExperimentResults]
|
19
63
|
def run
|
20
64
|
if @sample_method.nil?
|
21
65
|
raise MonteCarlo::Errors::NoSampleMethodError, 'A sample method for this experiment is not defined'
|
@@ -1,26 +1,53 @@
|
|
1
1
|
module MonteCarlo
|
2
|
+
# Class to setup an experiment using a DSL syntax
|
2
3
|
class ExperimentDSL
|
3
4
|
|
5
|
+
# Initializes a DSL instance for the given experiment
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# experiment = MonteCarlo::Experiment.new do
|
9
|
+
# times 100000
|
10
|
+
# sample_method { rand(10) }
|
11
|
+
# computation { |sample| sample >= 5 }
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# @param experiment [MonteCarlo::Experiment] the experiment to configure
|
15
|
+
# @return [MonteCarlo::ExperimentDSL]
|
4
16
|
def initialize(experiment)
|
5
17
|
@experiment = experiment
|
6
18
|
end
|
7
19
|
|
20
|
+
# Set the number of samples to generate
|
21
|
+
#
|
22
|
+
# @param times [#times]
|
8
23
|
def times(times)
|
9
24
|
@experiment.times = times
|
10
25
|
end
|
11
26
|
|
27
|
+
# Set the sample method of the experiment
|
28
|
+
#
|
29
|
+
# @param block [Block]
|
12
30
|
def sample_method(&block)
|
13
31
|
@experiment.sample_method = block
|
14
32
|
end
|
15
33
|
|
34
|
+
# Set the computation method of the experiment
|
35
|
+
#
|
36
|
+
# @param block [Block]
|
16
37
|
def computation(&block)
|
17
38
|
@experiment.computation = block
|
18
39
|
end
|
19
40
|
|
41
|
+
# Set the setup method of the experiment
|
42
|
+
#
|
43
|
+
# @param block [Block]
|
20
44
|
def setup(&block)
|
21
45
|
@experiment.setup = block
|
22
46
|
end
|
23
47
|
|
48
|
+
# Set the reset method of the experiment
|
49
|
+
#
|
50
|
+
# @param block [Block]
|
24
51
|
def reset(&block)
|
25
52
|
@experiment.reset = block
|
26
53
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
module MonteCarlo
|
2
|
+
# Class containing the results of a {MonteCarlo::Experiment}
|
2
3
|
class ExperimentResults
|
3
4
|
include Enumerable
|
4
5
|
|
@@ -6,21 +7,33 @@ module MonteCarlo
|
|
6
7
|
@results = []
|
7
8
|
end
|
8
9
|
|
10
|
+
# Returns an enumerable of the results or runs the given block
|
11
|
+
#
|
12
|
+
# @param block [optional, Block] the block to run on each of the results
|
9
13
|
def each(&block)
|
10
14
|
@results.each do |result|
|
11
15
|
block_given? ? block.call(result) : yield(result)
|
12
16
|
end
|
13
17
|
end
|
14
18
|
|
19
|
+
# Add a result to the list
|
20
|
+
#
|
21
|
+
# @param result [MonteCarlo::Result]
|
15
22
|
def << result
|
16
23
|
@results << result
|
17
24
|
reset_memoizers
|
18
25
|
end
|
19
26
|
|
27
|
+
# The number of results
|
28
|
+
#
|
29
|
+
# @return [Fixnum]
|
20
30
|
def size
|
21
31
|
@results.size
|
22
32
|
end
|
23
33
|
|
34
|
+
# Calculates the probabilty distribution of the results
|
35
|
+
#
|
36
|
+
# @return [Hash]
|
24
37
|
def probability_distribution
|
25
38
|
@probability_distribution ||= @results.group_by(&:value).inject({}) do |probabilites, (value, results)|
|
26
39
|
probabilites[value] = results.size.to_f / self.size
|
@@ -28,6 +41,9 @@ module MonteCarlo
|
|
28
41
|
end
|
29
42
|
end
|
30
43
|
|
44
|
+
# Calculates the frequency distibution of the results
|
45
|
+
#
|
46
|
+
# @return [Hash]
|
31
47
|
def frequency_distribution
|
32
48
|
@frequency_distribution ||= @results.group_by(&:value).inject({}) do |frequencies, (value, results)|
|
33
49
|
frequencies[value] = results.size
|
@@ -35,10 +51,18 @@ module MonteCarlo
|
|
35
51
|
end
|
36
52
|
end
|
37
53
|
|
54
|
+
# Calcuates the probablity of the given value in the results
|
55
|
+
#
|
56
|
+
# @param value the value for which to get the probability
|
57
|
+
# @return [Float]
|
38
58
|
def probability_of(value)
|
39
59
|
probability_distribution.fetch(value, 0)
|
40
60
|
end
|
41
61
|
|
62
|
+
# Calculates the frequency of the given value in the results
|
63
|
+
#
|
64
|
+
# @param value the value for which to get the frequency
|
65
|
+
# @return [Fixnum]
|
42
66
|
def frequency_of(value)
|
43
67
|
frequency_distribution.fetch(value, 0)
|
44
68
|
end
|
data/lib/monte_carlo/result.rb
CHANGED
@@ -1,7 +1,14 @@
|
|
1
1
|
module MonteCarlo
|
2
|
+
# Class that contains the result of a single sample of a {MonteCarlo::Experiment}
|
2
3
|
class Result
|
3
4
|
include Comparable
|
4
5
|
|
6
|
+
# @!attribute value
|
7
|
+
# @return the value returned after the computation
|
8
|
+
# @!attribute sample_value
|
9
|
+
# @return the raw value returned from the sample method
|
10
|
+
# @!attribute index
|
11
|
+
# @return [Fixnum] the index of the iteration the result was generated at
|
5
12
|
attr_accessor :value, :sample_value, :index
|
6
13
|
|
7
14
|
def initialize(index = nil, value = nil, sample_value = nil)
|
data/lib/monte_carlo/version.rb
CHANGED
data/monte_carlo.gemspec
CHANGED
@@ -20,8 +20,5 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
-
spec.add_development_dependency "bundler", "~> 1.
|
24
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
-
spec.add_development_dependency "rspec", "~> 3.1"
|
26
|
-
spec.add_development_dependency "rspec-its"
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.0"
|
27
24
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: monte_carlo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Assaf Gelber
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-11-
|
11
|
+
date: 2014-11-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,56 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
19
|
+
version: '1.0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rake
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ~>
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '10.0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ~>
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '10.0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rspec
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ~>
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '3.1'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ~>
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '3.1'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: rspec-its
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - '>='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - '>='
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
26
|
+
version: '1.0'
|
69
27
|
description: A small gem to help with Monte Carlo Method experiments in ruby.
|
70
28
|
email:
|
71
29
|
- assaf.gelber@gmail.com
|
@@ -75,6 +33,7 @@ extra_rdoc_files: []
|
|
75
33
|
files:
|
76
34
|
- .gitignore
|
77
35
|
- .travis.yml
|
36
|
+
- .yardopts
|
78
37
|
- Gemfile
|
79
38
|
- LICENSE.txt
|
80
39
|
- README.md
|
@@ -120,3 +79,4 @@ test_files:
|
|
120
79
|
- spec/lib/monte_carlo/experiment_results_spec.rb
|
121
80
|
- spec/lib/monte_carlo/experiment_spec.rb
|
122
81
|
- spec/spec_helper.rb
|
82
|
+
has_rdoc:
|