1 
2 /*! @file zlangs.c
3  * \brief Returns the value of the one norm
4  *
5  * <pre>
6  * -- SuperLU routine (version 2.0) --
7  * Univ. of California Berkeley, Xerox Palo Alto Research Center,
8  * and Lawrence Berkeley National Lab.
9  * November 15, 1997
10  *
11  * Modified from lapack routine ZLANGE
12  * </pre>
13  */
14 /*
15  * File name:	zlangs.c
16  * History:     Modified from lapack routine ZLANGE
17  */
18 #include <math.h>
19 #include "slu_zdefs.h"
20 
21 /*! \brief
22  *
23  * <pre>
24  * Purpose
25  *   =======
26  *
27  *   ZLANGS returns the value of the one norm, or the Frobenius norm, or
28  *   the infinity norm, or the element of largest absolute value of a
29  *   real matrix A.
30  *
31  *   Description
32  *   ===========
33  *
34  *   ZLANGE returns the value
35  *
36  *      ZLANGE = ( max(abs(A(i,j))), NORM = 'M' or 'm'
37  *               (
38  *               ( norm1(A),         NORM = '1', 'O' or 'o'
39  *               (
40  *               ( normI(A),         NORM = 'I' or 'i'
41  *               (
42  *               ( normF(A),         NORM = 'F', 'f', 'E' or 'e'
43  *
44  *   where  norm1  denotes the  one norm of a matrix (maximum column sum),
45  *   normI  denotes the  infinity norm  of a matrix  (maximum row sum) and
46  *   normF  denotes the  Frobenius norm of a matrix (square root of sum of
47  *   squares).  Note that  max(abs(A(i,j)))  is not a  matrix norm.
48  *
49  *   Arguments
50  *   =========
51  *
52  *   NORM    (input) CHARACTER*1
53  *           Specifies the value to be returned in ZLANGE as described above.
54  *   A       (input) SuperMatrix*
55  *           The M by N sparse matrix A.
56  *
57  *  =====================================================================
58  * </pre>
59  */
60 
zlangs(char * norm,SuperMatrix * A)61 double zlangs(char *norm, SuperMatrix *A)
62 {
63 
64     /* Local variables */
65     NCformat *Astore;
66     doublecomplex   *Aval;
67     int      i, j, irow;
68     double   value, sum;
69     double   *rwork;
70 
71     Astore = A->Store;
72     Aval   = Astore->nzval;
73 
74     if ( SUPERLU_MIN(A->nrow, A->ncol) == 0) {
75 	value = 0.;
76 
77     } else if (lsame_(norm, "M")) {
78 	/* Find max(abs(A(i,j))). */
79 	value = 0.;
80 	for (j = 0; j < A->ncol; ++j)
81 	    for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; i++)
82 		value = SUPERLU_MAX( value, z_abs( &Aval[i]) );
83 
84     } else if (lsame_(norm, "O") || *(unsigned char *)norm == '1') {
85 	/* Find norm1(A). */
86 	value = 0.;
87 	for (j = 0; j < A->ncol; ++j) {
88 	    sum = 0.;
89 	    for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; i++)
90 		sum += z_abs( &Aval[i] );
91 	    value = SUPERLU_MAX(value,sum);
92 	}
93 
94     } else if (lsame_(norm, "I")) {
95 	/* Find normI(A). */
96 	if ( !(rwork = (double *) SUPERLU_MALLOC(A->nrow * sizeof(double))) )
97 	    ABORT("SUPERLU_MALLOC fails for rwork.");
98 	for (i = 0; i < A->nrow; ++i) rwork[i] = 0.;
99 	for (j = 0; j < A->ncol; ++j)
100 	    for (i = Astore->colptr[j]; i < Astore->colptr[j+1]; i++) {
101 		irow = Astore->rowind[i];
102 		rwork[irow] += z_abs( &Aval[i] );
103 	    }
104 	value = 0.;
105 	for (i = 0; i < A->nrow; ++i)
106 	    value = SUPERLU_MAX(value, rwork[i]);
107 
108 	SUPERLU_FREE (rwork);
109 
110     } else if (lsame_(norm, "F") || lsame_(norm, "E")) {
111 	/* Find normF(A). */
112 	ABORT("Not implemented.");
113     } else
114 	ABORT("Illegal norm specified.");
115 
116     return (value);
117 
118 } /* zlangs */
119 
120