Ejemplo n.º 1
0
/*! \fn allocate memory for linear system solver UmfPack
 *
 */
int
allocateUmfPackData(int n_row, int n_col, int nz, void** voiddata)
{
    DATA_UMFPACK* data = (DATA_UMFPACK*) malloc(sizeof(DATA_UMFPACK));
    assertStreamPrint(NULL, 0 != data, "Could not allocate data for linear solver UmfPack.");

    data->symbolic = NULL;
    data->numeric = NULL;

    data->n_col = n_col;
    data->n_row = n_row;
    data->nnz = nz;


    data->Ap = (int*) calloc((n_row+1),sizeof(int));

    data->Ai = (int*) calloc(nz,sizeof(int));
    data->Ax = (double*) calloc(nz,sizeof(double));
    data->work = (double*) calloc(n_col,sizeof(double));

    data->numberSolving=0;
    umfpack_di_defaults(data->control);

    data->control[UMFPACK_PIVOT_TOLERANCE] = 0.1;
    data->control[UMFPACK_IRSTEP] = 2;
    data->control[UMFPACK_SCALE] = 1;
    data->control[UMFPACK_STRATEGY] = 5;



    *voiddata = (void*)data;

    return 0;
}
Ejemplo n.º 2
0
int UMF::Factor() {
    int status;
    double Info[UMFPACK_INFO];  // UMF internal communcation array
    double Control[UMFPACK_CONTROL];

    memcpy(&_rows[0], _rows_ptr, _nnz*sizeof(int));
    memcpy(&_cols[0], _cols_ptr, _nnz*sizeof(int));
    memcpy(&_vals[0], _vals_ptr, _nnz*sizeof(double));

    _Ap.size(_dim+1);
    _Ai.size(_nnz);
    _Ax.size(_nnz);

    _NRC = _nnz;

    /* get the default control parameters */
    umfpack_di_defaults (Control) ;

    /* convert to column form */
    status = umfpack_di_triplet_to_col(_dim, _dim, _NRC,
                                       &_rows[0], &_cols[0],
                                       &_vals[0], &_Ap[0], &_Ai[0], &_Ax[0], (int*)NULL) ;
    if (status < 0 ) {
        umfpack_di_report_status (Control, status) ;
        fprintf(stderr,"umfpack_di_triplet_to_col failed\n");
        return (-1);
    }

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

    if ( _Symbolic == NULL ) { // skip the symbolic factorization steps except the very first one
        status = umfpack_di_symbolic (_dim, _dim, &_Ap[0], &_Ai[0], &_Ax[0], &_Symbolic, Control, Info) ;
        if (status < 0 ) {
            umfpack_di_report_info (Control, Info) ;
            umfpack_di_report_status (Control, status) ;
            fprintf(stderr,"umfpack_di_symbolic failed\n");
            return (-1);
        }
    }

    /* ---------------------------------------------------------------------- */
    /* numeric factorization */
    /* ---------------------------------------------------------------------- */
    if ( _Numeric )  umfpack_di_free_numeric (&_Numeric);
    status = umfpack_di_numeric (&_Ap[0], &_Ai[0], &_Ax[0], _Symbolic, &_Numeric, Control, Info) ;
    if (status < 0 ) {
        umfpack_di_report_info (Control, Info) ;
        umfpack_di_report_status (Control, status) ;
        fprintf(stderr,"umfpack_di_numeric failed\n") ;
        return (-1);
    }
    _is_factored = 1;

    return 0;
}
Ejemplo n.º 3
0
bool CommonSolverUmfpack::solve(Matrix *mat, double *res)
{
    printf("UMFPACK solver\n");

    CSCMatrix *Acsc = NULL;

    if (CooMatrix *mcoo = dynamic_cast<CooMatrix*>(mat))
        Acsc = new CSCMatrix(mcoo);
    else if (CSCMatrix *mcsc = dynamic_cast<CSCMatrix*>(mat))
        Acsc = mcsc;
    else if (CSRMatrix *mcsr = dynamic_cast<CSRMatrix*>(mat))
        Acsc = new CSCMatrix(mcsr);
    else
        _error("Matrix type not supported.");

    int nnz = Acsc->get_nnz();
    int size = Acsc->get_size();

    // solve
    umfpack_di_defaults(control_array);

    /* symbolic analysis */
    void *symbolic, *numeric;
    int status_symbolic = umfpack_di_symbolic(size, size,
                                              Acsc->get_Ap(), Acsc->get_Ai(), NULL, &symbolic,
                                              control_array, info_array);
    print_status(status_symbolic);

    /* LU factorization */
    int status_numeric = umfpack_di_numeric(Acsc->get_Ap(), Acsc->get_Ai(), Acsc->get_Ax(), symbolic, &numeric,
                                            control_array, info_array);
    print_status(status_numeric);

    umfpack_di_free_symbolic(&symbolic);

    double *x = new double[size];

    /* solve system */
    int status_solve = umfpack_di_solve(UMFPACK_A,
                                        Acsc->get_Ap(), Acsc->get_Ai(), Acsc->get_Ax(), x, res, numeric,
                                        control_array, info_array);

    print_status(status_solve);

    umfpack_di_free_numeric(&numeric);

    if (symbolic) umfpack_di_free_symbolic(&symbolic);
    if (numeric) umfpack_di_free_numeric(&numeric);

    memcpy(res, x, size*sizeof(double));
    delete[] x;

    if (!dynamic_cast<CSCMatrix*>(mat))
        delete Acsc;
}
Ejemplo n.º 4
0
int main (void) {
	double **Y = new_square_matrix(n);
	Y[0][0] = 1; Y[0][1] = 0; Y[0][2] = 0; 
	Y[1][0] = 0; Y[1][1] = 0.2; Y[1][2] = 1; 
	Y[2][0] = 0; Y[2][1] = 1; Y[2][2] = 0; 
	int nz = count_entry(Y,n);
	int Ti[nz];
	int Tj[nz];
	double Tx[nz];
	matrix_to_triplet(Ti,Tj,Tx,nz,Y,n);

	int n_row = n;
	int n_col = n;
	int * Ap = new int [n_col+1];
	int * Ai = new int [nz];
	double * Ax = new double [nz];

	int status;
	double Control [UMFPACK_CONTROL];
	umfpack_di_defaults (Control) ;
	status = umfpack_di_triplet_to_col(n_row, n_col, nz, Ti, Tj, Tx, 
			Ap, Ai, Ax, (int *) NULL);
	
	if( status < 0 ) {
		umfpack_di_report_status (Control, status) ;
		report_exit("umfpack_zi_triplet_to_col failed\n") ;
	}


	double *null = (double *) NULL ;
	int i ;
	void *Symbolic, *Numeric ;
	(void) umfpack_di_symbolic (n, n, Ap, Ai, Ax, &Symbolic, null, null) ;
	(void) umfpack_di_numeric (Ap, Ai, Ax, Symbolic, &Numeric, null, null) ;
	umfpack_di_free_symbolic (&Symbolic) ;
	(void) umfpack_di_solve (UMFPACK_A, Ap, Ai, Ax, v, J, Numeric, null, null) ;
	umfpack_di_free_numeric (&Numeric) ;
	for (i = 0 ; i < n ; i++) printf ("v [%d] = %lf\n", i, v[i]) ;

	delete [] Ap;
	delete [] Ai;
	delete [] Ax;
	return (0) ;
}
Ejemplo n.º 5
0
int umfpack_solver(struct simulation *sim,int col,int nz,int *Ti,int *Tj, long double *lTx,long double *lb)
{
int i;
void *Symbolic, *Numeric;
int status;
double *dtemp;
int *itemp;


if ((sim->last_col!=col)||(sim->last_nz!=nz))
{
	dtemp = realloc(sim->x,col*sizeof(double));
	if (dtemp==NULL)
	{
		ewe(sim,"realloc failed\n");
	}else
	{
		sim->x=dtemp;
	}


	dtemp = realloc(sim->b,col*sizeof(double));
	if (dtemp==NULL)
	{
		ewe(sim,"realloc failed\n");
	}else
	{
		sim->b=dtemp;
	}

	itemp = realloc(sim->Ap,(col+1)*sizeof(int));
	if (itemp==NULL)
	{
		ewe(sim,"realloc failed\n");
	}else
	{
		sim->Ap=itemp;
	}

	itemp = realloc(sim->Ai,(nz)*sizeof(int));
	if (itemp==NULL)
	{
		ewe(sim,"realloc failed\n");
	}else
	{
		sim->Ai=itemp;
	}

	dtemp  = realloc(sim->Ax,(nz)*sizeof(double));
	if (dtemp==NULL)
	{
		ewe(sim,"realloc failed\n");
	}else
	{
		sim->Ax=dtemp;
	}

	dtemp  = realloc(sim->Tx,(nz)*sizeof(double));
	if (dtemp==NULL)
	{
		ewe(sim,"realloc failed\n");
	}else
	{
		sim->Tx=dtemp;
	}


	sim->last_col=col;
	sim->last_nz=nz;
}

for (i=0;i<col;i++)
{
	sim->b[i]=(double)lb[i];
}

for (i=0;i<nz;i++)
{
	sim->Tx[i]=(double)lTx[i];
}


double Control [UMFPACK_CONTROL],Info [UMFPACK_INFO];

umfpack_di_defaults (Control) ;
Control[UMFPACK_BLOCK_SIZE]=20;
//Control [UMFPACK_STRATEGY]=UMFPACK_STRATEGY_SYMMETRIC;//UMFPACK_STRATEGY_UNSYMMETRIC;
//Control [UMFPACK_ORDERING]=UMFPACK_ORDERING_BEST;//UMFPACK_ORDERING_AMD;//UMFPACK_ORDERING_BEST;//
//printf("%lf\n",Control[UMFPACK_BLOCK_SIZE]);
//Control [UMFPACK_PIVOT_TOLERANCE]=0.0001;
//Control[UMFPACK_SINGLETONS]=1;
//Control[UMFPACK_SCALE]=3;
status = umfpack_di_triplet_to_col(col, col, nz, Ti, Tj, sim->Tx, sim->Ap, sim->Ai, sim->Ax, NULL);
//printf("rod1\n");
//getchar();

if (status != UMFPACK_OK) {
	error_report(status, __FILE__, __func__, __LINE__);
	return EXIT_FAILURE;
}

// symbolic analysis
//printf("here2 %d\n",col);
status = umfpack_di_symbolic(col, col, sim->Ap, sim->Ai, sim->Ax, &Symbolic, Control, Info);
//printf("rod2\n");
//getchar();

//printf("here3\n");

if (status != UMFPACK_OK) {
	error_report(status, __FILE__, __func__, __LINE__);
	return EXIT_FAILURE;
}

// LU factorization
umfpack_di_numeric(sim->Ap, sim->Ai, sim->Ax, Symbolic, &Numeric, Control, Info);
//printf("rod5\n");
//getchar();


if (status != UMFPACK_OK) {
	error_report(status, __FILE__, __func__, __LINE__);
	return EXIT_FAILURE;
}
// solve system

umfpack_di_free_symbolic(&Symbolic);
//printf("rod a\n");
//getchar();


umfpack_di_solve(UMFPACK_A, sim->Ap, sim->Ai, sim->Ax, sim->x, sim->b, Numeric, Control, Info);

//printf("rod b\n");
//getchar();

//printf("%lf\n",Info [UMFPACK_ORDERING_USED]);

if (status != UMFPACK_OK) {
	error_report(status, __FILE__, __func__, __LINE__);
	return EXIT_FAILURE;
}

umfpack_di_free_numeric(&Numeric);
//printf("rod\n");
//getchar();

for (i=0;i<col;i++)
{
lb[i]=(long double)sim->x[i];
}

//memcpy(b, x, col*sizeof(double));
//umfpack_toc(stats);


return 0;
}
Ejemplo n.º 6
0
 UMFPackLinearMatrixSolver<Scalar>::UMFPackLinearMatrixSolver(CSCMatrix<Scalar> *m, SimpleVector<Scalar> *rhs)
   : DirectSolver<Scalar>(m, rhs), m(m), rhs(rhs), symbolic(nullptr), numeric(nullptr)
 {
   umfpack_di_defaults(Control);
 }
Ejemplo n.º 7
0
//=============================================================================
int Amesos_Umfpack::PerformNumericFactorization( ) 
{
  // MS // no overhead time in this method
  ResetTimer(0);

  RcondValidOnAllProcs_ = false ; 
  if (MyPID_ == 0) {
    std::vector<double> Control(UMFPACK_CONTROL);
    std::vector<double> Info(UMFPACK_INFO);
    umfpack_di_defaults( &Control[0] ) ; 
    if (Numeric) umfpack_di_free_numeric (&Numeric) ;
    int status = umfpack_di_numeric (&Ap[0], 
				     &Ai[0], 
				     &Aval[0], 
				     Symbolic, 
				     &Numeric, 
				     &Control[0], 
				     &Info[0]) ;
    Rcond_ = Info[UMFPACK_RCOND]; 

#if NOT_DEF
    std::cout << " Rcond_ = " << Rcond_ << std::endl ; 

    int lnz1 = 1000 ;
    int unz1 = 1000 ;
    int n = 4;
    int * Lp = (int *) malloc ((n+1) * sizeof (int)) ;
    int * Lj = (int *) malloc (lnz1 * sizeof (int)) ;
    double * Lx = (double *) malloc (lnz1 * sizeof (double)) ;
    int * Up = (int *) malloc ((n+1) * sizeof (int)) ;
    int * Ui = (int *) malloc (unz1 * sizeof (int)) ;
    double * Ux = (double *) malloc (unz1 * sizeof (double)) ;
    int * P = (int *) malloc (n * sizeof (int)) ;
    int * Q = (int *) malloc (n * sizeof (int)) ;
    double * Dx = (double *) NULL ;	/* D vector not requested */
    double * Rs  = (double *) malloc (n * sizeof (double)) ;
    if (!Lp || !Lj || !Lx || !Up || !Ui || !Ux || !P || !Q || !Rs)
    {
      assert( false ) ; 
    }
    int do_recip;
    status = umfpack_di_get_numeric (Lp, Lj, Lx, Up, Ui, Ux,
	P, Q, Dx, &do_recip, Rs, Numeric) ;
    if (status < 0)
    {
      assert( false ) ; 
    }

    printf ("\nL (lower triangular factor of C): ") ;
    (void) umfpack_di_report_matrix (n, n, Lp, Lj, Lx, 0, &Control[0]) ;
    printf ("\nU (upper triangular factor of C): ") ;
    (void) umfpack_di_report_matrix (n, n, Up, Ui, Ux, 1, &Control[0]) ;
    printf ("\nP: ") ;
    (void) umfpack_di_report_perm (n, P, &Control[0]) ;
    printf ("\nQ: ") ;
    (void) umfpack_di_report_perm (n, Q, &Control[0]) ;
    printf ("\nScale factors: row i of A is to be ") ;

#endif

    assert( status == 0 ) ; 
  }
  
  NumFactTime_ = AddTime("Total numeric factorization time", NumFactTime_, 0);

  return 0;
}
Ejemplo n.º 8
0
/* This returns an integer identifier that should be unique to your
 * system.  There were problems with UMF mixing up systems becuase it
 * would identify unique systems just by its size.
 *
 * This unique identifier is passed in as system_id.  If you're
 * creating the matrix for the first time, then you should pass in a
 * -1, otherwise you should pass in the returned value from SL_UMF
 * when you created your system.
 *
 * Note that we don't do this very intelligently.  We simply use
 * indices sequentially.  There is no mechanism to allow re-use.
 */
int
SL_UMF ( int system_id,
	 int *first,
	 int *fact_optn,
	 int *matr_form,
	 int *nj,
	 int *nnz_j,
	 int *row,
	 int *col,
	 double *a,
	 double *b,
	 double *x  )
{
  /* Static struct holds all linear systems also keep track of number
   * of systems we have set up */
  static struct UMF_Linear_Solver_System ums_a[UMF_MAX_SYSTEMS];
  static int number_systems = 0;
  
  double Control[UMFPACK_CONTROL], Info[UMFPACK_INFO];
        
  struct UMF_Linear_Solver_System *ums = 0;  /* pointer to current system */

  int i, j, k, umf_option = 0;
  int hit_diag, err;

  for (i = 0; i < UMFPACK_CONTROL; i++) {
    Control[i] = 0;
  }

  for (i = 0; i < UMFPACK_INFO; i++) {
    Info[i] = 0;
  }
          
#ifdef DEBUG_SL_UMF
  fprintf(stderr, "SL_UMF: system_id = %d, *first = %d, *fact_optn = %d\n",
	  system_id, *first, *fact_optn);
#endif

  /* MEMORY */
  switch (*first) {
  case 1:
    /* If *first == 1, then we're creating a new matrix. */

    /* If system_id isn't -1, then we're probably making some sort of mistake... */
    if(system_id != -1)
      EH(-1, "Entered SL_UMF with *first == 1, but system_id != -1");
    /* If we've already gone through all of our slots, get out. */
    if(number_systems == UMF_MAX_SYSTEMS)
      EH(-1, "Already created UMF_MAX_SYSTEMS systems");

    system_id = number_systems;
    ums = &ums_a[number_systems++];
    ums->n = *nj;
    ums->nnz = *nnz_j;

    /* MATRIX VECTORS */
    ums->ap = Ivector_birth(ums->n + 1);
    ums->ai = Ivector_birth(ums->nnz);
    ums->ax = Dvector_birth(ums->nnz);

    /* MSR needs extra allocation for A-transpose */
    ums->atp = NULL;
    ums->ati = NULL;
    ums->atx = NULL;
    if ( *matr_form == 1 ) {
      ums->atp = Ivector_birth(ums->n + 1);
      ums->ati = Ivector_birth(ums->nnz);
      ums->atx = Dvector_birth(ums->nnz);
    } 
    
    break;
                         
  case 0:
    /* If *first == 0, then we want to just reuse a previously created 
     * system. */

    /* system_id should have the appropriate identifier. */
    if(system_id == -1)
      EH(-1, "Conflicting orders: system_id == -1 and *first != 1");
    if(system_id < 0 || system_id >= UMF_MAX_SYSTEMS)
      EH(-1, "Index out of range: system_id");

    /* Grab the hopeful system. */
    ums = &ums_a[system_id];

    /* Run through some sanity checks to help ensure we're dealing
     * with the correct system. */
    if(ums->n != *nj || ums->nnz != *nnz_j)
      EH(-1, "Tried to access a bad system");
    break;

  case -1:
    /* If *first == -1, then we want to free space. */

    /* system_id should have the appropriate identifier. */
    if(system_id == -1)
      EH(-1, "Conflicting orders: system_id == -1 and *first != 1");
    if(system_id < 0 || system_id >= UMF_MAX_SYSTEMS)
      EH(-1, "Index out of range: system_id");

    ums = &ums_a[system_id];
    /* Run through some sanity checks to help ensure we're dealing
     * with the correct system. */
    if(ums->n != *nj || ums->nnz != *nnz_j)
      EH(-1, "Tried to free a bad system");

    umfpack_di_free_symbolic(&ums->symbolic);
    ums->symbolic = NULL;  
    umfpack_di_free_numeric(&ums->numeric);
    ums->numeric = NULL;                
    Ivector_death(ums->ap, ums->n + 1);
    Ivector_death(ums->ai, ums->nnz);
    Dvector_death(ums->ax, ums->nnz);

    if ( ums->atp != NULL ) {
      Ivector_death(ums->atp, ums->n + 1);
      Ivector_death(ums->ati, ums->nnz);
      Dvector_death(ums->atx, ums->nnz);
    } 

    /* MMH: The fix that changed the world... */
    ums->n = 0;
    ums->nnz = 0;

    /* So things break later in case we actually use the return value
     * after deallocating space. */
    system_id = -1;

    break;
  }

  /* CONVERT MSR FORMAT TO MATLAB FORMAT IF NEEDED */
  if (abs(*fact_optn) < 3) { 
    switch (*matr_form) {
    case 0: /* COORDINATE FORMAT */
      umfpack_di_triplet_to_col( ums->n, ums->n, ums->nnz,
                                 row, col, a,
                                 ums->ap, ums->ai, ums->ax,
                                 NULL );
      break;
    case 1: /* MSR FORMAT */
      /* Note: MSR is row-oriented and UMF wants column-oriented data.
         So, assemble A-transpose in UMF format, and use umf utility
         to get back A in UMF format.
         Note also that UMF can operate directly on A-transpose.  This
         can save having to make another copy of the matrix, but it limited
         experiments, I found it to be slower. -DRN

         To form A-transpose in UMF format, merge the diagonal entries
         back into the rows.
      */
      k = 0;
      for (i=0;i<ums->n;i++) {  /* loop over rows */
        ums->atp[i] = k;
        hit_diag = FALSE;
	for (j=col[i];j<col[i+1];j++) {  /* loop over colums within row */
          /* if we get to the spot where the diagonal term belongs, merge it in */
          if (!hit_diag && col[j] > i ) {
            ums->ati[k] = i;
            ums->atx[k] = a[i];
            k++;
            hit_diag = TRUE;
          }
          ums->ati[k] = col[j];
          ums->atx[k] = a[j];
          k++;
        }
        /* if we never got to the diagonal, merge it in now */
        if (!hit_diag) {
          ums->ati[k] = i;
          ums->atx[k] = a[i];
          k++;
          hit_diag = TRUE;
        }
      }
      ums->atp[ums->n] = ums->nnz;
      
      if (ums->nnz != k) {
	DPRINTF(stderr, "E: NNZ=%12d CT=%12d\n", ums->nnz, k);
	exit(0);
      }
      
      /* transpose matrix */
      err = umfpack_di_transpose (ums->n, ums->n, ums->atp, ums->ati, ums->atx,
	(int *) NULL, (int *) NULL, ums->ap, ums->ai, ums->ax);
      if ( err != UMFPACK_OK )
        {
	  fprintf(stderr,"UMFPACK error = %d\n",err);
	  EH(-1,"Error computing matrix transpose using umfpack_di_transpose\n");
	}

      break;
    case 2: /* CSR FORMAT - NOT DONE YET */
      EH(-1, "Sorry, cannot convert CSR systems");
      break;
    }

    /* SET OPTIONS */
    switch (*fact_optn) {
    case -2: /* FULL ANALYSIS AND FACTORIZATION */
      umf_option = 1;
      break;
    case -1: /* FACTORIZATION WITH PAST ANALYSIS */
      umf_option = 0;
      break;
    case  0: /* FULL ANALYSIS AND FACTORIZATION */
      umf_option = 1;
      break;
    case  1: /* FACTORIZATION WITH PAST ANALYSIS */
      umf_option = 0;
      break;
    case 3:
      umf_option = 0;
      break;
    default:
      EH(-1, "Bad *fact_optn");
    }

    /* load default control parameters for UMF */
    umfpack_di_defaults( Control );
    /* optionally can ask for feedback from routines by uncommenting below */
    /*Control[UMFPACK_PRL] = 2.;*/
    /* optionally force solution strategy */
    Control[UMFPACK_STRATEGY] = UMFPACK_STRATEGY_UNSYMMETRIC;
    
    if ( umf_option == 1 ) {
      /* analysis */
      if ( ums->symbolic != NULL ) {
        umfpack_di_free_symbolic(&ums->symbolic);
        ums->symbolic = NULL;
      }
      err = umfpack_di_symbolic( ums->n, ums->n,
                                 ums->ap, ums->ai, ums->ax,
                                 &ums->symbolic, Control, Info );
      umfpack_di_report_status(Control, err);
      umfpack_di_report_info(Control, Info);
    }

    /* factorization */
    if ( ums->numeric != NULL ) {
      umfpack_di_free_numeric(&ums->numeric);
      ums->numeric = NULL;
    }
    err = umfpack_di_numeric( ums->ap, ums->ai, ums->ax,
                              ums->symbolic, &ums->numeric, Control, Info );
    umfpack_di_report_status(Control, err);
    umfpack_di_report_info(Control, Info);

  }

  /* solve */
  if ( *fact_optn >= 0 ) {
    err = umfpack_di_solve( UMFPACK_A, ums->ap, ums->ai, ums->ax,
                            x, b,
                            ums->numeric, Control, Info );
    umfpack_di_report_status(Control, err);
    umfpack_di_report_info(Control, Info);
  }

  return system_id;

} /* END of routine SL_UMF */
Ejemplo n.º 9
0
Archivo: umf4.c Proyecto: 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) ;
}
Ejemplo n.º 10
0
 inline
 void defaults (double, int, double* Control) {
   umfpack_di_defaults (Control);
 }
Ejemplo n.º 11
0
int sci_umf_lusolve(char* fname, unsigned long l)
{
    SciErr sciErr;

    int mb      = 0;
    int nb      = 0;
    int it_flag = 0;
    int i       = 0;
    int j       = 0;

    int NoTranspose = 0;
    int NoRaffinement = 0;
    SciSparse AA;
    CcsSparse A;

    /* umfpack stuff */
    double Info[UMFPACK_INFO]; // double *Info = (double *) NULL;
    double Control[UMFPACK_CONTROL];
    void* Numeric = NULL;
    int lnz = 0, unz = 0, n = 0, n_col = 0, nz_udiag = 0, umf_flag = 0;
    int* Wi = NULL;
    int mW = 0;
    double *W = NULL;

    int iComplex = 0;

    int* piAddr1 = NULL;
    int* piAddr2 = NULL;
    int* piAddr3 = NULL;
    int* piAddr4 = NULL;

    double* pdblBR = NULL;
    double* pdblBI = NULL;
    double* pdblXR = NULL;
    double* pdblXI = NULL;

    int mA              = 0; // rows
    int nA              = 0; // cols
    int iNbItem         = 0;
    int* piNbItemRow    = NULL;
    int* piColPos       = NULL;
    double* pdblSpReal  = NULL;
    double* pdblSpImg   = NULL;

    /* Check numbers of input/output arguments */
    CheckInputArgument(pvApiCtx, 2, 4);
    CheckOutputArgument(pvApiCtx, 1, 1);

    /* First get arg #1 : the pointer to the LU factors */
    sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr1);
    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    sciErr = getPointer(pvApiCtx, piAddr1, &Numeric);
    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    /* Check if this pointer is a valid ref to a umfpack LU numeric object */
    if ( ! IsAdrInList(Numeric, ListNumeric, &it_flag) )
    {
        Scierror(999, _("%s: Wrong value for input argument #%d: Must be a valid reference to (umf) LU factors.\n"), fname, 1);
        return 1;
    }

    /*  get some parameters of the factorization (for some checking) */
    if ( it_flag == 0 )
    {
        umfpack_di_get_lunz(&lnz, &unz, &n, &n_col, &nz_udiag, Numeric);
    }
    else
    {
        iComplex = 1;
        umfpack_zi_get_lunz(&lnz, &unz, &n, &n_col, &nz_udiag, Numeric);
    }

    if ( n != n_col )
    {
        Scierror(999, _("%s: An error occurred: %s.\n"), fname, _("This is not a factorization of a square matrix"));
        return 1;
    }

    if ( nz_udiag < n )
    {
        Scierror(999, _("%s: An error occurred: %s.\n"), fname, _("This is a factorization of a singular matrix"));
        return 1;
    }

    /* Get now arg #2 : the vector b */
    sciErr = getVarAddressFromPosition(pvApiCtx, 2, &piAddr2);
    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    if (isVarComplex(pvApiCtx, piAddr2))
    {
        iComplex = 1;
        sciErr = getComplexMatrixOfDouble(pvApiCtx, piAddr2, &mb, &nb, &pdblBR, &pdblBI);
    }
    else
    {
        sciErr = getMatrixOfDouble(pvApiCtx, piAddr2, &mb, &nb, &pdblBR);
    }

    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    if (mb != n || nb < 1)    /* test if the right hand side is compatible */
    {
        Scierror(999, _("%s: Wrong size for input argument #%d.\n"), fname, 2);
        return 1;
    }

    /* allocate memory for the solution x */
    if (iComplex)
    {
        sciErr = allocComplexMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, mb, nb, &pdblXR, &pdblXI);
    }
    else
    {
        sciErr = allocMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, mb, nb, &pdblXR);
    }

    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    /*  selection between the different options :
     *   -- solving Ax=b or A'x=b (Note: we could add  A.'x=b)
     *   -- with or without raffinement
     */

    if (nbInputArgument(pvApiCtx) == 2)
    {
        NoTranspose = 1;
        NoRaffinement = 1;
    }
    else  /* 3 or 4 input arguments but the third must be a string */
    {
        char* pStr = NULL;
        sciErr = getVarAddressFromPosition(pvApiCtx, 3, &piAddr3);
        if (sciErr.iErr)
        {
            printError(&sciErr, 0);
            return 1;
        }

        getAllocatedSingleString(pvApiCtx, piAddr3, &pStr);
        if (strcmp(pStr, "Ax=b") == 0)
        {
            NoTranspose = 1;
        }
        else if ( strcmp(pStr, "A'x=b") == 0 )
        {
            NoTranspose = 0;
        }
        else
        {
            Scierror(999, _("%s: Wrong input argument #%d: '%s' or '%s' expected.\n"), fname, 3, "Ax=b", "A'x=b");
            return 1;
        }

        if (nbInputArgument(pvApiCtx) == 4)
        {
            sciErr = getVarAddressFromPosition(pvApiCtx, 4, &piAddr4);
            if (sciErr.iErr)
            {
                printError(&sciErr, 0);
                return 1;
            }

            if (isVarComplex(pvApiCtx, piAddr4))
            {
                AA.it = 1;
                sciErr = getComplexSparseMatrix(pvApiCtx, piAddr4, &mA, &nA, &iNbItem, &piNbItemRow, &piColPos, &pdblSpReal, &pdblSpImg);
            }
            else
            {
                AA.it = 0;
                sciErr = getSparseMatrix(pvApiCtx, piAddr4, &mA, &nA, &iNbItem, &piNbItemRow, &piColPos, &pdblSpReal);
            }

            if (sciErr.iErr)
            {
                printError(&sciErr, 0);
                return 1;
            }

            // fill struct sparse
            AA.m     = mA;
            AA.n     = nA;
            AA.nel   = iNbItem;
            AA.mnel  = piNbItemRow;
            AA.icol  = piColPos;
            AA.R     = pdblSpReal;
            AA.I     = pdblSpImg;

            /*  some check... but we can't be sure that the matrix corresponds to the LU factors */
            if ( mA != nA || mA != n || AA.it != it_flag )
            {
                Scierror(999, _("%s: Wrong size for input argument #%d: %s.\n"), fname, 4, _("Matrix is not compatible with the given LU factors"));
                return 1;
            }

            NoRaffinement = 0;
        }
        else
        {
            NoRaffinement = 1;   /* only 3 input var => no raffinement */
        }
    }

    /* allocate memory for umfpack_di_wsolve usage or umfpack_zi_wsolve usage*/
    Wi = (int*)MALLOC(n * sizeof(int));

    if (it_flag == 1)
    {
        if (NoRaffinement)
        {
            mW = 4 * n;
        }
        else
        {
            mW = 10 * n;
        }
    }
    else
    {
        if (NoRaffinement)
        {
            mW = n;
        }
        else
        {
            mW = 5 * n;
        }
    }

    W = (double*)MALLOC(mW * sizeof(double));

    if (NoRaffinement == 0)
    {
        SciSparseToCcsSparse(&AA, &A);
    }
    else
    {
        A.p = NULL;
        A.irow = NULL;
        A.R = NULL;
        A.I = NULL;
    }

    /* get the pointer for b */
    if (it_flag == 1  &&  pdblBI == NULL)
    {
        int iSize = mb * nb * sizeof(double);
        pdblBI = (double*)MALLOC(iSize);
        memset(pdblBI, 0x00, iSize);
    }

    /* init Control */
    if (it_flag == 0)
    {
        umfpack_di_defaults(Control);
    }
    else
    {
        umfpack_zi_defaults(Control);
    }

    if (NoRaffinement)
    {
        Control[UMFPACK_IRSTEP] = 0;
    }

    if (NoTranspose)
    {
        umf_flag = UMFPACK_A;
    }
    else
    {
        umf_flag = UMFPACK_At;
    }

    if (it_flag == 0)
    {
        for (j = 0; j < nb ; j++)
        {
            umfpack_di_wsolve(umf_flag, A.p, A.irow, A.R, &pdblXR[j * mb], &pdblBR[j * mb], Numeric, Control, Info, Wi, W);
        }

        if (iComplex == 1)
        {
            for (j = 0; j < nb ; j++)
            {
                umfpack_di_wsolve(umf_flag, A.p, A.irow, A.R, &pdblXI[j * mb], &pdblBI[j * mb], Numeric, Control, Info, Wi, W);
            }
        }
    }
    else
    {
        for (j = 0; j < nb ; j++)
        {
            umfpack_zi_wsolve(umf_flag, A.p, A.irow, A.R, A.I, &pdblXR[j * mb], &pdblXI[j * mb], &pdblBR[j * mb], &pdblBI[j * mb], Numeric, Control, Info, Wi, W);
        }
    }

    if (isVarComplex(pvApiCtx, piAddr2) == 0)
    {
        FREE(pdblBI);
    }

    freeCcsSparse(A);

    FREE(W);
    FREE(Wi);

    AssignOutputVariable(pvApiCtx, 1) = nbInputArgument(pvApiCtx) + 1;
    ReturnArguments(pvApiCtx);
    return 0;
}