Title: | Applies various odd models for coin flipping |
---|---|
Description: | Everyone uses the binomial as the distribution for coin flipping: this assumes for a given coin, the probability of landing heads is constant for all time. It is likely a very sound assumption. However, even for this simple example other models may be possible. This package contains such models. |
Authors: | Brian O'Meara [aut, cre] |
Maintainer: | Brian O'Meara <[email protected]> |
License: | GPL (>= 3) |
Version: | 0.0.1 |
Built: | 2024-11-20 02:48:32 UTC |
Source: | https://github.com/bomeara/flipped |
Compute probability of observations given an exponential decay model
d_coin_multiplicative( nheads, nflips, multiplier, log = FALSE, possibilities = get_possibilities(nheads, nflips), outside_bounds_is_NA = FALSE )
d_coin_multiplicative( nheads, nflips, multiplier, log = FALSE, possibilities = get_possibilities(nheads, nflips), outside_bounds_is_NA = FALSE )
nheads |
Number of heads |
nflips |
Total number of flips (heads and tails) |
multiplier |
How much to multiply by each flip |
log |
If TRUE return log transformed probabilities. |
possibilities |
All possible sequences of flips that lead to the observed number of heads |
outside_bounds_is_NA |
If TRUE, if any probability of heads is outside the bounds of probability, the function returns NA. Otherwise, it sets the value to the nearer bound. |
The likelihood of the data (or log likelihood if log=TRUE)
Compute probability of observations given an exponential decay model The idea is that the coin before handling has 100% chance of heads, but each time it is picked up that probability will decrease (maybe it is bent by the statistician's mighty thumb). After halflife times handling it, the probability of heads is 50%, and it keeps dropping from there.
dcoin_exponential_decay( nheads, nflips, halflife, log = FALSE, possibilities = get_possibilities(nheads, nflips) )
dcoin_exponential_decay( nheads, nflips, halflife, log = FALSE, possibilities = get_possibilities(nheads, nflips) )
nheads |
Number of heads |
nflips |
Total number of flips (heads and tails) |
halflife |
How many flips to get to 50% heads |
log |
If TRUE return log transformed probabilities. |
possibilities |
All possible sequences of flips that lead to the observed number of heads |
The likelihood of the data (or log likelihood if log=TRUE)
Compute probability of observations given a vector of probability of heads
dcoin_from_probability( pheads, nheads, nflips, log = FALSE, possibilities = get_possibilities(nheads, nflips), diff_value = NULL )
dcoin_from_probability( pheads, nheads, nflips, log = FALSE, possibilities = get_possibilities(nheads, nflips), diff_value = NULL )
pheads |
Vector with the probability of a heads on flip 1, 2, etc. |
nheads |
Number of heads |
nflips |
Total number of flips (heads and tails) |
log |
If TRUE return log transformed probabilities. |
possibilities |
All possible sequences of flips that lead to the observed number of heads |
diff_value |
If not NULL, the final likelihood will be abs(likelihood - diff_value) for minimizing a function |
The likelihood of the data (or log likelihood if log=TRUE)
The idea is that the coin before handling has some probability of heads, but each time it is picked up that probability could change (maybe it is bent by the statistician's mighty thumb). The slope gives the amount of change in this probability each flip: for example, a coin that starts fair and which has a slope of 0.01 has a probability of heads of 0.51 (0.50 + 0.01) on its first flip, 0.52 on its second, and so forth. If the act of flipping has absolutely no effect on the probability of heads, slope can be set to be zero, though using stats::dbinom() for this particular edge case should be faster.
dcoin_linear( nheads, nflips, preflip_prob = 0.5, slope = 0.1, log = FALSE, outside_bounds_is_NA = FALSE )
dcoin_linear( nheads, nflips, preflip_prob = 0.5, slope = 0.1, log = FALSE, outside_bounds_is_NA = FALSE )
nheads |
Number of heads |
nflips |
Total number of flips (heads and tails) |
preflip_prob |
Probability of heads before the coin is handled |
slope |
How much the probability changes each time the coin is flipped |
log |
If TRUE return log transformed probabilities. |
outside_bounds_is_NA |
If TRUE, if any probability of heads is outside the bounds of probability, the function returns NA. Otherwise, it sets the value to the nearer bound. |
Of course, if all we have is the total number of heads and total number of flips, we do not know if it was HTT, THT, or TTH. For the particular case of a slope set to exactly zero the order does not matter, but in the general case it will. For example, if the probability of heads increases with each flip, HTT is less likely than TTH even though each has one heads out of three flips. The current code looks at all possibilities exhaustively, but more efficient ways to calculate this undoubtedly exist. Pull requests are welcome. It also means this may be slow as the number of flips increases.
For some slopes and preflip probabilities,the probabilities of heads on a given flip may be outside the 0 to 1 bounds. By default, if this happens the function returns NA. If outside_bounds_is_NA is FALSE, it moves the probabilities to the nearer bound.
The likelihood of the data (or log likelihood if log=TRUE)
Find congruent models to a simple binomial model This will find the parameter values for other models that equal the likelihood for a simple binomial model. This may not be the MLE for these other models
find_congruent_models( nheads, nflips, slopes = c(0, 0.1, -0.05), stopval = 1e-04 )
find_congruent_models( nheads, nflips, slopes = c(0, 0.1, -0.05), stopval = 1e-04 )
nheads |
Number of heads |
nflips |
Total number of flips (heads and tails) |
slopes |
Vector of slopes to use |
stopval |
How large a difference in probability is considered close enough between the flat model and others |
A list containing the parameter estimates with likelihoods for each model and the probabilities for heads at each model
This grows very large with the number of flips. It will throw an error if you try too many flips.
get_possibilities(nheads, nflips)
get_possibilities(nheads, nflips)
nheads |
Number of heads |
nflips |
Total number of flips (heads and tails) |
data.frame with each potential trial as a row. 1=heads, 0=tails.
Compute the probability of heads with each flip given an exponential model The model assumes 100% chance of heads before a coin is picked up and it drops exponentially each time the coin is handled.
prob_heads_exponential_decay(nflips, halflife)
prob_heads_exponential_decay(nflips, halflife)
nflips |
Total number of flips (heads and tails) |
halflife |
How many flips to get to 50% heads |
Vector of probability of heads for the first flip, second flip, etc.
Compute the probability of heads with each flip given a linear change model.
prob_heads_linear(nflips, preflip_prob = 0.5, slope = 0.1)
prob_heads_linear(nflips, preflip_prob = 0.5, slope = 0.1)
nflips |
Total number of flips (heads and tails) |
preflip_prob |
Probability of heads before the coin is handled |
slope |
How much the probability changes each time the coin is flipped |
Vector of probability of heads for the first flip, second flip, etc.
Compute the probability of heads with each flip given a multiplier model The model assumes 50% chance of heads before a coin is picked up and it changes as a percentage of the previous value each flip. i.e., the probability of heads is 101% of the probability the previous flip with a multiplier of 1.01.
prob_heads_multiplicative(nflips, multiplier, outside_bounds_is_NA = FALSE)
prob_heads_multiplicative(nflips, multiplier, outside_bounds_is_NA = FALSE)
nflips |
Total number of flips (heads and tails) |
multiplier |
Factor to multiply the previous probability by |
outside_bounds_is_NA |
If TRUE, if any probability of heads is outside the bounds of probability, the function returns NA. Otherwise, it sets the value to the nearer bound. |
Vector of probability of heads for the first flip, second flip, etc.
Computes the likelihood for a range of values using an exponential coin model
profile_exponential_decay_model( nheads, nflips, param_range = c(0, nflips * 10), number_of_steps = 1000, log = FALSE )
profile_exponential_decay_model( nheads, nflips, param_range = c(0, nflips * 10), number_of_steps = 1000, log = FALSE )
nflips |
Total number of flips (heads and tails) |
param_range |
Range of parameters to try |
number_of_steps |
How many values of the parameter to try |
vector of likelihoods
nheads <- 8 nflips <- 10 exp_results <- profile_exponential_decay_model(nheads, nflips) plot(x=exp_results$preflip_prob, y=exp_results$likelihood, type="l") best_param <- exp_results$halflife[which.max(exp_results$likelihood, na.rm=TRUE)] print(best_param)
nheads <- 8 nflips <- 10 exp_results <- profile_exponential_decay_model(nheads, nflips) plot(x=exp_results$preflip_prob, y=exp_results$likelihood, type="l") best_param <- exp_results$halflife[which.max(exp_results$likelihood, na.rm=TRUE)] print(best_param)
Computes the likelihood for a range of values using a linear coin model
profile_linear_model( nheads, nflips, param_range = c(0, 1), slope = 0.1, number_of_steps = 1000, log = FALSE, outside_bounds_is_NA = FALSE )
profile_linear_model( nheads, nflips, param_range = c(0, 1), slope = 0.1, number_of_steps = 1000, log = FALSE, outside_bounds_is_NA = FALSE )
nflips |
Total number of flips (heads and tails) |
param_range |
Range of parameters to try |
slope |
How much the probability changes each time the coin is flipped |
number_of_steps |
How many values of the parameter to try |
vector of likelihoods
nheads <- 8 nflips <- 10 linear_results <- profile_linear_model(nheads, nflips) plot(x=linear_results$preflip_prob, y=linear_results$likelihood, type="l") dbinom_proportions <- seq(from=0, to=1, length.out=1000) lines(dbinom_proportions, dbinom(nheads, nflips, dbinom_proportions), col="red") best_param <- linear_results$preflip_prob[which.max(linear_results$likelihood, na.rm=TRUE)] print(best_param)
nheads <- 8 nflips <- 10 linear_results <- profile_linear_model(nheads, nflips) plot(x=linear_results$preflip_prob, y=linear_results$likelihood, type="l") dbinom_proportions <- seq(from=0, to=1, length.out=1000) lines(dbinom_proportions, dbinom(nheads, nflips, dbinom_proportions), col="red") best_param <- linear_results$preflip_prob[which.max(linear_results$likelihood, na.rm=TRUE)] print(best_param)
Compute probability of observations across many potential vectors This will try (1/stepsize)^nflips possible vectors, computing the probability of the observation for each
try_many_vectors( nheads, nflips, number_samples = 1000, stopval = 1e-05, log = FALSE, possibilities = get_possibilities(nheads, nflips) )
try_many_vectors( nheads, nflips, number_samples = 1000, stopval = 1e-05, log = FALSE, possibilities = get_possibilities(nheads, nflips) )
nheads |
Number of heads |
nflips |
Total number of flips (heads and tails) |
number_samples |
How many vectors to sample |
stopval |
How large a difference in probability is considered close enough between the flat model and others |
log |
If TRUE return log transformed probabilities. |
possibilities |
All possible sequences of flips that lead to the observed number of heads |
The likelihood of the data (or log likelihood if log=TRUE)