///|
pub(all) struct SeriesSummary {
name : String
count : Int
minimum : Double
maximum : Double
mean : Double
rms : Double
span : Double
} derive(Debug, ToJson)
///|
pub fn summarize_series(
name : String,
values : ArrayView[Double],
) -> SeriesSummary {
{
name,
count: values.length(),
minimum: min_value(values, 0.0),
maximum: max_value(values, 0.0),
mean: mean(values),
rms: series_rms(values),
span: series_range(values),
}
}
///|
pub fn summary_to_csv(summary : SeriesSummary) -> String {
"name,count,minimum,maximum,mean,rms,span\n\{summary.name},\{summary.count},\{summary.minimum},\{summary.maximum},\{summary.mean},\{summary.rms},\{summary.span}\n"
}
///|
pub fn percentile(values : ArrayView[Double], fraction : Double) -> Double {
let quantile = sample_quantiles(values, 101)
if quantile.length() == 0 {
0.0
} else {
quantile[clamp_int(
(clamp(fraction, 0.0, 1.0) * 100.0).to_int(),
0,
quantile.length() - 1,
)]
}
}
///|
pub fn median(values : ArrayView[Double]) -> Double {
percentile(values, 0.5)
}
///|
pub fn interquartile_range(values : ArrayView[Double]) -> Double {
percentile(values, 0.75) - percentile(values, 0.25)
}
///|
pub fn z_scores(values : ArrayView[Double]) -> Array[Double] {
let average = mean(values)
let variance = sample_variance(values)
let scale = variance.sqrt()
if scale == 0.0 {
values.map(fn(_) { 0.0 })
} else {
values.map(fn(value) { (value - average) / scale })
}
}
///|
pub fn finite_difference_series(
values : ArrayView[Double],
spacing : Double,
) -> Array[Double] {
let output = zeros(values.length())
if values.length() > 1 {
output[0] = (values[1] - values[0]) / spacing
for i in 1..<(values.length() - 1) {
output[i] = (values[i + 1] - values[i - 1]) / (2.0 * spacing)
}
output[values.length() - 1] = (
values[values.length() - 1] - values[values.length() - 2]
) /
spacing
}
output
}
///|
pub fn cumulative_series(
values : ArrayView[Double],
spacing : Double,
) -> Array[Double] {
let output = zeros(values.length())
for i in 1.. Array[SeriesSummary] {
Array::makei(values.length(), fn(i) {
summarize_series("series_\{i}", values[i])
})
}