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

📄 trlinsolve.pas

📁 maths lib with source
💻 PAS
📖 第 1 页 / 共 3 页
字号:
                end;
            end
            else
            begin
                
                //
                // A is unit triangular.
                //
                // Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
                //
                GROW := Min(1, 1/Max(XBND, SMLNUM));
                J := JFIRST;
                while (JINC>0) and (J<=JLAST) or (JINC<0) and (J>=JLAST) do
                begin
                    
                    //
                    // Exit the loop if the growth factor is too small.
                    //
                    if GROW<=SMLNUM then
                    begin
                        Break;
                    end;
                    
                    //
                    // G(j) = G(j-1)*( 1 + CNORM(j) )
                    //
                    GROW := GROW*(1/(1+CNORM[J]));
                    J := J+JINC;
                end;
            end;
        end;
    end
    else
    begin
        
        //
        // Compute the growth in A' * x = b.
        //
        if UPPER then
        begin
            JFIRST := 1;
            JLAST := N;
            JINC := 1;
        end
        else
        begin
            JFIRST := N;
            JLAST := 1;
            JINC := -1;
        end;
        if TSCAL<>1 then
        begin
            GROW := 0;
        end
        else
        begin
            if NOUNIT then
            begin
                
                //
                // A is non-unit triangular.
                //
                // Compute GROW = 1/G(j) and XBND = 1/M(j).
                // Initially, M(0) = max{x(i), i=1,...,n}.
                //
                GROW := 1/Max(XBND, SMLNUM);
                XBND := GROW;
                J := JFIRST;
                while (JINC>0) and (J<=JLAST) or (JINC<0) and (J>=JLAST) do
                begin
                    
                    //
                    // Exit the loop if the growth factor is too small.
                    //
                    if GROW<=SMLNUM then
                    begin
                        Break;
                    end;
                    
                    //
                    // G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) )
                    //
                    XJ := 1+CNORM[J];
                    GROW := Min(GROW, XBND/XJ);
                    
                    //
                    // M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j))
                    //
                    TJJ := ABSReal(A[J,J]);
                    if XJ>TJJ then
                    begin
                        XBND := XBND*(TJJ/XJ);
                    end;
                    if J=JLAST then
                    begin
                        GROW := Min(GROW, XBND);
                    end;
                    J := J+JINC;
                end;
            end
            else
            begin
                
                //
                // A is unit triangular.
                //
                // Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}.
                //
                GROW := Min(1, 1/Max(XBND, SMLNUM));
                J := JFIRST;
                while (JINC>0) and (J<=JLAST) or (JINC<0) and (J>=JLAST) do
                begin
                    
                    //
                    // Exit the loop if the growth factor is too small.
                    //
                    if GROW<=SMLNUM then
                    begin
                        Break;
                    end;
                    
                    //
                    // G(j) = ( 1 + CNORM(j) )*G(j-1)
                    //
                    XJ := 1+CNORM[J];
                    GROW := GROW/XJ;
                    J := J+JINC;
                end;
            end;
        end;
    end;
    if GROW*TSCAL>SMLNUM then
    begin
        
        //
        // Use the Level 2 BLAS solve if the reciprocal of the bound on
        // elements of X is not too small.
        //
        if UPPER and NOTRAN or  not UPPER and  not NOTRAN then
        begin
            if NOUNIT then
            begin
                VD := A[N,N];
            end
            else
            begin
                VD := 1;
            end;
            X[N] := X[N]/VD;
            I:=N-1;
            while I>=1 do
            begin
                IP1 := I+1;
                if Upper then
                begin
                    V := APVDotProduct(@A[I][0], IP1, N, @X[0], IP1, N);
                end
                else
                begin
                    V := 0.0;
                    for i_ := IP1 to N do
                    begin
                        V := V + A[i_,I]*X[i_];
                    end;
                end;
                if NOUNIT then
                begin
                    VD := A[I,I];
                end
                else
                begin
                    VD := 1;
                end;
                X[I] := (X[I]-V)/VD;
                Dec(I);
            end;
        end
        else
        begin
            if NOUNIT then
            begin
                VD := A[1,1];
            end
            else
            begin
                VD := 1;
            end;
            X[1] := X[1]/VD;
            I:=2;
            while I<=N do
            begin
                IM1 := I-1;
                if Upper then
                begin
                    V := 0.0;
                    for i_ := 1 to IM1 do
                    begin
                        V := V + A[i_,I]*X[i_];
                    end;
                end
                else
                begin
                    V := APVDotProduct(@A[I][0], 1, IM1, @X[0], 1, IM1);
                end;
                if NOUNIT then
                begin
                    VD := A[I,I];
                end
                else
                begin
                    VD := 1;
                end;
                X[I] := (X[I]-V)/VD;
                Inc(I);
            end;
        end;
    end
    else
    begin
        
        //
        // Use a Level 1 BLAS solve, scaling intermediate results.
        //
        if XMAX>BIGNUM then
        begin
            
            //
            // Scale X so that its components are less than or equal to
            // BIGNUM in absolute value.
            //
            S := BIGNUM/XMAX;
            APVMul(@X[0], 1, N, S);
            XMAX := BIGNUM;
        end;
        if NOTRAN then
        begin
            
            //
            // Solve A * x = b
            //
            J := JFIRST;
            while (JINC>0) and (J<=JLAST) or (JINC<0) and (J>=JLAST) do
            begin
                
                //
                // Compute x(j) = b(j) / A(j,j), scaling x if necessary.
                //
                XJ := ABSReal(X[J]);
                Flg := 0;
                if NOUNIT then
                begin
                    TJJS := A[J,J]*TSCAL;
                end
                else
                begin
                    TJJS := TSCAL;
                    if TSCAL=1 then
                    begin
                        Flg := 100;
                    end;
                end;
                if Flg<>100 then
                begin
                    TJJ := ABSReal(TJJS);
                    if TJJ>SMLNUM then
                    begin
                        
                        //
                        // abs(A(j,j)) > SMLNUM:
                        //
                        if TJJ<1 then
                        begin
                            if XJ>TJJ*BIGNUM then
                            begin
                                
                                //
                                // Scale x by 1/b(j).
                                //
                                REC := 1/XJ;
                                APVMul(@X[0], 1, N, REC);
                                S := S*REC;
                                XMAX := XMAX*REC;
                            end;
                        end;
                        X[J] := X[J]/TJJS;
                        XJ := ABSReal(X[J]);
                    end
                    else
                    begin
                        if TJJ>0 then
                        begin
                            
                            //
                            // 0 < abs(A(j,j)) <= SMLNUM:
                            //
                            if XJ>TJJ*BIGNUM then
                            begin
                                
                                //
                                // Scale x by (1/abs(x(j)))*abs(A(j,j))*BIGNUM
                                // to avoid overflow when dividing by A(j,j).
                                //
                                REC := TJJ*BIGNUM/XJ;
                                if CNORM[J]>1 then
                                begin
                                    
                                    //
                                    // Scale by 1/CNORM(j) to avoid overflow when
                                    // multiplying x(j) times column j.
                                    //
                                    REC := REC/CNORM[J];
                                end;
                                APVMul(@X[0], 1, N, REC);
                                S := S*REC;
                                XMAX := XMAX*REC;
                            end;
                            X[J] := X[J]/TJJS;
                            XJ := ABSReal(X[J]);
                        end
                        else
                        begin
                            
                            //
                            // A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and
                            // scale = 0, and compute a solution to A*x = 0.
                            //
                            I:=1;
                            while I<=N do
                            begin
                                X[I] := 0;
                                Inc(I);
                            end;
                            X[J] := 1;

⌨️ 快捷键说明

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