Example #1
0
void amd_order1(int n, int A_ptr[], int A_ind[], int P_per[])
{     /* approximate minimum degree ordering (AMD) */
      int k, ret;
      double Control[AMD_CONTROL], Info[AMD_INFO];
      /* get the default parameters */
      amd_defaults(Control);
#if 0
      /* and print them */
      amd_control(Control);
#endif
      /* make all indices 0-based */
      for (k = 1; k < A_ptr[n+1]; k++) A_ind[k]--;
      for (k = 1; k <= n+1; k++) A_ptr[k]--;
      /* call the ordering routine */
      ret = amd_order(n, &A_ptr[1], &A_ind[1], &P_per[1], Control, Info)
         ;
#if 0
      amd_info(Info);
#endif
      xassert(ret == AMD_OK || ret == AMD_OK_BUT_JUMBLED);
      /* retsore 1-based indices */
      for (k = 1; k <= n+1; k++) A_ptr[k]++;
      for (k = 1; k < A_ptr[n+1]; k++) A_ind[k]++;
      /* patch up permutation matrix */
      memset(&P_per[n+1], 0, n * sizeof(int));
      for (k = 1; k <= n; k++)
      {  P_per[k]++;
         xassert(1 <= P_per[k] && P_per[k] <= n);
         xassert(P_per[n+P_per[k]] == 0);
         P_per[n+P_per[k]] = k;
      }
      return;
}
Example #2
0
//=============================================================================
Amesos_Umfpack::Amesos_Umfpack(const Epetra_LinearProblem &prob ) :
  Symbolic(0),
  Numeric(0),
  SerialMatrix_(0), 
  UseTranspose_(false),
  Problem_(&prob), 
  Rcond_(0.0), 
  RcondValidOnAllProcs_(true),
  MtxConvTime_(-1),
  MtxRedistTime_(-1),
  VecRedistTime_(-1),
  SymFactTime_(-1),
  NumFactTime_(-1),
  SolveTime_(-1),
  OverheadTime_(-1)
{
  
  // MS // move declaration of Problem_ above because I need it
  // MS // set up before calling Comm()
  Teuchos::ParameterList ParamList ;
  SetParameters( ParamList ) ; 

  //
  //  Hack to deal with Bug #1418  - circular dependencies in amesos, umfpack and amd libraries 
  //  This causes the amd files to be pulled in from libamesos.a
  //
  if ( UseTranspose_ ) {
    double control[3];
    //  This should never be called
    Amesos_Klu Nothing(*Problem_); 
    amd_defaults(control);
  }

}
Example #3
0
/* Orders rows and saves pointer to matrix.and model */
int
ClpCholeskyUfl::order(ClpInterior * model)
{
     int iRow;
     model_ = model;
     if (preOrder(false, true, doKKT_))
          return -1;
     permuteInverse_ = new int [numberRows_];
     permute_ = new int[numberRows_];
     double Control[AMD_CONTROL];
     double Info[AMD_INFO];

     amd_defaults(Control);
     //amd_control(Control);

     int returnCode = amd_order(numberRows_, choleskyStart_, choleskyRow_,
                                permute_, Control, Info);
     delete [] choleskyRow_;
     choleskyRow_ = NULL;
     delete [] choleskyStart_;
     choleskyStart_ = NULL;
     //amd_info(Info);

     if (returnCode != AMD_OK) {
          std::cout << "AMD ordering failed" << std::endl;
          return 1;
     }
     for (iRow = 0; iRow < numberRows_; iRow++) {
          permuteInverse_[permute_[iRow]] = iRow;
     }
     return 0;
}
Example #4
0
    int order(const RCP<OrderingSolution<typename Adapter::lno_t,
                                         typename Adapter::gno_t> > &solution)
    {
#ifndef HAVE_ZOLTAN2_AMD
  throw std::runtime_error(
        "BUILD ERROR: AMD requested but not compiled into Zoltan2.\n"
        "Please set CMake flag Zoltan2_ENABLE_AMD:BOOL=ON.");
#else
      typedef typename Adapter::lno_t lno_t;
      typedef typename Adapter::scalar_t scalar_t;

      int ierr= 0;

      const size_t nVtx = model->getLocalNumVertices();

      //cout << "Local num vertices" << nVtx << endl;
      ArrayView<const gno_t> edgeIds;
      ArrayView<const lno_t> offsets;
      ArrayView<StridedData<lno_t, scalar_t> > wgts;

      // wgts are ignored in AMD
      model->getEdgeList(edgeIds, offsets, wgts);

      AMDTraits<lno_t> AMDobj;
      double Control[AMD_CONTROL];
      double Info[AMD_INFO];

      amd_defaults(Control);
      amd_control(Control);

      lno_t *perm;
      perm = (lno_t *) (solution->getPermutationRCP().getRawPtr());

      lno_t result = AMDobj.order(nVtx, offsets.getRawPtr(),
                             edgeIds.getRawPtr(), perm, Control, Info);

      if (result != AMD_OK && result != AMD_OK_BUT_JUMBLED)
          ierr = -1;

      solution->setHavePerm(true);
      return ierr;
#endif
    }
Example #5
0
std::vector<int> cAMD_Interf::DoRank(bool show) 
{
   Im2D_Bits<1> aM(1,1);
   if (show)
      aM = Im2D_Bits<1>(mNb,mNb,0);

   std::vector<int> Ap,Ai,P;
   Ap.push_back(0);
   for (int aK=0 ; aK<mNb ; aK++)
   {
       std::vector<int> & aVK = mV[aK];
       std::sort(aVK.begin(),aVK.end());
       aVK.erase(std::unique(aVK.begin(),aVK.end()),aVK.end());

      for (int aI=0;aI<int(aVK.size()) ; aI++)
      {
          Ai.push_back(aVK[aI]);
          if (show)
          {
              aM.set(aK,aVK[aI],1);
          }
          // std::cout << " " << aVK[aI] ;
      }
      Ap.push_back(Ap.back()+aVK.size());
      P.push_back(0);
      // std::cout << "\n";

   }



   double Control [AMD_CONTROL] , Info [AMD_INFO] ;

   amd_defaults (Control) ;
   // amd_control  (Control) ;

   int result;
   result = amd_order(mNb,VData(Ap),VData(Ai), VData(P),Control,Info);

   ELISE_ASSERT(result==0,"amd_order");
   //std::cout << "RES = "  << result << "\n";

   std::vector<int> aRes(mNb,-1);
   for (int aK=0 ; aK<mNb ; aK++)
   {
       aRes[P[aK]] = aK;
   }
   if (show)
   {
      for (int aK=0 ; aK<mNb ; aK++)
      {
   
      }
      std::cout << "\n";
   }
    // result = amd_order (n, Ap, Ai, P, Control, Info) ;

   if (show)
   {
       Im2D_Bits<1> aM2(mNb,mNb);
       for (int aX=0 ; aX<mNb ; aX++)
       {
           for (int aY=0 ; aY<mNb ; aY++)
           {
                 aM2.set(aRes[aX],aRes[aY],aM.get(aX,aY));
                // aM2.set(aX,aY,aM.get(P[aX],P[aY]));
           }
       }
       ShowMat(aM);
       std::cout << "\n";
       ShowMat(aM2);
   }
   return aRes;
}
Example #6
0
int amd_demo_1 (void)
{
    /* The symmetric can_24 Harwell/Boeing matrix, including upper and lower
     * triangular parts, and the diagonal entries.  Note that this matrix is
     * 0-based, with row and column indices in the range 0 to n-1. */
    int n = 24, nz,
    Ap [ ] = { 0, 9, 15, 21, 27, 33, 39, 48, 57, 61, 70, 76, 82, 88, 94, 100,
	106, 110, 119, 128, 137, 143, 152, 156, 160 },
    Ai [ ] = {
	/* column  0: */    0, 5, 6, 12, 13, 17, 18, 19, 21,
	/* column  1: */    1, 8, 9, 13, 14, 17,
	/* column  2: */    2, 6, 11, 20, 21, 22,
	/* column  3: */    3, 7, 10, 15, 18, 19,
	/* column  4: */    4, 7, 9, 14, 15, 16,
	/* column  5: */    0, 5, 6, 12, 13, 17,
	/* column  6: */    0, 2, 5, 6, 11, 12, 19, 21, 23,
	/* column  7: */    3, 4, 7, 9, 14, 15, 16, 17, 18,
	/* column  8: */    1, 8, 9, 14,
	/* column  9: */    1, 4, 7, 8, 9, 13, 14, 17, 18,
	/* column 10: */    3, 10, 18, 19, 20, 21,
	/* column 11: */    2, 6, 11, 12, 21, 23,
	/* column 12: */    0, 5, 6, 11, 12, 23,
	/* column 13: */    0, 1, 5, 9, 13, 17,
	/* column 14: */    1, 4, 7, 8, 9, 14,
	/* column 15: */    3, 4, 7, 15, 16, 18,
	/* column 16: */    4, 7, 15, 16,
	/* column 17: */    0, 1, 5, 7, 9, 13, 17, 18, 19,
	/* column 18: */    0, 3, 7, 9, 10, 15, 17, 18, 19,
	/* column 19: */    0, 3, 6, 10, 17, 18, 19, 20, 21,
	/* column 20: */    2, 10, 19, 20, 21, 22,
	/* column 21: */    0, 2, 6, 10, 11, 19, 20, 21, 22,
	/* column 22: */    2, 20, 21, 22,
	/* column 23: */    6, 11, 12, 23 } ;

    int P [24], Pinv [24], i, j, k, jnew, p, inew, result ;
    double Control [AMD_CONTROL], Info [AMD_INFO] ;
    char A [24][24] ;

    /* here is an example of how to use AMD_VERSION.  This code will work in
     * any version of AMD. */
#if defined(AMD_VERSION) && (AMD_VERSION >= AMD_VERSION_CODE(1,2))
    printf ("AMD version %d.%d, date: %s\n", AMD_MAIN_VERSION, AMD_SUB_VERSION,
	    AMD_DATE) ;
#else
    printf ("AMD version: 1.1 or earlier\n") ;
#endif

    printf ("AMD demo, with the 24-by-24 Harwell/Boeing matrix, can_24:\n") ;

    /* get the default parameters, and print them */
    amd_defaults (Control) ;
    amd_control  (Control) ;

    /* print the input matrix */
    nz = Ap [n] ;
    printf ("\nInput matrix:  %d-by-%d, with %d entries.\n"
	   "   Note that for a symmetric matrix such as this one, only the\n"
	   "   strictly lower or upper triangular parts would need to be\n"
	   "   passed to AMD, since AMD computes the ordering of A+A'.  The\n"
	   "   diagonal entries are also not needed, since AMD ignores them.\n"
	   , n, n, nz) ;
    for (j = 0 ; j < n ; j++)
    {
	printf ("\nColumn: %d, number of entries: %d, with row indices in"
		" Ai [%d ... %d]:\n    row indices:",
		j, Ap [j+1] - Ap [j], Ap [j], Ap [j+1]-1) ;
	for (p = Ap [j] ; p < Ap [j+1] ; p++)
	{
	    i = Ai [p] ;
	    printf (" %d", i) ;
	}
	printf ("\n") ;
    }

    /* print a character plot of the input matrix.  This is only reasonable
     * because the matrix is small. */
    printf ("\nPlot of input matrix pattern:\n") ;
    for (j = 0 ; j < n ; j++)
    {
	for (i = 0 ; i < n ; i++) A [i][j] = '.' ;
	for (p = Ap [j] ; p < Ap [j+1] ; p++)
	{
	    i = Ai [p] ;
	    A [i][j] = 'X' ;
	}
    }
    printf ("    ") ;
    for (j = 0 ; j < n ; j++) printf (" %1d", j % 10) ;
    printf ("\n") ;
    for (i = 0 ; i < n ; i++)
    {
	printf ("%2d: ", i) ;
	for (j = 0 ; j < n ; j++)
	{
	    printf (" %c", A [i][j]) ;
	}
	printf ("\n") ;
    }

    /* order the matrix */
    result = amd_order (n, Ap, Ai, P, Control, Info) ;
    printf ("return value from amd_order: %d (should be %d)\n",
	result, AMD_OK) ;

    /* print the statistics */
    amd_info (Info) ;

    if (result != AMD_OK)
    {
	printf ("AMD failed\n") ;
	ElEXIT (1,"AMD DEMO") ;
    }

    /* print the permutation vector, P, and compute the inverse permutation */
    printf ("Permutation vector:\n") ;
    for (k = 0 ; k < n ; k++)
    {
	/* row/column j is the kth row/column in the permuted matrix */
	j = P [k] ;
	Pinv [j] = k ;
	printf (" %2d", j) ;
    }
    printf ("\n\n") ;

    printf ("Inverse permutation vector:\n") ;
    for (j = 0 ; j < n ; j++)
    {
	k = Pinv [j] ;
	printf (" %2d", k) ;
    }
    printf ("\n\n") ;

    /* print a character plot of the permuted matrix. */
    printf ("\nPlot of permuted matrix pattern:\n") ;
    for (jnew = 0 ; jnew < n ; jnew++)
    {
	j = P [jnew] ;
	for (inew = 0 ; inew < n ; inew++) A [inew][jnew] = '.' ;
	for (p = Ap [j] ; p < Ap [j+1] ; p++)
	{
	    inew = Pinv [Ai [p]] ;
	    A [inew][jnew] = 'X' ;
	}
    }
    printf ("    ") ;
    for (j = 0 ; j < n ; j++) printf (" %1d", j % 10) ;
    printf ("\n") ;
    for (i = 0 ; i < n ; i++)
    {
	printf ("%2d: ", i) ;
	for (j = 0 ; j < n ; j++)
	{
	    printf (" %c", A [i][j]) ;
	}
	printf ("\n") ;
    }

    return (0) ;
}
Example #7
0
File: umf4.c Project: Al-th/matlab
int main (int argc, char **argv)
{
    int i, j, k, n, nz, *Ap, *Ai, *Ti, *Tj, status, *Pamd, nrow, ncol, rhs ;
    double *Ax, *b, *x, Control [UMFPACK_CONTROL], Info [UMFPACK_INFO], aij,
	*Tx, *r, amd_Control [AMD_CONTROL], amd_Info [AMD_INFO], tamd [2],
	stats [2], droptol ;
    void *Symbolic, *Numeric ;
    FILE *f, *f2 ;
    char s [SMAX] ;

    /* ---------------------------------------------------------------------- */
    /* set controls */
    /* ---------------------------------------------------------------------- */

    printf ("\n===========================================================\n"
	    "=== UMFPACK v%d.%d.%d ========================================\n"
	    "===========================================================\n",
	    UMFPACK_MAIN_VERSION, UMFPACK_SUB_VERSION, UMFPACK_SUBSUB_VERSION) ;

    umfpack_di_defaults (Control) ;
    Control [UMFPACK_PRL] = 3 ;
    Control [UMFPACK_BLOCK_SIZE] = 32 ;

    f = fopen ("tmp/control.umf4", "r") ;
    if (f != (FILE *) NULL)
    {
	printf ("Reading control file tmp/control.umf4\n") ;
	for (i = 0 ; i < UMFPACK_CONTROL ; i++)
	{
	    fscanf (f, "%lg\n", & Control [i]) ;
	}
	fclose (f) ;
    }

    if (argc > 1)
    {
	char *t = argv [1] ;

	/* get the strategy */
	if (t [0] == 'u')
	{
	    Control [UMFPACK_STRATEGY] = UMFPACK_STRATEGY_UNSYMMETRIC ;
	}
	else if (t [0] == 'a')
	{
	    Control [UMFPACK_STRATEGY] = UMFPACK_STRATEGY_AUTO ;
	}
	else if (t [0] == 's')
	{
	    Control [UMFPACK_STRATEGY] = UMFPACK_STRATEGY_SYMMETRIC ;
	}
	else if (t [0] == '2')
	{
	    printf ("unrecognized strategy: %s\n", argv [1]) ;
	}
	else if (t [0] == 'U')
	{
	    Control [UMFPACK_STRATEGY] = UMFPACK_STRATEGY_UNSYMMETRIC ;
	    Control [UMFPACK_SCALE] = UMFPACK_SCALE_MAX ;
	}
	else if (t [0] == 'A')
	{
	    Control [UMFPACK_STRATEGY] = UMFPACK_STRATEGY_AUTO ;
	    Control [UMFPACK_SCALE] = UMFPACK_SCALE_MAX ;
	}
	else if (t [0] == 'S')
	{
	    Control [UMFPACK_STRATEGY] = UMFPACK_STRATEGY_SYMMETRIC ;
	    Control [UMFPACK_SCALE] = UMFPACK_SCALE_MAX ;
	}
	else if (t [0] == 'T')
	{
	    printf ("unrecognized strategy: %s\n", argv [1]) ;
	}
	else
	{
	    printf ("unrecognized strategy: %s\n", argv [1]) ;
	}

	if (t [1] == 'n')
	{
	    /* no aggressive absorption */
	    Control [UMFPACK_AGGRESSIVE] = FALSE ;
	}
    }

    if (argc > 2)
    {
	/* get the drop tolerance */
	sscanf (argv [2], "%lg", &droptol) ;
	printf ("droptol %g\n", droptol) ;
	Control [UMFPACK_DROPTOL] = droptol ;
    }

    umfpack_di_report_control (Control) ;

    /* ---------------------------------------------------------------------- */
    /* open the matrix file (tmp/A) */
    /* ---------------------------------------------------------------------- */

    printf ("File: tmp/A\n") ;
    f = fopen ("tmp/A", "r") ;
    if (!f)
    {
	printf ("Unable to open file\n") ;
	exit (1) ;
    }

    /* ---------------------------------------------------------------------- */
    /* get n and nz */
    /* ---------------------------------------------------------------------- */

    printf ("File: tmp/Asize\n") ;
    f2 = fopen ("tmp/Asize", "r") ;
    if (f2)
    {
	fscanf (f2, "%d %d %d\n", &nrow, &ncol, &nz) ;
	fclose (f2) ;
    }
    else
    {
	nrow = 1 ;
	ncol = 1 ;
    }
    nz = 0 ;
    while (fgets (s, SMAX, f) != (char *) NULL)
    {
	sscanf (s, "%d %d %lg", &i, &j, &aij) ;
#ifdef ZERO_BASED
	/* matrix is zero based */
	i++ ;
	j++ ;
#endif
	nrow = MAX (nrow, i) ;
	ncol = MAX (ncol, j) ;
	nz++ ;
    }
    fclose (f) ;
    n = MAX (nrow, ncol) ;

    printf ("n %d nrow %d ncol %d nz %d\n", n, nrow, ncol, nz) ;

    /* ---------------------------------------------------------------------- */
    /* allocate space for the input triplet form */
    /* ---------------------------------------------------------------------- */

    Ti = (int *) malloc (nz * sizeof (int)) ;
    Tj = (int *) malloc (nz * sizeof (int)) ;
    Tx = (double *) malloc (nz * sizeof (double)) ;
    if (!Ti || !Tj || !Tx)
    {
	printf ("out of memory for input matrix\n") ;
	exit (1) ;
    }

    /* ---------------------------------------------------------------------- */
    /* read in the triplet form */
    /* ---------------------------------------------------------------------- */

    f2 = fopen ("tmp/A", "r") ;
    if (!f2)
    {
	printf ("Unable to open file\n") ;
	exit (1) ;
    }

    k = 0 ;
    while (fgets (s, SMAX, f2) != (char *) NULL)
    {
	sscanf (s, "%d %d %lg", &i, &j, &aij) ;
#ifndef ZERO_BASED
	i-- ;	/* convert to 0-based */
	j-- ;
#endif
	if (k >= nz)
	{
	    printf ("Error!  Matrix size is wrong\n") ;
	    exit (1) ;
	}
	Ti [k] = i ;
	Tj [k] = j ;
	Tx [k] = aij ;
	k++ ;
    }
    fclose (f2) ;

    (void) umfpack_di_report_triplet (nrow, ncol, nz, Ti, Tj, Tx, Control) ;

    /* ---------------------------------------------------------------------- */
    /* convert to column form */
    /* ---------------------------------------------------------------------- */

    /* convert to column form */
    Ap = (int *) malloc ((n+1) * sizeof (int)) ;
    Ai = (int *) malloc (nz * sizeof (int)) ;
    Ax = (double *) malloc (nz * sizeof (double)) ;
    b = (double *) malloc (n * sizeof (double)) ;
    r = (double *) malloc (n * sizeof (double)) ;
    x = (double *) malloc (n * sizeof (double)) ;

    if (!Ap || !Ai || !Ax || !b || !r)
    {
	printf ("out of memory") ;
	exit (1) ;
    }

    umfpack_tic (stats) ;
    status = umfpack_di_triplet_to_col (nrow, ncol, nz, Ti, Tj, Tx, Ap, Ai, Ax,
	(int *) NULL) ;
    umfpack_toc (stats) ;
    printf ("triplet-to-col time: wall %g cpu %g\n", stats [0], stats [1]) ;
    if (status != UMFPACK_OK)
    {
	umfpack_di_report_status (Control, status) ;
	printf ("umfpack_di_triplet_to_col failed") ;
	exit (1) ;
    }

    /* print the column-form of A */
    (void) umfpack_di_report_matrix (nrow, ncol, Ap, Ai, Ax, 1, Control) ;

    /* b = A * xtrue */
    rhs = FALSE ;
    if (nrow == ncol)
    {
	f = fopen ("tmp/b", "r") ;
	if (f != (FILE *) NULL)
	{
	    printf ("Reading tmp/b\n") ;
	    rhs = TRUE ;
	    for (i = 0 ; i < n ; i++)
	    {
		fscanf (f, "%lg\n", &b [i]) ;
	    }
	    fclose (f) ;
	}
	else
	{
	    Atimesx (n, Ap, Ai, Ax, b, FALSE) ;
	}
    }

    /* ---------------------------------------------------------------------- */
    /* free the triplet form */
    /* ---------------------------------------------------------------------- */

    free (Ti) ;
    free (Tj) ;
    free (Tx) ;

    /* ---------------------------------------------------------------------- */
    /* symbolic factorization */
    /* ---------------------------------------------------------------------- */

    status = umfpack_di_symbolic (nrow, ncol, Ap, Ai, Ax, &Symbolic,
	    Control, Info) ;

    umfpack_di_report_info (Control, Info) ;
    if (status != UMFPACK_OK)
    {
	umfpack_di_report_status (Control, status) ;
	printf ("umfpack_di_symbolic failed") ;
	exit (1) ;
    }

    /* print the symbolic factorization */
    (void) umfpack_di_report_symbolic (Symbolic, Control) ;

    /* ---------------------------------------------------------------------- */
    /* numeric factorization */
    /* ---------------------------------------------------------------------- */

    status = umfpack_di_numeric (Ap, Ai, Ax, Symbolic, &Numeric, Control, Info);
    if (status < UMFPACK_OK)
    {
	umfpack_di_report_info (Control, Info) ;
	umfpack_di_report_status (Control, status) ;
	fprintf (stderr, "umfpack_di_numeric failed: %d\n", status) ;
	printf ("umfpack_di_numeric failed\n") ;
	exit (1) ;
    }

    /* print the numeric factorization */
    (void) umfpack_di_report_numeric (Numeric, Control) ;

    /* ---------------------------------------------------------------------- */
    /* solve Ax=b */
    /* ---------------------------------------------------------------------- */

    if (nrow == ncol && status == UMFPACK_OK)
    {
	status = umfpack_di_solve (UMFPACK_A, Ap, Ai, Ax, x, b, Numeric,
		Control, Info) ;

	umfpack_di_report_info (Control, Info) ;
	umfpack_di_report_status (Control, status) ;
	if (status < UMFPACK_OK)
	{
	    printf ("umfpack_di_solve failed\n") ;
	    exit (1) ;
	}
	(void) umfpack_di_report_vector (n, x, Control) ;
	printf ("relative maxnorm of residual, ||Ax-b||/||b||: %g\n",
	    resid (n, Ap, Ai, Ax, x, r, b, FALSE)) ;
	if (!rhs)
	{
	    printf ("relative maxnorm of error, ||x-xtrue||/||xtrue||: %g\n\n",
		err (n, x)) ;
	}

	f = fopen ("tmp/x", "w") ;
	if (f != (FILE *) NULL)
	{
	    printf ("Writing tmp/x\n") ;
	    for (i = 0 ; i < n ; i++)
	    {
		fprintf (f, "%30.20e\n", x [i]) ;
	    }
	    fclose (f) ;
	}
	else
	{
	    printf ("Unable to write output x!\n") ;
	    exit (1) ;
	}

	f = fopen ("tmp/info.umf4", "w") ;
	if (f != (FILE *) NULL)
	{
	    printf ("Writing tmp/info.umf4\n") ;
	    for (i = 0 ; i < UMFPACK_INFO ; i++)
	    {
		fprintf (f, "%30.20e\n", Info [i]) ;
	    }
	    fclose (f) ;
	}
	else
	{
	    printf ("Unable to write output info!\n") ;
	    exit (1) ;
	}
    }
    else
    {
	/* don't solve, just report the results */
	umfpack_di_report_info (Control, Info) ;
	umfpack_di_report_status (Control, status) ;
    }

    /* ---------------------------------------------------------------------- */
    /* free the Symbolic and Numeric factorization */
    /* ---------------------------------------------------------------------- */

    umfpack_di_free_symbolic (&Symbolic) ;
    umfpack_di_free_numeric (&Numeric) ;

    printf ("umf4 done, strategy: %g\n", Control [UMFPACK_STRATEGY]) ;

    /* ---------------------------------------------------------------------- */
    /* test just AMD ordering (not part of UMFPACK, but a separate test) */
    /* ---------------------------------------------------------------------- */

    /* first make the matrix square */
    if (ncol < n)
    {
	for (j = ncol+1 ; j <= n ; j++)
	{
	    Ap [j] = Ap [ncol] ;
	}
    }

    printf (
	"\n\n===========================================================\n"
	"=== AMD ===================================================\n"
	"===========================================================\n") ;
    printf ("\n\n------- Now trying the AMD ordering.  This not part of\n"
	"the UMFPACK analysis or factorization, above, but a separate\n"
	"test of just the AMD ordering routine.\n") ;
	Pamd = (int *) malloc (n * sizeof (int)) ;
    if (!Pamd)
    {
	printf ("out of memory\n") ;
	exit (1) ;
    }
    amd_defaults (amd_Control) ;
    amd_control (amd_Control) ;
    umfpack_tic (tamd) ;
    status = amd_order (n, Ap, Ai, Pamd, amd_Control, amd_Info) ;
    umfpack_toc (tamd) ;
    printf ("AMD ordering time: cpu %10.2f wall %10.2f\n",
	tamd [1], tamd [0]) ;
    if (status != AMD_OK)
    {
	printf ("amd failed: %d\n", status) ;
	exit (1) ;
    }
    amd_info (amd_Info) ;
    free (Pamd) ;
    printf ("AMD test done\n") ;

    free (Ap) ;
    free (Ai) ;
    free (Ax) ;
    free (b) ;
    free (r) ;
    free (x) ;

    return (0) ;
}
Example #8
0
int main (int argc, char **argv)
{
    /* The symmetric can_24 Harwell/Boeing matrix (jumbled, and not symmetric).
     * Since AMD operates on A+A', only A(i,j) or A(j,i) need to be specified,
     * or both.  The diagonal entries are optional (some are missing).
     * There are many duplicate entries, which must be removed. */
    int n = 24, nz,
    Ap [ ] = { 0, 9, 14, 20, 28, 33, 37, 44, 53, 58, 63, 63, 66, 69, 72, 75,
	      78, 82, 86, 91, 97, 101, 112, 112, 116 },
    Ai [ ] = {
	/* column  0: */    0, 17, 18, 21, 5, 12, 5, 0, 13,
	/* column  1: */    14, 1, 8, 13, 17,
	/* column  2: */    2, 20, 11, 6, 11, 22,
	/* column  3: */    3, 3, 10, 7, 18, 18, 15, 19,
	/* column  4: */    7, 9, 15, 14, 16,
	/* column  5: */    5, 13, 6, 17,
	/* column  6: */    5, 0, 11, 6, 12, 6, 23,
	/* column  7: */    3, 4, 9, 7, 14, 16, 15, 17, 18,
	/* column  8: */    1, 9, 14, 14, 14,
	/* column  9: */    7, 13, 8, 1, 17,
	/* column 10: */
	/* column 11: */    2, 12, 23,
	/* column 12: */    5, 11, 12,
	/* column 13: */    0, 13, 17,
	/* column 14: */    1, 9, 14,
	/* column 15: */    3, 15, 16,
	/* column 16: */    16, 4, 4, 15,
	/* column 17: */    13, 17, 19, 17,
	/* column 18: */    15, 17, 19, 9, 10,
	/* column 19: */    17, 19, 20, 0, 6, 10,
	/* column 20: */    22, 10, 20, 21,
	/* column 21: */    6, 2, 10, 19, 20, 11, 21, 22, 22, 22, 22,
	/* column 22: */
	/* column 23: */    12, 11, 12, 23 } ;

    int Rp [25], Ri [116] ;
    int P [24], Pinv [24], i, j, k, jnew, p, inew, result ;
    double Control [AMD_CONTROL], Info [AMD_INFO] ;
    char A [24][24] ;

    printf ("AMD demo, with a jumbled version of the 24-by-24\n") ;
    printf ("Harwell/Boeing matrix, can_24:\n") ;

    /* get the default parameters, and print them */
    amd_defaults (Control) ;
    amd_control  (Control) ;

    /* print the input matrix */
    nz = Ap [n] ;
    printf ("\nJumbled input matrix:  %d-by-%d, with %d entries.\n"
	   "   Note that for a symmetric matrix such as this one, only the\n"
	   "   strictly lower or upper triangular parts would need to be\n"
	   "   passed to AMD, since AMD computes the ordering of A+A'.  The\n"
	   "   diagonal entries are also not needed, since AMD ignores them.\n"
	   "   This version of the matrix has jumbled columns and duplicate\n"
	   "   row indices, and must be fixed by amd_preprocess prior to\n"
	   "   ordering it with amd_order.\n" , n, n, nz) ;
    for (j = 0 ; j < n ; j++)
    {
	printf ("\nColumn: %d, number of entries: %d, with row indices in"
		" Ai [%d ... %d]:\n    row indices:",
		j, Ap [j+1] - Ap [j], Ap [j], Ap [j+1]-1) ;
	for (p = Ap [j] ; p < Ap [j+1] ; p++)
	{
	    i = Ai [p] ;
	    printf (" %d", i) ;
	}
	printf ("\n") ;
    }

    /* print a character plot of the input matrix.  This is only reasonable
     * because the matrix is small. */
    printf ("\nPlot of (jumbled) input matrix pattern:\n") ;
    for (j = 0 ; j < n ; j++)
    {
	for (i = 0 ; i < n ; i++) A [i][j] = '.' ;
	for (p = Ap [j] ; p < Ap [j+1] ; p++)
	{
	    i = Ai [p] ;
	    A [i][j] = 'X' ;
	}
    }
    printf ("    ") ;
    for (j = 0 ; j < n ; j++) printf (" %1d", j % 10) ;
    printf ("\n") ;
    for (i = 0 ; i < n ; i++)
    {
	printf ("%2d: ", i) ;
	for (j = 0 ; j < n ; j++)
	{
	    printf (" %c", A [i][j]) ;
	}
	printf ("\n") ;
    }

    /* sort, remove duplicates, and transpose A to get R */
    result = amd_preprocess (n, Ap, Ai, Rp, Ri) ;
    printf ("return value from amd_preprocess: %d (should be %d)\n",
	result, AMD_OK) ;

    if (result != AMD_OK)
    {
	printf ("AMD failed\n") ;
	exit (1) ;
    }

    /* print the sorted/transposed matrix R */
    printf ("\nThe column-oriented form of the sorted/transposed matrix R:\n");
    for (j = 0 ; j < n ; j++)
    {
	printf ("\nColumn: %d, number of entries: %d, with row indices in"
		" Ri [%d ... %d]:\n    row indices:",
		j, Rp [j+1] - Rp [j], Rp [j], Rp [j+1]-1) ;
	for (p = Rp [j] ; p < Rp [j+1] ; p++)
	{
	    i = Ri [p] ;
	    printf (" %d", i) ;
	}
	printf ("\n") ;
    }

    /* print a character plot of the matrix R. */
    printf ("\nPlot of the sorted/transposed matrix R:\n") ;
    for (j = 0 ; j < n ; j++)
    {
	for (i = 0 ; i < n ; i++) A [i][j] = '.' ;
	for (p = Rp [j] ; p < Rp [j+1] ; p++)
	{
	    i = Ri [p] ;
	    A [i][j] = 'X' ;
	}
    }
    printf ("    ") ;
    for (j = 0 ; j < n ; j++) printf (" %1d", j % 10) ;
    printf (" \n") ;
    for (i = 0 ; i < n ; i++)
    {
	printf ("%2d: ", i) ;
	for (j = 0 ; j < n ; j++)
	{
	    printf (" %c", A [i][j]) ;
	}
	printf (" \n") ;
    }

    /* print a character plot of the matrix R+R'. */
    printf ("\nPlot of symmetric matrix to be ordered by amd_order:\n") ;
    for (j = 0 ; j < n ; j++)
    {
	for (i = 0 ; i < n ; i++) A [i][j] = '.' ;
    }
    for (j = 0 ; j < n ; j++)
    {
	A [j][j] = 'X' ;
	for (p = Rp [j] ; p < Rp [j+1] ; p++)
	{
	    i = Ri [p] ;
	    A [i][j] = 'X' ;
	    A [j][i] = 'X' ;
	}
    }
    printf ("    ") ;
    for (j = 0 ; j < n ; j++) printf (" %1d", j % 10) ;
    printf ("\n") ;
    for (i = 0 ; i < n ; i++)
    {
	printf ("%2d: ", i) ;
	for (j = 0 ; j < n ; j++)
	{
	    printf (" %c", A [i][j]) ;
	}
	printf ("\n") ;
    }

    /* order the matrix */
    result = amd_order (n, Rp, Ri, P, Control, Info) ;
    printf ("return value from amd_order: %d (should be %d)\n",
	result, AMD_OK) ;

    /* print the statistics */
    amd_info (Info) ;

    if (result != AMD_OK)
    {
	printf ("AMD failed\n") ;
	exit (1) ;
    }

    /* print the permutation vector, P, and compute the inverse permutation */
    printf ("Permutation vector:\n") ;
    for (k = 0 ; k < n ; k++)
    {
	/* row/column j is the kth row/column in the permuted matrix */
	j = P [k] ;
	Pinv [j] = k ;
	printf (" %2d", j) ;
    }
    printf ("\n\n") ;

    printf ("Inverse permutation vector:\n") ;
    for (j = 0 ; j < n ; j++)
    {
	k = Pinv [j] ;
	printf (" %2d", k) ;
    }
    printf ("\n\n") ;

    /* print a character plot of the permuted matrix. */
    printf ("\nPlot of (symmetrized) permuted matrix pattern:\n") ;
    for (j = 0 ; j < n ; j++)
    {
	for (i = 0 ; i < n ; i++) A [i][j] = '.' ;
    }
    for (jnew = 0 ; jnew < n ; jnew++)
    {
	j = P [jnew] ;
	A [jnew][jnew] = 'X' ;
	for (p = Rp [j] ; p < Rp [j+1] ; p++)
	{
	    inew = Pinv [Ri [p]] ;
	    A [inew][jnew] = 'X' ;
	    A [jnew][inew] = 'X' ;
	}
    }
    printf ("    ") ;
    for (j = 0 ; j < n ; j++) printf (" %1d", j % 10) ;
    printf ("\n") ;
    for (i = 0 ; i < n ; i++)
    {
	printf ("%2d: ", i) ;
	for (j = 0 ; j < n ; j++)
	{
	    printf (" %c", A [i][j]) ;
	}
	printf ("\n") ;
    }

    return (0) ;
}
Example #9
0
static int set_defaults(double *control)
{
    int_t pos=0;
    int param_id;
    PyObject *param, *key, *value;
#if PY_MAJOR_VERSION < 3
    char *keystr; 
#endif
    char err_str[100];

    amd_defaults(control);

    if (!(param = PyObject_GetAttrString(amd_module, "options")) ||
        !PyDict_Check(param)){
        PyErr_SetString(PyExc_AttributeError, "missing amd.options"
            "dictionary");
        return 0;
    }
    while (PyDict_Next(param, &pos, &key, &value))
#if PY_MAJOR_VERSION >= 3
        if ((PyUnicode_Check(key)) && 
            get_param_idx(_PyUnicode_AsString(key),&param_id)) {
            if (!PyLong_Check(value) && !PyFloat_Check(value)){
                sprintf(err_str, "invalid value for AMD parameter: %-.20s",
                    _PyUnicode_AsString(key));
#else
        if ((keystr = PyString_AsString(key)) && get_param_idx(keystr,
            &param_id)) {
            if (!PyInt_Check(value) && !PyFloat_Check(value)){
                sprintf(err_str, "invalid value for AMD parameter: "
                    "%-.20s", keystr);
#endif
                PyErr_SetString(PyExc_ValueError, err_str);
                Py_DECREF(param);
                return 0;
            }
            control[param_id] = PyFloat_AsDouble(value);
        }
    Py_DECREF(param);
    return 1;
}


static char doc_order[] =
    "Computes the approximate minimum degree ordering of a square "
    "matrix.\n\n"
    "p = order(A, uplo='L')\n\n"
    "PURPOSE\n"
    "Computes a permutation p that reduces fill-in in the Cholesky\n"
    "factorization of A[p,p].\n\n"
    "ARGUMENTS\n"
    "A         square sparse matrix\n\n"
    "uplo      'L' or 'U'.  If uplo is 'L', the lower triangular part\n"
    "          of A is used and the upper triangular is ignored.  If\n"
    "          uplo is 'U', the upper triangular part is used and the\n"
    "          lower triangular part is ignored.\n\n"
    "p         'i' matrix of length equal to the order of A";


static PyObject* order_c(PyObject *self, PyObject *args, PyObject *kwrds)
{
    spmatrix *A;
    matrix *perm;
#if PY_MAJOR_VERSION >= 3
    int uplo_ = 'L';
#endif
    char uplo = 'L';
    int j, k, n, nnz, alloc=0, info;
    int_t *rowind=NULL, *colptr=NULL;
    double control[AMD_CONTROL];
    char *kwlist[] = {"A", "uplo", NULL};

#if PY_MAJOR_VERSION >= 3
    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|C", kwlist, &A,
        &uplo_)) return NULL;
    uplo = (char) uplo_;
#else
    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|c", kwlist, &A,
        &uplo)) return NULL;
#endif
    if (!set_defaults(control)) return NULL;
    if (!SpMatrix_Check(A) || SP_NROWS(A) != SP_NCOLS(A)){
        PyErr_SetString(PyExc_TypeError, "A must be a square sparse "
            "matrix");
        return NULL;
    }
    if (uplo != 'U' && uplo != 'L') err_char("uplo", "'L', 'U'");
    if (!(perm = (matrix *) Matrix_New((int)SP_NROWS(A),1,INT)))
        return PyErr_NoMemory();
    n = SP_NROWS(A);
    for (nnz=0, j=0; j<n; j++) {
        if (uplo == 'L'){
            for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1] && SP_ROW(A)[k]<j; k++);
            nnz += SP_COL(A)[j+1] - k;
        }
        else {
            for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1] && SP_ROW(A)[k] <= j;
                k++);
            nnz += k - SP_COL(A)[j];
        }
    }
    if (nnz == SP_NNZ(A)){
        colptr = (int_t *) SP_COL(A);
        rowind = (int_t *) SP_ROW(A);
    }
    else {
        alloc = 1;
        colptr = (int_t *) calloc(n+1, sizeof(int_t));
        rowind = (int_t *) calloc(nnz, sizeof(int_t));
        if (!colptr || !rowind) {
            Py_XDECREF(perm);  free(colptr);  free(rowind);
            return PyErr_NoMemory();
        }
        colptr[0] = 0;
        for (j=0; j<n; j++) {
            if (uplo == 'L'){
                for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1] && SP_ROW(A)[k] < j; 
                    k++);
                nnz = SP_COL(A)[j+1] - k;
                colptr[j+1] = colptr[j] + nnz;
                memcpy(rowind + colptr[j], (int_t *) SP_ROW(A) + k,
                    nnz*sizeof(int_t));
            }
            else {
                for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1] && SP_ROW(A)[k] <= j;
                    k++);
                nnz = k - SP_COL(A)[j];
                colptr[j+1] = colptr[j] + nnz;
                memcpy(rowind + colptr[j], (int_t *) (SP_ROW(A) +
                    SP_COL(A)[j]), nnz*sizeof(int_t));
            }
        }
    }
    info = amd_order(n, colptr, rowind, MAT_BUFI(perm), control, NULL);
    if (alloc){
        free(colptr);
        free(rowind);
    }
    switch (info) {
        case AMD_OUT_OF_MEMORY:
            Py_XDECREF(perm);
            return PyErr_NoMemory();

        case AMD_INVALID:
            Py_XDECREF(perm);
            return Py_BuildValue("");

        case AMD_OK:
            return (PyObject *) perm;
    }
    return Py_BuildValue("");
}

static PyMethodDef amd_functions[] = {
    {"order", (PyCFunction) order_c, METH_VARARGS|METH_KEYWORDS, doc_order},
    {NULL}  /* Sentinel */
};

#if PY_MAJOR_VERSION >= 3

static PyModuleDef amd_module_def = {
    PyModuleDef_HEAD_INIT,
    "amd",
    amd__doc__,
    -1,
    amd_functions,
    NULL, NULL, NULL, NULL
};

PyMODINIT_FUNC PyInit_amd(void)
{
    if (!(amd_module = PyModule_Create(&amd_module_def))) return NULL;
    PyModule_AddObject(amd_module, "options", PyDict_New());
    if (import_cvxopt() < 0) return NULL;
    return amd_module;
}

#else
PyMODINIT_FUNC initamd(void)
{
    amd_module = Py_InitModule3("cvxopt.amd", amd_functions, amd__doc__);
    PyModule_AddObject(amd_module, "options", PyDict_New());
    if (import_cvxopt() < 0) return;
}