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
29template <typename Entry, typename Int>
30static 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
104template <typename Entry, typename Int>
105Int 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