⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sp_coletree.c~

📁 SuperLU is a general purpose library for the direct solution of large, sparse, nonsymmetric systems
💻 C~
字号:
/*! @file sp_coletree.c * \brief Tree layout and computation routines * *<pre> * -- SuperLU routine (version 3.1) -- * Univ. of California Berkeley, Xerox Palo Alto Research Center, * and Lawrence Berkeley National Lab. * August 1, 2008 * * Copyright (c) 1994 by Xerox Corporation.  All rights reserved. * * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY * EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK. * * Permission is hereby granted to use or copy this program for any * purpose, provided the above notices are retained on all copies. * Permission to modify the code and to distribute modified code is * granted, provided the above notices are retained, and a notice that * the code was modified is included with the above copyright notice. * </pre>*//*  Elimination tree computation and layout routines */#include <stdio.h>#include <stdlib.h>#include "slu_ddefs.h"/*  *  Implementation of disjoint set union routines. *  Elements are integers in 0..n-1, and the  *  names of the sets themselves are of type int. *   *  Calls are: *  initialize_disjoint_sets (n) initial call. *  s = make_set (i)             returns a set containing only i. *  s = link (t, u)		 returns s = t union u, destroying t and u. *  s = find (i)		 return name of set containing i. *  finalize_disjoint_sets 	 final call. * *  This implementation uses path compression but not weighted union. *  See Tarjan's book for details. *  John Gilbert, CMI, 1987. * *  Implemented path-halving by XSL 07/05/95. */static int *mxCallocInt(int n){    register int i;    int *buf;    buf = (int *) SUPERLU_MALLOC( n * sizeof(int) );    if ( !buf ) {         ABORT("SUPERLU_MALLOC fails for buf in mxCallocInt()");       }    for (i = 0; i < n; i++) buf[i] = 0;    return (buf);}      staticvoid initialize_disjoint_sets (			       int n,			       int **pp			       ){	(*pp) = mxCallocInt(n);}staticint make_set (	      int i,	      int *pp	      ){	pp[i] = i;	return i;}staticint link (	  int s,	  int t,	  int *pp	  ){	pp[s] = t;	return t;}/* PATH HALVING */staticint find (	  int i,	  int *pp	  ){    register int p, gp;        p = pp[i];    gp = pp[p];    while (gp != p) {	pp[i] = gp;	i = gp;	p = pp[i];	gp = pp[p];    }    return (p);}#if 0/* PATH COMPRESSION */staticint find (	int i	){	if (pp[i] != i) 		pp[i] = find (pp[i]);	return pp[i];}#endifstaticvoid finalize_disjoint_sets (			     int *pp			     ){	SUPERLU_FREE(pp);}/* *      Find the elimination tree for A'*A. *      This uses something similar to Liu's algorithm.  *      It runs in time O(nz(A)*log n) and does not form A'*A. * *      Input: *        Sparse matrix A.  Numeric values are ignored, so any *        explicit zeros are treated as nonzero. *      Output: *        Integer array of parents representing the elimination *        tree of the symbolic product A'*A.  Each vertex is a *        column of A, and nc means a root of the elimination forest. * *      John R. Gilbert, Xerox, 10 Dec 1990 *      Based on code by JRG dated 1987, 1988, and 1990. *//* * Nonsymmetric elimination tree */intsp_coletree(	    int *acolst, int *acolend, /* column start and end past 1 */	    int *arow,                 /* row indices of A */	    int nr, int nc,            /* dimension of A */	    int *parent	               /* parent in elim tree */	    ){	int	*root;			/* root of subtee of etree 	*/	int     *firstcol;		/* first nonzero col in each row*/	int	rset, cset;             	int	row, col;	int	rroot;	int	p;	int     *pp;	root = mxCallocInt (nc);	initialize_disjoint_sets (nc, &pp);	/* Compute firstcol[row] = first nonzero column in row */	firstcol = mxCallocInt (nr);	for (row = 0; row < nr; firstcol[row++] = nc);	for (col = 0; col < nc; col++) 		for (p = acolst[col]; p < acolend[col]; p++) {			row = arow[p];			firstcol[row] = SUPERLU_MIN(firstcol[row], col);		}	/* Compute etree by Liu's algorithm for symmetric matrices,           except use (firstcol[r],c) in place of an edge (r,c) of A.	   Thus each row clique in A'*A is replaced by a star	   centered at its first vertex, which has the same fill. */	for (col = 0; col < nc; col++) {		cset = make_set (col, pp);		root[cset] = col;		parent[col] = nc; /* Matlab */		for (p = acolst[col]; p < acolend[col]; p++) {			row = firstcol[arow[p]];			if (row >= col) continue;			rset = find (row, pp);			rroot = root[rset];			if (rroot != col) {				parent[rroot] = col;				cset = link (cset, rset, pp);				root[cset] = col;			}		}	}	SUPERLU_FREE (root);	SUPERLU_FREE (firstcol);	finalize_disjoint_sets (pp);	return 0;}/* *  q = TreePostorder (n, p); * *	Postorder a tree. *	Input: *	  p is a vector of parent pointers for a forest whose *        vertices are the integers 0 to n-1; p[root]==n. *	Output: *	  q is a vector indexed by 0..n-1 such that q[i] is the *	  i-th vertex in a postorder numbering of the tree. * *        ( 2/7/95 modified by X.Li: *          q is a vector indexed by 0:n-1 such that vertex i is the *          q[i]-th vertex in a postorder numbering of the tree. *          That is, this is the inverse of the previous q. ) * *	In the child structure, lower-numbered children are represented *	first, so that a tree which is already numbered in postorder *	will not have its order changed. *     *  Written by John Gilbert, Xerox, 10 Dec 1990. *  Based on code written by John Gilbert at CMI in 1987. */static/* * Depth-first search from vertex v. */void etdfs (	    int	  v,	    int   first_kid[],	    int   next_kid[],	    int   post[], 	    int   *postnum	    ){	int	w;	for (w = first_kid[v]; w != -1; w = next_kid[w]) {		etdfs (w, first_kid, next_kid, post, postnum);	}	/* post[postnum++] = v; in Matlab */	post[v] = (*postnum)++;    /* Modified by X. Li on 08/10/07 */}static/* * Depth-first search from vertex n. * No recursion. */void nr_etdfs (int n, int *parent,	       int *first_kid, int *next_kid,	       int *post, int postnum){    int current = n, first, next;    while (postnum != n){             /* no kid for the current node */        first = first_kid[current];        /* no first kid for the current node */        if (first == -1){            /* numbering this node because it has no kid */            post[current] = postnum++;            /* looking for the next kid */            next = next_kid[current];            while (next == -1){                /* no more kids : back to the parent node */                current = parent[current];                /* numbering the parent node */                post[current] = postnum++;                /* get the next kid */                next = next_kid[current];	    }                        /* stopping criterion */            if (postnum==n+1) return;            /* updating current node */            current = next;        }        /* updating current node */        else {            current = first;	}    }}/* * Post order a tree */int *TreePostorder(		   int n,		   int *parent		   ){        int	*first_kid, *next_kid;	/* Linked list of children.	*/        int	*post, postnum;	int	v, dad;	/* Allocate storage for working arrays and results	*/	first_kid = 	mxCallocInt (n+1);	next_kid  = 	mxCallocInt (n+1);	post	  = 	mxCallocInt (n+1);	/* Set up structure describing children */	for (v = 0; v <= n; first_kid[v++] = -1);	for (v = n-1; v >= 0; v--) {		dad = parent[v];		next_kid[v] = first_kid[dad];		first_kid[dad] = v;	}	/* Depth-first search from dummy root vertex #n */	postnum = 0;#if 0	/* recursion */	etdfs (n, first_kid, next_kid, post, &postnum);#else	/* no recursion */	nr_etdfs(n, parent, first_kid, next_kid, post, postnum);#endif	SUPERLU_FREE (first_kid);	SUPERLU_FREE (next_kid);	return post;}/* *      p = spsymetree (A); * *      Find the elimination tree for symmetric matrix A. *      This uses Liu's algorithm, and runs in time O(nz*log n). * *      Input: *        Square sparse matrix A.  No check is made for symmetry; *        elements below and on the diagonal are ignored. *        Numeric values are ignored, so any explicit zeros are  *        treated as nonzero. *      Output: *        Integer array of parents representing the etree, with n *        meaning a root of the elimination forest. *      Note:   *        This routine uses only the upper triangle, while sparse *        Cholesky (as in spchol.c) uses only the lower.  Matlab's *        dense Cholesky uses only the upper.  This routine could *        be modified to use the lower triangle either by transposing *        the matrix or by traversing it by rows with auxiliary *        pointer and link arrays. * *      John R. Gilbert, Xerox, 10 Dec 1990 *      Based on code by JRG dated 1987, 1988, and 1990. *      Modified by X.S. Li, November 1999. *//* * Symmetric elimination tree */intsp_symetree(	    int *acolst, int *acolend, /* column starts and ends past 1 */	    int *arow,            /* row indices of A */	    int n,                /* dimension of A */	    int *parent	    /* parent in elim tree */	    ){	int	*root;		    /* root of subtree of etree 	*/	int	rset, cset;             	int	row, col;	int	rroot;	int	p;	int     *pp;	root = mxCallocInt (n);	initialize_disjoint_sets (n, &pp);	for (col = 0; col < n; col++) {		cset = make_set (col, pp);		root[cset] = col;		parent[col] = n; /* Matlab */		for (p = acolst[col]; p < acolend[col]; p++) {			row = arow[p];			if (row >= col) continue;			rset = find (row, pp);			rroot = root[rset];			if (rroot != col) {				parent[rroot] = col;				cset = link (cset, rset, pp);				root[cset] = col;			}		}	}	SUPERLU_FREE (root);	finalize_disjoint_sets (pp);	return 0;} /* SP_SYMETREE */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -