float ColorHistogram::KLDivergence(const ColorHistogram& rhs) const { DCHECK(IsNormalized() && rhs.IsNormalized()); const double eps = 1e-10; return 0.5 * GenericDistance(rhs, [eps](float a, float b) -> float { const double ratio = (a + eps) / (b + eps); return a * std::log(ratio) + b * std::log(1.0 / ratio); }); }
float ColorHistogram::JSDivergence(const ColorHistogram& rhs) const { DCHECK(IsNormalized() && rhs.IsNormalized()); const double eps = 1e-10; return 0.5 * GenericDistance(rhs, [eps](float a, float b) -> float { const double inv_mean = 1.0 / ((a + b) * 0.5 + eps); const double ratio_a = (a + eps) * inv_mean; const double ratio_b = (b + eps) * inv_mean; return a * std::log(ratio_a) + b * std::log(ratio_b); }); }
float ColorHistogram::ChiSquareDist(const ColorHistogram& rhs) const { DCHECK(IsNormalized() && rhs.IsNormalized()); return 0.5 * GenericDistance(rhs, [](float a, float b) -> float { const float add = a + b; if (fabs(add) > 1e-12) { const float sub = a - b; return sub * sub / add; } else { return 0.0f; } }); }