/* Last edited on 2011-05-15 11:47:56 by stolfi */ /* enorm.f -- translated by f2c (version of 17 January 1992 0:17:58). You must link the resulting object file with the libraries: -lf77 -li77 -lm -lc (in that order) */ #include #include #include #include #include double enorm_(int *n, double *x) { /* Initialized data */ static double one = 1.; static double zero = 0.; static double rdwarf = 3.834e-20; static double rgiant = 1.304e19; /* System generated locals */ int i__1; double ret_val = 0, d__1; /* Builtin functions */ double sqrt(); /* Local variables */ static double xabs, x1max, x3max; static int i; static double s1, s2, s3, agiant, floatn; /* ********** */ /* function enorm */ /* given an n-vector x, this function calculates the */ /* euclidean norm of x. */ /* the euclidean norm is computed by accumulating the sum of */ /* squares in three different sums. the sums of squares for the */ /* small and large components are scaled so that no overflows */ /* occur. non-destructive underflows are permitted. underflows */ /* and overflows do not occur in the computation of the unscaled */ /* sum of squares for the intermediate components. */ /* the definitions of small, intermediate and large components */ /* depend on two constants, rdwarf and rgiant. the main */ /* restrictions on these constants are that rdwarf**2 not */ /* underflow and rgiant**2 not overflow. the constants */ /* given here are suitable for every known computer. */ /* the function statement is */ /* double precision function enorm(n,x) */ /* where */ /* n is a positive int input variable. */ /* x is an input array of length n. */ /* subprograms called */ /* fortran-supplied ... dabs,dsqrt */ /* argonne national laboratory. minpack project. march 1980. */ /* burton s. garbow, kenneth e. hillstrom, jorge j. more */ /* ********** */ /* Parameter adjustments */ --x; /* Function Body */ s1 = zero; s2 = zero; s3 = zero; x1max = zero; x3max = zero; floatn = (double) (*n); agiant = rgiant / floatn; i__1 = *n; for (i = 1; i <= i__1; ++i) { xabs = (d__1 = x[i], abs(d__1)); if (isnan(xabs)) { fprintf(stderr, "*n = %d x[%d] = %24.16e xabs = %24.16e\n", i__1, i, x[i], xabs); } assert(! isnan(xabs)); if (xabs > rdwarf && xabs < agiant) { goto L70; } if (xabs <= rdwarf) { goto L30; } /* sum for large components. */ if (xabs <= x1max) { goto L10; } /* Computing 2nd power */ d__1 = x1max / xabs; s1 = one + s1 * (d__1 * d__1); x1max = xabs; goto L20; L10: /* Computing 2nd power */ d__1 = xabs / x1max; s1 += d__1 * d__1; L20: goto L60; L30: /* sum for small components. */ if (xabs <= x3max) { goto L40; } /* Computing 2nd power */ d__1 = x3max / xabs; s3 = one + s3 * (d__1 * d__1); x3max = xabs; goto L50; L40: if (xabs != zero) { /* Computing 2nd power */ d__1 = xabs / x3max; s3 += d__1 * d__1; } L50: L60: goto L80; L70: /* sum for intermediate components. */ /* Computing 2nd power */ d__1 = xabs; s2 += d__1 * d__1; L80: /* L90: */ ; } /* calculation of norm. */ if (s1 == zero) { goto L100; } ret_val = x1max * sqrt(s1 + s2 / x1max / x1max); goto L130; L100: if (s2 == zero) { goto L110; } if (s2 >= x3max) { d__1 = x3max * s3; ret_val = sqrt(s2 * (one + x3max / s2 * d__1)); } if (s2 < x3max) { ret_val = sqrt(x3max * (s2 / x3max + x3max * s3)); } goto L120; L110: ret_val = x3max * sqrt(s3); L120: L130: return ret_val; /* last card of function enorm. */ } /* enorm_ */