///|
pub fn validate_same_length(
first : Array[Double],
second : Array[Double],
) -> Bool {
first.length() == second.length()
}
///|
pub fn validate_non_empty(data : Array[Double]) -> Bool {
data.length() > 0
}
///|
pub fn validate_window(window : Int, data_length : Int) -> Bool {
window > 0 && data_length >= 0
}
///|
pub fn validate_trim_percent_value(trim_percent : Double) -> Bool {
trim_percent >= 0.0 && trim_percent < 0.5
}
///|
pub fn validate_probability_value(probability : Double) -> Bool {
probability >= 0.0 && probability <= 1.0
}
///|
pub fn validate_weights(weights : Array[Double]) -> Bool {
for weight in weights {
if weight < 0.0 {
return false
}
}
true
}
///|
pub fn validate_matrix(matrix : Array[Array[Double]]) -> Bool {
if matrix.length() == 0 {
return true
}
let width = matrix[0].length()
for row in matrix {
if row.length() != width {
return false
}
}
true
}
///|
pub fn validate_square_matrix(matrix : Array[Array[Double]]) -> Bool {
validate_matrix(matrix) &&
(matrix.length() == 0 || matrix[0].length() == matrix.length())
}
///|
pub fn validate_finite_range(
data : Array[Double],
lower : Double,
upper : Double,
) -> Bool {
if lower > upper {
return false
}
for value in data {
if value < lower || value > upper {
return false
}
}
true
}
///|
pub fn validate_sorted(data : Array[Double]) -> Bool {
is_sorted_non_decreasing(data) || is_sorted_non_increasing(data)
}
///|
pub fn validate_confidence_value(confidence : Double) -> Bool {
confidence > 0.0 && confidence < 1.0
}
///|
pub fn validate_positive(value : Double) -> Bool {
value > 0.0
}
///|
pub fn validate_non_negative(value : Double) -> Bool {
value >= 0.0
}
///|
pub fn validate_count(value : Int) -> Bool {
value >= 0
}
///|
pub fn validate_cluster_configuration(
cluster_count : Int,
max_iter : Int,
tol : Double,
) -> Bool {
cluster_count > 0 && max_iter > 0 && tol > 0.0
}
///|
pub fn validate_regression_inputs(x : Array[Double], y : Array[Double]) -> Bool {
x.length() > 0 && x.length() == y.length()
}
///|
pub fn validate_bootstrap_configuration(
data : Array[Double],
replicates : Int,
sample_size : Int,
) -> Bool {
data.length() > 0 && replicates > 0 && sample_size > 0
}
///|
pub fn validate_stream_configuration(capacity : Int, clip : Double) -> Bool {
capacity > 0 && clip > 0.0
}
///|
pub fn validate_detector_configuration(
window : Int,
threshold : Double,
) -> Bool {
window > 0 && threshold > 0.0
}
///|
pub fn validate_probability_grid(probabilities : Array[Double]) -> Bool {
for probability in probabilities {
if !validate_probability_value(probability) {
return false
}
}
true
}
///|
pub fn validate_monotone_grid(values : Array[Double]) -> Bool {
is_sorted_non_decreasing(values)
}
///|
pub fn validate_no_empty_rows(matrix : Array[Array[Double]]) -> Bool {
for row in matrix {
if row.length() == 0 {
return false
}
}
true
}
///|
pub fn validation_score(data : Array[Double]) -> Double {
if data.length() == 0 {
return 0.0
}
let checks = [
validate_non_empty(data),
validate_sorted(data),
is_constant(data),
validate_non_negative(mad(data)),
validate_non_negative(interquartile_range(data)),
]
let mut passed = 0
for check in checks {
if check {
passed += 1
}
}
passed.to_double() / checks.length().to_double()
}
///|
pub fn robust_input_score(data : Array[Double]) -> Double {
if data.length() == 0 {
0.0
} else {
1.0 - outlier_fraction(outlier_indices_z(data), data.length())
}
}
///|
pub fn compare_input_scores(
first : Array[Double],
second : Array[Double],
) -> Double {
robust_input_score(first) - robust_input_score(second)
}
///|
pub fn validation_report(data : Array[Double]) -> Array[Double] {
[
validation_score(data),
robust_input_score(data),
duplicate_fraction(data),
monotonicity_score(data),
zero_fraction(data),
]
}