1 /*
2  * lu_garbage_perm.c
3  *
4  * Copyright (C) 2016-2018  ERGO-Code
5  *
6  */
7 
8 #include "lu_internal.h"
9 
10 /*
11  * lu_garbage_perm()
12  *
13  * The sequence of pivot columns and pivot rows is stored in
14  *
15  *  pivotcol[0..pivotlen-1], pivotrow[0..pivotlen-1],
16  *
17  * where pivotlen >= m. When pivotlen > m, then the arrays contain duplicates.
18  * For each index its last occurence in the arrays is its position in the pivot
19  * sequence and occurences before mark unused slots.
20  *
21  * This routine removes duplicates and compresses the indices such that
22  * pivotlen == m.
23  */
24 
lu_garbage_perm(struct lu * this)25 void lu_garbage_perm(struct lu *this)
26 {
27     const lu_int m      = this->m;
28     lu_int pivotlen     = this->pivotlen;
29     lu_int *pivotcol    = this->pivotcol;
30     lu_int *pivotrow    = this->pivotrow;
31     lu_int *marked      = this->marked;
32 
33     lu_int j, get, put, marker;
34 
35     if (pivotlen > m)
36     {
37         marker = ++this->marker;
38         put = pivotlen;
39         for (get = pivotlen-1; get >= 0; get--)
40         {
41             if (marked[j = pivotcol[get]] != marker)
42             {
43                 marked[j] = marker;
44                 pivotcol[--put] = j;
45                 pivotrow[put] = pivotrow[get];
46             }
47         }
48         assert(put+m == pivotlen);
49         memmove(pivotcol, pivotcol+put, m*sizeof(lu_int));
50         memmove(pivotrow, pivotrow+put, m*sizeof(lu_int));
51         this->pivotlen = m;
52     }
53 }
54