fix(matlab): report learning rate via per-animal slope test, not anticonservative GLMM F-test

fitglme coefTest only offers observation-level DF (df2~=178), which overstates
the group x day interaction significance for this few-subject design (p~=0 in
every scenario). Replace the reported learning-rate result with a cluster-honest
per-animal slope test (per-subject OLS slope of success vs day, Welch + MWU,
B2 vs A2) -- now correctly parallel in all 6 scenarios, matching the Python GEE.
The GLMM F-test is kept as a flagged reference only. Adds a regression test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Experiments DB Dev
2026-07-20 08:40:47 -04:00
parent 13414d31fc
commit b1057f6105
3 changed files with 70 additions and 9 deletions
+16
View File
@@ -117,5 +117,21 @@ classdef tModels < matlab.unittest.TestCase
testCase.verifyFalse(metam.isUnmerged);
testCase.verifyEmpty(fieldnames(Rm.classify));
end
function testLearningPerAnimalSlopesParallel(testCase)
% The reported learning-rate result is a per-animal slope test and
% must show parallel learning (non-significant) -- matching the
% Python's cluster-robust conclusion. Guards against regressing to
% the anticonservative GLMM interaction F-test (which reads p~=0).
cfg = tdcs_config();
for sc = {'unmerged_full', 'mergeA2_full', 'mergeB2_full'}
[S, meta] = tdcs_scenario_data(sc{1});
R = tdcs_models(S, meta, cfg);
testCase.verifyGreaterThan(R.learn.slopeMWUp, 0.05, ...
sprintf('%s: per-animal learning slopes should be parallel (MWU p>0.05)', sc{1}));
testCase.verifyGreaterThan(R.learn.slopeWelchP, 0.05, ...
sprintf('%s: per-animal learning slopes should be parallel (Welch p>0.05)', sc{1}));
end
end
end
end