Amesos2 - Direct Sparse Solver Interfaces  Version of the Day
klu2_sort.hpp
1 /* ========================================================================== */
2 /* === KLU_sort ============================================================= */
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 /* sorts the columns of L and U so that the row indices appear in strictly
14  * increasing order.
15  */
16 
17 #ifndef KLU2_SORT_HPP
18 #define KLU2_SORT_HPP
19 
20 #include "klu2_internal.h"
21 #include "klu2_memory.hpp"
22 
23 /* ========================================================================== */
24 /* === sort ================================================================= */
25 /* ========================================================================== */
26 
27 /* Sort L or U using a double-transpose */
28 
29 template <typename Entry, typename Int>
30 static void sort (Int n, Int *Xip, Int *Xlen, Unit *LU, Int *Tp, Int *Tj,
31  Entry *Tx, Int *W)
32 {
33  Int *Xi ;
34  Entry *Xx ;
35  Int p, i, j, len, nz, tp, xlen, pend ;
36 
37  ASSERT (KLU_valid_LU (n, FALSE, Xip, Xlen, LU)) ;
38 
39  /* count the number of entries in each row of L or U */
40  for (i = 0 ; i < n ; i++)
41  {
42  W [i] = 0 ;
43  }
44  for (j = 0 ; j < n ; j++)
45  {
46  GET_POINTER (LU, Xip, Xlen, Xi, Xx, j, len) ;
47  for (p = 0 ; p < len ; p++)
48  {
49  W [Xi [p]]++ ;
50  }
51  }
52 
53  /* construct the row pointers for T */
54  nz = 0 ;
55  for (i = 0 ; i < n ; i++)
56  {
57  Tp [i] = nz ;
58  nz += W [i] ;
59  }
60  Tp [n] = nz ;
61  for (i = 0 ; i < n ; i++)
62  {
63  W [i] = Tp [i] ;
64  }
65 
66  /* transpose the matrix into Tp, Ti, Tx */
67  for (j = 0 ; j < n ; j++)
68  {
69  GET_POINTER (LU, Xip, Xlen, Xi, Xx, j, len) ;
70  for (p = 0 ; p < len ; p++)
71  {
72  tp = W [Xi [p]]++ ;
73  Tj [tp] = j ;
74  Tx [tp] = Xx [p] ;
75  }
76  }
77 
78  /* transpose the matrix back into Xip, Xlen, Xi, Xx */
79  for (j = 0 ; j < n ; j++)
80  {
81  W [j] = 0 ;
82  }
83  for (i = 0 ; i < n ; i++)
84  {
85  pend = Tp [i+1] ;
86  for (p = Tp [i] ; p < pend ; p++)
87  {
88  j = Tj [p] ;
89  GET_POINTER (LU, Xip, Xlen, Xi, Xx, j, len) ;
90  xlen = W [j]++ ;
91  Xi [xlen] = i ;
92  Xx [xlen] = Tx [p] ;
93  }
94  }
95 
96  ASSERT (KLU_valid_LU (n, FALSE, Xip, Xlen, LU)) ;
97 }
98 
99 
100 /* ========================================================================== */
101 /* === KLU_sort ============================================================= */
102 /* ========================================================================== */
103 
104 template <typename Entry, typename Int>
105 Int KLU_sort
106 (
107  KLU_symbolic<Entry, Int> *Symbolic,
108  KLU_numeric<Entry, Int> *Numeric,
109  KLU_common<Entry, Int> *Common
110 )
111 {
112  Int *R, *W, *Tp, *Ti, *Lip, *Uip, *Llen, *Ulen ;
113  Entry *Tx ;
114  Unit **LUbx ;
115  Int n, nk, nz, block, nblocks, maxblock, k1 ;
116  size_t m1 ;
117 
118  if (Common == NULL)
119  {
120  return (FALSE) ;
121  }
122  Common->status = KLU_OK ;
123 
124  n = Symbolic->n ;
125  R = Symbolic->R ;
126  nblocks = Symbolic->nblocks ;
127  maxblock = Symbolic->maxblock ;
128 
129  Lip = Numeric->Lip ;
130  Llen = Numeric->Llen ;
131  Uip = Numeric->Uip ;
132  Ulen = Numeric->Ulen ;
133  LUbx = (Unit **) Numeric->LUbx ;
134 
135  m1 = ((size_t) maxblock) + 1 ;
136 
137  /* allocate workspace */
138  nz = MAX (Numeric->max_lnz_block, Numeric->max_unz_block) ;
139  W = (Int *) KLU_malloc (maxblock, sizeof (Int), Common) ;
140  Tp = (Int *) KLU_malloc (m1, sizeof (Int), Common) ;
141  Ti = (Int *) KLU_malloc (nz, sizeof (Int), Common) ;
142  Tx = (Entry *) KLU_malloc (nz, sizeof (Entry), Common) ;
143 
144  PRINTF (("\n======================= Start sort:\n")) ;
145 
146  if (Common->status == KLU_OK)
147  {
148  /* sort each block of L and U */
149  for (block = 0 ; block < nblocks ; block++)
150  {
151  k1 = R [block] ;
152  nk = R [block+1] - k1 ;
153  if (nk > 1)
154  {
155  PRINTF (("\n-------------------block: %d nk %d\n", block, nk)) ;
156  sort (nk, Lip + k1, Llen + k1, LUbx [block], Tp, Ti, Tx, W) ;
157  sort (nk, Uip + k1, Ulen + k1, LUbx [block], Tp, Ti, Tx, W) ;
158  }
159  }
160  }
161 
162  PRINTF (("\n======================= sort done.\n")) ;
163 
164  /* free workspace */
165  KLU_free (W, maxblock, sizeof (Int), Common) ;
166  KLU_free (Tp, m1, sizeof (Int), Common) ;
167  KLU_free (Ti, nz, sizeof (Int), Common) ;
168  KLU_free (Tx, nz, sizeof (Entry), Common) ;
169  return (Common->status == KLU_OK) ;
170 }
171 
172 #endif