monte_carlo 0.0.5 → 0.0.6
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.
- 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:
|