zlatrs.c

来自「InsightToolkit-1.4.0(有大量的优化算法程序)」· C语言 代码 · 共 913 行 · 第 1/3 页

C
913
字号
            grow = 0.;
            goto L60;
        }

        if (nounit) {

/*           A is non-unit triangular. */

/*           Compute GROW = 1/G(j) and XBND = 1/M(j). */
/*           Initially, G(0) = max{x(i), i=1,...,n}. */

            grow = .5 / max(xbnd,smlnum);
            xbnd = grow;
            for (j = jfirst; j != jlast; j += jinc) {

/*              Exit the loop if the growth factor is too small. */

                if (grow <= smlnum) {
                    goto L60;
                }

                i__1 = j + j * *lda;
                tjjs.r = a[i__1].r, tjjs.i = a[i__1].i;
                tjj = abs(tjjs.r) + abs(tjjs.i);

                if (tjj >= smlnum) {

/*                 M(j) = G(j-1) / abs(A(j,j)) */

                    xbnd = min(xbnd, min(1.,tjj) * grow);
                } else {

/*                 M(j) could overflow, set XBND to 0. */

                    xbnd = 0.;
                }

                if (tjj + cnorm[j] >= smlnum) {

/*                 G(j) = G(j-1)*( 1 + CNORM(j) / abs(A(j,j)) ) */

                    grow *= tjj / (tjj + cnorm[j]);
                } else {

/*                 G(j) could overflow, set GROW to 0. */

                    grow = 0.;
                }
            }
            grow = xbnd;
        } else {

/*           A is unit triangular. */

/*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}. */

            grow = min(1., .5/max(xbnd,smlnum));
            for (j = jfirst; j != jlast; j += jinc) {

/*              Exit the loop if the growth factor is too small. */

                if (grow <= smlnum) {
                    goto L60;
                }

/*              G(j) = G(j-1)*( 1 + CNORM(j) ) */

                grow *= 1. / (cnorm[j] + 1.);
            }
        }
L60:
        ;
    } else {

/*        Compute the growth in A**T * x = b  or  A**H * x = b. */

        if (upper) {
            jfirst = 0;
            jlast = *n - 1;
            jinc = 1;
        } else {
            jfirst = *n - 1;
            jlast = 0;
            jinc = -1;
        }

        if (tscal != 1.) {
            grow = 0.;
            goto L90;
        }

        if (nounit) {

/*           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 = .5 / max(xbnd,smlnum);
            xbnd = grow;
            for (j = jfirst; j != jlast; j += jinc) {

/*              Exit the loop if the growth factor is too small. */

                if (grow <= smlnum) {
                    goto L90;
                }

/*              G(j) = max( G(j-1), M(j-1)*( 1 + CNORM(j) ) ) */

                xj = cnorm[j] + 1.;
                grow = min(grow,xbnd / xj);

                i__1 = j + j * *lda;
                tjjs.r = a[i__1].r, tjjs.i = a[i__1].i;
                tjj = abs(tjjs.r) + abs(tjjs.i);

                if (tjj >= smlnum) {

/*                 M(j) = M(j-1)*( 1 + CNORM(j) ) / abs(A(j,j)) */

                    if (xj > tjj) {
                        xbnd *= tjj / xj;
                    }
                } else {

/*                 M(j) could overflow, set XBND to 0. */

                    xbnd = 0.;
                }
            }
            grow = min(grow,xbnd);
        } else {

/*           A is unit triangular. */

/*           Compute GROW = 1/G(j), where G(0) = max{x(i), i=1,...,n}. */

            grow = min(1., .5/max(xbnd,smlnum));
            for (j = jfirst; j != jlast; j += jinc) {

/*              Exit the loop if the growth factor is too small. */

                if (grow <= smlnum) {
                    goto L90;
                }

/*              G(j) = ( 1 + CNORM(j) )*G(j-1) */

                xj = cnorm[j] + 1.;
                grow /= xj;
            }
        }
L90:
        ;
    }

    if (grow * tscal > smlnum) {

/*        Use the Level 2 BLAS solve if the reciprocal of the bound on */
/*        elements of X is not too small. */

        ztrsv_(uplo, trans, diag, n, a, lda, x, &c__1);
    } else {

/*        Use a Level 1 BLAS solve, scaling intermediate results. */

        if (xmax > bignum * .5) {

/*           Scale X so that its components are less than or equal to */
/*           BIGNUM in absolute value. */

            *scale = bignum * .5 / xmax;
            zdscal_(n, scale, x, &c__1);
            xmax = bignum;
        } else {
            xmax *= 2.;
        }

        if (notran) {

/*           Solve A * x = b */

            for (j = jfirst; j != jlast; j += jinc) {

/*              Compute x(j) = b(j) / A(j,j), scaling x if necessary. */

                xj = abs(x[j].r) + abs(x[j].i);
                if (nounit) {
                    i__1 = j + j * *lda;
                    tjjs.r = tscal * a[i__1].r, tjjs.i = tscal * a[i__1].i;
                } else {
                    tjjs.r = tscal, tjjs.i = 0.;
                    if (tscal == 1.) {
                        goto L110;
                    }
                }
                tjj = abs(tjjs.r) + abs(tjjs.i);
                if (tjj > smlnum) {

/*                    abs(A(j,j)) > SMLNUM: */

                    if (tjj < 1.) {
                        if (xj > tjj * bignum) {

/*                          Scale x by 1/b(j). */

                            rec = 1. / xj;
                            zdscal_(n, &rec, x, &c__1);
                            *scale *= rec;
                            xmax *= rec;
                        }
                    }
                    zladiv_(&x[j], &x[j], &tjjs);
                    xj = abs(x[j].r) + abs(x[j].i );
                } else if (tjj > 0.) {

/*                    0 < abs(A(j,j)) <= SMLNUM: */

                    if (xj > tjj * bignum) {

/*                       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.) {

/*                          Scale by 1/CNORM(j) to avoid overflow when */
/*                          multiplying x(j) times column j. */

                            rec /= cnorm[j];
                        }
                        zdscal_(n, &rec, x, &c__1);
                        *scale *= rec;
                        xmax *= rec;
                    }
                    zladiv_(&x[j], &x[j], &tjjs);
                    xj = abs(x[j].r) + abs(x[j].i);
                } else {

/*                    A(j,j) = 0:  Set x(1:n) = 0, x(j) = 1, and */
/*                    scale = 0, and compute a solution to A*x = 0. */

                    for (i = 0; i < *n; ++i) {
                        x[i].r = 0., x[i].i = 0.;
                    }
                    x[j].r = 1., x[j].i = 0.;
                    xj = 1.;
                    *scale = 0.;
                    xmax = 0.;
                }
L110:

/*              Scale x if necessary to avoid overflow when adding a */
/*              multiple of column j of A. */

                if (xj > 1.) {
                    rec = 1. / xj;
                    if (cnorm[j] > (bignum - xmax) * rec) {

/*                    Scale x by 1/(2*abs(x(j))). */

                        rec *= .5;
                        zdscal_(n, &rec, x, &c__1);
                        *scale *= rec;
                    }
                } else if (xj * cnorm[j] > bignum - xmax) {

/*                 Scale x by 1/2. */

                    zdscal_(n, &c_b36, x, &c__1);
                    *scale *= .5;
                }

                if (upper) {
                    if (j > 0) {

/*                    Compute the update */
/*                       x(1:j-1) := x(1:j-1) - x(j) * A(1:j-1,j) */

                        z__1.r = - tscal * x[j].r, z__1.i = - tscal * x[j].i;
                        zaxpy_(&j, &z__1, &a[j * *lda], &c__1, x, &c__1);
                        i = izamax_(&j, x, &c__1) - 1;
                        xmax = abs(x[i].r) + abs(x[i].i);
                    }
                } else {
                    if (j < *n - 1) {

/*                    Compute the update */
/*                       x(j+1:n) := x(j+1:n) - x(j) * A(j+1:n,j) */

                        z__1.r = - tscal * x[j].r, z__1.i = - tscal * x[j].i;
                        i__1 = *n - j - 1;
                        zaxpy_(&i__1, &z__1, &a[j + 1 + j * *lda], &c__1, &x[j + 1], &c__1);
                        i = j + izamax_(&i__1, &x[j + 1], &c__1);
                        xmax = abs(x[i].r) + abs(x[i].i);
                    }
                }
            }

        } else if (lsame_(trans, "T")) {

/*           Solve A**T * x = b */

            for (j = jfirst; j != jlast; j += jinc) {

⌨️ 快捷键说明

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