Ejemplo n.º 1
0
/*
 * ***************************************************************************
 * Routine:  Slu_solve
 *
 * Purpose:  Use sparse LU factors to back/forward solve a linear system.
 *
 * Author:   Michael Holst and Stephen Bond
 * ***************************************************************************
 */
VPUBLIC int Slu_solve(Slu *thee, int key, double *b, double *x)
{
    int status;
    int n = thee->n, m = thee->m, skey = thee->skey;
    int *Ap = thee->ia, *Ai = thee->ja;
    double *Ax = thee->a;
    void *Numeric = thee->work;

    VASSERT( thee != VNULL );
    VASSERT( thee->statLU );

    /* solve the system with the existing factors */

    if( (key == 0 && skey == 1) || (key == 1 && skey == 0) ) {
        status = umfpack_di_solve(UMFPACK_A, Ap, Ai, Ax, x, b, Numeric,
                                  VNULL, VNULL);
    } else {
        status = umfpack_di_solve(UMFPACK_At, Ap, Ai, Ax, x, b, Numeric,
                                  VNULL, VNULL);
    }

    /* return: 1=success, 0=failure */
    if ( UMFPACK_OK == status ) {
        return 1;
    } else {
        return 0;
    }
}
Ejemplo n.º 2
0
bool SparseMatrix::solveUMF (Vector& B, Real* rcond)
{
  if (!factored) this->optimiseSLU();

#ifdef HAS_UMFPACK
  double info[UMFPACK_INFO];
  Vector X(B.size());
  if (!umfSymbolic) {
    umfpack_di_symbolic(nrow, ncol, IA.data(), JA.data(),
                        A.data(), &umfSymbolic, nullptr, info);
    if (info[UMFPACK_STATUS] != UMFPACK_OK)
      return false;
  }

  void* numeric;
  umfpack_di_numeric(IA.data(), JA.data(), A.data(), umfSymbolic,
                     &numeric, nullptr, info);
  if (info[UMFPACK_STATUS] != UMFPACK_OK)
    return false;
  if (rcond)
    *rcond = info[UMFPACK_RCOND];
  umfpack_di_solve(UMFPACK_A,
                   IA.data(), JA.data(), A.data(),
                   &X[0], &B[0], numeric, nullptr, info);
  if (info[UMFPACK_STATUS] == UMFPACK_OK)
    B = X;
  umfpack_di_free_numeric(&numeric);
  return info[UMFPACK_STATUS] == UMFPACK_OK;
#else
  std::cerr <<"SparseMatrix::solve: UMFPACK solver not available"<< std::endl;
  return false;
#endif
}
Ejemplo n.º 3
0
/*---------------------------------------------------------------------------*/
void
sparse_solve(sparse_t *A, double *b, double *x)
/*---------------------------------------------------------------------------*/
{
  assert (A->m == A->n);

  if (sparse_is_triangular(A))
  {
    sparse_solve_triangular(A, b, x);
    return;
  }


  int n = A->m;

  /* UMFPACK expect compressed-sparse-column format. */
  sparse_t *B = NULL;  sparse_copy(&B, A);
  B = sparse_transpose(B);

  double *null = (double *) NULL ;

  void *Symbolic, *Numeric ;

  umfpack_di_symbolic (n, n, B->ia, B->ja, B->a, &Symbolic, null, null) ;
  umfpack_di_numeric  (B->ia, B->ja, B->a, Symbolic, &Numeric, null, null) ;
  umfpack_di_free_symbolic (&Symbolic);


  umfpack_di_solve (UMFPACK_A, B->ia, B->ja, B->a, x, b, Numeric, null, null) ;
  umfpack_di_free_numeric (&Numeric);

  sparse_free(B);
}
Ejemplo n.º 4
0
void SolveRealByLU(int numberOfRows, int numberOfColumn, int nnz, int *Ti, int *Tj, double *Tx, double *X, double *b)
{
	//创建 Compressed Row Storage 存储结构
	int *Ai = (int*)malloc(sizeof(int)*(nnz));
	int *Ap = (int*)malloc(sizeof(int)*(numberOfRows + 1));
	double *Ax = (double*)malloc(sizeof(double)*(nnz));

	//转换 triplet 到 CRS
	int staus = umfpack_di_triplet_to_col(numberOfRows, numberOfColumn, nnz, Ti, Tj, Tx, Ap, Ai, Ax, NULL);
	if (staus != UMFPACK_OK){
		return;
	}

	//因子化
	void *Symbolic, *Numeric;
	umfpack_di_symbolic(numberOfRows, numberOfColumn, Ap, Ai, Ax, &Symbolic, NULL, NULL);
	umfpack_di_numeric(Ap, Ai, Ax, Symbolic, &Numeric, NULL, NULL);
	umfpack_di_solve(UMFPACK_A, Ap, Ai, Ax, X, b, Numeric, NULL, NULL);

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

	if (Ai != NULL)
		free(Ai);
	if (Ap != NULL)
		free(Ap);
	if (Ax != NULL)
		free(Ax);
}
Ejemplo n.º 5
0
 inline
 int solve (int sys, int,
            int const* Ap, int const* Ai, double const* Ax,
            double* X, double const* B, void *Numeric,
            double const* Control, double* Info)
 {
   return umfpack_di_solve (sys, Ap, Ai, Ax, X, B, Numeric, Control, Info);
 }
Ejemplo n.º 6
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.º 7
0
/* Transform the target model like source_ref==>source_deformed, trans->target
   is modified to deformed model.  */
void Transform2TargetMeshModel(
    const dtMeshModel *source_deformed, dtTransformer *trans)
{
    __dt_BuildRhsConstantVector(source_deformed, &(trans->target), 
        &(trans->sinvlist), &(trans->tcdict), trans->C);

    __dt_CHOLMOD_Axc(trans->At, trans->C, trans->c);

    umfpack_di_solve(UMFPACK_A, 
        (const int*)(trans->AtA->p), (const int*)(trans->AtA->i), (const double*)(trans->AtA->x), 
        (double*)(trans->x->x), (const double*)(trans->c->x), 
        trans->numeric_obj, NULL, NULL);

    __apply_deformation_to_model(&(trans->target), trans->x);
}
Ejemplo n.º 8
0
int main(int argc, char *argv[]) {
	if (argc < 3) {
		printf("Not enough parameters.\n");
		return -1;
	}

	if (readFromBinaryFile(argv[1]) < 0) {
		return -1;
	}

	printf("symbolic analysis\n");
	void *symbolic, *numeric;
	if (umfpack_di_symbolic(ndofs, ndofs, Ap, Ai, Ax, &symbolic, NULL, NULL) < 0) {
		printf("umfpack_di_symbolic failed\n");
		return -1;
	}
	if (symbolic == NULL) {
		printf("umfpack_di_symbolic error: symbolic == NULL\n");
		return -1;
	}

	printf("numeric analysis\n");
	if (umfpack_di_numeric(Ap, Ai, Ax, symbolic, &numeric, NULL, NULL) < 0) {
		printf("umfpack_di_numeric failed\n");
		return -1;
	}
	if (numeric == NULL) {
		printf("umfpack_di_numeric error: numeric == NULL\n");
		return -1;
	}

	printf("solving\n");
	sln = new double [ndofs];

	if (umfpack_di_solve(UMFPACK_A, Ap, Ai, Ax, sln, rhs, numeric, NULL, NULL) < 0) {
		printf("umfpack_di_solve failed\n");
		return -1;
	}

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

	dump_rhs(argv[2]);

	printf("done\n");

	return 0;
}
Ejemplo n.º 9
0
void UMFPACK(int n, int *Ap, int *Ai, double *Ax, double *b, double *x)
{
	void *Symbolic, *Numeric;
	int i;

	/* symbolic analysis */
	umfpack_di_symbolic(n, n, Ap, Ai, Ax, &Symbolic, NULL, NULL);

	/* LU factorization */
	umfpack_di_numeric(Ap, Ai, Ax, Symbolic, &Numeric, NULL, NULL);
	umfpack_di_free_symbolic(&Symbolic);

	/* solve system */
	umfpack_di_solve(UMFPACK_A, Ap, Ai, Ax, x, b, Numeric, NULL, NULL);
	umfpack_di_free_numeric(&Numeric);
}
Ejemplo n.º 10
0
int UMF::Solve(double *rhs, double *x) {
    int status;

    if (!_is_factored) status = Factor();

    int NEQN = _dim;

    double Info[UMFPACK_INFO], Control[UMFPACK_CONTROL];

    /* load the rhs only (matrix already there) */
    if (x != rhs) memcpy( x, rhs, NEQN*sizeof(double) );

    /* deal with transpose later */
    status = umfpack_di_solve (UMFPACK_A, &_Ap[0], &_Ai[0], &_Ax[0], x, rhs, _Numeric, Control, Info);

    return (status);
}
Ejemplo n.º 11
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.º 12
0
DllExport int SolveLUUMFPACK(void * sp, double *x, double *b)
{
	UmfpackSolver *umfSolver = (UmfpackSolver*)sp;

	if (umfSolver->Ai == NULL || umfSolver->Ap == NULL || umfSolver->Ax == NULL) return -1;

	int *Ap = umfSolver->Ap;
	int *Ai = umfSolver->Ai;
	double *Ax = umfSolver->Ax;
	int n = umfSolver->n;
	int m = umfSolver->m;
	double *null = (double *)NULL;

	//解方程 Ax = b
	void *Numeric = umfSolver->Numeric;
	(void)umfpack_di_solve(UMFPACK_A, Ap, Ai, Ax, x, b, Numeric, null, null);

	return 0;
}
Ejemplo n.º 13
0
void SolveRealByLU_CCS(int numberOfRow, int numberOfColumn, int nnz, int *rowIndices, int *colPtr, double *values, double *X, double *b)
{

	int *Ai = (int*)malloc(sizeof(int)*(nnz));
	int *Ap = (int*)malloc(sizeof(int)*(numberOfColumn + 1));
	double *Ax = (double*)malloc(sizeof(double)*(nnz));

	memcpy(Ax, values, sizeof(double)*nnz);
	memcpy(Ap, colPtr, sizeof(int)*(numberOfColumn + 1));
	memcpy(Ai, rowIndices, sizeof(int)*nnz);

	void *Symbolic, *Numeric;
	(void)umfpack_di_symbolic(numberOfRow, numberOfColumn, Ap, Ai, Ax, &Symbolic, NULL, NULL);
	(void)umfpack_di_numeric(Ap, Ai, Ax, Symbolic, &Numeric, NULL, NULL);
	umfpack_di_solve(UMFPACK_A, Ap, Ai, Ax, X, b, Numeric, NULL, NULL);

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

	free(Ai);
	free(Ap);
	free(Ax);
}
Ejemplo n.º 14
0
//=============================================================================
int Amesos_Umfpack::Solve() 
{ 
  // if necessary, perform numeric factorization. 
  // This may call SymbolicFactorization() as well.
  if (!IsNumericFactorizationOK_)
    AMESOS_CHK_ERR(NumericFactorization()); 

  ResetTimer(1);

  Epetra_MultiVector* vecX = Problem_->GetLHS(); 
  Epetra_MultiVector* vecB = Problem_->GetRHS(); 

  if ((vecX == 0) || (vecB == 0))
    AMESOS_CHK_ERR(-1);

  int NumVectors = vecX->NumVectors(); 
  if (NumVectors != vecB->NumVectors())
    AMESOS_CHK_ERR(-1);

  Epetra_MultiVector *SerialB, *SerialX; 

  //  Extract Serial versions of X and B 
  //
  double *SerialXvalues ;
  double *SerialBvalues ;

  Epetra_MultiVector* SerialXextract = 0;
  Epetra_MultiVector* SerialBextract = 0;
    
  //  Copy B to the serial version of B
  //
  ResetTimer(0);
  
  if (IsLocal_ == 1) { 
    SerialB = vecB ; 
    SerialX = vecX ; 
  } else { 
    assert (IsLocal_ == 0);
    SerialXextract = new Epetra_MultiVector(SerialMap(),NumVectors); 
    SerialBextract = new Epetra_MultiVector(SerialMap(),NumVectors); 

    SerialBextract->Import(*vecB,Importer(),Insert);
    SerialB = SerialBextract; 
    SerialX = SerialXextract; 
  } 

  VecRedistTime_ = AddTime("Total vector redistribution time", VecRedistTime_, 0);
  
  //  Call UMFPACK to perform the solve
  //  Note:  UMFPACK uses a Compressed Column Storage instead of compressed row storage, 
  //  Hence to compute A X = B, we ask UMFPACK to perform A^T X = B and vice versa

  OverheadTime_ = AddTime("Total Amesos overhead time", OverheadTime_, 1);

  ResetTimer(0);

  int SerialBlda, SerialXlda ; 
  int UmfpackRequest = UseTranspose()?UMFPACK_A:UMFPACK_At ;
  int status = 0;

  if ( MyPID_ == 0 ) {
    int ierr;
    ierr = SerialB->ExtractView(&SerialBvalues, &SerialBlda);
    assert (ierr == 0);
    ierr = SerialX->ExtractView(&SerialXvalues, &SerialXlda);
    assert (ierr == 0);
    assert( SerialBlda == NumGlobalElements_ ) ; 
    assert( SerialXlda == NumGlobalElements_ ) ; 
    
    for ( int j =0 ; j < NumVectors; j++ ) { 
      double *Control = (double *) NULL, *Info = (double *) NULL ;

      status = umfpack_di_solve (UmfpackRequest, &Ap[0], 
				     &Ai[0], &Aval[0], 
				     &SerialXvalues[j*SerialXlda], 
				     &SerialBvalues[j*SerialBlda], 
				     Numeric, Control, Info) ;
    }
  }
    
  if (status) AMESOS_CHK_ERR(status);

  SolveTime_ = AddTime("Total solve time", SolveTime_, 0);
  
  //  Copy X back to the original vector
  
  ResetTimer(0);
  ResetTimer(1);

  if ( IsLocal_ == 0 ) {
    vecX->Export(*SerialX, Importer(), Insert ) ;
    if (SerialBextract) delete SerialBextract ;
    if (SerialXextract) delete SerialXextract ;
  }

  VecRedistTime_ = AddTime("Total vector redistribution time", VecRedistTime_, 0);

  if (ComputeTrueResidual_)
  {
    Epetra_RowMatrix* Matrix = 
      dynamic_cast<Epetra_RowMatrix*>(Problem_->GetOperator());
    ComputeTrueResidual(*Matrix, *vecX, *vecB, UseTranspose(), "Amesos_Umfpack");
  }

  if (ComputeVectorNorms_) {
    ComputeVectorNorms(*vecX, *vecB, "Amesos_Umfpack");
  }

  NumSolve_++;

  OverheadTime_ = AddTime("Total Amesos overhead time", OverheadTime_, 1); // Amesos overhead

  return(0);
}
Ejemplo n.º 15
0
int main ( )

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

    MAIN is the main program for UMFPACK_WEST.

  Discussion:

    This program uses UMFPACK to solve a linear system A*X=B for which the
    matrix is stored, in compressed column (CC) format, in three files.

  Licensing:

    This code is distributed under the GNU LGPL license. 

  Modified:

    16 July 2014

  Author:

    John Burkardt

  Reference:

    Timothy Davis,
    UMFPACK User Guide,
    Version 5.6.2, 25 April 2013
    http://suitesparse.com
*/
{
  double *acc;
  double *b;
  int *ccc;
  int i;
  int *icc;
  int m;
  int n;
  int ncc;
  double *null = ( double * ) NULL;
  void *Numeric;
  char prefix[] = "west";
  double r;
  int seed;
  int status;
  void *Symbolic;
  double *x1;
  double *x2;

  timestamp ( );
  printf ( "\n" );
  printf ( "UMFPACK_WEST:\n" );
  printf ( "  C version\n" );
  printf ( "  Use UMFPACK to solve the sparse linear system A*x=b.\n" );
  printf ( "  The matrix A is stored, in CC format, in 3 files.\n" );
/*
  Get the matrix size.
*/
  cc_header_read ( prefix, &ncc, &n );
  printf ( "\n" );
  printf ( "  Number of rows and columns = %d\n", n );
  printf ( "  Number of nonzeros NCC = %d\n", ncc );
/*
  Allocate space.
*/
  acc = ( double * ) malloc ( ncc * sizeof ( double ) );
  ccc = ( int * ) malloc ( ( n + 1 ) * sizeof ( int ) );
  icc = ( int * ) malloc ( ncc * sizeof ( int ) );
/*
  Read the matrix data.
*/
  cc_data_read ( prefix, ncc, n, icc, ccc, acc );
/*
  Print the matrix.
*/
  m = n;
  cc_print ( m, n, ncc, icc, ccc, acc, "  The CC matrix:" ); 
/*
  Set up the solution.
*/
  seed = 123456789;
  x1 = r8vec_uniform_01_new ( n, &seed );
/*
  Set the right hand side.
*/
  b = cc_mv ( m, n, ncc, icc, ccc, acc, x1 );
/*
  From the matrix data, create the symbolic factorization information.
*/
  status = umfpack_di_symbolic ( n, n, ccc, icc, acc, &Symbolic, null, null );
/*
  From the symbolic factorization information, carry out the numeric factorization.
*/
  status = umfpack_di_numeric ( ccc, icc, acc, Symbolic, &Numeric, null, null );
/*
  Free the symbolic factorization memory.
*/
  umfpack_di_free_symbolic ( &Symbolic );
/*
  Using the numeric factorization, solve the linear system.
*/
  x2 = ( double * ) malloc ( n * sizeof ( double ) );
  status = umfpack_di_solve ( UMFPACK_A, ccc, icc, acc, x2, b, Numeric, null, null );
/*
  Free the numeric factorization.
*/
  umfpack_di_free_numeric ( &Numeric );
/*
  Compute the error:
*/
  r = r8vec_diff_norm ( n, x1, x2 );
  printf ( "\n" );
  printf ( "  Residual: ||A*x-b|| = %g\n", r );
/*
  Free memory.
*/
  free ( acc );
  free ( b );
  free ( ccc );
  free ( icc );
  free ( x1 );
  free ( x2 );
/*
  Terminate.
*/
  printf ( "\n" );
  printf ( "UMFPACK_WEST:\n" );
  printf ( "  Normal end of execution.\n" );
  printf ( "\n" );
  timestamp ( );

  return 0;
}
Ejemplo n.º 16
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.º 17
0
std::vector<double> solveQ(std::vector<std::vector<double>> const &cols, std::vector<Vertex> const & fixed_cells, std::vector<Vertex> const * virtual_cells)
{
  //assert N x N dim of cols matrix
  assert(cols.size() == cols.at(0).size());

  int m_dim = cols.size();
  std::vector<double> retval;
  retval.resize(2*m_dim);

  double * X  = new double[m_dim]();
  double * Y  = new double[m_dim]();
  double * Bx = new double[m_dim]();
  double * By = new double[m_dim]();

  //construct rhs vectors - Bx, By
  for (unsigned int i=0; i < fixed_cells.size(); ++i)
  {
      std::list<Edge> const & adj_cells = fixed_cells.at(i).adj_list;
      for(auto it = adj_cells.begin(); it != adj_cells.end(); ++it)
      {
         if ((*it).tgt->fixed)
           continue;
         int idx = Vertex::v_map_table.at((*it).tgt->v_id - 1);
         assert(idx < m_dim && idx >= 0);
         Bx[idx] += (*it).weight * (double)fixed_cells.at(i).x_pos;
         By[idx] += (*it).weight * (double)fixed_cells.at(i).y_pos;
      }
  }
  //add weight contributions from virtual pins
  if (virtual_cells != nullptr)
  {
     for (unsigned int i=0; i < (*virtual_cells).size(); ++i)
     {
         std::list<Edge> const & adj_cells = (*virtual_cells).at(i).adj_list;
         for(auto it = adj_cells.begin(); it != adj_cells.end(); ++it)
         {
            if ((*it).tgt->fixed)
              continue;
            int idx = Vertex::v_map_table.at((*it).tgt->v_id - 1);
            assert(idx < m_dim && idx >= 0);
            Bx[idx] += (*it).weight * (double)(*virtual_cells).at(i).x_pos;
            By[idx] += (*it).weight * (double)(*virtual_cells).at(i).y_pos;
         }
     }
  }

  //UMFPACK sparse matrix solver arguments
  int *    Ap = new int[m_dim+1];
  int *    Ai;
  double * Ax;

  Ap[0] = 0;
  int nz_cnt = 0;
  for (int c=0; c<m_dim; ++c)
  {
    for(int r=0; r<m_dim; ++r)
    {
       if (cols[c][r] != 0)
          ++nz_cnt;
    }
    Ap[c+1] = nz_cnt;
  }

  Ai = new int[nz_cnt];
  Ax = new double[nz_cnt];

  int idx = 0;
  for (int c=0; c<m_dim; ++c)
  {
    for(int r=0; r<m_dim; ++r)
    {
       if (cols[c][r] != 0)
       { 
          Ai[idx] = r;
          Ax[idx] = cols[c][r];
          ++idx;
       }
    }
  }

#ifdef _DEBUG_
  std::cout << "Bx: ";
  for(int i =0; i<m_dim; ++i)
  {
    std::cout << Bx[i] << " ";
  }
  std::cout << "\n";
  std::cout << "By: ";
  for(int i =0; i<m_dim; ++i)
  {
    std::cout << Bx[i] << " ";
  }
  std::cout << "\n";
  std::cout << "Ap: ";
  for(int i =0; i<m_dim+1; ++i)
  {
    std::cout << Ap[i] << " ";
  }
  std::cout << "\n";
  std::cout << "Ai: ";
  for(int i =0; i<nz_cnt; ++i)
  {
    std::cout << Ai[i] << " ";
  }
  std::cout << "\n";
  std::cout << "Ax: ";
  for(int i =0; i<nz_cnt; ++i)
  {
    std::cout << Ax[i] << " ";
  }
  std::cout << "\n";
#endif

  double *null = (double *) NULL;
  void   *Symbolic, *Numeric;

  (void) umfpack_di_symbolic (m_dim, m_dim, 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, X, Bx, Numeric, null, null);
  (void) umfpack_di_solve (UMFPACK_A, Ap, Ai, Ax, Y, By, Numeric, null, null);
  umfpack_di_free_numeric(&Numeric);

  //push X, Y into return vector
  for(int i=0; i<m_dim; ++i)
  {
    retval[i] = X[i];
    retval[i+m_dim] = Y[i];
  }

  delete [] X;
  delete [] Y;
  delete [] Bx;
  delete [] By;
  delete [] Ap;
  delete [] Ai;
  delete [] Ax;

  return retval;
}
Ejemplo n.º 18
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.º 19
0
/*! \fn solve linear system with UmfPack method
 *
 *  \param  [in]  [data]
 *                [sysNumber] index of the corresponding linear system
 *
 *
 * author: kbalzereit, wbraun
 */
int
solveUmfPack(DATA *data, int sysNumber)
{
    LINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo.linearSystemData[sysNumber]);
    DATA_UMFPACK* solverData = (DATA_UMFPACK*)systemData->solverData;

    int i, j, status = UMFPACK_OK, success = 0, ni=0, n = systemData->size, eqSystemNumber = systemData->equationIndex, indexes[2] = {1,eqSystemNumber};

    infoStreamPrintWithEquationIndexes(LOG_LS, 0, indexes, "Start solving Linear System %d (size %d) at time %g with UMFPACK Solver",
                                       eqSystemNumber, (int) systemData->size,
                                       data->localData[0]->timeValue);


    rt_ext_tp_tick(&(solverData->timeClock));
    if (0 == systemData->method)
    {
        /* set A matrix */
        solverData->Ap[0] = 0;
        systemData->setA(data, systemData);
        solverData->Ap[solverData->n_row] = solverData->nnz;

        if (ACTIVE_STREAM(LOG_LS_V))
        {
            infoStreamPrint(LOG_LS_V, 1, "Matrix A");
            printMatrixCSR(solverData->Ap, solverData->Ai, solverData->Ax, n);
            messageClose(LOG_LS_V);
        }

        /* set b vector */
        systemData->setb(data, systemData);
    } else {

        solverData->Ap[0] = 0;
        /* calculate jacobian -> matrix A*/
        if(systemData->jacobianIndex != -1) {
            getAnalyticalJacobianUmfPack(data, sysNumber);
        } else {
            assertStreamPrint(data->threadData, 1, "jacobian function pointer is invalid" );
        }
        solverData->Ap[solverData->n_row] = solverData->nnz;

        /* calculate vector b (rhs) */
        memcpy(solverData->work, systemData->x, sizeof(double)*solverData->n_row);
        wrapper_fvec_umfpack(solverData->work, systemData->b, data, sysNumber);
    }

    infoStreamPrint(LOG_LS, 0, "###  %f  time to set Matrix A and vector b.", rt_ext_tp_tock(&(solverData->timeClock)));

    if (ACTIVE_STREAM(LOG_LS_V))
    {
        if (ACTIVE_STREAM(LOG_LS_V))
        {
            infoStreamPrint(LOG_LS_V, 1, "Old solution x:");
            for(i = 0; i < solverData->n_row; ++i)
                infoStreamPrint(LOG_LS_V, 0, "[%d] %s = %g", i+1, modelInfoGetEquation(&data->modelData.modelDataXml,eqSystemNumber).vars[i], systemData->x[i]);

            messageClose(LOG_LS_V);
        }
        infoStreamPrint(LOG_LS_V, 1, "Matrix A n_rows = %d", solverData->n_row);
        for (i=0; i<solverData->n_row; i++) {
            infoStreamPrint(LOG_LS_V, 0, "%d. Ap => %d -> %d", i, solverData->Ap[i], solverData->Ap[i+1]);
            for (j=solverData->Ap[i]; j<solverData->Ap[i+1]; j++) {
                infoStreamPrint(LOG_LS_V, 0, "A[%d,%d] = %f", i, solverData->Ai[j], solverData->Ax[j]);

            }
        }
        messageClose(LOG_LS_V);

        for (i=0; i<solverData->n_row; i++)
            infoStreamPrint(LOG_LS_V, 0, "b[%d] = %e", i, systemData->b[i]);
    }
    rt_ext_tp_tick(&(solverData->timeClock));

    /* symbolic pre-ordering of A to reduce fill-in of L and U */
    if (0 == solverData->numberSolving)
    {
        status = umfpack_di_symbolic(solverData->n_col, solverData->n_row, solverData->Ap, solverData->Ai, solverData->Ax, &(solverData->symbolic), solverData->control, solverData->info);
    }

    /* compute the LU factorization of A */
    if (0 == status) {
        status = umfpack_di_numeric(solverData->Ap, solverData->Ai, solverData->Ax, solverData->symbolic, &(solverData->numeric), solverData->control, solverData->info);
    }

    if (0 == status) {
        if (1 == systemData->method) {
            status = umfpack_di_solve(UMFPACK_A, solverData->Ap, solverData->Ai, solverData->Ax, systemData->x, systemData->b, solverData->numeric, solverData->control, solverData->info);
        } else {
            status = umfpack_di_solve(UMFPACK_Aat, solverData->Ap, solverData->Ai, solverData->Ax, systemData->x, systemData->b, solverData->numeric, solverData->control, solverData->info);
        }
    }

    if (status == UMFPACK_OK) {
        success = 1;
    }
    else if (status == UMFPACK_WARNING_singular_matrix)
    {
        if (!solveSingularSystem(systemData))
        {
            success = 1;
        }
    }
    infoStreamPrint(LOG_LS, 0, "Solve System: %f", rt_ext_tp_tock(&(solverData->timeClock)));

    /* print solution */
    if (1 == success) {

        if (1 == systemData->method) {
            /* take the solution */
            for(i = 0; i < solverData->n_row; ++i)
                systemData->x[i] += solverData->work[i];

            /* update inner equations */
            wrapper_fvec_umfpack(systemData->x, solverData->work, data, sysNumber);
        } else {
            /* the solution is automatically in x */
        }

        if (ACTIVE_STREAM(LOG_LS_V))
        {
            infoStreamPrint(LOG_LS_V, 1, "Solution x:");
            infoStreamPrint(LOG_LS_V, 0, "System %d numVars %d.", eqSystemNumber, modelInfoGetEquation(&data->modelData.modelDataXml,eqSystemNumber).numVar);

            for(i = 0; i < systemData->size; ++i)
                infoStreamPrint(LOG_LS_V, 0, "[%d] %s = %g", i+1, modelInfoGetEquation(&data->modelData.modelDataXml,eqSystemNumber).vars[i], systemData->x[i]);

            messageClose(LOG_LS_V);
        }
    }
    else
    {
        warningStreamPrint(LOG_STDOUT, 0,
                           "Failed to solve linear system of equations (no. %d) at time %f, system status %d.",
                           (int)systemData->equationIndex, data->localData[0]->timeValue, status);
    }
    solverData->numberSolving += 1;

    return success;
}
Ejemplo n.º 20
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.º 21
0
void solve_linear_system(const int_vector& lhs_row_index,
			 const int_vector& lhs_col_index,
			 const dbl_vector& lhs_values,
			 dbl_vector rhs,
			 dbl_vector& out_solution,
			 void* numeric)
{
  // Assume lhs is square.
  unsigned long num_nonzero = lhs_values.size();
  unsigned long num_rows = rhs.size();
  
   // Convert lhs matrix into the format used in UMFPACK.
  int* ti;
  int* tj;
  double* tx;  
  int* ap;
  int* ai;
  double* ax;
  double* x;
  double* b;

  ti = new int[num_nonzero];
  ELOG("ti memory allocated...");
  tj = new int[num_nonzero];
  ELOG("tj memory allocated...");
  tx = new double[num_nonzero];
  ELOG("tx memory allocated...");

  // Copy to input data.
  for(unsigned long i = 0; i < num_nonzero; i++) {
    ti[i] = lhs_row_index(i);
    tj[i] = lhs_col_index(i);
    tx[i] = lhs_values(i);
    ELOG("ti, tj, tx (", i, ") = ",
	 ti[i], ", ", tj[i], ", ", tx[i], ", ");
  }
  
  ap = new int[num_rows + 1];
  ELOG("ap memory allocated...");
  ai = new int[num_rows * num_rows];
  ELOG("ai memory allocated...");
  ax = new double[num_rows * num_rows];
  ELOG("ax memory allocated...");

  umfpack_di_triplet_to_col(num_rows, num_rows, num_nonzero,
			    ti, tj, tx,
			    ap, ai, ax,
			    null_int);

  delete [] ti;
  delete [] tj;
  delete [] tx;

  x = new double[num_rows];
  ELOG("x memory allocated...");
  b = new double[num_rows];
  ELOG("b memory allocated...");
  
  ELOG("Define right hand side...");
  // Set right hand side equal to portfolio.
  for(unsigned long i = 0; i < num_rows; ++i)
    b[i] = rhs(i);
  
  ELOG("Rhs to solve = ", rhs);

#ifdef DEBUG
  for(unsigned long i = 0; i < num_rows + 1; ++i)
    ELOG("ap[", i, "] = ", ap[i]);
  for(unsigned long i_row = 0;
      i_row < num_rows; ++i_row) {
    for(unsigned long i_col = 0;
	i_col < num_rows; ++i_col) {
      ELOG("A(", i_row, ",", i_col, ") = ", ax[ap[i_col] + i_row]);
    }
    ELOG("b(", i_row, ") = ", b[i_row]);
  }
#endif
  
  // Sovle system by LU factorization.
  void *symbolic;

  // If the numeric pointer is void then we need to perform the
  // factorization.
  if(numeric == null_void) {
  umfpack_di_symbolic(num_rows, num_rows,
		      ap, ai, ax,
		      &symbolic, null_double, null_double);
  umfpack_di_numeric(ap, ai, ax,
		     symbolic, &numeric, null_double, null_double);
  umfpack_di_free_symbolic(&symbolic);
  }

  umfpack_di_solve(UMFPACK_A, ap, ai, ax, x, b,
		   numeric, null_double, null_double);
  
#ifdef DEBUG
  // Calculate determinant for diagnostics.
  double *det = new double[2];
  umfpack_di_get_determinant(det, null_double, numeric, null_double);
  ELOG("Determinant of second moment = ", det[0]);
  delete[] det;
#endif

  // Do not free the numeric pointer because this function does not own it.
  
  // Store the solution in the output argument.
  for(unsigned long i = 0; i < num_rows; ++i)
    out_solution(i) = x[i];

  // Free memory.
  delete[] ap;
  delete[] ai;
  delete[] ax;
  delete[] x;
  delete[] b;
}
Ejemplo n.º 22
0
/*! \fn solve a singular linear system with UmfPack methods
 *
 *  \param  [in/out]  [systemData]
 *
 *
 *  solve even singular system
 *  (note that due to initialization A is given in its transposed form A^T)
 *
 *  A * x = b
 *  <=> P * R * A * Q * Q * x = P * R * b       |   P * R * A * Q = L * U
 *  <=> L * U * Q * x = P * R * b
 *
 *  note that P and Q are orthogonal permutation matrices, so P^(-1) = P^T and Q^(-1) = Q^T
 *
 *   (1) L * y = P * R * b  <=>  P^T * L * y = R * b     (L is always regular so this can be solved by umfpack)
 *
 *   (2) U * z = y      (U is singular, this cannot be solved by umfpack)
 *
 *   (3) Q * x = z  <=>  x = Q^T * z
 *
 *
 * author: kbalzereit, wbraun
 */
int solveSingularSystem(LINEAR_SYSTEM_DATA* systemData)
{

    DATA_UMFPACK* solverData = (DATA_UMFPACK*) systemData->solverData;
    double *Ux, *Rs, r_ii, *b, sum, *y, *z;
    int *Up, *Ui, *Q, do_recip, rank = 0, current_rank, current_unz, i, j, k, l,
                                success = 0, status, stop = 0;

    int unz = solverData->info[UMFPACK_UNZ];

    Up = (int*) malloc((solverData->n_row + 1) * sizeof(int));
    Ui = (int*) malloc(unz * sizeof(int));
    Ux = (double*) malloc(unz * sizeof(double));

    Q = (int*) malloc(solverData->n_col * sizeof(int));
    Rs = (double*) malloc(solverData->n_row * sizeof(double));

    b = (double*) malloc(solverData->n_col * sizeof(double));
    y = (double*) malloc(solverData->n_col * sizeof(double));
    z = (double*) malloc(solverData->n_col * sizeof(double));

    infoStreamPrint(LOG_LS_V, 0, "Solve singular system");

    status = umfpack_di_get_numeric((int*) NULL, (int*) NULL, (double*) NULL, Up,
                                    Ui, Ux, (int*) NULL, Q, (double*) NULL, &do_recip, Rs,
                                    solverData->numeric);

    switch (status)
    {
    case UMFPACK_WARNING_singular_matrix:
    case UMFPACK_ERROR_out_of_memory:
    case UMFPACK_ERROR_argument_missing:
    case UMFPACK_ERROR_invalid_system:
    case UMFPACK_ERROR_invalid_Numeric_object:
        infoStreamPrint(LOG_LS_V, 0, "error: %d", status);
    }

    /* calculate R*b */
    if (do_recip == 0)
    {
        for (i = 0; i < solverData->n_row; i++)
        {
            b[i] = systemData->b[i] / Rs[i];
        }
    }
    else
    {
        for (i = 0; i < solverData->n_row; i++)
        {
            b[i] = systemData->b[i] * Rs[i];
        }
    }

    /* solve L * y = P * R * b  <=>  P^T * L * y = R * b */
    status = umfpack_di_solve(UMFPACK_Pt_L, solverData->Ap, solverData->Ai,
                              solverData->Ax, y, b, solverData->numeric, solverData->control,
                              solverData->info);

    switch (status)
    {
    case UMFPACK_WARNING_singular_matrix:
    case UMFPACK_ERROR_out_of_memory:
    case UMFPACK_ERROR_argument_missing:
    case UMFPACK_ERROR_invalid_system:
    case UMFPACK_ERROR_invalid_Numeric_object:
        infoStreamPrint(LOG_LS_V, 0, "error: %d", status);
    }

    /* rank is at most as high as the maximum in Ui */
    for (i = 0; i < unz; i++)
    {
        if (rank < Ui[i])
            rank = Ui[i];
    }

    /* if rank is already smaller than n set last component of result zero */
    for (i = rank + 1; i < solverData->n_col; i++)
    {
        if (y[i] < 1e-12)
        {
            z[i] = 0.0;
        }
        else
        {
            infoStreamPrint(LOG_LS_V, 0, "error: system is not solvable*");
            /* free all used memory */
            free(Up);
            free(Ui);
            free(Ux);

            free(Q);
            free(Rs);

            free(b);
            free(y);
            free(z);
            return -1;
        }
    }

    current_rank = rank;
    current_unz = unz;

    while ((stop == 0) && (current_rank > 1))
    {
        /* check if last two rows of U are the same */
        if ((Ux[current_unz] == Ux[current_unz - 1])
                && (Ui[current_unz] == Ui[current_unz - 1])
                && (Up[current_rank] - Up[current_rank - 1] > 1))
        {
            /* if diagonal entry on second to last row is nonzero, remaining matrix is regular */
            if (Ui[Up[current_rank] - 1] == current_rank - 1)
            {
                stop = 1;
            }
            /* last two rows are the same -> under-determined system, calculate one value and set the other one zero */
            else
            {
                z[current_rank] = y[current_rank] / Ux[current_unz];

                /* reduce system */
                for (i = Up[current_rank]; i < current_unz; i++)
                {
                    y[Ui[i]] -= z[current_rank] * Ux[i];
                }

                current_unz = Up[current_rank] - 1;
                current_rank--;

                /* now last row has only zero entries */
                if (y[current_rank] < 1e-12)
                {
                    z[current_rank] = 0.0;
                }
                else
                {
                    infoStreamPrint(LOG_LS_V, 0, "error: system is not solvable");
                    /* free all used memory */
                    free(Up);
                    free(Ui);
                    free(Ux);

                    free(Q);
                    free(Rs);

                    free(b);
                    free(y);
                    free(z);
                    return -1;
                }

                current_rank--;
            }
        }
        else
        {
            stop = 1;
        }
    }

    /* remaining system is regular so solve system by back substitution */
    z[current_rank] = Ux[current_unz] * y[current_rank];

    for (i = current_rank - 1; i >= 0; i--)
    {
        /* get diagonal element r_ii, j shows where the element is in vector Ux, Ui */
        j = Up[i];
        while (Ui[j] != i)
        {
            j++;
        }
        r_ii = Ux[j];
        sum = 0.0;
        for (k = i + 1; k < current_rank; k++)
        {
            for (l = Up[k]; l < Up[k + 1]; l++)
            {
                if (Ui[l] == Ui[i])
                {
                    sum += Ux[i] * z[k];
                }
            }
        }
        z[i] = (y[i] - sum) / r_ii;
    }

    /* x = Q^T * z */
    for (i = 0; i < solverData->n_col; i++)
    {
        systemData->x[Q[i]] = z[i];
    }

    /* free all used memory */
    free(Up);
    free(Ui);
    free(Ux);

    free(Q);
    free(Rs);

    free(b);
    free(y);
    free(z);

    return success;
}
Ejemplo n.º 23
0
dbl_vector solve_linear_system(dbl_matrix lhs, dbl_vector rhs)
{
  // Assume lhs is square.
  unsigned long num_rows = lhs.size1();
  
   // Convert lhs matrix into the format used in UMFPACK.
  int* ap;
  int* ai;
  double* ax;
  double* x;
  double* b;
  
  ap = new int[num_rows + 1];
  ELOG("ap memory allocated...");

  ai = new int[num_rows * num_rows];
  ELOG("ai memory allocated...");

  ax = new double[num_rows * num_rows];
  ELOG("ax memory allocated...");

  x = new double[num_rows];
  ELOG("x memory allocated...");

  b = new double[num_rows];
  ELOG("b memory allocated...");
 
  ap[0] = 0;
  for(unsigned long i_col = 1;
      i_col < num_rows + 1; ++i_col) {
    ap[i_col] = num_rows * i_col;
    ELOG("ap[", i_col, "] = ", ap[i_col]);
    for(unsigned long i_row = 0;
	i_row < num_rows; ++i_row) {
      ai[ap[i_col-1] + i_row] = i_row;
      ax[ap[i_col-1] + i_row] =
	lhs(i_row, i_col - 1);
    }
  }

  ELOG("Define right hand side...");
  // Set right hand side equal to portfolio.
  for(unsigned long i = 0; i < num_rows; ++i)
    b[i] = rhs(i);
  
  ELOG("Rhs to solve = ", rhs);

#ifdef DEBUG
  for(unsigned long i = 0; i < num_rows + 1; ++i)
    ELOG("ap[", i, "] = ", ap[i]);
  for(unsigned long i_row = 0;
      i_row < num_rows; ++i_row) {
    for(unsigned long i_col = 0;
	i_col < num_rows; ++i_col) {
      ELOG("A(", i_row, ",", i_col, ") = ", ax[ap[i_col] + i_row]);
    }
    ELOG("b(", i_row, ") = ", b[i_row]);
  }
#endif
  
  // Multiply inverted matrix and the transformed first_moment via lu
  // factorization and substitution.
  void *symbolic, *numeric;
  umfpack_di_symbolic(num_rows, num_rows,
		      ap, ai, ax,
		      &symbolic, null_double, null_double);
  umfpack_di_numeric(ap, ai, ax,
		     symbolic, &numeric, null_double, null_double);
  umfpack_di_free_symbolic(&symbolic);
  umfpack_di_solve(UMFPACK_A, ap, ai, ax, x, b,
		   numeric, null_double, null_double);
  
#ifdef DEBUG
  // Calculate determinant for diagnostics.
  double *det = new double[2];
  umfpack_di_get_determinant(det, null_double, numeric, null_double);
  ELOG("Determinant of second moment = ", det[0]);
  delete[] det;
#endif

  umfpack_di_free_numeric(&numeric);
  
  // Store solution in rhs.
  for(unsigned long i = 0; i < num_rows; ++i)
    rhs(i) = x[i];

  // Free memory.
  delete[] ap;
  delete[] ai;
  delete[] ax;
  delete[] x;
  delete[] b;

  return rhs;
}