///|
pub(all) struct Summary {
total : Int32
finite_count : Int32
nonfinite_count : Int32
minimum : Double?
maximum : Double?
mean : Double?
population_variance : Double?
rms : Double?
} derive(Eq, Debug)
///|
pub fn DataObject::summary(self : DataObject) -> Summary raise TdmsError {
demand(
self.kind is Some(k) && k != Text && k != Time,
"summary requires a numeric channel",
)
let mut n = 0
let mut lo = 1.0 / 0.0
let mut hi = -(1.0 / 0.0)
let mut mean = 0.0
let mut m2 = 0.0
let mut scale = 0.0
let mut squares = 0.0
let kind = self.kind.unwrap()
for value in self.values {
value.validate(kind)
let x = value.as_double()
if !finite(x) {
continue
}
n += 1
if x < lo {
lo = x
}
if x > hi {
hi = x
}
let delta = x - mean
mean += delta / n.to_double()
m2 += delta * (x - mean)
demand(finite(mean) && finite(m2), "numeric summary overflow")
let magnitude = x.abs()
if magnitude > 0.0 {
if scale < magnitude {
let ratio = scale / magnitude
squares = 1.0 + squares * ratio * ratio
scale = magnitude
} else {
let ratio = magnitude / scale
squares += ratio * ratio
}
}
}
let has = n > 0
{
total: self.values.length(),
finite_count: n,
nonfinite_count: self.values.length() - n,
minimum: if has {
Some(lo)
} else {
None
},
maximum: if has {
Some(hi)
} else {
None
},
mean: if has {
Some(mean)
} else {
None
},
population_variance: if has {
Some(m2 / n.to_double())
} else {
None
},
rms: if has {
Some(scale * (squares / n.to_double()).sqrt())
} else {
None
},
}
}
///|
pub extend Summary with Eq::{equal, not_equal}
///|
pub extend Summary with @debug.Debug::{to_repr}