Eventsims
Description
Eventsims is a Ruby package that uses various useful tools in simulating discrete system events based on outcome and probabilities easily.
Requirements
- Any version of Ruby
Installation
Add this line to your application's Gemfile:
gem 'eventsims'
And then execute:
$ bundle
Or install it yourself as:
$ gem install eventsims
Module name --> Eventsims
It contains four main classes and two methods.
Module Classes
Calculate
Calculate has six methods for calculating/generating probability
, estimated variance
, estimated mean
, estimated standard deviation
, expectation value
and discreteEmp
.
Eventsims' "Calculate
class" takes two arguments
: outcome
and cummulative probability
or a third optional argument which is amount of times to be generated
(steps
).
Methods
Calculate methods are:
- prob() ----> To calculate the probability based on the given outcome list(second argument of the Calculate instance).
- discreteemp() ----> To generate a random outcome depending on its probability of occurrence.
- expectval() ----> To generate an expectation value i.e. the mean of the outcome depending on its probability
- estmean() ----> Same as expectval() because they always give the same output.
- estvar() ----> To calculate the estimated variance of the list data
- eststddev ----> To calculate the estimated standard deviation of the list data
Usage
You can use the Calculate class in the following way:
Example 1
Two arguments
Usage: Calculate.new(outcome list, cummulative probability list)
require "Eventsims"
sample = Eventsims::Calculate.new(a, b)
a = [-1,0,3,4]
b = [0.1, 0.4, 0.7, 1]
puts "Probability: #{sample.prob()}"
puts "DiscreteEmp: #{sample.discreteemp()}"
puts "Expectation value: #{sample.expectval()}"
puts "Estimated Mean: #{sample.estmean()}"
puts "Estimated Variance: #{sample.estvar()}"
puts "Estimated Standard deviation: #{sample.eststddev()}"
Result 1
Probability: [0.1, 0.3, 0.3, 0.3]
DiscreteEmp: 3
Expectation value: 2.0
Estimated Mean: 2.0
Estimated Variance: 3.6
Estimated Standard deviation: 1.8974
Example 2
three arguments
Usage: Calculate.new(outcome list, cummulative probability list, "Optional: amount/steps
")
require "Eventsims"
a = [-1,0,3,4]
b = [0.1, 0.4, 0.7, 1]
sample = Eventsims::Calculate.new(a, b, 10)
puts "Probability: #{sample.prob() }"
puts "DiscreteEmp: #{sample.discreteemp() }"
puts "Expectation value: #{sample.expectval() }"
puts "Estimated Mean: #{sample.estmean() }"
puts "Estimated Variance: #{sample.estvar() }"
puts "Estimated Standard deviation: #{sample.eststddev() }"
Result 2
Probability: [0.1, 0.3, 0.3, 0.3]
DiscreteEmp: [3, 0, 4, 4, 4, 4, 3, 0, 0, 0]
Expectation value: 20.0
Estimated Mean: 20.0
Estimated Variance: 36.0
Estimated Standard deviation: 6.0
argument one of the Calculate class should be the outcome list while argument two should be the cummulative probability list. Argument three (steps) is optional and only needed if any of the data is to be calculated after a certain number of times or to generate a list of discreteEmp values.
If no optional argument is given (same as if an optional argument is set to 1), discreteemp will generate only one outcome but if more the optional argument is more than one e.g. 5, then discreteemp will generate a list containing several generated outcomes (5 items in a list in this case).
Generate
Generate takes integer values as arguments (from no arguments
up to and including five arguments
) with optional string
arguments being "r" or "s". r for reverse (descending order) ** sorting and **s for ascending order sorting. It has five methods which can be called on its instance namely:
Methods
- outcome() ----> generate outcomes based on the inputs supplied as arguments.
- unique() ----> generate unique outcomes based on the inputs supplied as arguments. You can think of it as a set of the outcome() method result.
- occur() ----> generate the number of times a unique item is found.
- getprob() ----> generate the probability of the outcome with respect to the unique outcome.
- getcum() ----> generate the cummulative probability of occurrence with respect to the unique outcome.
Usage
You can use the Generate class in the following ways:
The following examples will cover how arguments are used in the Generate class. In the examples, we assume that the class has been required first as
require "Eventsims"
Example 1a
zero arguments
Usage: Eventsims::Generate.new()
What this does is populate the outcome list with random values (between 0 and 10) the default amount of times (i.e. a random number between 2 and 20).
sample = Eventsims::Generate.new()
puts "Outcome: #{sample.outcome() }"
puts "Unique Outcome: #{sample.unique() }"
puts "Occurrence: #{sample.occur() }"
puts "Probability: #{sample.getprob() }"
puts "Cummulative Probability: #{sample.getcum() }"
Result 1a
Outcome: [10, 4, 0, 5, 5, 2, 8, 4]
Unique Outcome: [10, 4, 0, 5, 2, 8]
Occurrence: [1, 2, 1, 2, 1, 1]
Probability: [0.25, 0.5, 0.25, 0.5, 0.25, 0.25]
Cummulative Probability: [0.25, 0.75, 1.0, 1.5, 1.75, 1.0]
Example 1b
Optional string argument
Usage: Eventsims::Generate.new('optional: sort ')
Adding an optional string argument "r" will sort the outcome in descending order whereas using the "s" string argument will sort the outcome in ascending order
sample = Eventsims::Generate.new("r")
puts "Outcome: #{sample.outcome() }"
puts "Unique Outcome: #{sample.unique() }"
puts "Occurrence: #{sample.occur() }"
puts "Probability: #{sample.getprob() }"
puts "Cummulative Probability: #{sample.getcum() }"
Result 1b
Outcome: [5, 3, 2, 2, 1]
Unique Outcome: [5, 3, 2, 1]
Occurrence: [1, 1, 2, 1]
Probability: [0.2, 0.2, 0.4, 0.2]
Cummulative Probability: [0.2, 0.4, 0.8, 1.0]
Example 2a
one argument
Usage: Eventsims::Generate.new(amount)
What this does is populate the outcome list with random values (between 0 and 10) the amount of times specified in the argument. For example if 10 was specified in the argument, it will populate the outcome list with values ten times
sample = Eventsims::Generate.new(8)
puts "Outcome: #{sample.outcome() } "
puts "Unique Outcome: #{sample.unique() } "
puts "Occurrence: #{sample.occur() } "
puts "Probability: #{sample.getprob() } "
puts "Cummulative Probability: #{sample.getcum() } "
Result 2a
Outcome: [8, 4, 8, 1, 2, 9, 2, 9]
Unique Outcome: [8, 4, 1, 2, 9]
Occurrence: [2, 1, 1, 2, 2]
Probability: [0.25, 0.125, 0.125, 0.25, 0.25]
Cummulative Probability: [0.25, 0.375, 0.5, 0.75, 1.0
Example 2b
Optional string argument
Usage: Eventsims::Generate.new(amount, 'optional: sort')
Adding an optional string argument "r" will sort the outcome in descending order whereas using the "s" string argument will sort the outcome in ascending order
sample = Eventsims::Generate.new(10,"s")
puts "Outcome: #{sample.outcome() } "
puts "Unique Outcome: #{sample.unique() } "
puts "Occurrence: #{sample.occur() } "
puts "Probability: #{sample.getprob() } "
puts "Cummulative Probability: #{sample.getcum() } "
Result 2b
Outcome: [0, 1, 1, 1, 3, 4, 7, 7, 9, 10]
Unique Outcome: [0, 1, 3, 4, 7, 9, 10]
Occurrence: [1, 3, 1, 1, 2, 1, 1]
Probability: [0.1, 0.3, 0.1, 0.1, 0.2, 0.1, 0.1]
Cummulative Probability: [0.1, 0.4, 0.5, 0.6, 0.8, 0.9, 1.0]
Example 3a
two arguments
Usage: Eventsims::Generate.new(start, stop)
What this does is populate the outcome list with values (between argument one and argument two) the default amount of times (i.e. a random number between 2 and 20).
sample = Eventsims::Generate.new(3, 7)
puts "Outcome: #{sample.outcome() } "
puts "Unique Outcome: #{sample.unique() } "
puts "Occurrence: #{sample.occur() } "
puts "Probability: #{sample.getprob() } "
puts "Cummulative Probability: #{sample.getcum() } "
Result 3a
Outcome: [4, 7, 7, 4, 3, 3, 4, 4]
Unique Outcome: [4, 7, 3]
Occurrence: [4, 2, 2]
Probability: [0.5, 0.25, 0.25]
Cummulative Probability: [0.5, 0.75, 1.0]
Example 3b
Optional string argument
Usage: Eventsims::Generate.new(start, stop, 'optional: sort ')
Adding an optional string argument "r" will sort the outcome in descending order whereas using the "s" string argument will sort the outcome in ascending order
sample = Eventsims::Generate.new(2, 6, "r")
puts "Outcome: #{sample.outcome() } "
puts "Unique Outcome: #{sample.unique() } "
puts "Occurrence: #{sample.occur() } "
puts "Probability: #{sample.getprob() } "
puts "Cummulative Probability: #{sample.getcum() } "
Result 3b
Outcome: [6, 5, 5, 5, 4, 4, 4, 4, 2, 2]
Unique Outcome: [6, 5, 4, 2]
Occurrence: [1, 3, 4, 2]
Probability: [0.1, 0.3, 0.4, 0.2]
Cummulative Probability: [0.1, 0.4, 0.8, 1.0]
Example 4a
three arguments
Usage: Eventsims::Generate.new(start, stop, amount)
What this does is populate the outcome list with values (between argument one and argument two) the amount of times supplied in argument three. i.e. if 4 was supplied as the third argument, there will be four values in the outcome list.
sample = Eventsims::Generate.new(2, 5, 7)
puts "Outcome: #{sample.outcome() } "
puts "Unique Outcome: #{sample.unique() } "
puts "Occurrence: #{sample.occur() } "
puts "Probability: #{sample.getprob() } "
puts "Cummulative Probability: #{sample.getcum() } "
Result 4a
Outcome: [5, 5, 4, 4, 4, 2, 3]
Unique Outcome: [5, 4, 2, 3]
Occurrence: [2, 3, 1, 1]
Probability: [0.2857, 0.4286, 0.1429, 0.1429]
Cummulative Probability: [0.2857, 0.7143, 0.8572, 1.0]
Example 4b
Optional string argument
Usage: Eventsims::Generate.new(start, stop, amount, 'optional: sort ')
Adding an optional string argument "r" will sort the outcome in descending order whereas using the "s" string argument will sort the outcome in ascending order
sample = Eventsims::Generate.new(2, 5, 7, "s")
puts "Outcome: #{sample.outcome() } "
puts "Unique Outcome: #{sample.unique() } "
puts "Occurrence: #{sample.occur() } "
puts "Probability: #{sample.getprob() } "
puts "Cummulative Probability: #{sample.getcum() } "
Result 4b
Outcome: [2, 3, 3, 4, 4, 5, 5]
Unique Outcome: [2, 3, 4, 5]
Occurrence: [1, 2, 2, 2]
Probability: [0.1429, 0.2857, 0.2857, 0.2857]
Cummulative Probability: [0.1429, 0.4286, 0.7143, 1.0]
Example 5a
four arguments
Usage: Eventsims::Generate.new(start, stop, step, amount)
What this does is populate the outcome list with values (between argument one and argument two) in steps of argument three value the amount of times in argument four's value.
sample = Eventsims::Generate.new(2, 20, 3, 10)
puts "Outcome: #{sample.outcome() } "
puts "Unique Outcome: #{sample.unique() } "
puts "Occurrence: #{sample.occur() } "
puts "Probability: #{sample.getprob() } "
puts "Cummulative Probability: #{sample.getcum() } "
Result 5a
Outcome: [20, 8, 11, 5, 11, 17, 20, 17, 14, 20]
Unique Outcome: [20, 8, 11, 5, 17, 14]
Occurrence: [3, 1, 2, 1, 2, 1]
Probability: [0.3, 0.1, 0.2, 0.1, 0.2, 0.1]
Cummulative Probability: [0.3, 0.4, 0.6, 0.7, 0.9, 1.0]
Example 5b
Optional string argument
Usage: Eventsims::Generate.new(start, stop, step, amount, 'optional: sort ')
Adding an optional string argument "r" will sort the outcome in descending order whereas using the "s" string argument will sort the outcome in ascending order
sample = Eventsims::Generate.new(2, 20, 3, 10, "r")
puts "Outcome: #{sample.outcome() } "
puts "Unique Outcome: #{sample.unique() } "
puts "Occurrence: #{sample.occur() } "
puts "Probability: #{sample.getprob() } "
puts "Cummulative Probability: #{sample.getcum() } "
Result 5b
Unique Outcome: [20, 17, 14, 11, 8, 5, 2]
Occurrence: [3, 1, 1, 1, 1, 1, 2]
Probability: [0.3, 0.1, 0.1, 0.1, 0.1, 0.1, 0.2]
Cummulative Probability: [0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 1.0]
Randomsim
Randomsim helps to quickly simulate and generate a scenario with random values by just passing your desired argument values into it. It takes between 0 to 3 arguments. The generated results are then stored into the inter-arrival time and service time list needed to generate the rest of the values.
Methods
This class has eight methods that can be called on its instance namely:
- intarrival() ----> Displays the inter-arrival time in a list.
- arrival() ----> Displays the arrival time in a list.
- service() ----> Displays the service time in a list.
- servbegin() ----> Display the time service begins in a list.
- servend() ----> Display the time service ends in a list.
- queuewait() ----> Display the time the customer spent waiting in a list.
- custspend() ----> Display the time the customer spent in the system i.e. total time of service.
- idle() ---> Display the idle time of the server (cashier).
Usage
You can use the Randomsim class the following ways:
The following examples will cover how arguments are used in the Generate class. In the examples, we assume that the class has been required first as
require "Eventsims"
and you can then respectively use it like in the following examples:
Example 1a
zero arguments
What this does is populate the inter-arrival and service time list with random numbers (between 1 and 10) random amount of times (2 to 20). The first value of the inter-arrival time defaults to 0.
sample = Eventsims::Randomsim.new()
puts "Inter-arrival time: #{sample.intarrival() } "
puts "Arrival time: #{sample.arrival() } "
puts "Service time: #{sample.service() } "
puts "Time when Service begins: #{sample.servbegin() } "
puts "Time when Service ends: #{sample.servend() } "
puts "Time customer spends waiting in Queue: #{sample.queuewait() } "
puts "Time customer spends in system: #{sample.custspend() } "
puts "Idle time of server: #{sample.idle() } "
Result 1a
Inter-arrival time: [0, 8, 4, 10, 1]
Arrival time: [0, 8, 12, 22, 23]
Service time: [2, 9, 4, 5, 5]
Time when Service begins: [0, 8, 17, 22, 27]
Time when Service ends: [2, 17, 21, 27, 32]
Time customer spends waiting in Queue: [0, 0, 5, 0, 4]
Time customer spends in system: [2, 9, 9, 5, 9]
Idle time of server: [0, 6, 0, 1, 0]
Example 1b
one argument
Usage: Eventsims::Randomsim.new(list size)
What this does is populate the inter-arrival and service time list with random numbers (between 1 and 10) the amount of times supplied as the only argument value. The first value of the inter-arrival time defaults to 0.
sample = Eventsims::Randomsim.new(6)
puts "Inter-arrival time: #{sample.intarrival() }"
puts "Arrival time: #{sample.arrival() }"
puts "Service time: #{sample.service() }"
puts "Time when Service begins: #{sample.servbegin() }"
puts "Time when Service ends: #{sample.servend() }"
puts "Time customer spends waiting in Queue: #{sample.queuewait() }"
puts "Time customer spends in system: #{sample.custspend() }"
puts "Idle time of server: #{sample.idle() }"
Result 1b
Inter-arrival time: [0, 4, 10, 9, 1, 9]
Arrival time: [0, 4, 14, 23, 24, 33]
Service time: [4, 10, 1, 8, 10, 5]
Time when Service begins: [0, 4, 14, 23, 31, 41]
Time when Service ends: [4, 14, 15, 31, 41, 46]
Time customer spends waiting in Queue: [0, 0, 0, 0, 7, 8]
Time customer spends in system: [4, 10, 1, 8, 17, 13]
Idle time of server: [0, 0, 0, 8, 0, 0]
Example 1c
two arguments
Usage: Eventsims::Randomsim.new(max value, list size)
What this does is populate the inter-arrival and service time list with numbers not more than the first argument starting from 1. The list is populated the amount of times specified as the second argument.
sample = Eventsims::Randomsim.new(4,6)
puts "Inter-arrival time: #{sample.intarrival() }"
puts "Arrival time: #{sample.arrival() }"
puts "Service time: #{sample.service() }"
puts "Time when Service begins: #{sample.servbegin() }"
puts "Time when Service ends: #{sample.servend() }"
puts "Time customer spends waiting in Queue: #{sample.queuewait() }"
puts "Time customer spends in system: #{sample.custspend() }"
puts "Idle time of server: #{sample.idle() }"
Result 1c
Inter-arrival time: [0, 1, 2, 2, 2, 4]
Arrival time: [0, 1, 3, 5, 7, 11]
Service time: [1, 2, 1, 4, 2, 4]
Time when Service begins: [0, 1, 3, 5, 9, 11]
Time when Service ends: [1, 3, 4, 9, 11, 15]
Time customer spends waiting in Queue: [0, 0, 0, 0, 2, 0]
Time customer spends in system: [1, 2, 1, 4, 4, 4]
Idle time of server: [0, 0, 0, 1, 0, 0]
Example 1d
three arguments
Usage: Eventsims::Randomsim.new(max value for inter-arrival time, max value for service time, list size)
What this does is populate the inter-arrival with numbers between 1 and the value passed into the first argument, service time is populated with values between 1 and the second argument while the third argument is the amount/size of the two lists.
sample = Eventsims::Randomsim.new(4, 6, 8)
puts "Inter-arrival time: #{sample.intarrival() } "
puts "Arrival time: #{sample.arrival() } "
puts "Service time: #{sample.service() } "
puts "Time when Service begins: #{sample.servbegin() } "
puts "Time when Service ends: #{sample.servend() } "
puts "Time customer spends waiting in Queue: #{sample.queuewait() } "
puts "Time customer spends in system: #{sample.custspend() } "
puts "Idle time of server: #{sample.idle() } "
Result 1d
Inter-arrival time: [0, 3, 2, 2, 3, 3, 3, 4]
Arrival time: [0, 3, 5, 7, 10, 13, 16, 20]
Service time: [6, 2, 2, 2, 4, 5, 6, 4]
Time when Service begins: [0, 6, 8, 10, 12, 16, 21, 27]
Time when Service ends: [6, 8, 10, 12, 16, 21, 27, 31]
Time customer spends waiting in Queue: [0, 3, 3, 3, 2, 3, 5, 7]
Time customer spends in system: [6, 5, 5, 5, 6, 8, 11, 11]
Idle time of server: [0, 0, 0, 0, 0, 0, 0, 0]
Simulate
Simulate helps to quickly simulate and generate a scenario with user-defined values. It is more flexible in that it allows you to input your own data rather than input just numbers as compared to Randomsim. It can take one or two arguments which are inter-arrival time list and service time list. They must be of the same length.
Methods
This class has eight methods (same as Randomsim
) that can be called on its instance namely:
- intarrival() ----> Displays the inter-arrival time in a list.
- arrival() ----> Displays the arrival time in a list.
- service() ----> Displays the service time in a list.
- servbegin() ----> Display the time service begins in a list.
- servend() ----> Display the time service ends in a list.
- queuewait() ----> Display the time the customer spent waiting in a list.
- custspend() ----> Display the time the customer spent in the system i.e. total time of service.
- idle() ---> Display the idle time of the server (cashier).
Usage
The following examples will cover how arguments are used in the Simulate class. In the examples, we assume that the class has been required first as:
require "Eventsims"
Example 2a
one argument
Usage: Eventsims::Simulate.new(inter-arrival list)
What this does is populate the inter-arrival time with the user-defined argument (must be a list) and service time would be automatically generated (populated with numbers between 1 and 10 with the same size as inter-arrival time).
sample = Eventsims::Simulate.new([7, 9, 6])
puts "Inter-arrival time: #{sample.intarrival() } "
puts "Arrival time: #{sample.arrival() } "
puts "Service time: #{sample.service() } "
puts "Time when Service begins: #{sample.servbegin() } "
puts "Time when Service ends: #{sample.servend() } "
puts "Time customer spends waiting in Queue: #{sample.queuewait() } "
puts "Time customer spends in system: #{sample.custspend() } "
puts "Idle time of server: #{sample.idle() } "
Result 2a
Inter-arrival time: [7, 9, 6]
Arrival time: [7, 16, 22]
Service time: [2, 5, 1]
Time when Service begins: [7, 16, 22]
Time when Service ends: [9, 21, 23]
Time customer spends waiting in Queue: [0, 0, 0]
Time customer spends in system: [2, 5, 1]
Idle time of server: [0, 7, 1]
Example 2b
two arguments
Usage: Eventsims::Randomsim.new(inter-arrival list, service time list)
What this does is populate the inter-arrival with the first list argument and the service time with the second argument which is then used to calcuate the the rest.
sample = Eventsims::Simulate.new([0, 5, 6, 3, 7, 9, 3], [4, 7, 2, 1, 3, 11, 7])
puts "Inter-arrival time: #{sample.intarrival() } "
puts "Arrival time: #{sample.arrival() } "
puts "Service time: #{sample.service() } "
puts "Time when Service begins: #{sample.servbegin() } "
puts "Time when Service ends: #{sample.servend() } "
puts "Time customer spends waiting in Queue: #{sample.queuewait() } "
puts "Time customer spends in system: #{sample.custspend() } "
puts "Idle time of server: #{sample.idle() } "
Result 2b
Inter-arrival time: [0, 5, 6, 3, 7, 9, 3]
Arrival time: [0, 5, 11, 14, 21, 30, 33]
Service time: [4, 7, 2, 1, 3, 11, 7]
Time when Service begins: [0, 5, 12, 14, 21, 30, 41]
Time when Service ends: [4, 12, 14, 15, 24, 41, 48]
Time customer spends waiting in Queue: [0, 0, 1, 0, 0, 0, 8]
Time customer spends in system: [4, 7, 3, 1, 3, 11, 15]
Idle time of server: [0, 1, 0, 0, 6, 6, 0]
Module methods
trimval
trimval that takes in one argument, (numbers or lists and strips it of leading zeros and round up to 4 decimal places
trimlist
trimlist that takes in as many arguments as possibe and does the same thing trimval does but very useful if there is a nested list in the list of arguments.
They both help to display lists and numbers in a better and easier way to read rather than have values with many leading decimal numbers in a list(Array) keeping it concise. `
Usage
Usage: Eventsims::trimval(single argument) Usage: Eventsims::trimlist(any Array argument)
example
require "Eventsims"
sample = Eventsims.trimval([3.6789876])
puts "new value: #{sample}"
sample = Eventsims.trimlist([3.6789876], "dog", [2.76542, "rat", [4]])
puts "new list: #{sample}"
Result
new val: [[3.679]]
new list: [[3.679], "dog", [2.7654, "rat", [4]]
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/tushortz/eventsims.
License
The gem is available as open source under the terms of the MIT License.