Beispiel #1
0
DllExport void* CreateSolverLUUMFPACK(int numberOfRows, int numberOfNoneZero, int *Ti, int *Tj, double *Tx)
{
	//创建 Compressed Row Storage 存储结构
	int *Ai = (int*)malloc(sizeof(int)*(numberOfNoneZero));
	int *Ap = (int*)malloc(sizeof(int)*(numberOfRows + 1));
	double *Ax = (double*)malloc(sizeof(double)*(numberOfNoneZero));

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

	//创建 solver
	UmfpackSolver *umpsolver = (UmfpackSolver*)malloc(sizeof(UmfpackSolver));

	//设置 solver
	umpsolver->Ai = Ai;
	umpsolver->Ap = Ap;
	umpsolver->Ax = Ax;
	umpsolver->AiSize = umpsolver->AxSize = numberOfNoneZero;
	umpsolver->ApSize = numberOfRows + 1;
	umpsolver->n = numberOfRows;
	umpsolver->m = numberOfRows;

	//因子化
	void *Symbolic, *Numeric;
	(void)umfpack_di_symbolic(numberOfRows, numberOfRows, Ap, Ai, Ax, &Symbolic, NULL, NULL);
	(void)umfpack_di_numeric(Ap, Ai, Ax, Symbolic, &Numeric, NULL, NULL);
	umfpack_di_free_symbolic(&Symbolic);
	umpsolver->Numeric = Numeric;

	return umpsolver;
};
Beispiel #2
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);
}
Beispiel #3
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
}
Beispiel #4
0
/*
 * ***************************************************************************
 * Routine:  Slu_factor
 *
 * Purpose:  Sparse LU factor the system.
 *
 * Author:   Michael Holst and Stephen Bond
 * ***************************************************************************
 */
VPUBLIC int Slu_factor(Slu *thee)
{
    int status;
    int n = thee->n, m = thee->m;
    int *Ap = thee->ia, *Ai = thee->ja;
    double *Ax = thee->a;

    void *Symbolic, *Numeric;

    VASSERT( thee != VNULL );

    if( thee->statLU == 1 ) {
        umfpack_di_free_numeric( thee->work );
        thee->statLU = 0;
    }

    status = umfpack_di_symbolic(n, m, Ap, Ai, Ax, &Symbolic, VNULL, VNULL);
    if (UMFPACK_OK != status) {
        return 0;
    }
    status = umfpack_di_numeric(Ap, Ai, Ax, Symbolic, &Numeric, VNULL, VNULL);
    umfpack_di_free_symbolic(&Symbolic);
    if (UMFPACK_OK != status) {
        return 0;
    }

    thee->work = Numeric;
    thee->statLU = 1;

    return 1;
}
Beispiel #5
0
DllExport void* CreateSolverLUUMFPACK_CCS(int numberOfRow, int numberOfColumn, int nnz, int *rowIndices, int *columnPtr, double *Values)
{

	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, columnPtr, 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);

	//创建 solver
	UmfpackSolver *umpsolver = (UmfpackSolver*)malloc(sizeof(UmfpackSolver));

	//设置 solver
	umpsolver->Ai = Ai;
	umpsolver->Ap = Ap;
	umpsolver->Ax = Ax;
	umpsolver->Az = NULL;
	umpsolver->AiSize = umpsolver->AxSize = nnz;
	umpsolver->ApSize = numberOfRow + 1;
	umpsolver->n = numberOfColumn;
	umpsolver->m = numberOfRow;
	umpsolver->Numeric = Numeric;

	return umpsolver;
}
Beispiel #6
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);
}
 inline
 int symbolic (int n_row, int n_col,
               int const* Ap, int const* Ai, double const* Ax,
               void **Symbolic, double const* Control, double* Info)
 {
   return umfpack_di_symbolic (n_row, n_col, Ap, Ai, Ax,
                               Symbolic, Control, Info);
 }
Beispiel #8
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;
}
Beispiel #9
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;
}
/* Create a deformation transfer object, once created, this object can help 
   deforming the target mesh like the source mesh deformation quicky and 
   faithfully. 
*/
void CreateDeformationTransformer(
    const char *source_ref_name, const char *target_ref_name,
    const char *tricorrs_name, dt_size_type n_maxcorrs,
    dtTransformer *trans)
{
    __dt_TriangleCorrsList tclist;

    cholmod_sparse   *A;
    __dt_SparseMatrix A_tri;
    void *symbolic_obj;        /* for umfpack's symbolic analysis */

    /* Load data */
    __dt_ReadObjFile_commit_or_crash(source_ref_name, &(trans->source_ref));
    __dt_ReadObjFile_commit_or_crash(target_ref_name, &(trans->target));

    if (__dt_LoadTriangleCorrsList(
            tricorrs_name, &tclist) == -1) {
        perror("Loading triangle correspondence failed");
        exit(1);
    }

    /* Initialize triangle correspondence dictionary */
    __dt_StripTriangleCorrsList(&tclist, n_maxcorrs);
    __dt_CreateTriangleCorrsDict(&(trans->target), &tclist, &(trans->tcdict));

    /* Precalculate inverse of surface matrices of source reference model*/
    __dt_InitializeSurfaceInvVList(&(trans->source_ref), &(trans->sinvlist));

    /* Allocate for linear system */
    __dt_AllocDeformationEquation(&(trans->target), &(trans->tcdict), &A_tri, &(trans->C));
    trans->c = __dt_CHOLMOD_dense_zeros(A_tri->ncol, 1);      /* rhs vector: ncol*1 */
    trans->x = __dt_CHOLMOD_dense_zeros(A_tri->ncol, 1); /* solution vector: ncol*1 */

    /* Building coefficient matrix: 
       A_tri(triplet) ==> A(sparse) ==> At ==> AtA */
    printf("building equation...\n");
    __dt_BuildCoefficientMatrix(&(trans->target), &(trans->tcdict), A_tri);
    A = __dt_CHOLMOD_triplet_to_sparse(A_tri); __dt_CHOLMOD_free_triplet(&A_tri);
    trans->At  = __dt_CHOLMOD_transpose(A);    __dt_CHOLMOD_free_sparse(&A);
    trans->AtA = __dt_CHOLMOD_AxAt(trans->At);

    printf("factorizing...\n");
    /* factorize AtA */
    umfpack_di_symbolic(
        (int)trans->AtA->nrow, (int)trans->AtA->ncol, 
        (const int*)trans->AtA->p, (const int*)trans->AtA->i, (const double*)trans->AtA->x, 
        &symbolic_obj, NULL, NULL);

    umfpack_di_numeric(
        (const int*)trans->AtA->p, (const int*)trans->AtA->i, (const double*)trans->AtA->x, 
        symbolic_obj, &(trans->numeric_obj), NULL, NULL);

    umfpack_di_free_symbolic(&symbolic_obj);
}
Beispiel #11
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;
}
Beispiel #12
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);
}
Beispiel #13
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) ;
}
Beispiel #14
0
//=============================================================================
int Amesos_Umfpack::PerformSymbolicFactorization() 
{
  // MS // no overhead time in this method
  ResetTimer(0);  
  
  double *Control = (double *) NULL, *Info = (double *) NULL;
  
  if (Symbolic) 
    umfpack_di_free_symbolic (&Symbolic) ;
  if (MyPID_== 0) {
    (void) umfpack_di_symbolic (NumGlobalElements_, NumGlobalElements_, &Ap[0], 
				&Ai[0], &Aval[0], 
				&Symbolic, Control, Info) ;
  }

  SymFactTime_ = AddTime("Total symbolic factorization time", SymFactTime_, 0);

  return 0;
}
Beispiel #15
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);
}
Beispiel #16
0
int sci_umfpack(char* fname, void* pvApiCtx)
{
    SciErr sciErr;

    int mb      = 0;
    int nb      = 0;
    int i       = 0;
    int num_A   = 0;
    int num_b   = 0;
    int mW      = 0;
    int Case    = 0;
    int stat    = 0;

    SciSparse AA;
    CcsSparse A;

    int* piAddrA = NULL;
    int* piAddr2 = NULL;
    int* piAddrB = NULL;

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

    int iComplex = 0;
    int freepdblBI = 0;

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

    /* umfpack stuff */
    double Info[UMFPACK_INFO];
    double* Control = NULL;
    void* Symbolic  = NULL;
    void* Numeric   = NULL;
    int* Wi         = NULL;
    double* W       = NULL;
    char* pStr      = NULL;
    int iType2      = 0;
    int iTypeA      = 0;
    int iTypeB      = 0;

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

    /* First get arg #2 : a string of length 1 */
    sciErr = getVarAddressFromPosition(pvApiCtx, 2, &piAddr2);
    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    sciErr = getVarType(pvApiCtx, piAddr2, &iType2);
    if (sciErr.iErr || iType2 != sci_strings)
    {
        printError(&sciErr, 0);
        Scierror(999, _("%s: Wrong type for input argument #%d: string expected.\n"), fname, 2);
        return 1;
    }

    if (getAllocatedSingleString(pvApiCtx, piAddr2, &pStr))
    {
        return 1;
    }

    /* select Case 1 or 2 depending (of the first char of) the string ... */
    if (pStr[0] == '\\') // compare pStr[0] with '\'
    {
        Case  = 1;
        num_A = 1;
        num_b = 3;
    }
    else if (pStr[0] == '/')
    {
        Case  = 2;
        num_A = 3;
        num_b = 1;
    }
    else
    {
        Scierror(999, _("%s: Wrong input argument #%d: '%s' or '%s' expected.\n"), fname, 2, "\\", "/");
        FREE(pStr);
        return 1;
    }
    FREE(pStr);

    /* get A */
    sciErr = getVarAddressFromPosition(pvApiCtx, num_A, &piAddrA);
    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    sciErr = getVarType(pvApiCtx, piAddrA, &iTypeA);
    if (sciErr.iErr || iTypeA != sci_sparse)
    {
        printError(&sciErr, 0);
        Scierror(999, _("%s: Wrong type for input argument #%d: A sparse matrix expected.\n"), fname, 1);
        return 1;
    }

    if (isVarComplex(pvApiCtx, piAddrA))
    {
        AA.it = 1;
        iComplex = 1;
        sciErr = getComplexSparseMatrix(pvApiCtx, piAddrA, &mA, &nA, &iNbItem, &piNbItemRow, &piColPos, &pdblSpReal, &pdblSpImg);
    }
    else
    {
        AA.it = 0;
        sciErr = getSparseMatrix(pvApiCtx, piAddrA, &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;

    if ( mA != nA || mA < 1 )
    {
        Scierror(999, _("%s: Wrong size for input argument #%d.\n"), fname, num_A);
        return 1;
    }

    /* get B*/
    sciErr = getVarAddressFromPosition(pvApiCtx, num_b, &piAddrB);
    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    sciErr = getVarType(pvApiCtx, piAddrB, &iTypeB);
    if (sciErr.iErr || iTypeB != sci_matrix)
    {
        printError(&sciErr, 0);
        Scierror(999, _("%s: Wrong type for input argument #%d: A matrix expected.\n"), fname, 3);
        return 1;
    }

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

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

    if ( (Case == 1 && ( mb != mA || nb < 1 )) || (Case == 2 && ( nb != mA || mb < 1 )) )
    {
        Scierror(999, _("%s: Wrong size for input argument #%d.\n"), fname, num_b);
        return 1;
    }

    SciSparseToCcsSparse(&AA, &A);

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

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

    if (A.it == 1)
    {
        mW = 10 * mA;
    }
    else
    {
        mW = 5 * mA;
    }

    if (A.it == 1  &&  pdblBI == NULL)
    {
        int iSize = mb * nb * sizeof(double);
        pdblBI = (double*)MALLOC(iSize);
        memset(pdblBI, 0x00, iSize);
        freepdblBI = 1;
    }

    /* Now calling umfpack routines */
    if (A.it == 1)
    {
        stat = umfpack_zi_symbolic(mA, nA, A.p, A.irow, A.R, A.I, &Symbolic, Control, Info);
    }
    else
    {
        stat = umfpack_di_symbolic(mA, nA, A.p, A.irow, A.R, &Symbolic, Control, Info);
    }

    if ( stat  != UMFPACK_OK )
    {
        Scierror(999, _("%s: An error occurred: %s: %s\n"), fname, _("symbolic factorization"), UmfErrorMes(stat));
        freeCcsSparse(A);
        if (freepdblBI)
        {
            FREE(pdblBI);
        }
        return 1;
    }

    if (A.it == 1)
    {
        stat = umfpack_zi_numeric(A.p, A.irow, A.R, A.I, Symbolic, &Numeric, Control, Info);
    }
    else
    {
        stat = umfpack_di_numeric(A.p, A.irow, A.R, Symbolic, &Numeric, Control, Info);
    }

    if (A.it == 1)
    {
        umfpack_zi_free_symbolic(&Symbolic);
    }
    else
    {
        umfpack_di_free_symbolic(&Symbolic);
    }

    if ( stat  != UMFPACK_OK )
    {
        Scierror(999, _("%s: An error occurred: %s: %s\n"), fname, _("numeric factorization"), UmfErrorMes(stat));
        if (A.it == 1)
        {
            umfpack_zi_free_numeric(&Numeric);
        }
        else
        {
            umfpack_di_free_numeric(&Numeric);
        }
        freeCcsSparse(A);
        if (freepdblBI)
        {
            FREE(pdblBI);
        }
        return 1;
    }
 
    /* allocate memory for umfpack_di_wsolve usage or umfpack_zi_wsolve usage*/
    Wi = (int*)MALLOC(mA * sizeof(int));
    W = (double*)MALLOC(mW * sizeof(double));

    if ( Case == 1 )   /*  x = A\b  <=> Ax = b */
    {
        if (A.it == 0)
        {
            for ( i = 0 ; i < nb ; i++ )
            {
                umfpack_di_wsolve(UMFPACK_A, A.p, A.irow, A.R, &pdblXR[i * mb], &pdblBR[i * mb],
                                  Numeric, Control, Info, Wi, W);
            }

            if (isVarComplex(pvApiCtx, piAddrB))
            {
                for ( i = 0 ; i < nb ; i++ )
                {
                    umfpack_di_wsolve(UMFPACK_A, A.p, A.irow, A.R, &pdblXI[i * mb], &pdblBI[i * mb],
                                      Numeric, Control, Info, Wi, W);
                }
            }
        }
        else /*  A.it == 1  */
        {
            for ( i = 0 ; i < nb ; i++ )
            {
                umfpack_zi_wsolve(UMFPACK_A, A.p, A.irow, A.R, A.I, &pdblXR[i * mb], &pdblXI[i * mb],
                                  &pdblBR[i * mb], &pdblBI[i * mb], Numeric, Control, Info, Wi, W);
            }
        }
    }
    else  /* Case == 2,   x = b/A  <=> x A = b <=> A.'x.' = b.' */
    {
        if (A.it == 0)
        {
            TransposeMatrix(pdblBR, mb, nb, pdblXR);    /* put b in x (with transposition) */
            for ( i = 0 ; i < mb ; i++ )
            {
                umfpack_di_wsolve(UMFPACK_At, A.p, A.irow, A.R, &pdblBR[i * nb], &pdblXR[i * nb],
                                  Numeric, Control, Info, Wi, W);      /* the solutions are in br */
            }

            TransposeMatrix(pdblBR, nb, mb, pdblXR);         /* put now br in xr with transposition */

            if (isVarComplex(pvApiCtx, piAddrB))
            {
                TransposeMatrix(pdblBI, mb, nb, pdblXI);    /* put b in x (with transposition) */
                for ( i = 0 ; i < mb ; i++ )
                {
                    umfpack_di_wsolve(UMFPACK_At, A.p, A.irow, A.R, &pdblBI[i * nb], &pdblXI[i * nb],
                                      Numeric, Control, Info, Wi, W);      /* the solutions are in bi */
                }
                TransposeMatrix(pdblBI, nb, mb, pdblXI);         /* put now bi in xi with transposition */
            }
        }
        else /*  A.it==1  */
        {
            TransposeMatrix(pdblBR, mb, nb, pdblXR);
            TransposeMatrix(pdblBI, mb, nb, pdblXI);
            for ( i = 0 ; i < mb ; i++ )
            {
                umfpack_zi_wsolve(UMFPACK_Aat, A.p, A.irow, A.R, A.I, &pdblBR[i * nb], &pdblBI[i * nb],
                                  &pdblXR[i * nb], &pdblXI[i * nb], Numeric, Control, Info, Wi, W);
            }
            TransposeMatrix(pdblBR, nb, mb, pdblXR);
            TransposeMatrix(pdblBI, nb, mb, pdblXI);
        }
    }

    if (A.it == 1)
    {
        umfpack_zi_free_numeric(&Numeric);
    }
    else
    {
        umfpack_di_free_numeric(&Numeric);
    }

    if (piNbItemRow != NULL)
    {
        FREE(piNbItemRow);
    }
    if (piColPos != NULL)
    {
        FREE(piColPos);
    }
    if (pdblSpReal != NULL)
    {
        FREE(pdblSpReal);
    }
    if (pdblSpImg != NULL)
    {
        FREE(pdblSpImg);
    }
    FREE(W);
    FREE(Wi);
    if (freepdblBI)
    {
        FREE(pdblBI);
    }
    freeCcsSparse(A);

    AssignOutputVariable(pvApiCtx, 1) = 4;
    ReturnArguments(pvApiCtx);
    return 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;
}
Beispiel #18
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 */
Beispiel #19
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;
}
Beispiel #20
0
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) ;
}
Beispiel #21
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;
}
Beispiel #22
0
static int cs_fact_init_umfpack( cs_fact_t *umfd, const cs *A )
{
#ifdef USE_UMFPACK
   int ret;
   void *symbolic;
   cs *T;

   /* Create matrix and sort. */
   /* Non-symmetric case. */
   if (0) {
      T        = cs_transpose( A, 1 );
      umfd->A  = cs_transpose( T, 1 );
      cs_spfree( T );
   }
   /* Symmetric case. */
   else {
      umfd->A  = cs_transpose( A, 1 );
   }
   cs_dupl( umfd->A );

   /* Generate symbolic. */
   ret = umfpack_di_symbolic( umfd->n, umfd->n, umfd->A->p, umfd->A->i, umfd->A->x, &symbolic, NULL, NULL );
   if (ret < UMFPACK_OK)
      goto err_sym;

   /* Generate numeric. */
   ret = umfpack_di_numeric(  umfd->A->p, umfd->A->i, umfd->A->x, symbolic, &umfd->numeric, NULL, NULL );
   if (ret < UMFPACK_OK)
      goto err_num;
   else if (ret > UMFPACK_OK) {
      switch (ret) {
         case UMFPACK_WARNING_singular_matrix:
            fprintf( stderr, "UMFPACK: Matrix is singular.\n" );
            break;
         case UMFPACK_WARNING_determinant_underflow:
            fprintf( stderr, "UMFPACK: Determinant underflow.\n" );
            break;
         case UMFPACK_WARNING_determinant_overflow:
            fprintf( stderr, "UMFPACK: Determinant overflow.\n" );
            break;
      }
   }

   /* Clean up symbolic. */
   umfpack_di_free_symbolic( &symbolic );

   /* Allocate buffers. */
   umfd->wi = malloc( umfd->n * sizeof(int) );
   if (umfd->wi == NULL)
      goto err_wi;
   umfd->w  = malloc( umfd->n*5 * sizeof(double) ); /* We consider iteration refinement. */
   if (umfd->w == NULL)
      goto err_w;
   umfd->x  = calloc( umfd->n, sizeof(double) );
   if (umfd->x == NULL)
      goto err_x;

   umfd->type = CS_FACT_UMFPACK;
   return 0;
err_x:
   free( umfd->w );
err_w:
   free( umfd->wi );
err_wi:
   umfpack_di_free_numeric( &umfd->numeric );
err_num:
   umfpack_di_free_symbolic( &symbolic );
err_sym:
   cs_spfree( umfd->A );
   return -1;
#else /* USE_UMFPACK */
   (void) umfd;
   (void) A;
   return -1;
#endif /* USE_UMFPACK */
}
int sci_umf_lufact(char* fname, void* pvApiCtx)
{
    SciErr sciErr;
    int stat = 0;
    SciSparse AA;
    CcsSparse A;

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

    /* umfpack stuff */
    double* Control = NULL;
    double* Info    = NULL;
    void* Symbolic  = NULL;
    void* Numeric   = NULL;

    int* piAddr1 = NULL;
    int iComplex = 0;
    int iType1   = 0;

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

    /* get A the sparse matrix to factorize */
    sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr1);
    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    /* check if the first argument is a sparse matrix */
    sciErr = getVarType(pvApiCtx, piAddr1, &iType1);
    if (sciErr.iErr || iType1 != sci_sparse)
    {
        printError(&sciErr, 0);
        Scierror(999, _("%s: Wrong type for input argument #%d: A sparse matrix expected.\n"), fname, 1);
        return 1;
    }

    if (isVarComplex(pvApiCtx, piAddr1))
    {
        iComplex = 1;
        sciErr = getComplexSparseMatrix(pvApiCtx, piAddr1, &mA, &nA, &iNbItem, &piNbItemRow, &piColPos, &pdblSpReal, &pdblSpImg);
    }
    else
    {
        sciErr = getSparseMatrix(pvApiCtx, piAddr1, &mA, &nA, &iNbItem, &piNbItemRow, &piColPos, &pdblSpReal);
    }

    if (sciErr.iErr)
    {
        FREE(piNbItemRow);
        FREE(piColPos);
        FREE(pdblSpReal);
        if (pdblSpImg)
        {
            FREE(pdblSpImg);
        }
        printError(&sciErr, 0);
        return 1;
    }

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

    if (nA <= 0 || mA <= 0)
    {
        FREE(piNbItemRow);
        FREE(piColPos);
        FREE(pdblSpReal);
        if (pdblSpImg)
        {
            FREE(pdblSpImg);
        }
        Scierror(999, _("%s: Wrong size for input argument #%d.\n"), fname, 1);
        return 1;
    }

    SciSparseToCcsSparse(&AA, &A);

    FREE(piNbItemRow);
    FREE(piColPos);
    FREE(pdblSpReal);
    if (pdblSpImg)
    {
        FREE(pdblSpImg);
    }

    /* symbolic factorization */
    if (A.it == 1)
    {
        stat = umfpack_zi_symbolic(nA, mA, A.p, A.irow, A.R, A.I, &Symbolic, Control, Info);
    }
    else
    {
        stat = umfpack_di_symbolic(nA, mA, A.p, A.irow, A.R, &Symbolic, Control, Info);
    }

    if (stat != UMFPACK_OK)
    {
        freeCcsSparse(A);
        Scierror(999, _("%s: An error occurred: %s: %s\n"), fname, _("symbolic factorization"), UmfErrorMes(stat));
        return 1;
    }

    /* numeric factorization */
    if (A.it == 1)
    {
        stat = umfpack_zi_numeric(A.p, A.irow, A.R, A.I, Symbolic, &Numeric, Control, Info);
    }
    else
    {
        stat = umfpack_di_numeric(A.p, A.irow, A.R, Symbolic, &Numeric, Control, Info);
    }

    if (A.it == 1)
    {
        umfpack_zi_free_symbolic(&Symbolic);
    }
    else
    {
        umfpack_di_free_symbolic(&Symbolic);
    }

    if ( stat != UMFPACK_OK  &&  stat != UMFPACK_WARNING_singular_matrix )
    {
        freeCcsSparse(A);
        Scierror(999, _("%s: An error occurred: %s: %s\n"), fname, _("symbolic factorization"), UmfErrorMes(stat));
        return 1;
    }

    if ( stat == UMFPACK_WARNING_singular_matrix  &&  mA == nA )
    {
        if (getWarningMode())
        {
            Sciwarning("\n%s:%s\n", _("Warning"), _("The (square) matrix appears to be singular."));
        }
    }

    /*  add the pointer in the list ListNumeric  */
    if (! AddAdrToList(Numeric, A.it, &ListNumeric))
    {
        /* AddAdrToList return 0 if malloc have failed : as it is just
        for storing 2 pointers this is unlikely to occurs but ... */
        if (A.it == 1)
        {
            umfpack_zi_free_numeric(&Numeric);
        }
        else
        {
            umfpack_di_free_numeric(&Numeric);
        }

        freeCcsSparse(A);
        Scierror(999, _("%s: An error occurred: %s\n"), fname, _("no place to store the LU pointer in ListNumeric."));
        return 1;
    }

    freeCcsSparse(A);

    /* create the scilab object to store the pointer onto the LU factors */
    sciErr = createPointer(pvApiCtx, 2, Numeric);
    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 1;
    }

    /* return the pointer */
    AssignOutputVariable(pvApiCtx, 1) = 2;
    ReturnArguments(pvApiCtx);
    return 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;
}
/*! \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;
}
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;
}