feat(matlab): phased days x tDCS LME + Monte-Carlo power analysis
Adds tdcs_phase_lme (same LME refit within learning phases 0-5/6-10/6-13, with per-phase slopes + interaction 95% CI) as phase_* switch cases, and tdcs_power_sim (Monte-Carlo power for the early-phase interaction, scored by the cluster-honest per-animal test and the LME test) + run_power. Findings: the Box-B2 faster-acquisition signal is in the early phase; at n=3-5/group honest power is 0.3-0.7 even at the observed effect (need ~8/group if effect is as observed, ~20/group if half). Adds tPhasePower tests. Suite 35/35. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
classdef tPhasePower < matlab.unittest.TestCase
|
||||
%TPHASEPOWER Tests for the phased days x tDCS LME (tdcs_phase_lme) and the
|
||||
% Monte-Carlo power analysis (tdcs_power_sim).
|
||||
|
||||
methods (Test)
|
||||
|
||||
function testPhaseEarlyFasterAndSlowDown(testCase)
|
||||
% Early phase: Box-B2 slope > Box-A2 slope (faster acquisition) and
|
||||
% strong learning; late phase: shallower slopes (fast->slow).
|
||||
cfg = tdcs_config();
|
||||
evalc('P = tdcs_phase_lme(''mergeA2'', cfg);'); % run in-workspace, suppress print
|
||||
early = P.phases{1}; % [0 5]
|
||||
late = P.phases{2}; % [6 10]
|
||||
testCase.verifyEqual(early.phase, [0 5]);
|
||||
testCase.verifyGreaterThan(early.b2Slope, early.a2Slope); % B2 faster early
|
||||
testCase.verifyLessThan(early.dayP, 0.01); % strong early learning
|
||||
testCase.verifyGreaterThan(early.b2Slope, late.b2Slope); % slow-down (fast->slow)
|
||||
testCase.verifyGreaterThan(early.interEst, 0); % positive interaction
|
||||
end
|
||||
|
||||
function testPhaseSwitchWritesResults(testCase)
|
||||
here = fileparts(fileparts(mfilename('fullpath'))); % analysis/matlab
|
||||
outFile = fullfile(here, 'results', 'phase_mergeA2.txt');
|
||||
if exist(outFile, 'file'); delete(outFile); end
|
||||
evalc("tdcs_glm('phase_mergeA2')");
|
||||
testCase.verifyTrue(exist(outFile, 'file') == 2);
|
||||
end
|
||||
|
||||
function testPowerMonotonicAndBounded(testCase)
|
||||
% Small, fast config: power rises with N and stays in [0,1].
|
||||
cfg = tdcs_config();
|
||||
PW = tdcs_power_sim('mergeA2', [0 5], [4 24], 1.0, 30, cfg);
|
||||
testCase.verifyTrue(all(PW.powerPerAnimal >= 0 & PW.powerPerAnimal <= 1));
|
||||
testCase.verifyTrue(all(PW.powerLME >= 0 & PW.powerLME <= 1));
|
||||
pSmall = PW.powerPerAnimal(PW.N == 4);
|
||||
pLarge = PW.powerPerAnimal(PW.N == 24);
|
||||
testCase.verifyGreaterThan(pLarge, pSmall); % more subjects -> more power
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user