How do you compute this probability density function, with a triangular distribution of parameters (a,b,c)?
f(x)= 0 , x<a
2(x-a)/((b-a)(c-a)) , a <= x <= c
2(b-x)/((b-a)(b-c)) , c < x <=b
0 , x> b
Expanding on #StéphaneLaurent‘s comments, you can define a piecewise function using a series of ifelse() calls (or dplyr::case_when()).
f <- function(x, A, B, C) {
out <- ifelse(
x < A | B < x,
0,
ifelse(
A <= x & x <= C,
(2*(x-A))/((B-A)*(C-A)),
ifelse(
C < x & x <= B,
(2*(B-x))/((B-A)*(B-C)),
NA_real_
)))
if (any((is.na(out) | is.nan(out)) & (!is.na(x) & !is.nan(x)))) {
warning("f(x) undefined for some input values")
}
out
}
Taking it for a spin:
library(ggplot2)
dat <- expand.grid(
x = seq(-1.5, 1.5, by = 0.1),
A = -1:1,
B = -1:1,
C = -1:1
)
dat$y <- with(dat, f(x, A, B, C))
# Warning message:
# In f(x, A, B, C) : f(x) undefined for some input values
ggplot(dat, aes(x, y)) +
geom_line(aes(color = factor(C))) +
facet_grid(B ~ A, labeller = label_both)
Here is an option for a density function and a random function.
dtri <- function(x, A, B, C) {
n <- length(x)
i <- 1:n
if (length(A) == 1) A <- rep(A, n)
if (length(B) == 1) B <- rep(B, n)
if (length(C) == 1) C <- rep(C, n)
abc <- Rfast::rowSort(matrix(c(A, B, C), n, 3))
bln <- x < abc[,2]
p <- 2*abs(x - abc[i + 2*n*!bln])/(abc[,3] - abc[,1])/(abc[i + n*(2 - bln)] - abc[i + n*(1 - bln)])
p[x < abc[,1] | x > abc[,3]] <- 0
p
}
rtri <- function(n, a, b, c) {
if (a > b) {a <- (b - a) + (b <- a)}
if (b > c) {c <- (b - c) + (b <- c)}
fb <- (b - a)/(c - a)
U <- runif(n)
blna <- U < fb
r <-numeric(n)
r[blna] <- a + sqrt(U[blna]*(c - a)*(b - a))
r[!blna] <- c - sqrt((1 - U[!blna])*(c - a)*(c - b))
r
}
Using R's vectorized cabilities:
my_fun <- function(x, a, b, c) {
i1 <- x >= a & x <= c
i2 <- x > c & x <= b
f <- rep(NA, length(x))
f[x < a | x > b] <- 0
f[i1] <- 2 * (x[i1] - a) / ((b - a) * (c - a))
f[i2] <- 2 * (b - x[i2]) / ((b - a) * (b - c))
return(f)
}
Test:
set.seed(123)
x <- sort(rnorm(1000, 0, 5))
a <- runif(1, -10, -2)
c <- runif(1, -2, 2)
b <- runif(1, 2, 10)
f <- my_fun(x, a, b, c)
plot(x, f, type="l")
Related
I wanna print the rule like following:
rule(0,0,0) = 0
rule(0,0,1) = 1
rule(0,1,0) = 1
rule(0,1,1) = 1
rule(1,0,0) = 1
rule(1,0,1) = 0
rule(1,1,0) = 0
rule(1,1,1) = 0
I tried to write a set of “if-else” conditions that test for zeroes and ones in the input values, returning the corresponding value from the table as output but it didnt work
A single comparison will do. This would be the most performant implementation I can think of.
rule <- function(a, b, c) +(abs(4*a + 2*b + c - 2.5) < 2)
A parsimonious solution:
rule <- function(a, b, c) +xor(a, b | c)
Note both solutions are vectorized.
Benchmarking:
rule1 <- function(a, b, c) +(abs(4*a + 2*b + c - 2.5) < 2)
rule2 <- function(a, b, c) +xor(a, b | c)
rule3 <- function(x, y, z) +((4 * x + 2 * y + z) %in% 1:4)
abc <- matrix(sample(0:1, 3e6, 1), 1e6, 3)
microbenchmark::microbenchmark(rule1 = rule1(abc[,1], abc[,2], abc[,3]),
rule2 = rule2(abc[,1], abc[,2], abc[,3]),
Thomas = rule3(abc[,1], abc[,2], abc[,3]),
check = "identical")
#> Unit: milliseconds
#> expr min lq mean median uq max neval
#> rule1 13.5161 16.58425 20.74505 17.69030 20.22745 53.9513 100
#> rule2 32.7552 35.05735 39.41473 36.27760 39.38165 74.8564 100
#> Thomas 24.6562 28.39065 33.78937 29.70875 33.19045 65.9709 100
A possibility is to concatenate the three digits and then use switch:
rule <- function(a, b, c) {
x <- paste0(a, b, c)
switch(
x,
"000" = 0,
"001" = 1,
......
)
}
You can try
rule <- function(x, y, z) {
+((4 * x + 2 * y + z) %in% 1:4)
}
or
rule <- function(x, y, z) {
bitwXor(x, bitwOr(y, z))
}
Benchmark
rule1 <- function(a, b, c) +(abs(4 * a + 2 * b + c - 2.5) < 2)
rule2 <- function(a, b, c) +xor(a, b | c)
rule3 <- function(x, y, z) +((4 * x + 2 * y + z) %in% 1:4)
rule4 <- function(x, y, z) bitwXor(x, bitwOr(y, z))
abc <- matrix(sample(0:1, 3e6, 1), 1e6, 3)
microbenchmark::microbenchmark(
rule1 = rule1(abc[, 1], abc[, 2], abc[, 3]),
rule2 = rule2(abc[, 1], abc[, 2], abc[, 3]),
Thomas1 = rule3(abc[, 1], abc[, 2], abc[, 3]),
Thomas2 = rule4(abc[, 1], abc[, 2], abc[, 3]),
check = "identical"
)
gives
Unit: milliseconds
expr min lq mean median uq max neval
rule1 16.1315 22.82880 32.91071 24.48080 28.29635 113.1915 100
rule2 33.6093 40.93665 50.12914 44.77415 48.90045 128.0033 100
Thomas1 26.6938 34.78615 43.34770 37.63255 42.49940 114.3973 100
Thomas2 9.1119 12.25080 18.46705 16.26445 18.46835 105.1263 100
In the case that your rule can't be expressed as a mathematical expression (as jblood94 and ThomasIsCoding did), you can create a list with the options, check which option was passed, and get the result associated with that option.
rule = function(n1, n2, n3){
combin = list(c(0,0,0), c(1,0,0), c(0,1,0), c(0,0,1), c(1,1,0), c(1,0,1), c(0,1,1), c(1,1,1))
result = c(0, 1, 1, 1, 0, 0, 1, 0)
index = which(sapply(combin, function(x){identical(x, c(n1, n2, n3))}))
result[index]
}
rule(0, 1, 0)
[1] 1
For the fun of brevity:
rule <- function(first, second, third){
bits_as_decimal = paste(first, second, third, sep = '') |>
strtoi(base = 2)
bits_as_decimal %in% 1:4 |> as.integer()
}
What happens:
the three arguments are considered a three bit binary (e. g. 001)
binary gets converted to its decimal equivalent (strtoi)
check if the decimal equivalent falls into the range 1-4 (which you want to convert to 1)
re-cast the boolean value to binary
This question already has answers here:
Interpreting "condition has length > 1" warning from `if` function
(7 answers)
Closed 3 years ago.
i want to use a function for each row in a vector.
when I try my code I receive this message:
the condition has length > 1 and only the first element will be used
function(Inn, x, y, z, xx, b, i, Dp){
if (Inn == 0) {
if (runif(1) <= x) { # success.probability.imitation
absorptive.capacity <- max(y, z)
}
else{
absorptive.capacity <- min(x, x + b/sqrt(i) - Dp)
}
} else{
if (runif(1) <= xx) { # sucess innovation
absorptive.capacity <- y + b / sqrt(i)
} else{
absorptive.capacity <- y + b / sqrt(i) - Dp
}
}
if (absorptive.capacity > 1) {
absorptive.capacity = 1
}
return(absorptive.capacity)
}
absorptive.capacity(c(0, 1), c(0.5, 0), c(0.7, 0.8), 0.7, c(0, 06), 0.5, c(64, 94), 0.06)
I want return each value after that transformation, this is the purpose for my function. Some one can help me?
absorptive.capacity<-function(Inn, x, y, z, xx, b, i, Dp){
ifelse( Inn == 0,
ifelse(runif(1) <= x,
absorptive.capacity <- max(y, z),
absorptive.capacity <- min(x, x + b/sqrt(i) - Dp)),
ifelse(runif(1) <= xx,
absorptive.capacity <- y + b / sqrt(i),
absorptive.capacity <- y + b / sqrt(i) - Dp))
ifelse(absorptive.capacity > 1,
absorptive.capacity == 1,
absorptive.capacity == absorptive.capacity)
return(absorptive.capacity)
}
I have a function:
f(x1, x2) = (x2-x1)/(c-x1),
where 0<x1,x2<1 and c = 0, 1
Now I need to optimize the function in this way where f(x1, x2) will stay in the range [-1, 1]. I am trying to solve this using the following R code.
require("stats")
# c=0
f <- function(x) { (x[2] - x[1]) / (0 - x[1]) }
initial_x <- c(0.1, 0.1)
x_optimal <- optim(initial_x, f, method="CG")
x_min <- x_optimal$par
x_min
x_optimal$value
# c=1
f <- function(x) { (x[2] - x[1]) / (1 - x[1]) }
initial_x <- c(0.1, 0.1)
x_optimal <- optim(initial_x, f, method="CG")
x_min <- x_optimal$par
x_min
x_optimal$value
But it is not working. Could anyone help me to solve this? Thanks in advance.
Here is a solution with the nloptr package. I treat the case c=1.
library(nloptr)
# c = 1
# objective function (to minimize)
f <- function(x) (x[2]-x[1]) / (1-x[1])
# constraints
# f(x) < 1 <=> x2-x1 < 1-x1 <=> x2 < 1
# f(x) > -1 <=> x2-x1 > x1 - 1 <=> 2*x1 - x2 - 1 < 0
# => constraint function
g <- function(x) 2*x[1] - x[2] - 1
# run optimization
opt <- nloptr(
x0 = c(0.5, 0.5),
eval_f = f,
lb = c(0, 0),
ub = c(1, 1),
eval_g_ineq = g,
opts = list(algorithm = "NLOPT_LN_COBYLA")
)
We obtain:
> # solution
> opt$solution
[1] 0.7569765 0.5139531
> # value of objective function
> opt$objective
[1] -1
Now the case c=0.
library(nloptr)
# c = 0
# objective function (to minimize)
f <- function(x) (x[1]-x[2]) / x[1]
# constraints
# f(x) < 1 <=> x1-x2 < x1 <=> x2 > 0
# f(x) > -1 <=> x1-x2 > -x1 <=> x2 - 2*x1 < 0
# => constraint function
g <- function(x) x[2] - 2*x[1]
# run optimization
opt <- nloptr(
x0 = c(0.5, 0.5),
eval_f = f,
lb = c(0, 0),
ub = c(1, 1),
eval_g_ineq = g,
opts = list(algorithm = "NLOPT_LN_COBYLA")
)
We get:
> # solution
> opt$solution
[1] 0.5 1.0
> # value of objective function
> opt$objective
[1] -1
I've been running the following code which returns the correct coefficients. However, no matter where I put a plot call, I can't get any plot output.
I'm not sure if a reproducible example is needed here, as I think this can be solved by looking at my gradientDescent function below? It's my first attempt at running this algorithm in R:
gradientDescent <- function(x, y, learn_rate, conv_threshold, n, max_iter) {
m <- runif(1, 0, 1)
c <- runif(1, 0, 1)
yhat <- m * x + c
cost_error <- (1 / (n + 2)) * sum((y - yhat) ^ 2)
converged = F
iterations = 0
while(converged == F) {
m_new <- m - learn_rate * ((1 / n) * (sum((yhat - y) * x)))
c_new <- c - learn_rate * ((1 / n) * (sum(yhat - y)))
m <- m_new
c <- c_new
yhat <- m * x + c
cost_error_new <- (1 / (n + 2)) * sum((y - yhat) ^ 2)
if(cost_error - cost_error_new <= conv_threshold) {
converged = T
}
iterations = iterations + 1
if(iterations > max_iter) {
converged = T
return(paste("Optimal intercept:", c, "Optimal slope:", m))
}
}
}
It's unclear what you have been doing that was ineffective. The base graphics functions plot and abline should be able to produce output even when used inside functions. Lattice and ggplot2 graphics are based on grid-grpahics and would therefore need a print() wrapped around the function calls to create output (as described in the R-FAQ). So try this:
gradientDescent <- function(x, y, learn_rate, conv_threshold, n, max_iter)
{ ## plot.new() perhaps not needed
plot(x,y)
m <- runif(1, 0, 1)
c <- runif(1, 0, 1)
yhat <- m * x + c
cost_error <- (1 / (n + 2)) * sum((y - yhat) ^ 2)
converged = F
iterations = 0
while(converged == F) {
m_new <- m - learn_rate * ((1 / n) * (sum((yhat - y) * x)))
c_new <- c - learn_rate * ((1 / n) * (sum(yhat - y)))
m <- m_new
c <- c_new
yhat <- m * x + c
cost_error_new <- (1 / (n + 2)) * sum((y - yhat) ^ 2)
if(cost_error - cost_error_new <= conv_threshold) {
converged = T
}
iterations = iterations + 1
if(iterations > max_iter) { abline( c, m) #calculated
dev.off()
converged = T
return(paste("Optimal intercept:", c, "Optimal slope:", m))
}
}
}
The cvm.test() from dgof package provides a way of doing the one-sample Cramer-von Mises test on discrete distributions, my goal is to develop a function that does the test for continuous distributions as well (like the Kolmogorov-Smirnov ks.test() from the stats package).
Note:this post is concerned only with fully specified df null hypothesis, so please no bootstraping or Monte Carlo Simulation here
> cvm.test
function (x, y, type = c("W2", "U2", "A2"), simulate.p.value = FALSE,
B = 2000, tol = 1e-08)
{
cvm.pval.disc <- function(STAT, lambda) {
x <- STAT
theta <- function(u) {
VAL <- 0
for (i in 1:length(lambda)) {
VAL <- VAL + 0.5 * atan(lambda[i] * u)
}
return(VAL - 0.5 * x * u)
}
rho <- function(u) {
VAL <- 0
for (i in 1:length(lambda)) {
VAL <- VAL + log(1 + lambda[i]^2 * u^2)
}
VAL <- exp(VAL * 0.25)
return(VAL)
}
fun <- function(u) return(sin(theta(u))/(u * rho(u)))
pval <- 0
try(pval <- 0.5 + integrate(fun, 0, Inf, subdivisions = 1e+06)$value/pi,
silent = TRUE)
if (pval > 0.001)
return(pval)
if (pval <= 0.001) {
df <- sum(lambda != 0)
est1 <- dchisq(STAT/max(lambda), df)
logf <- function(t) {
ans <- -t * STAT
ans <- ans - 0.5 * sum(log(1 - 2 * t * lambda))
return(ans)
}
est2 <- 1
try(est2 <- exp(nlm(logf, 1/(4 * max(lambda)))$minimum),
silent = TRUE)
return(min(est1, est2))
}
}
cvm.stat.disc <- function(x, y, type = c("W2", "U2", "A2")) {
type <- match.arg(type)
I <- knots(y)
N <- length(x)
e <- diff(c(0, N * y(I)))
obs <- rep(0, length(I))
for (j in 1:length(I)) {
obs[j] <- length(which(x == I[j]))
}
S <- cumsum(obs)
T <- cumsum(e)
H <- T/N
p <- e/N
t <- (p + p[c(2:length(p), 1)])/2
Z <- S - T
Zbar <- sum(Z * t)
S0 <- diag(p) - p %*% t(p)
A <- matrix(1, length(p), length(p))
A <- apply(row(A) >= col(A), 2, as.numeric)
E <- diag(t)
One <- rep(1, nrow(E))
K <- diag(0, length(H))
diag(K)[-length(H)] <- 1/(H[-length(H)] * (1 - H[-length(H)]))
Sy <- A %*% S0 %*% t(A)
M <- switch(type, W2 = E, U2 = (diag(1, nrow(E)) - E %*%
One %*% t(One)) %*% E %*% (diag(1, nrow(E)) - One %*%
t(One) %*% E), A2 = E %*% K)
lambda <- eigen(M %*% Sy)$values
STAT <- switch(type, W2 = sum(Z^2 * t)/N, U2 = sum((Z -
Zbar)^2 * t)/N, A2 = sum((Z^2 * t/(H * (1 - H)))[-length(I)])/N)
return(c(STAT, lambda))
}
cvm.pval.disc.sim <- function(STATISTIC, lambda, y, type,
tol, B) {
knots.y <- knots(y)
fknots.y <- y(knots.y)
u <- runif(B * length(x))
u <- sapply(u, function(a) return(knots.y[sum(a > fknots.y) +
1]))
dim(u) <- c(B, length(x))
s <- apply(u, 1, cvm.stat.disc, y, type)
s <- s[1, ]
return(sum(s >= STATISTIC - tol)/B)
}
type <- match.arg(type)
DNAME <- deparse(substitute(x))
if (is.stepfun(y)) {
if (length(setdiff(x, knots(y))) != 0) {
stop("Data are incompatable with null distribution; ",
"Note: This function is meant only for discrete distributions ",
"you may be receiving this error because y is continuous.")
}
tempout <- cvm.stat.disc(x, y, type = type)
STAT <- tempout[1]
lambda <- tempout[2:length(tempout)]
if (!simulate.p.value) {
PVAL <- cvm.pval.disc(STAT, lambda)
}
else {
PVAL <- cvm.pval.disc.sim(STAT, lambda, y, type,
tol, B)
}
METHOD <- paste("Cramer-von Mises -", type)
names(STAT) <- as.character(type)
RVAL <- list(statistic = STAT, p.value = PVAL, alternative = "Two.sided",
method = METHOD, data.name = DNAME)
}
else {
stop("Null distribution must be a discrete.")
}
class(RVAL) <- "htest"
return(RVAL)
}
<environment: namespace:dgof>
Kolmogorov-Smirnov ks.test() from stats package for comparison (note that this function does both the one-sample and two-sample tests):
> ks.test
function (x, y, ..., alternative = c("two.sided", "less", "greater"),
exact = NULL, tol = 1e-08, simulate.p.value = FALSE, B = 2000)
{
pkolmogorov1x <- function(x, n) {
if (x <= 0)
return(0)
if (x >= 1)
return(1)
j <- seq.int(from = 0, to = floor(n * (1 - x)))
1 - x * sum(exp(lchoose(n, j) + (n - j) * log(1 - x -
j/n) + (j - 1) * log(x + j/n)))
}
exact.pval <- function(alternative, STATISTIC, x, n, y, knots.y,
tol) {
ts.pval <- function(S, x, n, y, knots.y, tol) {
f_n <- ecdf(x)
eps <- min(tol, min(diff(knots.y)) * tol)
eps2 <- min(tol, min(diff(y(knots.y))) * tol)
a <- rep(0, n)
b <- a
f_a <- a
for (i in 1:n) {
a[i] <- min(c(knots.y[which(y(knots.y) + S >=
i/n + eps2)[1]], Inf), na.rm = TRUE)
b[i] <- min(c(knots.y[which(y(knots.y) - S >
(i - 1)/n - eps2)[1]], Inf), na.rm = TRUE)
f_a[i] <- ifelse(!(a[i] %in% knots.y), y(a[i]),
y(a[i] - eps))
}
f_b <- y(b)
p <- rep(1, n + 1)
for (i in 1:n) {
tmp <- 0
for (k in 0:(i - 1)) {
tmp <- tmp + choose(i, k) * (-1)^(i - k - 1) *
max(f_b[k + 1] - f_a[i], 0)^(i - k) * p[k +
1]
}
p[i + 1] <- tmp
}
p <- max(0, 1 - p[n + 1])
if (p > 1) {
warning("numerical instability in p-value calculation.")
p <- 1
}
return(p)
}
less.pval <- function(S, n, H, z, tol) {
m <- ceiling(n * (1 - S))
c <- S + (1:m - 1)/n
CDFVAL <- H(sort(z))
for (j in 1:length(c)) {
ifelse((min(abs(c[j] - CDFVAL)) < tol), c[j] <- 1 -
c[j], c[j] <- 1 - CDFVAL[which(order(c(c[j],
CDFVAL)) == 1)])
}
b <- rep(0, m)
b[1] <- 1
for (k in 1:(m - 1)) b[k + 1] <- 1 - sum(choose(k,
1:k - 1) * c[1:k]^(k - 1:k + 1) * b[1:k])
p <- sum(choose(n, 0:(m - 1)) * c^(n - 0:(m - 1)) *
b)
return(p)
}
greater.pval <- function(S, n, H, z, tol) {
m <- ceiling(n * (1 - S))
c <- 1 - (S + (1:m - 1)/n)
CDFVAL <- c(0, H(sort(z)))
for (j in 1:length(c)) {
if (!(min(abs(c[j] - CDFVAL)) < tol))
c[j] <- CDFVAL[which(order(c(c[j], CDFVAL)) ==
1) - 1]
}
b <- rep(0, m)
b[1] <- 1
for (k in 1:(m - 1)) b[k + 1] <- 1 - sum(choose(k,
1:k - 1) * c[1:k]^(k - 1:k + 1) * b[1:k])
p <- sum(choose(n, 0:(m - 1)) * c^(n - 0:(m - 1)) *
b)
return(p)
}
p <- switch(alternative, two.sided = ts.pval(STATISTIC,
x, n, y, knots.y, tol), less = less.pval(STATISTIC,
n, y, knots.y, tol), greater = greater.pval(STATISTIC,
n, y, knots.y, tol))
return(p)
}
sim.pval <- function(alternative, STATISTIC, x, n, y, knots.y,
tol, B) {
fknots.y <- y(knots.y)
u <- runif(B * length(x))
u <- sapply(u, function(a) return(knots.y[sum(a > fknots.y) +
1]))
dim(u) <- c(B, length(x))
getks <- function(a, knots.y, fknots.y) {
dev <- c(0, ecdf(a)(knots.y) - fknots.y)
STATISTIC <- switch(alternative, two.sided = max(abs(dev)),
greater = max(dev), less = max(-dev))
return(STATISTIC)
}
s <- apply(u, 1, getks, knots.y, fknots.y)
return(sum(s >= STATISTIC - tol)/B)
}
alternative <- match.arg(alternative)
DNAME <- deparse(substitute(x))
x <- x[!is.na(x)]
n <- length(x)
if (n < 1L)
stop("not enough 'x' data")
PVAL <- NULL
if (is.numeric(y)) {
DNAME <- paste(DNAME, "and", deparse(substitute(y)))
y <- y[!is.na(y)]
n.x <- as.double(n)
n.y <- length(y)
if (n.y < 1L)
stop("not enough 'y' data")
if (is.null(exact))
exact <- (n.x * n.y < 10000)
METHOD <- "Two-sample Kolmogorov-Smirnov test"
TIES <- FALSE
n <- n.x * n.y/(n.x + n.y)
w <- c(x, y)
z <- cumsum(ifelse(order(w) <= n.x, 1/n.x, -1/n.y))
if (length(unique(w)) < (n.x + n.y)) {
warning("cannot compute correct p-values with ties")
z <- z[c(which(diff(sort(w)) != 0), n.x + n.y)]
TIES <- TRUE
}
STATISTIC <- switch(alternative, two.sided = max(abs(z)),
greater = max(z), less = -min(z))
nm_alternative <- switch(alternative, two.sided = "two-sided",
less = "the CDF of x lies below that of y", greater = "the CDF of x lies above that of y")
if (exact && (alternative == "two.sided") && !TIES)
PVAL <- 1 - .C("psmirnov2x", p = as.double(STATISTIC),
as.integer(n.x), as.integer(n.y), PACKAGE = "dgof")$p
}
else if (is.stepfun(y)) {
z <- knots(y)
if (is.null(exact))
exact <- (n <= 30)
if (exact && n > 30) {
warning("numerical instability may affect p-value")
}
METHOD <- "One-sample Kolmogorov-Smirnov test"
dev <- c(0, ecdf(x)(z) - y(z))
STATISTIC <- switch(alternative, two.sided = max(abs(dev)),
greater = max(dev), less = max(-dev))
if (simulate.p.value) {
PVAL <- sim.pval(alternative, STATISTIC, x, n, y,
z, tol, B)
}
else {
PVAL <- switch(exact, `TRUE` = exact.pval(alternative,
STATISTIC, x, n, y, z, tol), `FALSE` = NULL)
}
nm_alternative <- switch(alternative, two.sided = "two-sided",
less = "the CDF of x lies below the null hypothesis",
greater = "the CDF of x lies above the null hypothesis")
}
else {
if (is.character(y))
y <- get(y, mode = "function")
if (mode(y) != "function")
stop("'y' must be numeric or a string naming a valid function")
if (is.null(exact))
exact <- (n < 100)
METHOD <- "One-sample Kolmogorov-Smirnov test"
TIES <- FALSE
if (length(unique(x)) < n) {
warning(paste("default ks.test() cannot compute correct p-values with ties;\n",
"see help page for one-sample Kolmogorov test for discrete distributions."))
TIES <- TRUE
}
x <- y(sort(x), ...) - (0:(n - 1))/n
STATISTIC <- switch(alternative, two.sided = max(c(x,
1/n - x)), greater = max(1/n - x), less = max(x))
if (exact && !TIES) {
PVAL <- if (alternative == "two.sided")
1 - .C("pkolmogorov2x", p = as.double(STATISTIC),
as.integer(n), PACKAGE = "dgof")$p
else 1 - pkolmogorov1x(STATISTIC, n)
}
nm_alternative <- switch(alternative, two.sided = "two-sided",
less = "the CDF of x lies below the null hypothesis",
greater = "the CDF of x lies above the null hypothesis")
}
names(STATISTIC) <- switch(alternative, two.sided = "D",
greater = "D^+", less = "D^-")
pkstwo <- function(x, tol = 1e-06) {
if (is.numeric(x))
x <- as.vector(x)
else stop("argument 'x' must be numeric")
p <- rep(0, length(x))
p[is.na(x)] <- NA
IND <- which(!is.na(x) & (x > 0))
if (length(IND)) {
p[IND] <- .C("pkstwo", as.integer(length(x[IND])),
p = as.double(x[IND]), as.double(tol), PACKAGE = "dgof")$p
}
return(p)
}
if (is.null(PVAL)) {
PVAL <- ifelse(alternative == "two.sided", 1 - pkstwo(sqrt(n) *
STATISTIC), exp(-2 * n * STATISTIC^2))
}
RVAL <- list(statistic = STATISTIC, p.value = PVAL, alternative = nm_alternative,
method = METHOD, data.name = DNAME)
class(RVAL) <- "htest"
return(RVAL)
}
<environment: namespace:dgof>