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 
30 template <typename Entry, typename Int>
31 Int 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 Ap[]
Column offsets.
Definition: klu2_simple.cpp:52
int Ai[]
Row values.
Definition: klu2_simple.cpp:54