1 /* ========================================================================= */
2 /* === AMD_preprocess ====================================================== */
3 /* ========================================================================= */
4 
5 /* ------------------------------------------------------------------------- */
6 /* AMD, Copyright (c) Timothy A. Davis,					     */
7 /* Patrick R. Amestoy, and Iain S. Duff.  See ../README.txt for License.     */
8 /* email: DrTimothyAldenDavis@gmail.com                                      */
9 /* ------------------------------------------------------------------------- */
10 
11 /* Sorts, removes duplicate entries, and transposes from the nonzero pattern of
12  * a column-form matrix A, to obtain the matrix R.  The input matrix can have
13  * duplicate entries and/or unsorted columns (AMD_valid (n,Ap,Ai) must not be
14  * AMD_INVALID).
15  *
16  * This input condition is NOT checked.  This routine is not user-callable.
17  */
18 
19 module amd_preprocess;
20 
21 nothrow @nogc extern(C):
22 
23 import amd_internal;
24 import amd_valid;
25 import amd;
26 
27 /* ========================================================================= */
28 /* === AMD_preprocess ====================================================== */
29 /* ========================================================================= */
30 
31 /* AMD_preprocess does not check its input for errors or allocate workspace.
32  * On input, the condition (AMD_valid (n,n,Ap,Ai) != AMD_INVALID) must hold.
33  */
34 
35 void AMD_preprocess
36 (
37     Int n,		/* input matrix: A is n-by-n */
38     const Int * Ap,	/* size n+1 */
39     const Int * Ai,	/* size nz = Ap [n] */
40 
41     /* output matrix R: */
42     Int * Rp,		/* size n+1 */
43     Int * Ri,		/* size nz (or less, if duplicates present) */
44 
45     Int * W,		/* workspace of size n */
46     Int * Flag	/* workspace of size n */
47 )
48 {
49 
50     /* --------------------------------------------------------------------- */
51     /* local variables */
52     /* --------------------------------------------------------------------- */
53 
54     Int i, j, p, p2 ;
55 
56     ASSERT (AMD_valid (n, n, Ap, Ai) != AMD_INVALID) ;
57 
58     /* --------------------------------------------------------------------- */
59     /* count the entries in each row of A (excluding duplicates) */
60     /* --------------------------------------------------------------------- */
61 
62     for (i = 0 ; i < n ; i++)
63     {
64 	W [i] = 0 ;		/* # of nonzeros in row i (excl duplicates) */
65 	Flag [i] = EMPTY ;	/* Flag [i] = j if i appears in column j */
66     }
67     for (j = 0 ; j < n ; j++)
68     {
69 	p2 = Ap [j+1] ;
70 	for (p = Ap [j] ; p < p2 ; p++)
71 	{
72 	    i = Ai [p] ;
73 	    if (Flag [i] != j)
74 	    {
75 		/* row index i has not yet appeared in column j */
76 		W [i]++ ;	    /* one more entry in row i */
77 		Flag [i] = j ;	    /* flag row index i as appearing in col j*/
78 	    }
79 	}
80     }
81 
82     /* --------------------------------------------------------------------- */
83     /* compute the row pointers for R */
84     /* --------------------------------------------------------------------- */
85 
86     Rp [0] = 0 ;
87     for (i = 0 ; i < n ; i++)
88     {
89 	Rp [i+1] = Rp [i] + W [i] ;
90     }
91     for (i = 0 ; i < n ; i++)
92     {
93 	W [i] = Rp [i] ;
94 	Flag [i] = EMPTY ;
95     }
96 
97     /* --------------------------------------------------------------------- */
98     /* construct the row form matrix R */
99     /* --------------------------------------------------------------------- */
100 
101     /* R = row form of pattern of A */
102     for (j = 0 ; j < n ; j++)
103     {
104 	p2 = Ap [j+1] ;
105 	for (p = Ap [j] ; p < p2 ; p++)
106 	{
107 	    i = Ai [p] ;
108 	    if (Flag [i] != j)
109 	    {
110 		/* row index i has not yet appeared in column j */
111 		Ri [W [i]++] = j ;  /* put col j in row i */
112 		Flag [i] = j ;	    /* flag row index i as appearing in col j*/
113 	    }
114 	}
115     }
116 
117 version(NDEBUG){}
118 else {
119     ASSERT (AMD_valid (n, n, Rp, Ri) == AMD_OK) ;
120     for (j = 0 ; j < n ; j++)
121     {
122 	ASSERT (W [j] == Rp [j+1]) ;
123     }
124 }
125 }