///|
pub(all) struct SpectrumBin {
mode : Int
frequency : Double
real : Double
imaginary : Double
power : Double
} derive(Debug, ToJson)
///|
pub fn discrete_spectrum(signal : ArrayView[Double]) -> Array[SpectrumBin] {
let n = signal.length()
let output : Array[SpectrumBin] = []
for mode in 0.. Int {
if spectrum.length() == 0 {
0
} else {
let mut index = 0
let mut power = spectrum[0].power
let upper = spectrum.length() / 2 + 1
for i in 1.. power {
power = spectrum[i].power
index = i
}
}
index
}
}
///|
pub fn power_spectrum(signal : ArrayView[Double]) -> Array[Double] {
discrete_spectrum(signal).map(fn(bin) { bin.power })
}
///|
pub fn autocorrelation(signal : ArrayView[Double], lag : Int) -> Double {
if signal.length() == 0 || lag < 0 || lag >= signal.length() {
0.0
} else {
let mut total = 0.0
let mut count = 0
for i in 0..<(signal.length() - lag) {
total = total + signal[i] * signal[i + lag]
count = count + 1
}
total / count.to_double()
}
}
///|
pub fn autocorrelation_series(signal : ArrayView[Double]) -> Array[Double] {
Array::makei(signal.length(), fn(lag) { autocorrelation(signal, lag) })
}
///|
pub fn mean_subtract(signal : ArrayView[Double]) -> Array[Double] {
let average = mean(signal)
signal.map(fn(value) { value - average })
}
///|
pub fn hann_window(signal : ArrayView[Double]) -> Array[Double] {
let n = signal.length()
Array::makei(n, fn(i) {
let factor = if n <= 1 {
1.0
} else {
0.5 - 0.5 * @math.cos(2.0 * pi * i.to_double() / (n - 1).to_double())
}
signal[i] * factor
})
}
///|
pub fn spectral_centroid(spectrum : ArrayView[SpectrumBin]) -> Double {
let denominator = spectrum.fold(init=0.0, fn(acc, bin) { acc + bin.power })
if denominator == 0.0 {
0.0
} else {
spectrum.fold(init=0.0, fn(acc, bin) { acc + bin.frequency * bin.power }) /
denominator
}
}
///|
pub fn spectrum_band_power(
spectrum : ArrayView[SpectrumBin],
low : Double,
high : Double,
) -> Double {
spectrum.fold(init=0.0, fn(acc, bin) {
if bin.frequency >= low && bin.frequency <= high {
acc + bin.power
} else {
acc
}
})
}
///|
pub fn spectrum_to_csv(spectrum : ArrayView[SpectrumBin]) -> String {
let output = StringBuilder()
output.write_string("mode,frequency,real,imaginary,power\n")
for bin in spectrum {
output.write_string(
"\{bin.mode},\{bin.frequency},\{bin.real},\{bin.imaginary},\{bin.power}\n",
)
}
output.to_string()
}