# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#------------------------------------------------------------------------------
# R source file to validate Binomial distribution tests in
# org.apache.commons.math.distribution.BinomialDistributionTest
#
# To run the test, install R, put this file and testFunctions
# into the same directory, launch R from this directory and then enter
# source("<name-of-this-file>")
#
# R functions used
# dbinom(x, size, prob, log = FALSE) <- density
# pbinom(q, size, prob, lower.tail = TRUE, log.p = FALSE) <- distribution
# qbinom(p, size, prob, lower.tail = TRUE, log.p = FALSE) <- quantiles
#------------------------------------------------------------------------------
tol <- 1E-4                       # error tolerance for tests
#------------------------------------------------------------------------------
# Function definitions

source("testFunctions")           # utility test functions

# function to verify density computations

verifyDensity <- function(points, expected, n, p, tol) {
    rDensityValues <- rep(0, length(points))
    i <- 0
    for (point in points) {
        i <- i + 1
        rDensityValues[i] <- dbinom(point, n, p, log = FALSE)
    }
    output <- c("Density test n = ", n, ", p = ", p)
    if (assertEquals(expected,rDensityValues,tol,"Density Values")) {
        displayPadded(output, SUCCEEDED, WIDTH)
    } else {
        displayPadded(output, FAILED, WIDTH)
    }
}

# function to verify distribution computations

verifyDistribution <- function(points, expected, n, p, tol) {
    rDistValues <- rep(0, length(points))
    i <- 0
    for (point in points) {
        i <- i + 1
        rDistValues[i] <- pbinom(point, n, p, log = FALSE)
    }
    output <- c("Distribution test n = ", n, ", p = ", p)
    if (assertEquals(expected,rDistValues,tol,"Distribution Values")) {
        displayPadded(output, SUCCEEDED, WIDTH)
    } else {
        displayPadded(output, FAILED, WIDTH)
    }
}

#--------------------------------------------------------------------------
cat("Binomial test cases\n")

size <- 10.0
probability <- 0.70

densityPoints <- c(-1,0,1,2,3,4,5,6,7,8,9,10,11)
densityValues <- c(0, 0.0000, 0.0001, 0.0014, 0.0090, 0.0368, 0.1029,
                0.2001, 0.2668, 0.2335, 0.1211, 0.0282, 0)
distributionValues <- c(0, 0.0000, 0.0001, 0.0016, 0.0106, 0.0473,
                0.1503, 0.3504, 0.6172, 0.8507, 0.9718, 1, 1)
inverseCumPoints <- c( 0.001, 0.010, 0.025, 0.050, 0.100, 0.999,
                0.990, 0.975, 0.950, 0.900)
inverseCumValues <- c(1, 2, 3, 4, 4, 9, 9, 9, 8, 8)

verifyDensity(densityPoints,densityValues,size,probability,tol)
verifyDistribution(densityPoints, distributionValues, size, probability, tol)

i <- 0
rInverseCumValues <- rep(0,length(inverseCumPoints))
for (point in inverseCumPoints) {
  i <- i + 1
  rInverseCumValues[i] <- qbinom(point, size, probability, log = FALSE)
}

output <- c("Inverse Distribution test n = ", size, ", p = ", probability)
# R defines quantiles from the right, need to subtract one
if (assertEquals(inverseCumValues, rInverseCumValues-1, tol,
    "Inverse Dist Values")) {
    displayPadded(output, SUCCEEDED, 80)
} else {
    displayPadded(output, FAILED, 80)
}

# Degenerate cases

size <- 5
probability <- 0.0

densityPoints <- c(-1, 0, 1, 10, 11)
densityValues <- c(0, 1, 0, 0, 0)
distributionPoints <- c(-1, 0, 1, 5, 10)
distributionValues <- c(0, 1, 1, 1, 1)

verifyDensity(densityPoints,densityValues,size,probability,tol)
verifyDistribution(distributionPoints,distributionValues,size,probability,tol)

size <- 5
probability <- 1.0

densityPoints <- c(-1, 0, 1, 2, 5, 10)
densityValues <- c(0, 0, 0, 0, 1, 0)
distributionPoints <- c(-1, 0, 1, 2, 5, 10)
distributionValues <- c(0, 0, 0, 0, 1, 1)

verifyDensity(densityPoints,densityValues,size,probability,tol)
verifyDistribution(distributionPoints,distributionValues,size,probability,tol)

displayDashes(WIDTH)
