Amesos2 - Direct Sparse Solver Interfaces Version of the Day
klu2_scale.hpp
1/* ========================================================================== */
2/* === KLU_scale ============================================================ */
3/* ========================================================================== */
4// @HEADER
5// *****************************************************************************
6// KLU2: A Direct Linear Solver package
7//
8// Copyright 2011 NTESS and the KLU2 contributors.
9// SPDX-License-Identifier: LGPL-2.1-or-later
10// *****************************************************************************
11// @HEADER
12
13/* Scale a matrix and check to see if it is valid. Can be called by the user.
14 * This is called by KLU_factor and KLU_refactor. Returns TRUE if the input
15 * matrix is valid, FALSE otherwise. If the W input argument is non-NULL,
16 * then the input matrix is checked for duplicate entries.
17 *
18 * scaling methods:
19 * <0: no scaling, do not compute Rs, and do not check input matrix.
20 * 0: no scaling
21 * 1: the scale factor for row i is sum (abs (A (i,:)))
22 * 2 or more: the scale factor for row i is max (abs (A (i,:)))
23 */
24
25#ifndef KLU2_SCALE_HPP
26#define KLU2_SCALE_HPP
27
28#include "klu2_internal.h"
29
30template <typename Entry, typename Int>
31Int KLU_scale /* return TRUE if successful, FALSE otherwise */
32(
33 /* inputs, not modified */
34 Int scale, /* 0: none, 1: sum, 2: max */
35 Int n,
36 Int Ap [ ], /* size n+1, column pointers */
37 Int Ai [ ], /* size nz, row indices */
38 /* TODO : double to Entry */
39 Entry Ax [ ],
40 /* outputs, not defined on input */
41 /* TODO : double to Entry */
42 double Rs [ ], /* size n, can be NULL if scale <= 0 */
43 /* workspace, not defined on input or output */
44 Int W [ ], /* size n, can be NULL */
45 /* --------------- */
46 KLU_common<Entry, Int> *Common
47)
48{
49 double a ;
50 Entry *Az ;
51 Int row, col, p, pend, check_duplicates ;
52
53 /* ---------------------------------------------------------------------- */
54 /* check inputs */
55 /* ---------------------------------------------------------------------- */
56
57 if (Common == NULL)
58 {
59 return (FALSE) ;
60 }
61 Common->status = KLU_OK ;
62
63 if (scale < 0)
64 {
65 /* return without checking anything and without computing the
66 * scale factors */
67 return (TRUE) ;
68 }
69
70 Az = (Entry *) Ax ;
71
72 if (n <= 0 || Ap == NULL || Ai == NULL || Az == NULL ||
73 (scale > 0 && Rs == NULL))
74 {
75 /* Ap, Ai, Ax and Rs must be present, and n must be > 0 */
76 Common->status = KLU_INVALID ;
77 return (FALSE) ;
78 }
79 if (Ap [0] != 0 || Ap [n] < 0)
80 {
81 /* nz = Ap [n] must be >= 0 and Ap [0] must equal zero */
82 Common->status = KLU_INVALID ;
83 return (FALSE) ;
84 }
85 for (col = 0 ; col < n ; col++)
86 {
87 if (Ap [col] > Ap [col+1])
88 {
89 /* column pointers must be non-decreasing */
90 Common->status = KLU_INVALID ;
91 return (FALSE) ;
92 }
93 }
94
95 /* ---------------------------------------------------------------------- */
96 /* scale */
97 /* ---------------------------------------------------------------------- */
98
99 if (scale > 0)
100 {
101 /* initialize row sum or row max */
102 for (row = 0 ; row < n ; row++)
103 {
104 Rs [row] = 0 ;
105 }
106 }
107
108 /* check for duplicates only if W is present */
109 check_duplicates = (W != (Int *) NULL) ;
110 if (check_duplicates)
111 {
112 for (row = 0 ; row < n ; row++)
113 {
114 W [row] = AMESOS2_KLU2_EMPTY ;
115 }
116 }
117
118 for (col = 0 ; col < n ; col++)
119 {
120 pend = Ap [col+1] ;
121 for (p = Ap [col] ; p < pend ; p++)
122 {
123 row = Ai [p] ;
124 if (row < 0 || row >= n)
125 {
126 /* row index out of range, or duplicate entry */
127 Common->status = KLU_INVALID ;
128 return (FALSE) ;
129 }
130 if (check_duplicates)
131 {
132 if (W [row] == col)
133 {
134 /* duplicate entry */
135 Common->status = KLU_INVALID ;
136 return (FALSE) ;
137 }
138 /* flag row i as appearing in column col */
139 W [row] = col ;
140 }
141 /* a = ABS (Az [p]) ;*/
142 KLU2_ABS (a, Az [p]) ;
143 if (scale == 1)
144 {
145 /* accumulate the abs. row sum */
146 Rs [row] += a ;
147 }
148 else if (scale > 1)
149 {
150 /* find the max abs. value in the row */
151 Rs [row] = MAX (Rs [row], a) ;
152 }
153 }
154 }
155
156 if (scale > 0)
157 {
158 /* do not scale empty rows */
159 for (row = 0 ; row < n ; row++)
160 {
161 /* matrix is singular */
162 PRINTF (("Rs [%d] = %g\n", row, Rs [row])) ;
163
164 if (Rs [row] == 0.0)
165 {
166 PRINTF (("Row %d of A is all zero\n", row)) ;
167 Rs [row] = 1.0 ;
168 }
169 }
170 }
171
172 return (TRUE) ;
173}
174#endif
void scale(ArrayView< Scalar1 > vals, size_t l, size_t ld, ArrayView< Scalar2 > s)
Scales a 1-D representation of a multivector.
int Ai[]
Row values.
Definition klu2_simple.cpp:54
int Ap[]
Column offsets.
Definition klu2_simple.cpp:52