⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 teststestunit.pas

📁 maths lib with source
💻 PAS
字号:
unit teststestunit;
interface
uses Math, Ap, Sysutils, gammaf, normaldistr, ibetaf, nearunityunit, binomialdistr, stest;

function TestSignTest(Silent : Boolean):Boolean;
function teststestunit_test_silent():Boolean;
function teststestunit_test():Boolean;

implementation

procedure Generate(N : Integer;
     Med : Double;
     Width : Double;
     var R : TReal1DArray);forward;
procedure GenerateDiscrete(N : Integer;
     Med : Integer;
     Width : Integer;
     var R : TReal1DArray);forward;


function TestSignTest(Silent : Boolean):Boolean;
var
    PassCount : Integer;
    DetailedReport : Boolean;
    SigmaThreshold : Double;
    N : Integer;
    Pass : Integer;
    DTask : Integer;
    NPos : Integer;
    NCnt : Integer;
    NTbl : TInteger1DArray;
    QCnt : Integer;
    BTQTbl : TReal1DArray;
    LRQTbl : TReal1DArray;
    BTSigmaTbl : TReal1DArray;
    LRSigmaTbl : TReal1DArray;
    BTTbl : TReal1DArray;
    LTTbl : TReal1DArray;
    RTTbl : TReal1DArray;
    BT : Double;
    LT : Double;
    RT : Double;
    LPower : Double;
    RPower : Double;
    BPower : Double;
    X : TReal1DArray;
    TmpTestOK : Boolean;
    DTestOK : Boolean;
    CTestOK : Boolean;
    PowerTestOK : Boolean;
    WasErrors : Boolean;
    I : Integer;
    J : Integer;
    K : Integer;
    Med : Integer;
    V : Double;
begin
    WasErrors := False;
    DetailedReport := True;
    PassCount := 20000;
    SigmaThreshold := 5;
    N := 100;
    
    //
    // Prepare place
    //
    SetLength(X, N-1+1);
    
    //
    // Prepare quantiles tables for both-tail test and left/right test.
    // Note that since sign test statistic has discrete distribution
    // we should carefully select quantiles. Equation P(tail<=alpha)=alpha
    // holds only for some specific alpha.
    //
    QCnt := 5;
    SetLength(BTTbl, QCnt-1+1);
    SetLength(LTTbl, QCnt-1+1);
    SetLength(RTTbl, QCnt-1+1);
    SetLength(BTQTbl, QCnt-1+1);
    SetLength(LRQTbl, QCnt-1+1);
    SetLength(BTSigmaTbl, QCnt-1+1);
    SetLength(LRSigmaTbl, QCnt-1+1);
    BTQTbl[0] := 0.272;
    BTQTbl[1] := 0.195;
    BTQTbl[2] := 0.134;
    BTQTbl[3] := 0.057;
    BTQTbl[4] := 0.036;
    I:=0;
    while I<=QCnt-1 do
    begin
        LRQTbl[I] := 0.5*BTQTbl[I];
        Inc(I);
    end;
    I:=0;
    while I<=QCnt-1 do
    begin
        BTSigmaTbl[I] := Sqrt(BTQTbl[I]*(1-BTQTbl[I])/PassCount);
        LRSigmaTbl[I] := Sqrt(LRQTbl[I]*(1-LRQTbl[I])/PassCount);
        Inc(I);
    end;
    
    //
    // Report header
    //
    if  not Silent then
    begin
        Write(Format('TESTING SIGN TEST'#13#10'',[]));
    end;
    
    //
    // Continuous distribuiton test for validity.
    //
    
    //
    // Prepare p-table
    //
    I:=0;
    while I<=QCnt-1 do
    begin
        BTTbl[I] := 0;
        LTTbl[I] := 0;
        RTTbl[I] := 0;
        Inc(I);
    end;
    
    //
    // Fill p-table
    //
    Pass:=1;
    while Pass<=PassCount do
    begin
        Med := RandomInteger(11)-5;
        Generate(N, Med, 1.0, X);
        OneSampleSignTest(X, N, Med, BT, LT, RT);
        I:=0;
        while I<=QCnt-1 do
        begin
            if BT<=BTQTbl[I] then
            begin
                BTTbl[I] := BTTbl[I]+1/PassCount;
            end;
            if LT<=LRQTbl[I] then
            begin
                LTTbl[I] := LTTbl[I]+1/PassCount;
            end;
            if RT<=LRQTbl[I] then
            begin
                RTTbl[I] := RTTbl[I]+1/PassCount;
            end;
            Inc(I);
        end;
        Inc(Pass);
    end;
    
    //
    // Check
    //
    TmpTestOK := True;
    I:=0;
    while I<=QCnt-1 do
    begin
        if AbsReal(BTTbl[I]-BTQTbl[I])/BTSigmaTbl[I]>SigmaThreshold then
        begin
            TmpTestOK := False;
        end;
        if AbsReal(RTTbl[I]-LRQTbl[I])/LRSigmaTbl[I]>SigmaThreshold then
        begin
            TmpTestOK := False;
        end;
        if AbsReal(LTTbl[I]-LRQTbl[I])/LRSigmaTbl[I]>SigmaThreshold then
        begin
            TmpTestOK := False;
        end;
        Inc(I);
    end;
    CTestOK := TmpTestOK;
    
    //
    // Report
    //
    if  not Silent and DetailedReport then
    begin
        Write(Format(''#13#10'CONTINUOUS TEST TABLE'#13#10'',[]));
        Write(Format('Q no.     BT err.   LT err.   RT err.   '#13#10'',[]));
        I:=0;
        while I<=QCnt-1 do
        begin
            Write(Format('%1d         %3.1f std.  %3.1f std.  %3.1f std.  '#13#10'',[
                I+1,
                AbsReal(BTTbl[I]-BTQTbl[I])/BTSigmaTbl[I],
                AbsReal(LTTbl[I]-LRQTbl[I])/LRSigmaTbl[I],
                AbsReal(RTTbl[I]-LRQTbl[I])/LRSigmaTbl[I]]));
            Inc(I);
        end;
        if TmpTestOK then
        begin
            Write(Format('TEST PASSED'#13#10''#13#10'',[]));
        end
        else
        begin
            Write(Format('TEST FAILED'#13#10''#13#10'',[]));
        end;
    end;
    
    //
    // Discrete distribuiton test for validity.
    // Note discrete specifics: due to possible X[i]=Med
    // we can't expect that P(tail<=alpha) = alpha.
    // We can expect only that P(tail<=alpha) <= alpha.
    // So test code is slightly modified.
    //
    
    //
    // Prepare p-table
    //
    I:=0;
    while I<=QCnt-1 do
    begin
        BTTbl[I] := 0;
        LTTbl[I] := 0;
        RTTbl[I] := 0;
        Inc(I);
    end;
    
    //
    // Fill p-table
    //
    Pass:=1;
    while Pass<=PassCount do
    begin
        Med := RandomInteger(11)-5;
        GenerateDiscrete(N, Med, 2, X);
        OneSampleSignTest(X, N, Med, BT, LT, RT);
        I:=0;
        while I<=QCnt-1 do
        begin
            if BT<=BTQTbl[I] then
            begin
                BTTbl[I] := BTTbl[I]+1/PassCount;
            end;
            if LT<=LRQTbl[I] then
            begin
                LTTbl[I] := LTTbl[I]+1/PassCount;
            end;
            if RT<=LRQTbl[I] then
            begin
                RTTbl[I] := RTTbl[I]+1/PassCount;
            end;
            Inc(I);
        end;
        Inc(Pass);
    end;
    
    //
    // Check
    //
    TmpTestOK := True;
    I:=0;
    while I<=QCnt-1 do
    begin
        if (BTTbl[I]-BTQTbl[I])/BTSigmaTbl[I]>SigmaThreshold then
        begin
            TmpTestOK := False;
        end;
        if (RTTbl[I]-LRQTbl[I])/LRSigmaTbl[I]>SigmaThreshold then
        begin
            TmpTestOK := False;
        end;
        if (LTTbl[I]-LRQTbl[I])/LRSigmaTbl[I]>SigmaThreshold then
        begin
            TmpTestOK := False;
        end;
        Inc(I);
    end;
    DTestOK := TmpTestOK;
    
    //
    // Report
    //
    if  not Silent and DetailedReport then
    begin
        Write(Format(''#13#10'DISCRETE TEST TABLE (dont worry, zeros are normal)'#13#10'',[]));
        Write(Format('Q no.     BT err.   LT err.   RT err.   '#13#10'',[]));
        I:=0;
        while I<=QCnt-1 do
        begin
            Write(Format('%1d         %3.1f std.  %3.1f std.  %3.1f std.  '#13#10'',[
                I+1,
                Max((BTTbl[I]-BTQTbl[I])/BTSigmaTbl[I], 0),
                Max((LTTbl[I]-LRQTbl[I])/LRSigmaTbl[I], 0),
                Max((RTTbl[I]-LRQTbl[I])/LRSigmaTbl[I], 0)]));
            Inc(I);
        end;
        if TmpTestOK then
        begin
            Write(Format('TEST PASSED'#13#10''#13#10'',[]));
        end
        else
        begin
            Write(Format('TEST FAILED'#13#10''#13#10'',[]));
        end;
    end;
    
    //
    // Power test
    //
    
    //
    // Prepare p-table
    //
    I:=0;
    while I<=QCnt-1 do
    begin
        BTTbl[I] := 0;
        LTTbl[I] := 0;
        RTTbl[I] := 0;
        Inc(I);
    end;
    
    //
    // Fill p-table
    //
    LPower := 0;
    RPower := 0;
    BPower := 0;
    Pass:=1;
    while Pass<=PassCount do
    begin
        V := 0.7;
        Generate(N, 0.0, 1.0, X);
        OneSampleSignTest(X, N, V, BT, LT, RT);
        if LT<0.05 then
        begin
            LPower := LPower+1/PassCount;
        end;
        OneSampleSignTest(X, N, -V, BT, LT, RT);
        if RT<0.05 then
        begin
            RPower := RPower+1/PassCount;
        end;
        OneSampleSignTest(X, N, V*(2*RandomInteger(2)-1), BT, LT, RT);
        if BT<0.05 then
        begin
            BPower := BPower+1/PassCount;
        end;
        Inc(Pass);
    end;
    
    //
    // Check
    //
    PowerTestOK := (LPower>0.95) and (RPower>0.95) and (BPower>0.95);
    
    //
    // Report
    //
    if  not Silent and DetailedReport then
    begin
        Write(Format(''#13#10'POWER TEST TABLE'#13#10'',[]));
        Write(Format('LEFT-TAIL TEST POWER:  %4.2f'#13#10'',[
            LPower]));
        Write(Format('RIGHT-TAIL TEST POWER: %4.2f'#13#10'',[
            RPower]));
        Write(Format('BOTH-TAIL TEST POWER:  %4.2f'#13#10'',[
            BPower]));
        if PowerTestOK then
        begin
            Write(Format('TEST PASSED'#13#10''#13#10'',[]));
        end
        else
        begin
            Write(Format('TEST FAILED'#13#10''#13#10'',[]));
        end;
    end;
    
    //
    // Final report
    //
    WasErrors :=  not CTestOK or  not DTestOK or  not PowerTestOK;
    if  not Silent then
    begin
        Write(Format('CONTINUOUS VALIDITY TEST:                ',[]));
        if CTestOK then
        begin
            Write(Format('OK'#13#10'',[]));
        end
        else
        begin
            Write(Format('FAILED'#13#10'',[]));
        end;
        Write(Format('DISCRETE VALIDITY TEST:                  ',[]));
        if DTestOK then
        begin
            Write(Format('OK'#13#10'',[]));
        end
        else
        begin
            Write(Format('FAILED'#13#10'',[]));
        end;
        Write(Format('POWER TEST:                              ',[]));
        if PowerTestOK then
        begin
            Write(Format('OK'#13#10'',[]));
        end
        else
        begin
            Write(Format('FAILED'#13#10'',[]));
        end;
        if WasErrors then
        begin
            Write(Format('TEST SUMMARY: FAILED'#13#10'',[]));
        end
        else
        begin
            Write(Format('TEST SUMMARY: PASSED'#13#10'',[]));
        end;
        Write(Format(''#13#10''#13#10'',[]));
    end;
    Result :=  not WasErrors;
end;


procedure Generate(N : Integer;
     Med : Double;
     Width : Double;
     var R : TReal1DArray);
var
    I : Integer;
begin
    i:=0;
    while i<=N-1 do
    begin
        R[I] := Med+Width*(2*RandomReal-1);
        Inc(i);
    end;
end;


procedure GenerateDiscrete(N : Integer;
     Med : Integer;
     Width : Integer;
     var R : TReal1DArray);
var
    I : Integer;
begin
    i:=0;
    while i<=N-1 do
    begin
        R[I] := Med+(RandomInteger(2*Width+1)-Width);
        Inc(i);
    end;
end;


(*************************************************************************
Silent unit test
*************************************************************************)
function teststestunit_test_silent():Boolean;
begin
    Result := TestSignTest(True);
end;


(*************************************************************************
Unit test
*************************************************************************)
function teststestunit_test():Boolean;
begin
    Result := TestSignTest(False);
end;


end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -