src/amd/amd_postorder.c
author Alpar Juttner <alpar@cs.elte.hu>
Sun, 05 Dec 2010 17:35:23 +0100
changeset 2 4c8956a7bdf4
permissions -rw-r--r--
Set up CMAKE build environment
alpar@1
     1
/* ========================================================================= */
alpar@1
     2
/* === AMD_postorder ======================================================= */
alpar@1
     3
/* ========================================================================= */
alpar@1
     4
alpar@1
     5
/* ------------------------------------------------------------------------- */
alpar@1
     6
/* AMD, Copyright (c) Timothy A. Davis,                                      */
alpar@1
     7
/* Patrick R. Amestoy, and Iain S. Duff.  See ../README.txt for License.     */
alpar@1
     8
/* email: davis at cise.ufl.edu    CISE Department, Univ. of Florida.        */
alpar@1
     9
/* web: http://www.cise.ufl.edu/research/sparse/amd                          */
alpar@1
    10
/* ------------------------------------------------------------------------- */
alpar@1
    11
alpar@1
    12
/* Perform a postordering (via depth-first search) of an assembly tree. */
alpar@1
    13
alpar@1
    14
#include "amd_internal.h"
alpar@1
    15
alpar@1
    16
GLOBAL void AMD_postorder
alpar@1
    17
(
alpar@1
    18
    /* inputs, not modified on output: */
alpar@1
    19
    Int nn,             /* nodes are in the range 0..nn-1 */
alpar@1
    20
    Int Parent [ ],     /* Parent [j] is the parent of j, or EMPTY if root */
alpar@1
    21
    Int Nv [ ],         /* Nv [j] > 0 number of pivots represented by node j,
alpar@1
    22
                         * or zero if j is not a node. */
alpar@1
    23
    Int Fsize [ ],      /* Fsize [j]: size of node j */
alpar@1
    24
alpar@1
    25
    /* output, not defined on input: */
alpar@1
    26
    Int Order [ ],      /* output post-order */
alpar@1
    27
alpar@1
    28
    /* workspaces of size nn: */
alpar@1
    29
    Int Child [ ],
alpar@1
    30
    Int Sibling [ ],
alpar@1
    31
    Int Stack [ ]
alpar@1
    32
)
alpar@1
    33
{
alpar@1
    34
    Int i, j, k, parent, frsize, f, fprev, maxfrsize, bigfprev, bigf, fnext ;
alpar@1
    35
alpar@1
    36
    for (j = 0 ; j < nn ; j++)
alpar@1
    37
    {
alpar@1
    38
        Child [j] = EMPTY ;
alpar@1
    39
        Sibling [j] = EMPTY ;
alpar@1
    40
    }
alpar@1
    41
alpar@1
    42
    /* --------------------------------------------------------------------- */
alpar@1
    43
    /* place the children in link lists - bigger elements tend to be last */
alpar@1
    44
    /* --------------------------------------------------------------------- */
alpar@1
    45
alpar@1
    46
    for (j = nn-1 ; j >= 0 ; j--)
alpar@1
    47
    {
alpar@1
    48
        if (Nv [j] > 0)
alpar@1
    49
        {
alpar@1
    50
            /* this is an element */
alpar@1
    51
            parent = Parent [j] ;
alpar@1
    52
            if (parent != EMPTY)
alpar@1
    53
            {
alpar@1
    54
                /* place the element in link list of the children its parent */
alpar@1
    55
                /* bigger elements will tend to be at the end of the list */
alpar@1
    56
                Sibling [j] = Child [parent] ;
alpar@1
    57
                Child [parent] = j ;
alpar@1
    58
            }
alpar@1
    59
        }
alpar@1
    60
    }
alpar@1
    61
alpar@1
    62
#ifndef NDEBUG
alpar@1
    63
    {
alpar@1
    64
        Int nels, ff, nchild ;
alpar@1
    65
        AMD_DEBUG1 (("\n\n================================ AMD_postorder:\n"));
alpar@1
    66
        nels = 0 ;
alpar@1
    67
        for (j = 0 ; j < nn ; j++)
alpar@1
    68
        {
alpar@1
    69
            if (Nv [j] > 0)
alpar@1
    70
            {
alpar@1
    71
                AMD_DEBUG1 (( ""ID" :  nels "ID" npiv "ID" size "ID
alpar@1
    72
                    " parent "ID" maxfr "ID"\n", j, nels,
alpar@1
    73
                    Nv [j], Fsize [j], Parent [j], Fsize [j])) ;
alpar@1
    74
                /* this is an element */
alpar@1
    75
                /* dump the link list of children */
alpar@1
    76
                nchild = 0 ;
alpar@1
    77
                AMD_DEBUG1 (("    Children: ")) ;
alpar@1
    78
                for (ff = Child [j] ; ff != EMPTY ; ff = Sibling [ff])
alpar@1
    79
                {
alpar@1
    80
                    AMD_DEBUG1 ((ID" ", ff)) ;
alpar@1
    81
                    ASSERT (Parent [ff] == j) ;
alpar@1
    82
                    nchild++ ;
alpar@1
    83
                    ASSERT (nchild < nn) ;
alpar@1
    84
                }
alpar@1
    85
                AMD_DEBUG1 (("\n")) ;
alpar@1
    86
                parent = Parent [j] ;
alpar@1
    87
                if (parent != EMPTY)
alpar@1
    88
                {
alpar@1
    89
                    ASSERT (Nv [parent] > 0) ;
alpar@1
    90
                }
alpar@1
    91
                nels++ ;
alpar@1
    92
            }
alpar@1
    93
        }
alpar@1
    94
    }
alpar@1
    95
    AMD_DEBUG1 (("\n\nGo through the children of each node, and put\n"
alpar@1
    96
                 "the biggest child last in each list:\n")) ;
alpar@1
    97
#endif
alpar@1
    98
alpar@1
    99
    /* --------------------------------------------------------------------- */
alpar@1
   100
    /* place the largest child last in the list of children for each node */
alpar@1
   101
    /* --------------------------------------------------------------------- */
alpar@1
   102
alpar@1
   103
    for (i = 0 ; i < nn ; i++)
alpar@1
   104
    {
alpar@1
   105
        if (Nv [i] > 0 && Child [i] != EMPTY)
alpar@1
   106
        {
alpar@1
   107
alpar@1
   108
#ifndef NDEBUG
alpar@1
   109
            Int nchild ;
alpar@1
   110
            AMD_DEBUG1 (("Before partial sort, element "ID"\n", i)) ;
alpar@1
   111
            nchild = 0 ;
alpar@1
   112
            for (f = Child [i] ; f != EMPTY ; f = Sibling [f])
alpar@1
   113
            {
alpar@1
   114
                ASSERT (f >= 0 && f < nn) ;
alpar@1
   115
                AMD_DEBUG1 (("      f: "ID"  size: "ID"\n", f, Fsize [f])) ;
alpar@1
   116
                nchild++ ;
alpar@1
   117
                ASSERT (nchild <= nn) ;
alpar@1
   118
            }
alpar@1
   119
#endif
alpar@1
   120
alpar@1
   121
            /* find the biggest element in the child list */
alpar@1
   122
            fprev = EMPTY ;
alpar@1
   123
            maxfrsize = EMPTY ;
alpar@1
   124
            bigfprev = EMPTY ;
alpar@1
   125
            bigf = EMPTY ;
alpar@1
   126
            for (f = Child [i] ; f != EMPTY ; f = Sibling [f])
alpar@1
   127
            {
alpar@1
   128
                ASSERT (f >= 0 && f < nn) ;
alpar@1
   129
                frsize = Fsize [f] ;
alpar@1
   130
                if (frsize >= maxfrsize)
alpar@1
   131
                {
alpar@1
   132
                    /* this is the biggest seen so far */
alpar@1
   133
                    maxfrsize = frsize ;
alpar@1
   134
                    bigfprev = fprev ;
alpar@1
   135
                    bigf = f ;
alpar@1
   136
                }
alpar@1
   137
                fprev = f ;
alpar@1
   138
            }
alpar@1
   139
            ASSERT (bigf != EMPTY) ;
alpar@1
   140
alpar@1
   141
            fnext = Sibling [bigf] ;
alpar@1
   142
alpar@1
   143
            AMD_DEBUG1 (("bigf "ID" maxfrsize "ID" bigfprev "ID" fnext "ID
alpar@1
   144
                " fprev " ID"\n", bigf, maxfrsize, bigfprev, fnext, fprev)) ;
alpar@1
   145
alpar@1
   146
            if (fnext != EMPTY)
alpar@1
   147
            {
alpar@1
   148
                /* if fnext is EMPTY then bigf is already at the end of list */
alpar@1
   149
alpar@1
   150
                if (bigfprev == EMPTY)
alpar@1
   151
                {
alpar@1
   152
                    /* delete bigf from the element of the list */
alpar@1
   153
                    Child [i] = fnext ;
alpar@1
   154
                }
alpar@1
   155
                else
alpar@1
   156
                {
alpar@1
   157
                    /* delete bigf from the middle of the list */
alpar@1
   158
                    Sibling [bigfprev] = fnext ;
alpar@1
   159
                }
alpar@1
   160
alpar@1
   161
                /* put bigf at the end of the list */
alpar@1
   162
                Sibling [bigf] = EMPTY ;
alpar@1
   163
                ASSERT (Child [i] != EMPTY) ;
alpar@1
   164
                ASSERT (fprev != bigf) ;
alpar@1
   165
                ASSERT (fprev != EMPTY) ;
alpar@1
   166
                Sibling [fprev] = bigf ;
alpar@1
   167
            }
alpar@1
   168
alpar@1
   169
#ifndef NDEBUG
alpar@1
   170
            AMD_DEBUG1 (("After partial sort, element "ID"\n", i)) ;
alpar@1
   171
            for (f = Child [i] ; f != EMPTY ; f = Sibling [f])
alpar@1
   172
            {
alpar@1
   173
                ASSERT (f >= 0 && f < nn) ;
alpar@1
   174
                AMD_DEBUG1 (("        "ID"  "ID"\n", f, Fsize [f])) ;
alpar@1
   175
                ASSERT (Nv [f] > 0) ;
alpar@1
   176
                nchild-- ;
alpar@1
   177
            }
alpar@1
   178
            ASSERT (nchild == 0) ;
alpar@1
   179
#endif
alpar@1
   180
alpar@1
   181
        }
alpar@1
   182
    }
alpar@1
   183
alpar@1
   184
    /* --------------------------------------------------------------------- */
alpar@1
   185
    /* postorder the assembly tree */
alpar@1
   186
    /* --------------------------------------------------------------------- */
alpar@1
   187
alpar@1
   188
    for (i = 0 ; i < nn ; i++)
alpar@1
   189
    {
alpar@1
   190
        Order [i] = EMPTY ;
alpar@1
   191
    }
alpar@1
   192
alpar@1
   193
    k = 0 ;
alpar@1
   194
alpar@1
   195
    for (i = 0 ; i < nn ; i++)
alpar@1
   196
    {
alpar@1
   197
        if (Parent [i] == EMPTY && Nv [i] > 0)
alpar@1
   198
        {
alpar@1
   199
            AMD_DEBUG1 (("Root of assembly tree "ID"\n", i)) ;
alpar@1
   200
            k = AMD_post_tree (i, k, Child, Sibling, Order, Stack
alpar@1
   201
#ifndef NDEBUG
alpar@1
   202
                , nn
alpar@1
   203
#endif
alpar@1
   204
                ) ;
alpar@1
   205
        }
alpar@1
   206
    }
alpar@1
   207
}