1 /* ========================================================================== */
2 /* === UMFPACK_report_matrix ================================================ */
3 /* ========================================================================== */
4 
5 /* -------------------------------------------------------------------------- */
6 /* Copyright (c) 2005-2012 by Timothy A. Davis, http://www.suitesparse.com.   */
7 /* All Rights Reserved.  See ../Doc/License.txt for License.                  */
8 /* -------------------------------------------------------------------------- */
9 
10 /*
11     User-callable.  Prints a column or row-oriented matrix.  See
12     umfpack_report_matrix.h for details.
13 */
14 
15 #include "umf_internal.h"
16 
UMFPACK_report_matrix(Int n_row,Int n_col,const Int Ap[],const Int Ai[],const double Ax[],const double Az[],Int col_form,const double Control[UMFPACK_CONTROL])17 GLOBAL Int UMFPACK_report_matrix
18 (
19     Int n_row,
20     Int n_col,
21     const Int Ap [ ],
22     const Int Ai [ ],
23     const double Ax [ ],
24 #ifdef COMPLEX
25     const double Az [ ],
26 #endif
27     Int col_form,		/* 1: column form, 0: row form */
28     const double Control [UMFPACK_CONTROL]
29 )
30 {
31     Entry a ;
32     Int prl, i, k, length, ilast, p, nz, prl1, p1, p2, n, n_i, do_values ;
33     char *vector_kind, *index_kind ;
34 #ifdef COMPLEX
35     Int split = SPLIT (Az) ;
36 #endif
37 
38     /* ---------------------------------------------------------------------- */
39     /* determine the form, and check if inputs exist */
40     /* ---------------------------------------------------------------------- */
41 
42     prl = GET_CONTROL (UMFPACK_PRL, UMFPACK_DEFAULT_PRL) ;
43 
44     if (prl <= 2)
45     {
46 	return (UMFPACK_OK) ;
47     }
48 
49     if (col_form)
50     {
51 	vector_kind = "column" ;	/* column vectors */
52 	index_kind = "row" ;		/* with row indices */
53 	n = n_col ;
54 	n_i = n_row ;
55     }
56     else
57     {
58 	vector_kind = "row" ;	/* row vectors */
59 	index_kind = "column" ;	/* with column indices */
60 	n = n_row ;
61 	n_i = n_col ;
62     }
63 
64     PRINTF (("%s-form matrix, n_row "ID" n_col "ID", ",
65         vector_kind, n_row, n_col)) ;
66 
67     if (n_row <= 0 || n_col <= 0)
68     {
69 	PRINTF (("ERROR: n_row <= 0 or n_col <= 0\n\n")) ;
70 	return (UMFPACK_ERROR_n_nonpositive) ;
71     }
72 
73     if (!Ap)
74     {
75 	PRINTF (("ERROR: Ap missing\n\n")) ;
76 	return (UMFPACK_ERROR_argument_missing) ;
77     }
78 
79     nz = Ap [n] ;
80     PRINTF (("nz = "ID". ", nz)) ;
81     if (nz < 0)
82     {
83 	PRINTF (("ERROR: number of entries < 0\n\n")) ;
84 	return (UMFPACK_ERROR_invalid_matrix) ;
85     }
86 
87     if (Ap [0] != 0)
88     {
89 	PRINTF (("ERROR: Ap ["ID"] = "ID" must be "ID"\n\n",
90 	    (Int) INDEX (0), INDEX (Ap [0]), (Int) INDEX (0))) ;
91 	return (UMFPACK_ERROR_invalid_matrix) ;
92     }
93 
94     if (!Ai)
95     {
96 	PRINTF (("ERROR: Ai missing\n\n")) ;
97 	return (UMFPACK_ERROR_argument_missing) ;
98     }
99 
100     do_values = Ax != (double *) NULL ;
101 
102     PRINTF4 (("\n")) ;
103 
104     /* ---------------------------------------------------------------------- */
105     /* check the row/column pointers, Ap */
106     /* ---------------------------------------------------------------------- */
107 
108     for (k = 0 ; k < n ; k++)
109     {
110 	if (Ap [k] < 0)
111 	{
112 	    PRINTF (("ERROR: Ap ["ID"] < 0\n\n", INDEX (k))) ;
113 	    return (UMFPACK_ERROR_invalid_matrix) ;
114 	}
115 	if (Ap [k] > nz)
116 	{
117 	    PRINTF (("ERROR: Ap ["ID"] > size of Ai\n\n", INDEX (k))) ;
118 	    return (UMFPACK_ERROR_invalid_matrix) ;
119 	}
120     }
121 
122     for (k = 0 ; k < n ; k++)
123     {
124 	length = Ap [k+1] - Ap [k] ;
125 	if (length < 0)
126 	{
127 	    PRINTF (("ERROR: # entries in %s "ID" is < 0\n\n",
128 		vector_kind, INDEX (k))) ;
129 	    return (UMFPACK_ERROR_invalid_matrix) ;
130 	}
131     }
132 
133     /* ---------------------------------------------------------------------- */
134     /* print each vector */
135     /* ---------------------------------------------------------------------- */
136 
137     prl1 = prl ;
138 
139     for (k = 0 ; k < n ; k++)
140     {
141 	/* if prl is 4, print the first 10 entries of the first 10 vectors */
142 	if (k < 10)
143 	{
144 	    prl = prl1 ;
145 	}
146 	/* get the vector pointers */
147 	p1 = Ap [k] ;
148 	p2 = Ap [k+1] ;
149 	length = p2 - p1 ;
150 	PRINTF4 (("\n    %s "ID": start: "ID" end: "ID" entries: "ID"\n",
151 	    vector_kind, INDEX (k), p1, p2-1, length)) ;
152 	ilast = EMPTY ;
153 	for (p = p1 ; p < p2 ; p++)
154 	{
155 	    i = Ai [p] ;
156 	    PRINTF4 (("\t%s "ID" ", index_kind, INDEX (i))) ;
157 	    if (do_values && prl >= 4)
158 	    {
159 		PRINTF ((":")) ;
160 		ASSIGN (a, Ax, Az, p, split) ;
161 		PRINT_ENTRY (a) ;
162 	    }
163 	    if (i < 0 || i >= n_i)
164 	    {
165 		PRINTF ((" ERROR: %s index "ID" out of range in %s "ID"\n\n",
166 		    index_kind, INDEX (i), vector_kind, INDEX (k))) ;
167 		return (UMFPACK_ERROR_invalid_matrix) ;
168 	    }
169 	    if (i <= ilast)
170 	    {
171 		PRINTF ((" ERROR: %s index "ID" out of order (or duplicate) in "
172 		    "%s "ID"\n\n", index_kind, INDEX (i),
173                     vector_kind, INDEX (k))) ;
174 		return (UMFPACK_ERROR_invalid_matrix) ;
175 	    }
176 	    PRINTF4 (("\n")) ;
177 	    /* truncate printout, but continue to check matrix */
178 	    if (prl == 4 && (p - p1) == 9 && length > 10)
179 	    {
180 		PRINTF4 (("\t...\n")) ;
181 		prl-- ;
182 	    }
183 	    ilast = i ;
184 	}
185 	/* truncate printout, but continue to check matrix */
186 	if (prl == 4 && k == 9 && n > 10)
187 	{
188 	    PRINTF4 (("\n    ...\n")) ;
189 	    prl-- ;
190 	}
191     }
192     prl = prl1 ;
193 
194     /* ---------------------------------------------------------------------- */
195     /* return the status of the matrix */
196     /* ---------------------------------------------------------------------- */
197 
198     PRINTF4 (("    %s-form matrix ", vector_kind)) ;
199     PRINTF (("OK\n\n")) ;
200 
201     return (UMFPACK_OK) ;
202 }
203