src/amd/amd_post_tree.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_post_tree ======================================================= */
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
/* Post-ordering of a supernodal elimination tree.  */
alpar@1
    13
alpar@1
    14
#include "amd_internal.h"
alpar@1
    15
alpar@1
    16
GLOBAL Int AMD_post_tree
alpar@1
    17
(
alpar@1
    18
    Int root,                   /* root of the tree */
alpar@1
    19
    Int k,                      /* start numbering at k */
alpar@1
    20
    Int Child [ ],              /* input argument of size nn, undefined on
alpar@1
    21
                                 * output.  Child [i] is the head of a link
alpar@1
    22
                                 * list of all nodes that are children of node
alpar@1
    23
                                 * i in the tree. */
alpar@1
    24
    const Int Sibling [ ],      /* input argument of size nn, not modified.
alpar@1
    25
                                 * If f is a node in the link list of the
alpar@1
    26
                                 * children of node i, then Sibling [f] is the
alpar@1
    27
                                 * next child of node i.
alpar@1
    28
                                 */
alpar@1
    29
    Int Order [ ],              /* output order, of size nn.  Order [i] = k
alpar@1
    30
                                 * if node i is the kth node of the reordered
alpar@1
    31
                                 * tree. */
alpar@1
    32
    Int Stack [ ]               /* workspace of size nn */
alpar@1
    33
#ifndef NDEBUG
alpar@1
    34
    , Int nn                    /* nodes are in the range 0..nn-1. */
alpar@1
    35
#endif
alpar@1
    36
)
alpar@1
    37
{
alpar@1
    38
    Int f, head, h, i ;
alpar@1
    39
alpar@1
    40
#if 0
alpar@1
    41
    /* --------------------------------------------------------------------- */
alpar@1
    42
    /* recursive version (Stack [ ] is not used): */
alpar@1
    43
    /* --------------------------------------------------------------------- */
alpar@1
    44
alpar@1
    45
    /* this is simple, but can caouse stack overflow if nn is large */
alpar@1
    46
    i = root ;
alpar@1
    47
    for (f = Child [i] ; f != EMPTY ; f = Sibling [f])
alpar@1
    48
    {
alpar@1
    49
        k = AMD_post_tree (f, k, Child, Sibling, Order, Stack, nn) ;
alpar@1
    50
    }
alpar@1
    51
    Order [i] = k++ ;
alpar@1
    52
    return (k) ;
alpar@1
    53
#endif
alpar@1
    54
alpar@1
    55
    /* --------------------------------------------------------------------- */
alpar@1
    56
    /* non-recursive version, using an explicit stack */
alpar@1
    57
    /* --------------------------------------------------------------------- */
alpar@1
    58
alpar@1
    59
    /* push root on the stack */
alpar@1
    60
    head = 0 ;
alpar@1
    61
    Stack [0] = root ;
alpar@1
    62
alpar@1
    63
    while (head >= 0)
alpar@1
    64
    {
alpar@1
    65
        /* get head of stack */
alpar@1
    66
        ASSERT (head < nn) ;
alpar@1
    67
        i = Stack [head] ;
alpar@1
    68
        AMD_DEBUG1 (("head of stack "ID" \n", i)) ;
alpar@1
    69
        ASSERT (i >= 0 && i < nn) ;
alpar@1
    70
alpar@1
    71
        if (Child [i] != EMPTY)
alpar@1
    72
        {
alpar@1
    73
            /* the children of i are not yet ordered */
alpar@1
    74
            /* push each child onto the stack in reverse order */
alpar@1
    75
            /* so that small ones at the head of the list get popped first */
alpar@1
    76
            /* and the biggest one at the end of the list gets popped last */
alpar@1
    77
            for (f = Child [i] ; f != EMPTY ; f = Sibling [f])
alpar@1
    78
            {
alpar@1
    79
                head++ ;
alpar@1
    80
                ASSERT (head < nn) ;
alpar@1
    81
                ASSERT (f >= 0 && f < nn) ;
alpar@1
    82
            }
alpar@1
    83
            h = head ;
alpar@1
    84
            ASSERT (head < nn) ;
alpar@1
    85
            for (f = Child [i] ; f != EMPTY ; f = Sibling [f])
alpar@1
    86
            {
alpar@1
    87
                ASSERT (h > 0) ;
alpar@1
    88
                Stack [h--] = f ;
alpar@1
    89
                AMD_DEBUG1 (("push "ID" on stack\n", f)) ;
alpar@1
    90
                ASSERT (f >= 0 && f < nn) ;
alpar@1
    91
            }
alpar@1
    92
            ASSERT (Stack [h] == i) ;
alpar@1
    93
alpar@1
    94
            /* delete child list so that i gets ordered next time we see it */
alpar@1
    95
            Child [i] = EMPTY ;
alpar@1
    96
        }
alpar@1
    97
        else
alpar@1
    98
        {
alpar@1
    99
            /* the children of i (if there were any) are already ordered */
alpar@1
   100
            /* remove i from the stack and order it.  Front i is kth front */
alpar@1
   101
            head-- ;
alpar@1
   102
            AMD_DEBUG1 (("pop "ID" order "ID"\n", i, k)) ;
alpar@1
   103
            Order [i] = k++ ;
alpar@1
   104
            ASSERT (k <= nn) ;
alpar@1
   105
        }
alpar@1
   106
alpar@1
   107
#ifndef NDEBUG
alpar@1
   108
        AMD_DEBUG1 (("\nStack:")) ;
alpar@1
   109
        for (h = head ; h >= 0 ; h--)
alpar@1
   110
        {
alpar@1
   111
            Int j = Stack [h] ;
alpar@1
   112
            AMD_DEBUG1 ((" "ID, j)) ;
alpar@1
   113
            ASSERT (j >= 0 && j < nn) ;
alpar@1
   114
        }
alpar@1
   115
        AMD_DEBUG1 (("\n\n")) ;
alpar@1
   116
        ASSERT (head < nn) ;
alpar@1
   117
#endif
alpar@1
   118
alpar@1
   119
    }
alpar@1
   120
    return (k) ;
alpar@1
   121
}