コード例 #1
0
ファイル: int_list.c プロジェクト: cran/BPHO
void print_int_list(int_list * list, int items_line)
{ /*int i,k;*/
  int_node* p = list->next;
  
  printf("Totally %d vectors in list\n", list->ll);
  int i;
  for(i = 0; i < list->ll; i++){
     printf("[[%d]]:\n", i);
     int k;
     print_int_vec(p->value,items_line);          
     p = p->next;     
  }  
}
コード例 #2
0
ファイル: qrnzcnt.c プロジェクト: DBorello/OpenSees
int
qrnzcnt(int neqns, int adjlen, int *xadj, int *adjncy, int *zfdperm,
	int *perm, int *invp, int *etpar, int *colcnt_h,
	int *nlnz, int *part_super_ata, int *part_super_h)
{
/*
     o 5/20/95 Xiaoye S. Li:
         Translated from fcnthn.f using f2c;
         Modified to use 0-based indexing in C;
         Initialize xsup = 0 as suggested by B. Peyton to handle singletons.

     o 5/24/95 Xiaoye S. Li:
         Modified to compute row/column counts of R in QR factorization
           1. Compute row counts of A, and f(i) in a separate pass
	                        def
	   2. Re-define hadj[k] ===   U    { j | j in Struct(A_i*), j>k}
	                          i:f(i)==k
	 Record supernode partition in part_super_ata[*] of size neqns:
	   part_super_ata[k] = size of the supernode beginning at column k;
 	                     = 0, elsewhere.

     o 1/16/96 Xiaoye S. Li:
         Modified to incorporate row/column counts of the Householder
	 Matrix H in the QR factorization A --> H , R.
	 
	 Record supernode partition in part_super_h[*] of size neqns:
	   part_super_h[k] = size of the supernode beginning at column k;
 	                   = 0, elsewhere.
	 
   ***********************************************************************   
     Version:        0.3   
     Last modified:  January 12, 1995   
     Authors:        Esmond G. Ng and Barry W. Peyton   

     Mathematical Sciences Section, Oak Ridge National Laboratoy   

   ***********************************************************************   
   **************     FCNTHN  ..... FIND NONZERO COUNTS    ***************   
   ***********************************************************************   

     PURPOSE:   
         THIS SUBROUTINE DETERMINES THE ROW COUNTS AND COLUMN COUNTS IN   
         THE CHOLESKY FACTOR.  IT USES A DISJOINT SET UNION ALGORITHM.   

         TECHNIQUES:   
         1) SUPERNODE DETECTION.   
         2) PATH HALVING.   
         3) NO UNION BY RANK.   

     NOTES:   
         1) ASSUMES A POSTORDERING OF THE ELIMINATION TREE.   

     INPUT PARAMETERS:   
         (I) NEQNS       -   NUMBER OF EQUATIONS.   
         (I) ADJLEN      -   LENGTH OF ADJACENCY STRUCTURE.   
         (I) XADJ(*)     -   ARRAY OF LENGTH NEQNS+1, CONTAINING POINTERS   
                             TO THE ADJACENCY STRUCTURE.
         (I) ADJNCY(*)   -   ARRAY OF LENGTH ADJLEN, CONTAINING   
                             THE ADJACENCY STRUCTURE.
         (I) ZFDPERM(*)  -   THE ROW PERMUTATION VECTOR THAT PERMUTES THE
	                     MATRIX TO HAVE ZERO-FREE DIAGONAL.
			     ZFDPERM(I) = J MEANS ROW I OF THE ORIGINAL
			     MATRIX IS IN ROW J OF THE PERMUTED MATRIX.
         (I) PERM(*)     -   ARRAY OF LENGTH NEQNS, CONTAINING THE   
                             POSTORDERING.   
         (I) INVP(*)     -   ARRAY OF LENGTH NEQNS, CONTAINING THE   
                             INVERSE OF THE POSTORDERING.   
         (I) ETPAR(*)    -   ARRAY OF LENGTH NEQNS, CONTAINING THE   
                             ELIMINATION TREE OF THE POSTORDERED MATRIX.   

     OUTPUT PARAMETERS:   
         (I) ROWCNT(*)   -   ARRAY OF LENGTH NEQNS, CONTAINING THE NUMBER   
                             OF NONZEROS IN EACH ROW OF THE FACTOR,   
                             INCLUDING THE DIAGONAL ENTRY.   
         (I) COLCNT(*)   -   ARRAY OF LENGTH NEQNS, CONTAINING THE NUMBER   
                             OF NONZEROS IN EACH COLUMN OF THE FACTOR,   
                             INCLUDING THE DIAGONAL ENTRY.   
         (I) NLNZ        -   NUMBER OF NONZEROS IN THE FACTOR, INCLUDING   
                             THE DIAGONAL ENTRIES.
         (I) PART_SUPER_ATA  SUPERNODE PARTITION IN THE CHOLESKY FACTOR
	                     OF A'A.
	 (I) PART_SUPER_H    SUPERNODE PARTITION IN THE HOUSEHOLDER
	                     MATRIX H.

     WORK PARAMETERS:   
         (I) SET(*)      -   ARRAY OF LENGTH NEQNS USED TO MAINTAIN THE   
                             DISJOINT SETS (I.E., SUBTREES).   
         (I) PRVLF(*)    -   ARRAY OF LENGTH NEQNS USED TO RECORD THE   
                             PREVIOUS LEAF OF EACH ROW SUBTREE.   
         (I) LEVEL(*)    -   ARRAY OF LENGTH NEQNS+1 CONTAINING THE LEVEL   
                             (DISTANCE FROM THE ROOT).   
         (I) WEIGHT(*)   -   ARRAY OF LENGTH NEQNS+1 CONTAINING WEIGHTS   
                             USED TO COMPUTE COLUMN COUNTS.   
         (I) FDESC(*)    -   ARRAY OF LENGTH NEQNS+1 CONTAINING THE   
                             FIRST (I.E., LOWEST-NUMBERED) DESCENDANT.   
         (I) NCHILD(*)   -   ARRAY OF LENGTH NEQNS+1 CONTAINING THE   
                             NUMBER OF CHILDREN.   
         (I) PRVNBR(*)   -   ARRAY OF LENGTH NEQNS USED TO RECORD THE   
                             PREVIOUS ``LOWER NEIGHBOR'' OF EACH NODE.   

     FIRST CREATED ON    APRIL 12, 1990.   
     LAST UPDATED ON     JANUARY 12, 1995.   

   ***********************************************************************   
*/

    /* Local variables */
    int  temp, last1, last2, i, j, k, lflag, pleaf, hinbr, jstop,
	 jstrt, ifdesc, oldnbr, parent, lownbr, lca;
    int  xsup;        /* the ongoing supernode */
    int  *set, *prvlf, *level, *weight, *fdesc, *nchild, *prvnbr;
    int  *fnz;        /* first nonzero column subscript in each row */
    int  *marker;     /* used to remove duplicate indices */
    int  *fnz_hadj;   /* higher-numbered neighbors of the first nonzero
			 (higher adjacency set of A'A) */
    int  *hadj_begin; /* pointers to the fnz_hadj[] structure */
    int  *hadj_end;   /* pointers to the fnz_hadj[] structure */

    /* Locally malloc'd room for QR purpose */

    /* ----------------------------------------------------------
       FIRST set is defined as first[j] := { i : f[i] = j } ,
       which is a collection of disjoint sets of integers between
       0 and n-1.
       ---------------------------------------------------------- */    
    int  *first;    /* header pointing to FIRST set */
    int  *firstset; /* linked list to describe FIRST set */
    int  *weight_h; /* weights for H */
    int  *rowcnt;   /* row colunts for Lc */ 
    int  *colcnt;   /* column colunts for Lc */ 
    int  *rowcnt_h; /* row colunts for H */ 
    int  nsuper;    /* total number of fundamental supernodes in Lc */
    int  nhnz;
    
    set    = intMalloc(neqns);
    prvlf  = intMalloc(neqns);
    level  = intMalloc(neqns + 1);    /* length n+1 */
    weight = intMalloc(neqns + 1);    /* length n+1 */
    fdesc  = intMalloc(neqns + 1);    /* length n+1 */
    nchild = intMalloc(neqns + 1);    /* length n+1 */
    prvnbr = intMalloc(neqns);
    fnz_hadj   = intMalloc(adjlen + 2*neqns + 1);
    hadj_begin = fnz_hadj + adjlen;        /* neqns+1 */
    hadj_end   = hadj_begin + neqns + 1;   /* neqns */
    fnz        = set;    /* aliasing for the time being */
    marker     = prvlf;  /*     "    "    "             */
    
    first    = intMalloc(neqns);
    firstset = intMalloc(neqns);
    weight_h = intCalloc(neqns + 1);  /* length n+1 */
    rowcnt_h = intMalloc(neqns);
    rowcnt   = intMalloc(neqns);
    colcnt   = intMalloc(neqns);
    
    /* -------------------------------------------------------
     * Compute fnz[*], first[*], nchild[*] and row counts of A.
     * Also find supernodes in H.
     *
     * Note that the structure of each row of H forms a simple path in
     * the etree between fnz[i] and i (George, Liu & Ng (1988)).
     * The "first vertices" of the supernodes in H are characterized
     * by the following conditions:
     *     1) first nonzero in each row of A, i.e., fnz(i);
     *  or 2) nchild >= 2;
     * ------------------------------------------------------- */
    for (k = 0; k < neqns; ++k) {
	fnz[k] = first[k] = marker[k] = EMPTY;
	rowcnt[k] = part_super_ata[k] = 0;
	part_super_h[k] = 0;
	nchild[k] = 0;
    }
    nchild[ROOT] = 0;
    xsup = 0;
    for (k = 0; k < neqns; ++k) {
	parent = etpar[k];
	++nchild[parent];
	if ( k != 0 && nchild[k] >= 2 ) {
	    part_super_h[xsup] = k - xsup;
	    xsup = k;
	}
	oldnbr = perm[k];
	for (j = xadj[oldnbr]; j < xadj[oldnbr+1]; ++j) {
	    /*
	     * Renumber vertices of G(A) by postorder
	     */
/*	    i = invp[zfdperm[adjncy[j]]];*/
	    i = zfdperm[adjncy[j]];
	    ++rowcnt[i];
	    if (fnz[i] == EMPTY) {
		/*
		 * Build linked list to describe FIRST sets
		 */
		fnz[i] = k;
		firstset[i] = first[k];
		first[k] = i;
		if ( k != 0 && xsup != k ) {
		    part_super_h[xsup] = k - xsup;
		    xsup = k;
		}
	    }
	}
    }
    part_super_h[xsup] = neqns - xsup;

#ifdef CHK_NZCNT
    printf("%8s%8s%8s\n", "k", "fnz", "first");
    for (k = 0; k < neqns; ++k)
	printf("%8d%8d%8d\n", k, fnz[k], first[k]);
#endif
    
    /* Set up fnz_hadj[*] structure. */
    hadj_begin[0] = 0;
    for (k = 0; k < neqns; ++k) {
	temp = 0;
	oldnbr = perm[k];
	hadj_end[k] = hadj_begin[k];
	for (j = xadj[oldnbr]; j < xadj[oldnbr+1]; ++j) {
/*	    hinbr = invp[zfdperm[adjncy[j]]];*/
	    hinbr = zfdperm[adjncy[j]];
	    jstrt = fnz[hinbr];    /* first nonzero must be <= k */
	    if ( jstrt != k && marker[jstrt] < k ) {
		/* ----------------------------------
		   filtering k itself and duplicates
		   ---------------------------------- */
		fnz_hadj[hadj_end[jstrt]] = k;
		++hadj_end[jstrt];
		marker[jstrt] = k;
	    }
	    if ( jstrt == k ) temp += rowcnt[hinbr];
	}
	hadj_begin[k+1] = hadj_begin[k] + temp;
    }

#ifdef CHK_NZCNT
    printf("%8s%8s\n", "k", "hadj");
    for (k = 0; k < neqns; ++k) {
	printf("%8d", k);
	for (j = hadj_begin[k]; j < hadj_end[k]; ++j)
	    printf("%8d", fnz_hadj[j]);
	printf("\n");
    }
#endif
	
    /*   --------------------------------------------------   
         COMPUTE LEVEL(*), FDESC(*), NCHILD(*).   
         INITIALIZE ROWCNT(*), COLCNT(*),   
                    SET(*), PRVLF(*), WEIGHT(*), PRVNBR(*).   
         --------------------------------------------------   */
    level[ROOT] = 0;
    for (k = neqns-1; k >= 0; --k) {
	rowcnt[k] = 1;
	colcnt[k] = 0;
	set[k] = k;
	prvlf[k] = EMPTY;
	level[k] = level[etpar[k]] + 1;
	weight[k] = 1;
	fdesc[k] = k;
	prvnbr[k] = EMPTY;
    }
    fdesc[ROOT] = EMPTY;
    for (k = 0; k < neqns; ++k) {
	parent = etpar[k];
	weight[parent] = 0;
	colcnt_h[k] = 0;
	ifdesc = fdesc[k];
	if (ifdesc < fdesc[parent]) {
	    fdesc[parent] = ifdesc;
	}
    }

    xsup    = 0;      /* BUG FIX */
    nsuper = 0;
    
    /*   ------------------------------------   
         FOR EACH ``LOW NEIGHBOR'' LOWNBR ...   
         ------------------------------------ */
    for (lownbr = 0; lownbr < neqns; ++lownbr) {
	for (i = first[lownbr]; i != EMPTY; i = firstset[i]) {
	    rowcnt_h[i] = 1 + ( level[lownbr] - level[i] );
	    ++weight_h[lownbr];
	    parent = etpar[i];
	    --weight_h[parent];
	}
	
	lflag  = 0;
	ifdesc = fdesc[lownbr];
	jstrt  = hadj_begin[lownbr];
	jstop  = hadj_end[lownbr];
	/*   -----------------------------------------------   
             FOR EACH ``HIGH NEIGHBOR'', HINBR OF LOWNBR ...   
             ----------------------------------------------- */
	for (j = jstrt; j < jstop; ++j) {	    
	    hinbr = fnz_hadj[j];
	    if (hinbr > lownbr) {
                if (ifdesc > prvnbr[hinbr]) {
		    /*  -------------------------   
			INCREMENT WEIGHT(LOWNBR).   
			------------------------- */
		    ++weight[lownbr];
		    pleaf = prvlf[hinbr];
		    /*  -----------------------------------------   
			IF HINBR HAS NO PREVIOUS ``LOW NEIGHBOR'' THEN ...   
			----------------------------------------- */
		    if (pleaf == EMPTY) {
			/* -----------------------------------------   
			   ... ACCUMULATE LOWNBR-->HINBR PATH LENGTH   
			       IN ROWCNT(HINBR).   
			   ----------------------------------------- */
			rowcnt[hinbr] = rowcnt[hinbr] +
			                level[lownbr] - level[hinbr];
		    } else {
			/* -----------------------------------------   
			   ... OTHERWISE, LCA <-- FIND(PLEAF), WHICH   
                               IS THE LEAST COMMON ANCESTOR OF PLEAF   
                               AND LOWNBR. (PATH HALVING.)   
			   ----------------------------------------- */
			last1 = pleaf;
			last2 = set[last1];
			lca = set[last2];
			while ( lca != last2 ) {
			    set[last1] = lca;
			    last1 = lca;
			    last2 = set[last1];
			    lca = set[last2];
			}
			/* -------------------------------------   
			   ACCUMULATE PLEAF-->LCA PATH LENGTH IN   
			   ROWCNT(HINBR). DECREMENT WEIGHT(LCA).   
			   ------------------------------------- */
			rowcnt[hinbr] = rowcnt[hinbr] + 
					level[lownbr] - level[lca];
			--weight[lca];
		    }
		    /* ----------------------------------------------   
		       LOWNBR NOW BECOMES ``PREVIOUS LEAF'' OF HINBR.   
		       ---------------------------------------------- */
		    prvlf[hinbr] = lownbr;
		    lflag = 1;
        	}
		/* --------------------------------------------------   
		   LOWNBR NOW BECOMES ``PREVIOUS NEIGHBOR'' OF HINBR.   
		   -------------------------------------------------- */
		prvnbr[hinbr] = lownbr;
	    }
	} /* for j ... */
	
	/* ----------------------------------------------------   
	   DECREMENT WEIGHT ( PARENT(LOWNBR) ).   
	   SET ( P(LOWNBR) ) <-- SET ( P(LOWNBR) ) + SET(XSUP).   
	   ---------------------------------------------------- */
	parent = etpar[lownbr];
	--weight[parent];
	if (lflag == 1 || nchild[lownbr] >= 2) {
	    /* lownbr is detected as the beginning of the new supernode */
	    if ( lownbr != 0 ) part_super_ata[xsup] = lownbr - xsup;
	    ++nsuper;
	    xsup = lownbr;
	} else {
	    if ( parent == ROOT && ifdesc == lownbr ) {
		/* lownbr is a singleton, and begins a new supernode
		   but is not detected as doing so -- BUG FIX */
		part_super_ata[lownbr] = 1;
		++nsuper;
		xsup = lownbr;
	    }
	}
	set[xsup] = parent;
    } /* for lownbr ... */
    
    /* ---------------------------------------------------------   
       USE WEIGHTS TO COMPUTE COLUMN (AND TOTAL) NONZERO COUNTS.   
       --------------------------------------------------------- */
    *nlnz = nhnz = 0;
    for (k = 0; k < neqns; ++k) {
	/* for R */
	temp = colcnt[k] + weight[k];
	colcnt[k] = temp;
	*nlnz += temp;
	parent = etpar[k];
	if (parent != ROOT) {
	    colcnt[parent] += temp;
	}

	/* for H */
	temp = colcnt_h[k] + weight_h[k];
	colcnt_h[k] = temp;
	nhnz += temp;
	if (parent != ROOT) {
	    colcnt_h[parent] += temp;	    
	}
    }
    part_super_ata[xsup] = neqns - xsup;

    /* Fix the supernode partition in H. */
    
    free (set);
    free (prvlf);
    free (level);
    free (weight);
    free (fdesc);
    free (nchild);
    free (prvnbr);
    free (fnz_hadj);

    free (first);
    free (firstset);
    free (weight_h);
    free (rowcnt_h);
    free (rowcnt);
    free (colcnt);
    
#if ( PRNTlevel==1 )
    printf(".. qrnzcnt() nlnz %d, nhnz %d, nlnz/nhnz %.2f\n", 
		*nlnz, nhnz, (float) *nlnz/nhnz);
#endif

#if ( DEBUGlevel>=2 )
    print_int_vec("part_super_h", neqns, part_super_h);
#endif    

    return 0;
    
} /* qrnzcnt_ */
コード例 #3
0
ファイル: super_lu_d0.c プロジェクト: spino327/jburkardt-c
int main ( int argc, char *argv[] )

/**********************************************************************/
/*
  Purpose:

    SUPER_LU_D0 runs a small 5 by 5 example of the use of SUPER_LU.

  Modified:

    23 April 2004

  Reference:

    James Demmel, John Gilbert, Xiaoye Li,
    SuperLU Users's Guide,
    Sections 1 and 2.
*/
{
  double *a;
  SuperMatrix A;
  int *asub;
  SuperMatrix B;
  int i;
  int info;
  SuperMatrix L;
  int m;
  int n;
  int nnz;
  int nrhs;
  superlu_options_t options;
  int *perm_c;
  int *perm_r;
  int permc_spec;
  double *rhs;
  double sol[5];
  SuperLUStat_t stat;
  SuperMatrix U;
  int *xa;
/*
  Say hello.
*/
  printf ( "\n" );
  printf ( "SUPER_LU_D0:\n" );
  printf ( "  Simple 5 by 5 example of SUPER_LU solver.\n" );
/* 
  Initialize parameters. 
*/
  m = 5;
  n = 5;
  nnz = 12;
/* 
  Set aside space for the arrays. 
*/
  a = doubleMalloc ( nnz );
  if ( !a ) 
  {
    ABORT ( "Malloc fails for a[]." );
  }

  asub = intMalloc ( nnz );
  if ( !asub ) 
  {
    ABORT ( "Malloc fails for asub[]." );
  }

  xa = intMalloc ( n+1 );
  if ( !xa ) 
  { 
    ABORT ( "Malloc fails for xa[]." );
  }
/* 
  Initialize matrix A. 
*/
  a[0] = 19.0; 
  a[1] = 12.0; 
  a[2] = 12.0; 
  a[3] = 21.0; 
  a[4] = 12.0; 
  a[5] = 12.0;
  a[6] = 21.0; 
  a[7] = 16.0; 
  a[8] = 21.0; 
  a[9] =  5.0; 
  a[10]= 21.0; 
  a[11]= 18.0;

  asub[0] = 0; 
  asub[1] = 1; 
  asub[2] = 4; 
  asub[3] = 1;
  asub[4] = 2; 
  asub[5] = 4; 
  asub[6] = 0; 
  asub[7] = 2;
  asub[8] = 0; 
  asub[9] = 3; 
  asub[10]= 3; 
  asub[11]= 4;

  xa[0] = 0; 
  xa[1] = 3; 
  xa[2] = 6; 
  xa[3] = 8; 
  xa[4] = 10; 
  xa[5] = 12;

  sol[0] = -0.031250000;
  sol[1] =  0.065476190;
  sol[2] =  0.013392857;
  sol[3] =  0.062500000;
  sol[4] =  0.032738095;
/* 
  Create matrix A in the format expected by SuperLU. 
*/
  dCreate_CompCol_Matrix ( &A, m, n, nnz, a, asub, xa, SLU_NC, SLU_D, SLU_GE );
/* 
  Create the right-hand side matrix B. 
*/
  nrhs = 1;
  rhs = doubleMalloc ( m * nrhs );
  if ( !rhs ) 
  {
    ABORT("Malloc fails for rhs[].");
  }

  for ( i = 0; i < m; i++ ) 
  {
    rhs[i] = 1.0;
  }

  dCreate_Dense_Matrix ( &B, m, nrhs, rhs, m, SLU_DN, SLU_D, SLU_GE );
/* 
  Set up the arrays for the permutations. 
*/
  perm_r = intMalloc ( m );
  if ( !perm_r ) 
  {
    ABORT ( "Malloc fails for perm_r[]." );
  }

  perm_c = intMalloc ( n );
  if ( !perm_c ) 
  {
    ABORT ( "Malloc fails for perm_c[]." );
  }
/* 
  Set the default input options, and then adjust some of them.
*/
  set_default_options ( &options );
  options.ColPerm = NATURAL;
/* 
  Initialize the statistics variables. 
*/
  StatInit ( &stat );
/*
  Factor the matrix and solve the linear system.
*/
  dgssv ( &options, &A, perm_c, perm_r, &L, &U, &B, &stat, &info );
/*
  Print some of the results.
*/
  dPrint_CompCol_Matrix ( "Matrix A", &A );
  dPrint_SuperNode_Matrix ( "Factor L", &L );
  dPrint_CompCol_Matrix ( "Factor U", &U );
  dPrint_Dense_Matrix ( "Solution X", &B );

  printf ( "\n" );
  printf ( "  The exact solution:\n" );
  printf ( "\n" );
  for ( i = 0; i < n; i++ )
  {
    printf ( "%d  %f\n", i, sol[i] );
  }

  printf ( "\n" );
  print_int_vec ( "perm_r", m, perm_r );
/* 
  De-allocate storage.
*/
  SUPERLU_FREE ( rhs );
  SUPERLU_FREE ( perm_r );
  SUPERLU_FREE ( perm_c );
  Destroy_CompCol_Matrix ( &A );
  Destroy_SuperMatrix_Store ( &B );
  Destroy_SuperNode_Matrix ( &L );
  Destroy_CompCol_Matrix ( &U );
  StatFree ( &stat );

  printf ( "\n" );
  printf ( "SUPER_LU_D0:\n" );
  printf ( "  Normal end of execution.\n" );

  return 0;
}
コード例 #4
0
ファイル: sp_preorder.c プロジェクト: BranYang/scipy
/*! \brief
 *
 * <pre>
 * Purpose
 * =======
 *
 * sp_preorder() permutes the columns of the original matrix. It performs
 * the following steps:
 *
 *    1. Apply column permutation perm_c[] to A's column pointers to form AC;
 *
 *    2. If options->Fact = DOFACT, then
 *       (1) Compute column elimination tree etree[] of AC'AC;
 *       (2) Post order etree[] to get a postordered elimination tree etree[],
 *           and a postorder permutation post[];
 *       (3) Apply post[] permutation to columns of AC;
 *       (4) Overwrite perm_c[] with the product perm_c * post.
 *
 * Arguments
 * =========
 *
 * options (input) superlu_options_t*
 *         Specifies whether or not the elimination tree will be re-used.
 *         If options->Fact == DOFACT, this means first time factor A, 
 *         etree is computed, postered, and output.
 *         Otherwise, re-factor A, etree is input, unchanged on exit.
 *
 * A       (input) SuperMatrix*
 *         Matrix A in A*X=B, of dimension (A->nrow, A->ncol). The number
 *         of the linear equations is A->nrow. Currently, the type of A can be:
 *         Stype = NC or SLU_NCP; Mtype = SLU_GE.
 *         In the future, more general A may be handled.
 *
 * perm_c  (input/output) int*
 *	   Column permutation vector of size A->ncol, which defines the 
 *         permutation matrix Pc; perm_c[i] = j means column i of A is 
 *         in position j in A*Pc.
 *         If options->Fact == DOFACT, perm_c is both input and output.
 *         On output, it is changed according to a postorder of etree.
 *         Otherwise, perm_c is input.
 *
 * etree   (input/output) int*
 *         Elimination tree of Pc'*A'*A*Pc, dimension A->ncol.
 *         If options->Fact == DOFACT, etree is an output argument,
 *         otherwise it is an input argument.
 *         Note: etree is a vector of parent pointers for a forest whose
 *         vertices are the integers 0 to A->ncol-1; etree[root]==A->ncol.
 *
 * AC      (output) SuperMatrix*
 *         The resulting matrix after applied the column permutation
 *         perm_c[] to matrix A. The type of AC can be:
 *         Stype = SLU_NCP; Dtype = A->Dtype; Mtype = SLU_GE.
 * </pre>
 */
void
sp_preorder(superlu_options_t *options,  SuperMatrix *A, int *perm_c, 
	    int *etree, SuperMatrix *AC)
{
    NCformat  *Astore;
    NCPformat *ACstore;
    int       *iwork, *post;
    register  int n, i;

    n = A->ncol;
    
    /* Apply column permutation perm_c to A's column pointers so to
       obtain NCP format in AC = A*Pc.  */
    AC->Stype       = SLU_NCP;
    AC->Dtype       = A->Dtype;
    AC->Mtype       = A->Mtype;
    AC->nrow        = A->nrow;
    AC->ncol        = A->ncol;
    Astore          = A->Store;
    ACstore = AC->Store = (void *) SUPERLU_MALLOC( sizeof(NCPformat) );
    if ( !ACstore ) ABORT("SUPERLU_MALLOC fails for ACstore");
    ACstore->nnz    = Astore->nnz;
    ACstore->nzval  = Astore->nzval;
    ACstore->rowind = Astore->rowind;
    ACstore->colbeg = (int*) SUPERLU_MALLOC(n*sizeof(int));
    if ( !(ACstore->colbeg) ) ABORT("SUPERLU_MALLOC fails for ACstore->colbeg");
    ACstore->colend = (int*) SUPERLU_MALLOC(n*sizeof(int));
    if ( !(ACstore->colend) ) ABORT("SUPERLU_MALLOC fails for ACstore->colend");

#ifdef DEBUG
    print_int_vec("pre_order:", n, perm_c);
    check_perm("Initial perm_c", n, perm_c);
#endif      

    for (i = 0; i < n; i++) {
	ACstore->colbeg[perm_c[i]] = Astore->colptr[i]; 
	ACstore->colend[perm_c[i]] = Astore->colptr[i+1];
    }
	
    if ( options->Fact == DOFACT ) {
#undef ETREE_ATplusA
#ifdef ETREE_ATplusA
        /*--------------------------------------------
	  COMPUTE THE ETREE OF Pc*(A'+A)*Pc'.
	  --------------------------------------------*/
        int *b_colptr, *b_rowind, bnz, j;
	int *c_colbeg, *c_colend;

        /*printf("Use etree(A'+A)\n");*/

	/* Form B = A + A'. */
	at_plus_a(n, Astore->nnz, Astore->colptr, Astore->rowind,
		  &bnz, &b_colptr, &b_rowind);

	/* Form C = Pc*B*Pc'. */
	c_colbeg = (int*) SUPERLU_MALLOC(2*n*sizeof(int));
	c_colend = c_colbeg + n;
	if (!c_colbeg ) ABORT("SUPERLU_MALLOC fails for c_colbeg/c_colend");
	for (i = 0; i < n; i++) {
	    c_colbeg[perm_c[i]] = b_colptr[i]; 
  	    c_colend[perm_c[i]] = b_colptr[i+1];
	}
	for (j = 0; j < n; ++j) {
	    for (i = c_colbeg[j]; i < c_colend[j]; ++i) {
	        b_rowind[i] = perm_c[b_rowind[i]];
	    }
	}

	/* Compute etree of C. */
	sp_symetree(c_colbeg, c_colend, b_rowind, n, etree);

	SUPERLU_FREE(b_colptr);
	if ( bnz ) SUPERLU_FREE(b_rowind);
	SUPERLU_FREE(c_colbeg);
	
#else
        /*--------------------------------------------
	  COMPUTE THE COLUMN ELIMINATION TREE.
	  --------------------------------------------*/
	sp_coletree(ACstore->colbeg, ACstore->colend, ACstore->rowind,
		    A->nrow, A->ncol, etree);
#endif
#ifdef DEBUG	
	print_int_vec("etree:", n, etree);
#endif	
	
	/* In symmetric mode, do not do postorder here. */
	if ( options->SymmetricMode == NO ) {
	    /* Post order etree */
	    post = (int *) TreePostorder(n, etree);
	    /* for (i = 0; i < n+1; ++i) inv_post[post[i]] = i;
	       iwork = post; */

#ifdef DEBUG
	    print_int_vec("post:", n+1, post);
	    check_perm("post", n, post);	
#endif	
	    iwork = (int*) SUPERLU_MALLOC((n+1)*sizeof(int)); 
	    if ( !iwork ) ABORT("SUPERLU_MALLOC fails for iwork[]");

	    /* Renumber etree in postorder */
	    for (i = 0; i < n; ++i) iwork[post[i]] = post[etree[i]];
	    for (i = 0; i < n; ++i) etree[i] = iwork[i];

#ifdef DEBUG	
	    print_int_vec("postorder etree:", n, etree);
#endif
	
	    /* Postmultiply A*Pc by post[] */
	    for (i = 0; i < n; ++i) iwork[post[i]] = ACstore->colbeg[i];
	    for (i = 0; i < n; ++i) ACstore->colbeg[i] = iwork[i];
	    for (i = 0; i < n; ++i) iwork[post[i]] = ACstore->colend[i];
	    for (i = 0; i < n; ++i) ACstore->colend[i] = iwork[i];

	    for (i = 0; i < n; ++i)
	        iwork[i] = post[perm_c[i]];  /* product of perm_c and post */
	    for (i = 0; i < n; ++i) perm_c[i] = iwork[i];

#ifdef DEBUG
	    print_int_vec("Pc*post:", n, perm_c);
	    check_perm("final perm_c", n, perm_c);	
#endif
	    SUPERLU_FREE (post);
	    SUPERLU_FREE (iwork);
	} /* end postordering */

    } /* if options->Fact == DOFACT ... */

}
コード例 #5
0
ファイル: sane_color_options.c プロジェクト: yiannis/gsoc2009
static void OyInit_color_options(SANE_Handle device)
{
   const SANE_Option_Descriptor *opt = NULL;
   SANE_Int num_options = 0;
   SANE_Status status;
   unsigned int opt_num = 0, i = 0, chars = 0;
   char buf[BUFSIZE];

   /* We got a device, find out how many options it has */
   status = sane_control_option(device, 0, SANE_ACTION_GET_VALUE, &num_options, 0);
   if (status != SANE_STATUS_GOOD) {
      fprintf(stderr, "unable to determine option count\n");
      exit(1);
   }

   color_option_names = (char **)malloc(sizeof(char *) * num_options);
   color_option_values = (char **)malloc(sizeof(char *) * num_options);
   memset(color_option_names, 0, sizeof(char *) * num_options);
   memset(color_option_values, 0, sizeof(char *) * num_options);

   for (opt_num = 1; opt_num < num_options; opt_num++) {
      opt = sane_get_option_descriptor(device, opt_num);
      if (opt->cap & SANE_CAP_COLOUR) {
         void *val = malloc(opt->size);

         color_option_names[i] = (char *)malloc(strlen(opt->name) + 1);
         strcpy(color_option_names[i], opt->name);

         sane_control_option(device, opt_num, SANE_ACTION_GET_VALUE, val, 0);
         switch (opt->type) {
            case SANE_TYPE_BOOL:
               color_option_values[i] = *(SANE_Bool *) val ? "true" : "false";
               break;
            case SANE_TYPE_INT:
               if (opt->size == (SANE_Int) sizeof(SANE_Word))
                  chars = sprintf(buf, "%d", *(SANE_Int *) val);  /* use snprintf( ..,128,.. ) */
               else
                  chars = print_int_vec((SANE_Int *) val, opt->size, buf, BUFSIZE);
               color_option_values[i] = (char *)malloc(chars + 1);
               strcpy(color_option_values[i], buf);
               break;
            case SANE_TYPE_FIXED:
               chars = sprintf(buf, "%f", SANE_UNFIX(*(SANE_Fixed *) val));
               color_option_values[i] = (char *)malloc(chars + 1);
               strcpy(color_option_values[i], buf);
               break;
            case SANE_TYPE_STRING:
               color_option_values[i] = (char *)malloc(strlen((char *)val) + 1);
               strcpy(color_option_values[i], (char *)val);
               break;
            case SANE_TYPE_BUTTON:
               color_option_values[i] = "button";
               break;
            default:
               fprintf(stderr, "Do not know what to do with option %d\n", opt->type);
               exit(0);
               break;
         }
         i++;
      }
   }
}
コード例 #6
0
int main ( )

/******************************************************************************/
/*
  Purpose:

    D_SAMPLE_ST tests the SUPERLU solver with a 5x5 double precision real matrix.

  Discussion:

    The general (GE) representation of the matrix is:

      [ 19  0 21 21  0
        12 21  0  0  0
         0 12 16  0  0 
         0  0  0  5 21
        12 12  0  0 18 ]

    The (0-based) compressed column (CC) representation of this matrix is:

      I  CC   A
     --  --  --
      0   0  19
      1      12
      4      12

      1   3  21
      2      12
      4      12

      0   6  21
      2      16

      0   8  21
      3       5

      3  10  21
      4      18

      *  12   *

    The right hand side B and solution X are

      #   B     X
     --  --  ----------
      0   1  -0.03125
      1   1   0.0654762
      2   1   0.0133929
      3   1   0.0625
      4   1   0.0327381 

  Licensing:

    This code is distributed under the GNU LGPL license. 

  Modified:

    18 July 2014

  Author:

    John Burkardt

  Reference:

    James Demmel, John Gilbert, Xiaoye Li,
    SuperLU Users's Guide.
*/
{
  SuperMatrix A;
  double *acc;
  double *b;
  double *b2;
  SuperMatrix B;
  int *ccc;
  int i;
  int *icc;
  int info;
  int j;
  SuperMatrix L;
  int m;
  int n;
  int nrhs = 1;
  int ncc;
  superlu_options_t options;
  int *perm_c;
  int permc_spec;
  int *perm_r;
  SuperLUStat_t stat;
  SuperMatrix U;

  timestamp ( );
  printf ( "\n" );
  printf ( "D_SAMPLE_ST:\n" );
  printf ( "  C version\n" );
  printf ( "  SUPERLU solves a double precision real linear system.\n" );
  printf ( "  The matrix is read from a Sparse Triplet (ST) file.\n" );
/*
  Read the matrix from a file associated with standard input,
  in sparse triplet (ST) format, into compressed column (CC) format.
*/
  dreadtriple ( &m, &n, &ncc, &acc, &icc, &ccc );
/*
  Print the matrix.
*/
  cc_print ( m, n, ncc, icc, ccc, acc, "  CC Matrix:" );
/*
  Convert the compressed column (CC) matrix into a SuperMatrix A. 
*/
  dCreate_CompCol_Matrix ( &A, m, n, ncc, acc, icc, ccc, SLU_NC, SLU_D, SLU_GE );    
/*
  Create the right-hand side matrix.
*/
  b = ( double * ) malloc ( m * sizeof ( double ) );
  for ( i = 0; i < m; i++ )
  {
    b[i] = 1.0;
  }
  printf ( "\n" );
  printf ( "  Right hand side:\n" );
  printf ( "\n" );
  for ( i = 0; i < m; i++ )
  {
    printf ( "%g\n", b[i] );
  }
/*
  Create Super Right Hand Side.
*/
  dCreate_Dense_Matrix ( &B, m, nrhs, b, m, SLU_DN, SLU_D, SLU_GE );
/*
  Set space for the permutations.
*/
  perm_r = ( int * ) malloc ( m * sizeof ( int ) );
  perm_c = ( int * ) malloc ( n * sizeof ( int ) );
/*
  Set the input options. 
*/
  set_default_options ( &options );
  options.ColPerm = NATURAL;
/*
  Initialize the statistics variables. 
*/
  StatInit ( &stat );
/*
  Solve the linear system. 
*/
  dgssv ( &options, &A, perm_c, perm_r, &L, &U, &B, &stat, &info );
    
  dPrint_CompCol_Matrix ( ( char * ) "A", &A );
  dPrint_CompCol_Matrix ( ( char * ) "U", &U );
  dPrint_SuperNode_Matrix ( ( char * ) "L", &L );
  print_int_vec ( ( char * ) "\nperm_r", m, perm_r );
/*
  By some miracle involving addresses, 
  the solution has been put into the B vector.
*/
  printf ( "\n" );
  printf ( "  Computed solution:\n" );
  printf ( "\n" );
  for ( i = 0; i < m; i++ )
  {
    printf ( "%g\n", b[i] );
  }
/*
  Demonstrate that RHS is really the solution now.
  Multiply it by the matrix.
*/
  b2 = cc_mv ( m, n, ncc, icc, ccc, acc, b );
  printf ( "\n" );
  printf ( "  Product A*X:\n" );
  printf ( "\n" );
  for ( i = 0; i < m; i++ )
  {
    printf ( "%g\n", b2[i] );
  }
/*
  Free memory.
*/
  free ( b );
  free ( b2 );
  free ( perm_c );
  free ( perm_r );

  Destroy_SuperMatrix_Store ( &A );
  Destroy_SuperMatrix_Store ( &B );
  Destroy_SuperNode_Matrix ( &L );
  Destroy_CompCol_Matrix ( &U );
  StatFree ( &stat );
/*
  Terminate.
*/
  printf ( "\n" );
  printf ( "D_SAMPLE_ST:\n" );
  printf ( "  Normal end of execution.\n" );
  printf ( "\n" );
  timestamp ( );

  return 0;
}
コード例 #7
0
ファイル: sp_colorder.c プロジェクト: ivanBobrov/Xeon
void
sp_colorder(SuperMatrix *A, int *perm_c, superlumt_options_t *options,
	    SuperMatrix *AC)
{
/*
 * -- SuperLU MT routine (version 2.0) --
 * Lawrence Berkeley National Lab, Univ. of California Berkeley,
 * and Xerox Palo Alto Research Center.
 * September 10, 2007
 *
 *
 * Purpose
 * =======
 *
 * sp_colorder() permutes the columns of the original matrix A into AC. 
 * It performs the following steps:
 *
 *    1. Apply column permutation perm_c[] to A's column pointers to form AC;
 *
 *    2. If options->refact = NO, then
 *       (1) Allocate etree[], and compute column etree etree[] of AC'AC;
 *       (2) Post order etree[] to get a postordered elimination tree etree[],
 *           and a postorder permutation post[];
 *       (3) Apply post[] permutation to columns of AC;
 *       (4) Overwrite perm_c[] with the product perm_c * post.
 *       (5) Allocate storage, and compute the column count (colcnt_h) and the
 *           supernode partition (part_super_h) for the Householder matrix H.
 *
 * Arguments
 * =========
 *
 * A      (input) SuperMatrix*
 *        Matrix A in A*X=B, of dimension (A->nrow, A->ncol). The number
 *        of the linear equations is A->nrow. Currently, the type of A can be:
 *        Stype = NC or NCP; Dtype = _D; Mtype = GE.
 *
 * perm_c (input/output) int*
 *	  Column permutation vector of size A->ncol, which defines the 
 *        permutation matrix Pc; perm_c[i] = j means column i of A is 
 *        in position j in A*Pc.
 *
 * options (input/output) superlumt_options_t*
 *        If options->refact = YES, then options is an
 *        input argument. The arrays etree[], colcnt_h[] and part_super_h[]
 *        are available from a previous factor and will be re-used.
 *        If options->refact = NO, then options is an output argument. 
 *
 * AC     (output) SuperMatrix*
 *        The resulting matrix after applied the column permutation
 *        perm_c[] to matrix A. The type of AC can be:
 *        Stype = NCP; Dtype = _D; Mtype = GE.
 *
 */

    NCformat  *Astore;
    NCPformat *ACstore;
    int i, n, nnz, nlnz;
    yes_no_t  refact = options->refact;
    int *etree;
    int *colcnt_h;
    int *part_super_h;
    int *iwork, *post, *iperm;
    int *invp;
    int *part_super_ata;

    extern void at_plus_a(const int, const int,	int *, int *,
			  int *, int **, int **, int);

    n     = A->ncol;
    iwork = intMalloc(n+1);
    part_super_ata = intMalloc(n);
    
    /* Apply column permutation perm_c to A's column pointers so to
       obtain NCP format in AC = A*Pc.  */
    AC->Stype       = SLU_NCP;
    AC->Dtype       = A->Dtype;
    AC->Mtype       = A->Mtype;
    AC->nrow        = A->nrow;
    AC->ncol        = A->ncol;
    Astore          = A->Store;
    ACstore = AC->Store = (void *) malloc( sizeof(NCPformat) );
    ACstore->nnz    = Astore->nnz;
    ACstore->nzval  = Astore->nzval;
    ACstore->rowind = Astore->rowind;
    ACstore->colbeg = intMalloc(n);
    ACstore->colend = intMalloc(n);
    nnz             = Astore->nnz;

#ifdef CHK_COLORDER
    print_int_vec("pre_order:", n, perm_c);
    dcheck_perm("Initial perm_c", n, perm_c);
#endif      

    for (i = 0; i < n; i++) {
	ACstore->colbeg[perm_c[i]] = Astore->colptr[i]; 
	ACstore->colend[perm_c[i]] = Astore->colptr[i+1];
    }
	
    if ( refact == NO ) {
	int *b_colptr, *b_rowind, bnz, j;
	
	options->etree = etree = intMalloc(n);
	options->colcnt_h = colcnt_h = intMalloc(n);
	options->part_super_h = part_super_h = intMalloc(n);
	
	if ( options->SymmetricMode ) {
	    /* Compute the etree of C = Pc*(A'+A)*Pc'. */
	    int *c_colbeg, *c_colend;

	    /* Form B = A + A'. */
	    at_plus_a(n, Astore->nnz, Astore->colptr, Astore->rowind,
		      &bnz, &b_colptr, &b_rowind, 1);
	    
	    /* Form C = Pc*B*Pc'. */
	    c_colbeg = (int_t*) intMalloc(n);
	    c_colend = (int_t*) intMalloc(n);
	    if (!(c_colbeg) || !(c_colend) )
		SUPERLU_ABORT("SUPERLU_MALLOC fails for c_colbeg/c_colend");
	    for (i = 0; i < n; i++) {
		c_colbeg[perm_c[i]] = b_colptr[i]; 
		c_colend[perm_c[i]] = b_colptr[i+1];
	    }
	    for (j = 0; j < n; ++j) {
		for (i = c_colbeg[j]; i < c_colend[j]; ++i) {
		    b_rowind[i] = perm_c[b_rowind[i]];
		}
		iwork[perm_c[j]] = j; /* inverse perm_c */
	    }

	    /* Compute etree of C. */
	    sp_symetree(c_colbeg, c_colend, b_rowind, n, etree);

	    /* Restore B to be A+A', without column permutation */
	    for (i = 0; i < bnz; ++i)
		b_rowind[i] = iwork[b_rowind[i]];

	    SUPERLU_FREE(c_colbeg);
	    SUPERLU_FREE(c_colend);
	    
	} else {
	    /* Compute the column elimination tree. */
	    sp_coletree(ACstore->colbeg, ACstore->colend, ACstore->rowind,
			A->nrow, A->ncol, etree);
	}

#ifdef CHK_COLORDER	
	print_int_vec("etree:", n, etree);
#endif	

	/* Post order etree. */
	post = (int *) TreePostorder(n, etree);
	invp  = intMalloc(n);
	for (i = 0; i < n; ++i) invp[post[i]] = i;

#ifdef CHK_COLORDER
	print_int_vec("post:", n+1, post);
	dcheck_perm("post", n, post);	
#endif	

	/* Renumber etree in postorder. */
	for (i = 0; i < n; ++i) iwork[post[i]] = post[etree[i]];
	for (i = 0; i < n; ++i) etree[i] = iwork[i];

#ifdef CHK_COLORDER	
	print_int_vec("postorder etree:", n, etree);
#endif

	/* Postmultiply A*Pc by post[]. */
	for (i = 0; i < n; ++i) iwork[post[i]] = ACstore->colbeg[i];
	for (i = 0; i < n; ++i) ACstore->colbeg[i] = iwork[i];
	for (i = 0; i < n; ++i) iwork[post[i]] = ACstore->colend[i];
	for (i = 0; i < n; ++i) ACstore->colend[i] = iwork[i];

	for (i = 0; i < n; ++i)
	    iwork[i] = post[perm_c[i]];  /* product of perm_c and post */
	for (i = 0; i < n; ++i) perm_c[i] = iwork[i];
	for (i = 0; i < n; ++i) invp[perm_c[i]] = i; /* inverse of perm_c */

	iperm = post; /* alias to the same address */

#ifdef ZFD_PERM
	/* Permute the rows of AC to have zero-free diagonal. */
	printf("** Permute the rows to have zero-free diagonal....\n");
	for (i = 0; i < n; ++i)
	    iwork[i] = ACstore->colend[i] - ACstore->colbeg[i];
	zfdperm(n, nnz, ACstore->rowind, ACstore->colbeg, iwork, iperm);
#else
	for (i = 0; i < n; ++i) iperm[i] = i;
#endif	

	/* NOTE: iperm is returned as column permutation so that
	 * the diagonal is nonzero. Since a symmetric permutation
	 * preserves the diagonal, we can do the following:
	 *     P'(AP')P = P'A
	 * That is, we apply the inverse of iperm to rows of A
	 * to get zero-free diagonal. But since iperm is defined
	 * in MC21A inversely as our definition of permutation,
	 * so it is indeed an inverse for our purpose. We can
	 * apply it directly.
	 */

	if ( options->SymmetricMode ) {
	    /* Determine column count in the Cholesky factor of B = A+A' */
#if 0
	    cholnzcnt(n, Astore->colptr, Astore->rowind,
		      invp, perm_c, etree, colcnt_h, &nlnz, part_super_h);
#else
	    cholnzcnt(n, b_colptr, b_rowind,
		      invp, perm_c, etree, colcnt_h, &nlnz, part_super_h);
#endif
#if ( PRNTlevel>=1 ) 
	    printf(".. bnz %d\n", bnz);
#endif

	    SUPERLU_FREE(b_colptr);
	    if ( bnz ) SUPERLU_FREE(b_rowind);

	} else {
	    /* Determine the row and column counts in the QR factor. */
	    qrnzcnt(n, nnz, Astore->colptr, Astore->rowind, iperm,
		    invp, perm_c, etree, colcnt_h, &nlnz,
		    part_super_ata, part_super_h);
	}

#if ( PRNTlevel>=2 )
	dCheckZeroDiagonal(n, ACstore->rowind, ACstore->colbeg,
			   ACstore->colend, perm_c);
	print_int_vec("colcnt", n, colcnt_h);
	dPrintSuperPart("Hpart", n, part_super_h);
	print_int_vec("iperm", n, iperm);
#endif	
	
#ifdef CHK_COLORDER
	print_int_vec("Pc*post:", n, perm_c);
	dcheck_perm("final perm_c", n, perm_c);	
#endif

	SUPERLU_FREE (post);
	SUPERLU_FREE (invp);

    } /* if refact == NO */

    SUPERLU_FREE (iwork);
    SUPERLU_FREE (part_super_ata);
}