64 template <
typename T, TDataAssociationMetric METRIC>
76 std::vector<size_t> indices_pred(
78 std::vector<size_t> indices_obs(N);
86 indices_obs[i] = it->first;
87 indices_pred[i] = it->second;
96 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> COV;
97 Y_predictions_cov.extractSubmatrixSymmetricalBlocks(
106 Eigen::Matrix<T, Eigen::Dynamic, 1> innovations(N * info.
length_O);
107 T* dst_ptr = &innovations[0];
112 const T* pred_i_mean = Y_predictions_mean.get_unsafe_row(it->second);
113 const T* obs_i_mean = Z_observations_mean.get_unsafe_row(it->first);
115 for (
unsigned int k = 0; k < info.
length_O; k++)
116 *dst_ptr++ = pred_i_mean[k] - obs_i_mean[k];
121 COV.inv_fast(COV_inv);
131 const T cov_det = COV.det();
132 const double ml = exp(-0.5 * d2) / (std::pow(
M_2PI, info.
length_O * 0.5) *
137 template <TDataAssociationMetric METRIC>
159 template <
typename T, TDataAssociationMetric METRIC>
174 results.distance = joint_pdf_metric<T, METRIC>(
175 Z_observations_mean, Y_predictions_mean, Y_predictions_cov,
184 const double d2 = joint_pdf_metric<T, METRIC>(
185 Z_observations_mean, Y_predictions_mean, Y_predictions_cov,
188 if (isCloser<METRIC>(d2,
results.distance))
200 const size_t nPreds =
results.indiv_compatibility.rows();
207 const size_t potentials = std::accumulate(
208 results.indiv_compatibility_counts.begin() + (obsIdx + 1),
209 results.indiv_compatibility_counts.end(), 0);
216 if (
results.indiv_compatibility(predIdx, obsIdx))
219 bool already_asigned =
false;
224 if (itS->second == predIdx)
226 already_asigned =
true;
231 if (!already_asigned)
237 results.nNodesExploredInJCBB++;
239 JCBB_recursive<T, METRIC>(
240 Z_observations_mean, Y_predictions_mean,
241 Y_predictions_cov,
results, new_info,
255 results.nNodesExploredInJCBB++;
256 JCBB_recursive<T, METRIC>(
257 Z_observations_mean, Y_predictions_mean, Y_predictions_cov,
310 const bool DAT_ASOC_USE_KDTREE,
311 const std::vector<prediction_index_t>& predictions_IDs,
313 const double log_ML_compat_test_threshold)
324 const size_t nPredictions = Y_predictions_mean.rows();
325 const size_t nObservations = Z_observations_mean.rows();
327 const size_t length_O = Z_observations_mean.cols();
331 ASSERT_(length_O == (
size_t)Y_predictions_mean.cols());
332 ASSERT_(length_O * nPredictions == (
size_t)Y_predictions_cov.rows());
333 ASSERT_(Y_predictions_cov.isSquare());
334 ASSERT_(chi2quantile > 0 && chi2quantile < 1);
341 using KDTreeMatrixPtr =
342 std::unique_ptr<KDTreeEigenMatrixAdaptor<CMatrixDouble>>;
343 KDTreeMatrixPtr kd_tree;
344 const size_t N_KD_RESULTS = nPredictions;
345 std::vector<double> kd_result_distances(
346 DAT_ASOC_USE_KDTREE ? N_KD_RESULTS : 0);
347 std::vector<CMatrixDouble::Index> kd_result_indices(
348 DAT_ASOC_USE_KDTREE ? N_KD_RESULTS : 0);
349 std::vector<double> kd_queryPoint(DAT_ASOC_USE_KDTREE ? length_O : 0);
351 if (DAT_ASOC_USE_KDTREE)
354 kd_tree = KDTreeMatrixPtr(
new KDTreeEigenMatrixAdaptor<CMatrixDouble>(
355 length_O, Y_predictions_mean));
360 (metric ==
metricML) ? 0 : std::numeric_limits<double>::max();
365 results.indiv_distances.resize(nPredictions, nObservations);
366 results.indiv_compatibility.setSize(nPredictions, nObservations);
367 results.indiv_compatibility_counts.assign(nObservations, 0);
372 results.indiv_compatibility.fillAll(
false);
376 Eigen::VectorXd diff_means_i_j(length_O);
378 for (
size_t j = 0; j < nObservations; ++j)
380 if (!DAT_ASOC_USE_KDTREE)
383 for (
size_t i = 0; i < nPredictions; ++i)
386 const size_t pred_cov_idx =
388 Y_predictions_cov.extractMatrix(
389 pred_cov_idx, pred_cov_idx, length_O, length_O, pred_i_cov);
391 for (
size_t k = 0; k < length_O; k++)
392 diff_means_i_j[k] = Z_observations_mean.get_unsafe(j, k) -
393 Y_predictions_mean.get_unsafe(i, k);
399 diff_means_i_j, pred_i_cov, d2, ml);
407 const bool IC = (compatibilityTestMetric ==
metricML)
408 ? (ml > log_ML_compat_test_threshold)
410 results.indiv_compatibility(i, j) = IC;
411 if (IC)
results.indiv_compatibility_counts[j]++;
417 for (
size_t k = 0; k < length_O; k++)
418 kd_queryPoint[k] = Z_observations_mean.get_unsafe(j, k);
421 &kd_queryPoint[0], N_KD_RESULTS, &kd_result_indices[0],
422 &kd_result_distances[0]);
425 for (
size_t w = 0;
w < N_KD_RESULTS;
w++)
427 const size_t i = kd_result_indices[
w];
432 const size_t pred_cov_idx =
434 Y_predictions_cov.extractMatrix(
435 pred_cov_idx, pred_cov_idx, length_O, length_O, pred_i_cov);
437 for (
size_t k = 0; k < length_O; k++)
438 diff_means_i_j[k] = Z_observations_mean.get_unsafe(j, k) -
439 Y_predictions_mean.get_unsafe(i, k);
445 diff_means_i_j, pred_i_cov, d2, ml);
447 if (d2 > 6 * chi2thres)
457 const bool IC = (compatibilityTestMetric ==
metricML)
458 ? (ml > log_ML_compat_test_threshold)
460 results.indiv_compatibility(i, j) = IC;
461 if (IC)
results.indiv_compatibility_counts[j]++;
467 cout <<
"Distances: " << endl <<
results.indiv_distances << endl;
486 using TListAllICs = multimap<
490 TListAllICs lst_all_ICs;
494 multimap<double, prediction_index_t> ICs;
498 if (
results.indiv_compatibility.get_unsafe(i, j))
500 double d2 =
results.indiv_distances.get_unsafe(i, j);
502 ICs.insert(make_pair(d2, i));
508 const double best_dist = ICs.begin()->first;
509 lst_all_ICs.insert(make_pair(best_dist, make_pair(j, ICs)));
517 std::set<prediction_index_t> lst_already_taken_preds;
520 it != lst_all_ICs.end(); ++it)
523 const multimap<double, prediction_index_t>& lstCompats =
528 itP != lstCompats.end(); ++itP)
530 if (lst_already_taken_preds.find(itP->second) ==
531 lst_already_taken_preds.end())
534 results.associations[obs_id] = itP->second;
535 lst_already_taken_preds.insert(itP->second);
555 JCBB_recursive<CMatrixDouble::Scalar, metricMaha>(
556 Z_observations_mean, Y_predictions_mean, Y_predictions_cov,
559 JCBB_recursive<CMatrixDouble::Scalar, metricML>(
560 Z_observations_mean, Y_predictions_mean, Y_predictions_cov,
571 if (!predictions_IDs.empty())
573 ASSERT_(predictions_IDs.size() == nPredictions);
576 itAssoc !=
results.associations.end(); ++itAssoc)
577 itAssoc->second = predictions_IDs[itAssoc->second];
593 const bool DAT_ASOC_USE_KDTREE,
594 const std::vector<prediction_index_t>& predictions_IDs,
596 const double log_ML_compat_test_threshold)
602 const size_t nPredictions = Y_predictions_mean.rows();
603 const size_t nObservations = Z_observations_mean.rows();
605 const size_t length_O = Z_observations_mean.cols();
609 ASSERT_(length_O == (
size_t)Y_predictions_mean.cols());
611 length_O * nPredictions == (
size_t)Y_predictions_cov_stacked.rows());
612 ASSERT_(chi2quantile > 0 && chi2quantile < 1);
618 length_O * nPredictions, length_O * nPredictions);
620 for (
size_t i = 0; i < nPredictions; i++)
622 const size_t idx = i * length_O;
623 Y_predictions_cov_stacked.extractSubmatrix(
624 idx, idx + length_O - 1, 0, length_O - 1, COV_i);
625 Y_predictions_cov_full.insertMatrix(idx, idx, COV_i);
629 Z_observations_mean, Y_predictions_mean, Y_predictions_cov_full,
630 results, method, metric, chi2quantile, DAT_ASOC_USE_KDTREE,
631 predictions_IDs, compatibilityTestMetric, log_ML_compat_test_threshold);