///|
pub(all) struct FrameDelta {
changed : Int
mean_absolute : Double
maximum_absolute : Double
normalized : Double
} derive(Debug, Eq, ToJson)
///|
pub fn ThermalMatrix::delta(
a : ThermalMatrix,
b : ThermalMatrix,
) -> FrameDelta raise ThermalError {
if a.width != b.width || a.height != b.height {
raise InvalidDimensions(
width=a.width,
height=a.height,
values=b.values.length(),
)
}
let mut changed = 0
let mut sum = 0.0
let mut maximum = 0.0
for i in 0.. 0.0 {
changed += 1
}
sum = sum + difference
maximum = Double::max(maximum, difference)
}
let total = a.values.length().to_double()
{
changed,
mean_absolute: sum / total,
maximum_absolute: maximum,
normalized: changed.to_double() / total,
}
}
///|
pub(all) struct Trend {
slope : Double
intercept : Double
first : Double
last : Double
direction : Int
} derive(Debug, Eq, ToJson)
///|
pub fn trend(values : Array[Double]) -> Trend {
if values.is_empty() {
return { slope: 0.0, intercept: 0.0, first: 0.0, last: 0.0, direction: 0 }
}
let n = values.length().to_double()
let sx = (n - 1.0) * n / 2.0
let sxx = (n - 1.0) * n * (2.0 * n - 1.0) / 6.0
let sy = values.fold(init=0.0, fn(a, b) { a + b })
let mut sxy = 0.0
for i, value in values {
sxy = sxy + i.to_double() * value
}
let denominator = n * sxx - sx * sx
let slope = if denominator == 0.0 {
0.0
} else {
(n * sxy - sx * sy) / denominator
}
let intercept = (sy - slope * sx) / n
{
slope,
intercept,
first: values[0],
last: values[values.length() - 1],
direction: if slope > 0.0 {
1
} else if slope < 0.0 {
-1
} else {
0
},
}
}
///|
pub fn ThermalMatrix::row_trends(
matrix : ThermalMatrix,
) -> Array[Trend] raise ThermalError {
let result : Array[Trend] = []
for y in 0.. Array[Trend] {
let result : Array[Trend] = []
for x in 0..