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

📄 testsevdbiunit.pas

📁 maths lib with source
💻 PAS
📖 第 1 页 / 共 2 页
字号:
        begin
            
            //
            // Calculate V = A[i,j], A = Z*Lambda*Z'
            //
            V := 0;
            K:=0;
            while K<=N-1 do
            begin
                V := V+Z[I,K]*Lambda[K]*Z[J,K];
                Inc(K);
            end;
            
            //
            // Compare
            //
            if AbsInt(I-J)=0 then
            begin
                Result := Max(Result, AbsReal(V-D[I]));
            end;
            if AbsInt(I-J)=1 then
            begin
                Result := Max(Result, AbsReal(V-E[Min(I, J)]));
            end;
            if AbsInt(I-J)>1 then
            begin
                Result := Max(Result, AbsReal(V));
            end;
            Inc(J);
        end;
        Inc(I);
    end;
    MX := 0;
    I:=0;
    while I<=N-1 do
    begin
        MX := Max(MX, AbsReal(D[I]));
        Inc(I);
    end;
    I:=0;
    while I<=N-2 do
    begin
        MX := Max(MX, AbsReal(E[I]));
        Inc(I);
    end;
    if MX=0 then
    begin
        MX := 1;
    end;
    Result := Result/MX;
end;


(*************************************************************************
Tests Z*Z' against diag(1...1)
Returns absolute error.
*************************************************************************)
function TestOrt(const Z : TReal2DArray; N : Integer):Double;
var
    I : Integer;
    J : Integer;
    V : Double;
    i_ : Integer;
begin
    Result := 0;
    I:=0;
    while I<=N-1 do
    begin
        J:=0;
        while J<=N-1 do
        begin
            V := 0.0;
            for i_ := 0 to N-1 do
            begin
                V := V + Z[i_,I]*Z[i_,J];
            end;
            if I=J then
            begin
                V := V-1;
            end;
            Result := Max(Result, AbsReal(V));
            Inc(J);
        end;
        Inc(I);
    end;
end;


(*************************************************************************
Tests EVD problem
*************************************************************************)
procedure TestEVDProblem(const AFull : TReal2DArray;
     const AL : TReal2DArray;
     const AU : TReal2DArray;
     N : Integer;
     var ValErr : Double;
     var VecErr : Double;
     var WNSorted : Boolean;
     var FailC : Integer);
var
    Lambda : TReal1DArray;
    LambdaRef : TReal1DArray;
    Z : TReal2DArray;
    ZRef : TReal2DArray;
    A1 : TReal2DArray;
    A2 : TReal2DArray;
    AR : TReal2DArray;
    WSucc : Boolean;
    I : Integer;
    J : Integer;
    K : Integer;
    M : Integer;
    I1 : Integer;
    I2 : Integer;
    V : Double;
    A : Double;
    B : Double;
    i_ : Integer;
begin
    SetLength(LambdaRef, N-1+1);
    SetLength(ZRef, N-1+1, N-1+1);
    SetLength(A1, N-1+1, N-1+1);
    SetLength(A2, N-1+1, N-1+1);
    
    //
    // Reference EVD
    //
    if  not RefEVD(AFull, N, LambdaRef, ZRef) then
    begin
        FailC := FailC+1;
        Exit;
    end;
    
    //
    // Test different combinations
    //
    I1:=0;
    while I1<=N-1 do
    begin
        I2:=I1;
        while I2<=N-1 do
        begin
            
            //
            // Select A, B
            //
            if I1>0 then
            begin
                A := 0.5*(LambdaRef[I1]+LambdaRef[I1-1]);
            end
            else
            begin
                A := LambdaRef[0]-1;
            end;
            if I2<N-1 then
            begin
                B := 0.5*(LambdaRef[I2]+LambdaRef[I2+1]);
            end
            else
            begin
                B := LambdaRef[N-1]+1;
            end;
            
            //
            // Test interval, no vectors, lower A
            //
            Unset1D(Lambda);
            Unset2D(Z);
            if  not SMatrixEVDR(AL, N, 0, False, A, B, M, Lambda, Z) then
            begin
                FailC := FailC+1;
                Exit;
            end;
            if M<>I2-I1+1 then
            begin
                FailC := FailC+1;
                Exit;
            end;
            K:=0;
            while K<=M-1 do
            begin
                ValErr := Max(ValErr, AbsReal(Lambda[K]-LambdaRef[I1+K]));
                Inc(K);
            end;
            
            //
            // Test interval, no vectors, upper A
            //
            Unset1D(Lambda);
            Unset2D(Z);
            if  not SMatrixEVDR(AU, N, 0, True, A, B, M, Lambda, Z) then
            begin
                FailC := FailC+1;
                Exit;
            end;
            if M<>I2-I1+1 then
            begin
                FailC := FailC+1;
                Exit;
            end;
            K:=0;
            while K<=M-1 do
            begin
                ValErr := Max(ValErr, AbsReal(Lambda[K]-LambdaRef[I1+K]));
                Inc(K);
            end;
            
            //
            // Test indexes, no vectors, lower A
            //
            Unset1D(Lambda);
            Unset2D(Z);
            if  not SMatrixEVDI(AL, N, 0, False, I1, I2, Lambda, Z) then
            begin
                FailC := FailC+1;
                Exit;
            end;
            M := I2-I1+1;
            K:=0;
            while K<=M-1 do
            begin
                ValErr := Max(ValErr, AbsReal(Lambda[K]-LambdaRef[I1+K]));
                Inc(K);
            end;
            
            //
            // Test indexes, no vectors, upper A
            //
            Unset1D(Lambda);
            Unset2D(Z);
            if  not SMatrixEVDI(AU, N, 0, True, I1, I2, Lambda, Z) then
            begin
                FailC := FailC+1;
                Exit;
            end;
            M := I2-I1+1;
            K:=0;
            while K<=M-1 do
            begin
                ValErr := Max(ValErr, AbsReal(Lambda[K]-LambdaRef[I1+K]));
                Inc(K);
            end;
            
            //
            // Test interval, do not transform vectors, lower A
            //
            Unset1D(Lambda);
            Unset2D(Z);
            if  not SMatrixEVDR(AL, N, 1, False, A, B, M, Lambda, Z) then
            begin
                FailC := FailC+1;
                Exit;
            end;
            if M<>I2-I1+1 then
            begin
                FailC := FailC+1;
                Exit;
            end;
            K:=0;
            while K<=M-1 do
            begin
                ValErr := Max(ValErr, AbsReal(Lambda[K]-LambdaRef[I1+K]));
                Inc(K);
            end;
            J:=0;
            while J<=M-1 do
            begin
                V := 0.0;
                for i_ := 0 to N-1 do
                begin
                    V := V + Z[i_,J]*ZRef[i_,I1+J];
                end;
                if V<0 then
                begin
                    for i_ := 0 to N-1 do
                    begin
                        Z[i_,J] := -1*Z[i_,J];
                    end;
                end;
                Inc(J);
            end;
            I:=0;
            while I<=N-1 do
            begin
                J:=0;
                while J<=M-1 do
                begin
                    VecErr := Max(VecErr, AbsReal(Z[I,J]-ZRef[I,I1+J]));
                    Inc(J);
                end;
                Inc(I);
            end;
            
            //
            // Test interval, do not transform vectors, upper A
            //
            Unset1D(Lambda);
            Unset2D(Z);
            if  not SMatrixEVDR(AU, N, 1, True, A, B, M, Lambda, Z) then
            begin
                FailC := FailC+1;
                Exit;
            end;
            if M<>I2-I1+1 then
            begin
                FailC := FailC+1;
                Exit;
            end;
            K:=0;
            while K<=M-1 do
            begin
                ValErr := Max(ValErr, AbsReal(Lambda[K]-LambdaRef[I1+K]));
                Inc(K);
            end;
            J:=0;
            while J<=M-1 do
            begin
                V := 0.0;
                for i_ := 0 to N-1 do
                begin
                    V := V + Z[i_,J]*ZRef[i_,I1+J];
                end;
                if V<0 then
                begin
                    for i_ := 0 to N-1 do
                    begin
                        Z[i_,J] := -1*Z[i_,J];
                    end;
                end;
                Inc(J);
            end;
            I:=0;
            while I<=N-1 do
            begin
                J:=0;
                while J<=M-1 do
                begin
                    VecErr := Max(VecErr, AbsReal(Z[I,J]-ZRef[I,I1+J]));
                    Inc(J);
                end;
                Inc(I);
            end;
            
            //
            // Test indexes, do not transform vectors, lower A
            //
            Unset1D(Lambda);
            Unset2D(Z);
            if  not SMatrixEVDI(AL, N, 1, False, I1, I2, Lambda, Z) then
            begin
                FailC := FailC+1;
                Exit;
            end;
            M := I2-I1+1;
            K:=0;
            while K<=M-1 do
            begin
                ValErr := Max(ValErr, AbsReal(Lambda[K]-LambdaRef[I1+K]));
                Inc(K);
            end;
            J:=0;
            while J<=M-1 do
            begin
                V := 0.0;
                for i_ := 0 to N-1 do
                begin
                    V := V + Z[i_,J]*ZRef[i_,I1+J];
                end;
                if V<0 then
                begin
                    for i_ := 0 to N-1 do
                    begin
                        Z[i_,J] := -1*Z[i_,J];
                    end;
                end;
                Inc(J);
            end;
            I:=0;
            while I<=N-1 do
            begin
                J:=0;
                while J<=M-1 do
                begin
                    VecErr := Max(VecErr, AbsReal(Z[I,J]-ZRef[I,I1+J]));
                    Inc(J);
                end;
                Inc(I);
            end;
            
            //
            // Test indexes, do not transform vectors, upper A
            //
            Unset1D(Lambda);
            Unset2D(Z);
            if  not SMatrixEVDI(AU, N, 1, True, I1, I2, Lambda, Z) then
            begin
                FailC := FailC+1;
                Exit;
            end;
            M := I2-I1+1;
            K:=0;
            while K<=M-1 do
            begin
                ValErr := Max(ValErr, AbsReal(Lambda[K]-LambdaRef[I1+K]));
                Inc(K);
            end;
            J:=0;
            while J<=M-1 do
            begin
                V := 0.0;
                for i_ := 0 to N-1 do
                begin
                    V := V + Z[i_,J]*ZRef[i_,I1+J];
                end;
                if V<0 then
                begin
                    for i_ := 0 to N-1 do
                    begin
                        Z[i_,J] := -1*Z[i_,J];
                    end;
                end;
                Inc(J);
            end;
            I:=0;
            while I<=N-1 do
            begin
                J:=0;
                while J<=M-1 do
                begin
                    VecErr := Max(VecErr, AbsReal(Z[I,J]-ZRef[I,I1+J]));
                    Inc(J);
                end;
                Inc(I);
            end;
            Inc(I2);
        end;
        Inc(I1);
    end;
end;


(*************************************************************************
Silent unit test
*************************************************************************)
function testsevdbiunit_test_silent():Boolean;
begin
    Result := TestSEVDBI(True);
end;


(*************************************************************************
Unit test
*************************************************************************)
function testsevdbiunit_test():Boolean;
begin
    Result := TestSEVDBI(False);
end;


end.

⌨️ 快捷键说明

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