zeolite-lang-0.22.0.0: lib/math/test/random.0rt
/* -----------------------------------------------------------------------------
Copyright 2021 Kevin P. Barry
Licensed 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.
----------------------------------------------------------------------------- */
// Author: Kevin P. Barry [ta0kira@gmail.com]
testcase "valid instantiations" {
success
}
unittest exponential {
Generator<Float> random <- RandomExponential.new(1.0)
Float value <- random.generate()
}
unittest gaussian {
Generator<Float> random <- RandomGaussian.new(0.0,1.0)
Float value <- random.generate()
}
unittest uniform {
Generator<Float> random <- RandomUniform.new(0.0,1.0)
Float value <- random.generate()
}
unittest probability {
Generator<Float> random <- RandomUniform.probability()
Float value <- random.generate()
}
unittest constant {
Generator<Float> random <- GenerateConstant.new(1.0)
Float value <- random.generate()
}
unittest categorical {
CategoricalTree<Float> tree <- CategoricalTree<Float>.new()
.setWeight(0.0,1)
.setWeight(1.0,1)
.setWeight(2.0,1)
.setWeight(3.0,1)
.setWeight(4.0,1)
RandomCategorical<Float> random <- tree `RandomCategorical:sampleWith` RandomUniform.probability()
\ Testing.checkFalse(random.isEmpty())
Float value <- random.generate()
}
testcase "negative lambda in exponential" {
crash
require "lambda"
require "-1"
}
unittest test {
Generator<Float> random <- RandomExponential.new(-1.0)
}
testcase "negative standard deviation in gaussian" {
crash
require "standard deviation"
require "-1"
}
unittest test {
Generator<Float> random <- RandomGaussian.new(0.0,-1.0)
}
testcase "empty range in uniform" {
crash
require "range"
require "0,-1"
}
unittest test {
Generator<Float> random <- RandomUniform.new(0.0,-1.0)
}
testcase "sampling with empty CategoricalTree" {
crash
require "less than the total"
}
unittest categorical {
CategoricalTree<Float> tree <- CategoricalTree<Float>.new()
RandomCategorical<Float> random <- tree `RandomCategorical:sampleWith` RandomUniform.probability()
\ Testing.checkTrue(random.isEmpty())
Float value <- random.generate()
}
testcase "distribution sanity checks" {
success
}
unittest exponential { $DisableCoverage$
Int count <- 10000
Float lambda <- 10.0
$ReadOnly[count,lambda]$
Generator<Float> random <- RandomExponential.new(lambda)
Float sum <- 0.0
traverse (Counter.zeroIndexed(count) -> _) {
Float value <- random.generate()
\ Testing.checkGreaterThan(value,0.0)
sum <- sum+value
}
\ Testing.checkBetween(sum/count.asFloat(),0.9/lambda,1.1/lambda)
}
unittest gaussian { $DisableCoverage$
Int count <- 10000
Float mean <- 100.0
Float sd <- 1.0
$ReadOnly[count,mean,sd]$
Generator<Float> random <- RandomGaussian.new(mean,sd)
Float sum <- 0.0
traverse (Counter.zeroIndexed(count) -> _) {
sum <- sum+random.generate()
}
\ Testing.checkBetween(sum/count.asFloat(),mean-0.1*sd,mean+0.1*sd)
}
unittest uniform { $DisableCoverage$
Int count <- 10000
Float min <- -11.0
Float max <- 5.0
$ReadOnly[count,min,max]$
Generator<Float> random <- RandomUniform.new(min,max)
Float sum <- 0.0
traverse (Counter.zeroIndexed(count) -> _) {
Float value <- random.generate()
\ Testing.checkBetween(value,min,max)
sum <- sum+value
}
\ Testing.checkBetween(sum/count.asFloat(),(min+max)/2.0-0.1*(max-min),(min+max)/2.0+0.1*(max-min))
}
unittest probability { $DisableCoverage$
Int count <- 10000
$ReadOnly[count]$
Generator<Float> random <- RandomUniform.probability()
Float sum <- 0.0
traverse (Counter.zeroIndexed(count) -> _) {
Float value <- random.generate()
\ Testing.checkBetween(value,0.0,1.0)
sum <- sum+value
}
\ Testing.checkBetween(sum/count.asFloat(),0.4,0.6)
}
unittest constant { $DisableCoverage$
Int count <- 10000
Float constant <- 12345.0
$ReadOnly[count,constant]$
Generator<Float> random <- GenerateConstant.new(constant)
traverse (Counter.zeroIndexed(count) -> _) {
Float value <- random.generate()
\ Testing.checkEquals(constant,value)
}
}
unittest categorical { $DisableCoverage$
Int count <- 10000
CategoricalTree<Float> tree <- CategoricalTree<Float>.new()
.setWeight(0.0,1)
.setWeight(1.0,1)
.setWeight(2.0,1)
.setWeight(3.0,1)
.setWeight(4.0,1)
$ReadOnly[count,tree]$
Generator<Float> random <- tree `RandomCategorical:sampleWith` RandomUniform.probability()
Float sum <- 0.0
traverse (Counter.zeroIndexed(count) -> _) {
Float value <- random.generate()
\ Testing.checkBetween(value,0.0,4.0)
sum <- sum+value
}
\ Testing.checkBetween(sum/count.asFloat(),1.9,2.1)
}
testcase "distribution seed checks" {
success
}
unittest exponential {
Float lambda <- 10.0
$ReadOnly[lambda]$
RandomExponential random1 <- RandomExponential.new(lambda)
RandomExponential random2 <- RandomExponential.new(lambda)
Float v1 <- random1.generate()
Float v2 <- random2.generate()
random1 <- random1.setSeed(123)
Float v3 <- random1.generate()
random2 <- random2.setSeed(123)
Float v4 <- random2.generate()
\ Testing.checkNotEquals(v1,v2)
\ Testing.checkNotEquals(v1,v3)
\ Testing.checkEquals(v3,v4)
}
unittest gaussian {
Float mean <- 100.0
Float sd <- 1.0
$ReadOnly[mean,sd]$
RandomGaussian random1 <- RandomGaussian.new(mean,sd)
RandomGaussian random2 <- RandomGaussian.new(mean,sd)
Float v1 <- random1.generate()
Float v2 <- random2.generate()
random1 <- random1.setSeed(123)
Float v3 <- random1.generate()
random2 <- random2.setSeed(123)
Float v4 <- random2.generate()
\ Testing.checkNotEquals(v1,v2)
\ Testing.checkNotEquals(v1,v3)
\ Testing.checkEquals(v3,v4)
}
unittest uniform {
Float min <- -11.0
Float max <- 5.0
$ReadOnly[min,max]$
RandomUniform random1 <- RandomUniform.new(min,max)
RandomUniform random2 <- RandomUniform.new(min,max)
Float v1 <- random1.generate()
Float v2 <- random2.generate()
random1 <- random1.setSeed(123)
Float v3 <- random1.generate()
random2 <- random2.setSeed(123)
Float v4 <- random2.generate()
\ Testing.checkNotEquals(v1,v2)
\ Testing.checkNotEquals(v1,v3)
\ Testing.checkEquals(v3,v4)
}
testcase "Randomize tests" {
success
}
unittest permuteFrom {
CategoricalTree<String> tree <- CategoricalTree<String>.new()
.setWeight("a",2)
.setWeight("b",3)
.setWeight("c",1)
Vector<String> expected <- Vector<String>.new()
.append("a")
.append("a")
.append("b")
.append("b")
.append("b")
.append("c")
Vector<String> output <- Vector<String>.new()
\ Randomize:permuteFrom(tree,RandomUniform.new(0.0,1.0),output)
\ Sorting:sort(output)
\ Testing.checkEquals(output.size(),expected.size())
traverse (Counter.zeroIndexed(output.size()) -> Int pos) {
\ Testing.checkEquals(output.readAt(pos),expected.readAt(pos))
}
\ Testing.checkEquals(tree.getWeight("a"),2)
\ Testing.checkEquals(tree.getWeight("b"),3)
\ Testing.checkEquals(tree.getWeight("c"),1)
}
unittest permuteFromWeight {
CategoricalTree<String> tree <- CategoricalTree<String>.new()
.setWeight("a",2)
.setWeight("b",3)
.setWeight("c",1)
Vector<String> expected <- Vector<String>.new()
.append("a")
.append("b")
.append("c")
Vector<String> output <- Vector<String>.new()
\ Randomize:permuteFromWeight(tree,RandomUniform.new(0.0,1.0),output)
\ Sorting:sort(output)
\ Testing.checkEquals(output.size(),expected.size())
traverse (Counter.zeroIndexed(output.size()) -> Int pos) {
\ Testing.checkEquals(output.readAt(pos),expected.readAt(pos))
}
\ Testing.checkEquals(tree.getWeight("a"),2)
\ Testing.checkEquals(tree.getWeight("b"),3)
\ Testing.checkEquals(tree.getWeight("c"),1)
}