diff --git a/src/nyx/features/3d_ngldm.cpp b/src/nyx/features/3d_ngldm.cpp index 52532f0d..fa5c8145 100644 --- a/src/nyx/features/3d_ngldm.cpp +++ b/src/nyx/features/3d_ngldm.cpp @@ -305,17 +305,22 @@ void D3_NGLDM_feature::calc_features(const std::vector& Sg, const std::v f_GLNUN += sj * sj; // Grey Level Non Uniformity Normalised } - for (int i = 0; i < Ng; ++i) + // FIX (bug): DCNU/DCNUN summed the GREY-LEVEL (row) marginal s_{i.}=sum_j s_ij (outer loop over i, + // inner sum over j) -- byte-identical to the GLNU loop above, so DCNU==GLNU always. DCNU is the + // DEPENDENCE-COUNT (column) marginal: s_{.j}=sum_i s_ij, then sum_j s_{.j}^2. Transpose the loops + // (outer over dependence-count columns j, inner sum over grey levels i), matching the row-marginal's + // j in [1,Nr) convention. (The 2D twin ngldm.cpp is already correct via separate Sg/Sr arrays.) + for (int j = 1; j < Nr; ++j) // FIX: outer loop is now the dependence-count column j { - // Aggregate nonzero dependencies at each grey level - double si = 0; - for (int j = 1; j < Nr; ++j) // note: j \in [1,Nr) due to considering only nonzero dependencies + // Aggregate over grey levels at each dependence count + double scol = 0; // FIX: column marginal s_{.j} + for (int i = 0; i < Ng; ++i) // FIX: sum over grey levels i { double sij = NGLDM.yx(i, j); - si += sij; + scol += sij; } - f_DCNU += si * si; // Dependence Count Non Uniformity - f_DCNUN += si * si; // Dependence Count Non Uniformity Normalised + f_DCNU += scol * scol; // FIX: Dependence Count Non Uniformity = sum_j s_{.j}^2 + f_DCNUN += scol * scol; // FIX: Dependence Count Non Uniformity Normalised } for (int i = 0; i < Ng; ++i) diff --git a/tests/test_3d_coverage_common.h b/tests/test_3d_coverage_common.h index 248caf30..111a8480 100644 --- a/tests/test_3d_coverage_common.h +++ b/tests/test_3d_coverage_common.h @@ -392,8 +392,8 @@ static const std::map>& unvetted_3d_local_regre { "3NGLDM_DCENE", { 0.14348407632898436 } }, { "3NGLDM_DCENT", { 5.2277449211654039 } }, { "3NGLDM_DCM", { 13.485998122653307 } }, - { "3NGLDM_DCNU", { 115443.18172715895 } }, - { "3NGLDM_DCNUN", { 0.22575716076180957 } }, + { "3NGLDM_DCNU", { 85056.840050062572 } }, // FIXED: was 115443.18172715895 (== GLNU, a transposed-marginal bug in 3d_ngldm.cpp) + { "3NGLDM_DCNUN", { 0.16633455892143026 } }, // FIXED: was 0.22575716076180957 (== GLNUN, same bug) { "3NGLDM_DCP", { 1 } }, { "3NGLDM_DCV", { 86.17064428912758 } }, { "3NGLDM_GLM", { 16.955115769712151 } }, diff --git a/tests/test_3d_ngldm_ibsi.h b/tests/test_3d_ngldm_ibsi.h index 75a3340b..00e61f66 100644 --- a/tests/test_3d_ngldm_ibsi.h +++ b/tests/test_3d_ngldm_ibsi.h @@ -18,8 +18,8 @@ static std::unordered_map d3ngldm_GT{ { "3NGLDM_HDHGLE", 20030.0 }, { "3NGLDM_GLNU", 115443.0 }, { "3NGLDM_GLNUN", 0.23 }, - { "3NGLDM_DCNU", 115443.0 }, - { "3NGLDM_DCNUN", 0.23 }, + { "3NGLDM_DCNU", 85056.8 }, // FIXED: was 115443 (== GLNU) -- transposed-marginal bug in 3d_ngldm.cpp + { "3NGLDM_DCNUN", 0.166335 }, // FIXED: was 0.23 (== GLNUN), same bug { "3NGLDM_DCP", 1.0 }, { "3NGLDM_GLM", 17.0 }, { "3NGLDM_GLV", 190.0 },