the cost correction that pushes apart differently-labeled samples was computed backwards. it used missing_ys = (ys == -1) and the product of the two missing masks, so the large cost was applied only where both labels are missing, and never where two labeled samples have different labels. with all labels known the correction was a no-op, so ys/yt had no effect on the transport (see PythonOT#664). switched to present masks (ys != -1) so the correction applies exactly to labeled source/target pairs whose labels differ, matching the original pre-vectorized loop. restored the semisupervised tests that had been flipped to assert the buggy no-op (n_unsup == n_semisup) back to asserting the cost actually changes, and added a regression test. closes PythonOT#664
rflamary
changed the title
Fix label-aware cost correction in ot.da (closes #664)
[MRG] Fix label-aware cost correction in ot.da (closes #664)
Flastre pushed a commit to Flastre/POT that referenced this pull request
Jul 8, 2026…ythonOT#833) * fix label-aware cost correction in ot.da the cost correction that pushes apart differently-labeled samples was computed backwards. it used missing_ys = (ys == -1) and the product of the two missing masks, so the large cost was applied only where both labels are missing, and never where two labeled samples have different labels. with all labels known the correction was a no-op, so ys/yt had no effect on the transport (see PythonOT#664). switched to present masks (ys != -1) so the correction applies exactly to labeled source/target pairs whose labels differ, matching the original pre-vectorized loop. restored the semisupervised tests that had been flipped to assert the buggy no-op (n_unsup == n_semisup) back to asserting the cost actually changes, and added a regression test. closes PythonOT#664 * add PR number to releases entry * Apply suggestion from @rflamary * use MISSING_LABEL constant instead of bare -1 --------- Co-authored-by: Rémi Flamary <remi.flamary@gmail.com>