MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ fit_metric()

FeatureMetric MayaFlux::Kinesis::fit_metric ( std::span< const Eigen::VectorXd >  samples,
const Eigen::VectorXd &  periods = {} 
)
inline

Derive per-axis metric weights from the spread of a sample set.

Parameters
samplesObservations, all of the same dimension
periodsPer-axis wrap periods, or an empty vector for none
Returns
A metric whose weights are the reciprocal of each axis's standard deviation, so one standard deviation on any axis contributes equally to distance

The answer to incommensurate units when a corpus is available: rather than the caller guessing that pressure should count twice as much as speed, the weights come from how much each axis actually varied across the observations. An axis with no variation gets unit weight rather than an infinite one.

Definition at line 240 of file FeatureExtent.hpp.

242 {})
243{
244 if (samples.empty())
245 return {};
246
247 const Eigen::Index n = samples.front().size();
248 Eigen::VectorXd mean = Eigen::VectorXd::Zero(n);
249 for (const auto& s : samples)
250 mean += s;
251 mean /= static_cast<double>(samples.size());
252
253 Eigen::VectorXd var = Eigen::VectorXd::Zero(n);
254 for (const auto& s : samples) {
255 const Eigen::VectorXd d = s - mean;
256 var += d.cwiseProduct(d);
257 }
258 var /= static_cast<double>(samples.size());
259
260 Eigen::VectorXd weights(n);
261 for (Eigen::Index i = 0; i < n; ++i) {
262 const double sd = std::sqrt(var(i));
263 weights(i) = (sd > 1e-12) ? (1.0 / sd) : 1.0;
264 }
265
266 return { .weights = weights,
267 .periods = (periods.size() == n) ? periods : Eigen::VectorXd::Zero(n) };
268}