19 MatrixXf CDF_matrix(data.rows(), data.cols() + 1);
25 for (
unsigned col_id = 0; col_id != data.cols(); ++col_id) {
31 std::sort(
indices.begin(),
indices.end(), [col=data.col(col_id)](
unsigned first,
unsigned second) {
32 return col(first) < col(second);
36 unsigned last_pos = data.rows() - 1;
37 float last_value = data(indices[last_pos], col_id);
38 unsigned num_same = 0;
39 for (
unsigned i = data.rows(); i-->0;) {
40 if (data(indices[i], col_id) != last_value) {
41 last_value = data(indices[i], col_id);
45 CDF_matrix(indices[i], col_id) = float(last_pos + 1) / data.rows();
51 CDF_matrix.col(data.cols()) = VectorXf::Ones(data.rows());
58template<
typename URBG>
59MatrixXf create_w_b(
float stddev,
unsigned num_rows,
unsigned k, URBG &&g)
61 std::normal_distribution<float> normal_distribution(0.f, stddev);
62 MatrixXf w_b(num_rows, k);
63 for (
unsigned col_id = 0; col_id != k; ++col_id) {
64 auto col = w_b.col(col_id);
65 for (
unsigned row_id = 0; row_id != num_rows; ++row_id)
66 col(row_id) = normal_distribution(g);
78float m::rdc(
const Eigen::MatrixXf &
X,
const Eigen::MatrixXf &Y,
unsigned k,
float stddev)
87 M_insist(CDFs_of_X.cols() ==
X.cols() + 1);
88 M_insist(CDFs_of_Y.cols() == Y.cols() + 1);
93template<
typename URBG>
96 unsigned num_rows = CDFs_of_X.rows();
97 M_insist(num_rows == CDFs_of_Y.rows());
100 MatrixXf X_w_b = create_w_b(stddev, CDFs_of_X.cols(), k, g);
101 MatrixXf Y_w_b = create_w_b(stddev, CDFs_of_Y.cols(), k, g);
102 M_insist(X_w_b.rows() == CDFs_of_X.cols());
103 M_insist(Y_w_b.rows() == CDFs_of_Y.cols());
108 MatrixXf concat_matrix(CDFs_of_X.rows(), 2 * k);
109 concat_matrix << (CDFs_of_X * X_w_b), (CDFs_of_Y * Y_w_b);
110 concat_matrix.array() = concat_matrix.array().sin();
113 const RowVectorXf means = concat_matrix.colwise().mean();
114 concat_matrix.rowwise() -= means;
117 MatrixXf covariance_matrix = concat_matrix.adjoint() * concat_matrix / float(num_rows - 1);
119 FullPivLU<MatrixXf> CXX(covariance_matrix.block(0, 0, k, k));
120 FullPivLU<MatrixXf> CYY(covariance_matrix.block(k, k, k, k));
121 MatrixXf CXY = covariance_matrix.block(0, k, k, k);
122 MatrixXf CYX = covariance_matrix.block(k, 0, k, k);
124 SelfAdjointEigenSolver<MatrixXf> eigensolver((CXX.inverse() * CXY) * (CYY.inverse() * CYX));
126 return sqrtf(eigensolver.eigenvalues().maxCoeff());
Eigen::MatrixXf create_CDF_matrix(const Eigen::MatrixXf &data)
Creates a new matrix, mapping every cell of data to its position according to the cell's column's CDF...
float rdc(const Eigen::MatrixXf &X, const Eigen::MatrixXf &Y, unsigned k=5, float stddev=1.f/6.f)
Compute the Randomized Dependence Coefficient of two random variables.
float rdc_precomputed_CDF(Eigen::MatrixXf &CDFs_of_X, Eigen::MatrixXf &CDFs_of_Y, unsigned k=5, float stddev=1.f/6.f, URBG &&g=URBG())
Compute the RDC value without having to compute CDF matrices to avoid sorting the same data multiple ...