use super::Tensor;
use crate::{
approx::{approx_eq, ApproxEquality, RelativeEq},
nn::tensors::TensorGrad,
};
use tensor_optim::TensorOps;
fn __percentage_correct<const D: usize, const N: usize>(
output: &Tensor<D, N>,
target: &Tensor<D, N>,
) -> f64 {
let mut correct = 0f64;
for (a, b) in output.data().iter().zip(target.data().iter()) {
let prec = (a - b).approx_eq(&0.0);
if prec == ApproxEquality::Precise {
correct += 1.0;
} else if prec == ApproxEquality::Partial {
correct += 0.5;
} else if prec == ApproxEquality::Relative {
correct += 0.25;
} else if (a - b).abs() < 0.1 {
correct += 0.05;
}
}
(correct * 100.0) / (target.len() as f64)
}
#[must_use]
#[cfg(feature = "dyntensor")]
pub fn percentage_correct(output: &Tensor<0, 0>, target: &Tensor<0, 0>) -> f64 {
__percentage_correct::<0, 0>(output, target)
}
#[must_use]
#[cfg(not(feature = "dyntensor"))]
pub fn percentage_correct<const D: usize, const N: usize>(
output: &Tensor<D, N>,
target: &Tensor<D, N>,
) -> f64 {
__percentage_correct::<D, N>(output, target)
}
fn __accuracy_of<const D: usize, const N: usize>(
output: &Tensor<D, N>,
target: &Tensor<D, N>,
) -> f64 {
let mut correct = 0f64;
for (a, b) in output.data().iter().zip(target.data().iter()) {
if approx_eq(a, b) {
correct += 1.0;
}
}
(correct * 100.0) / (target.len().min(output.len()) as f64)
}
#[must_use]
#[cfg(feature = "dyntensor")]
pub fn accuracy_of(output: &Tensor<0, 0>, target: &Tensor<0, 0>) -> f64 {
__accuracy_of::<0, 0>(output, target)
}
#[must_use]
#[cfg(not(feature = "dyntensor"))]
pub fn accuracy_of<const D: usize, const N: usize>(
output: &Tensor<D, N>,
target: &Tensor<D, N>,
) -> f64 {
__accuracy_of::<D, N>(output, target)
}