Пример #1
0
 inline
 int numeric (int, int n_col,
              int const* Ap, int const* Ai, traits::complex_d const* Ax,
              void *Symbolic, void **Numeric,
              double const* Control, double* Info)
 {
   int nnz = Ap[n_col];
   bindings::detail::array<double> Axr (nnz);
   if (!Axr.valid()) return UMFPACK_ERROR_out_of_memory;
   bindings::detail::array<double> Axi (nnz);
   if (!Axi.valid()) return UMFPACK_ERROR_out_of_memory;
   traits::detail::disentangle (Ax, Ax+nnz,
                                Axr.storage(), Axi.storage());
   return umfpack_zi_numeric (Ap, Ai, Axr.storage(), Axi.storage(),
                              Symbolic, Numeric, Control, Info);
 }
Пример #2
0
DllExport void* CreateSolverLUUMFPACK_CCS_Complex(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));
	double *Az = (double*)malloc(sizeof(double)*(nnz));

	for (size_t i = 0; i < nnz; i++)
	{
		Ax[i] = Values[2 * i];
		Az[i] = Values[2 * i + 1];
	}

	memcpy(Ap, columnPtr, sizeof(int)*(numberOfColumn + 1));
	memcpy(Ai, rowIndices, sizeof(int)*nnz);

	void *Symbolic, *Numeric;
	(void)umfpack_zi_symbolic(numberOfRow, numberOfColumn, Ap, Ai, Ax, Az, &Symbolic, NULL, NULL);
	(void)umfpack_zi_numeric(Ap, Ai, Ax, Az, Symbolic, &Numeric, NULL, NULL);


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

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

	return umpsolver;
}
Пример #3
0
void forward_shot_SH(struct waveAC *waveAC, struct PML_AC *PML_AC, struct matSH *matSH, float ** srcpos, int nshots, int ** recpos, int ntr, int nstage, int nfreq){

	/* declaration of global variables */
        extern int NSHOT1, NSHOT2, NONZERO, NX, NY, NXNY, NF;
        extern int SNAP, SEISMO, MYID, INFO, N_STREAMER, READ_REC;
        extern float DH;
        extern char SNAP_FILE[STRING_SIZE];
	extern FILE * FP;
    
        /* declaration of local variables */
        int ishot, status, nxsrc, nysrc, i;
    	double *null = (double *) NULL ;

	int     *Ap, *Ai;
	double  *Ax, *Az, *xr, *xi; 
	double  time1, time2;
        char filename[STRING_SIZE];
        void *Symbolic, *Numeric;

	/* Allocate memory for compressed sparse column form and solution vector */
	Ap = malloc(sizeof(int)*(NXNY+1));
	Ai = malloc(sizeof(int)*NONZERO);
	Ax = malloc(sizeof(double)*NONZERO);
	Az = malloc(sizeof(double)*NONZERO);
	xr = malloc(sizeof(double)*NONZERO);
	xi = malloc(sizeof(double)*NONZERO);

        /* assemble acoustic impedance matrix */
        init_A_SH_9p_pml(PML_AC,matSH,waveAC);

        /* convert triplet to compressed sparse column format */
        status = umfpack_zi_triplet_to_col(NXNY,NXNY,NONZERO,(*waveAC).irow,(*waveAC).icol,(*waveAC).Ar,(*waveAC).Ai,Ap,Ai,Ax,Az,NULL);

	/* Here is something buggy (*waveAC).Ar != Ax and (*waveAC).Ai != Az.
           Therefore, set  Ax = (*waveAC).Ar and Az = (*waveAC).Ai */
	for (i=0;i<NONZERO;i++){
	     Ax[i] = (*waveAC).Ar[i];
	     Az[i] = (*waveAC).Ai[i];
        }

	if((MYID==0)&&(INFO==1)){
	  printf("\n==================================== \n");
	  printf("\n *****  LU factorization **********  \n");
	  printf("\n==================================== \n\n");
	  time1=MPI_Wtime(); 
	}

        /* symbolic factorization */
	status = umfpack_zi_symbolic(NXNY, NXNY, Ap, Ai, Ax, Az, &Symbolic, null, null);

        /* sparse LU decomposition */
	status = umfpack_zi_numeric(Ap, Ai, Ax, Az, Symbolic, &Numeric, null, null);
        umfpack_zi_free_symbolic (&Symbolic);

	if((MYID==0)&&(INFO==1)){
	  time2=MPI_Wtime();
	  printf("\n Finished after %4.2f s \n",time2-time1);
	}

	if((MYID==0)&&(INFO==1)){
	  printf("\n============================================================================================================= \n");
	  printf("\n *****  Solve elastic SH forward problem by FDFD for shot %d - %d (f = %3.2f Hz) on MPI process no. %d **********  \n",NSHOT1,NSHOT2-1,(*waveAC).freq, MYID);
	  printf("\n============================================================================================================= \n\n");				
	  time1=MPI_Wtime(); 
	}

        /* loop over all shots */
	for (ishot=NSHOT1;ishot<NSHOT2;ishot++){

		/* read receiver positions from receiver files for each shot */
		if(READ_REC==1){
		    acq.recpos=receiver(FP, &ntr, 1);			                         
      		}

                /* define source vector RHS */
                RHS_source_AC(waveAC,srcpos,ishot);

                /* solve forward problem by forward and back substitution */
    		status = umfpack_zi_solve(UMFPACK_A, Ap, Ai, Ax, Az, xr, xi, (*waveAC).RHSr, (*waveAC).RHSi, Numeric, null, null);

		/* convert vector xr/xi to pr/pi */
		vec2mat((*waveAC).pr,(*waveAC).pi,xr,xi);

		/* write real part of pressure wavefield to file */
		if(SNAP==1){
		   sprintf(filename,"%s_shot_%d.p",SNAP_FILE,ishot);
		   /* writemod(filename,(*waveAC).pr,3); */
		   writemod_true(filename,(*waveAC).pr,3);
		}

		/* write FD seismogram files */
		if(SEISMO==1){		   
		   calc_seis_AC(waveAC,acq.recpos,ntr,ishot,nshots,nfreq);
		}

		if(READ_REC==1){
		   free_imatrix(acq.recpos,1,3,1,ntr);
		   ntr=0;
 		}

	}

	if((MYID==0)&&(INFO==1)){
	  time2=MPI_Wtime();
	  printf("\n Finished after %4.2f s \n",time2-time1);
	}
         	    
	/* free memory */
    	free(Ap); free(Ai); free(Ax); free(Az); free(xr); free(xi); 

	umfpack_zi_free_numeric (&Numeric);	

}
Пример #4
0
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;
}
Пример #5
0
int main (int argc, char **argv)
{
    double Info [UMFPACK_INFO], Control [UMFPACK_CONTROL], *Ax, *Cx, *Lx, *Ux,
	*W, t [2], *Dx, rnorm, *Rb, *y, *Rs ;
    double *Az, *Lz, *Uz, *Dz, *Cz, *Rbz, *yz ;
    int *Ap, *Ai, *Cp, *Ci, row, col, p, lnz, unz, nr, nc, *Lp, *Li, *Ui, *Up,
	*P, *Q, *Lj, i, j, k, anz, nfr, nchains, *Qinit, fnpiv, lnz1, unz1, nz1,
	status, *Front_npivcol, *Front_parent, *Chain_start, *Wi, *Pinit, n1,
	*Chain_maxrows, *Chain_maxcols, *Front_1strow, *Front_leftmostdesc,
	nzud, do_recip ;
    void *Symbolic, *Numeric ;

    /* ---------------------------------------------------------------------- */
    /* initializations */
    /* ---------------------------------------------------------------------- */

    umfpack_tic (t) ;

    printf ("\nUMFPACK V%d.%d (%s) demo: _zi_ version\n",
	    UMFPACK_MAIN_VERSION, UMFPACK_SUB_VERSION, UMFPACK_DATE) ;

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

    /* change the default print level for this demo */
    /* (otherwise, nothing will print) */
    Control [UMFPACK_PRL] = 6 ;

    /* print the license agreement */
    umfpack_zi_report_status (Control, UMFPACK_OK) ;
    Control [UMFPACK_PRL] = 5 ;

    /* print the control parameters */
    umfpack_zi_report_control (Control) ;

    /* ---------------------------------------------------------------------- */
    /* print A and b, and convert A to column-form */
    /* ---------------------------------------------------------------------- */

    /* print the right-hand-side */
    printf ("\nb: ") ;
    (void) umfpack_zi_report_vector (n, b, bz, Control) ;

    /* print the triplet form of the matrix */
    printf ("\nA: ") ;
    (void) umfpack_zi_report_triplet (n, n, nz, Arow, Acol, Aval, Avalz,
	Control) ;

    /* convert to column form */
    nz1 = MAX (nz,1) ;	/* ensure arrays are not of size zero. */
    Ap = (int *) malloc ((n+1) * sizeof (int)) ;
    Ai = (int *) malloc (nz1 * sizeof (int)) ;
    Ax = (double *) malloc (nz1 * sizeof (double)) ;
    Az = (double *) malloc (nz1 * sizeof (double)) ;
    if (!Ap || !Ai || !Ax || !Az)
    {
	error ("out of memory") ;
    }

    status = umfpack_zi_triplet_to_col (n, n, nz, Arow, Acol, Aval, Avalz,
	Ap, Ai, Ax, Az, (int *) NULL) ;

    if (status < 0)
    {
	umfpack_zi_report_status (Control, status) ;
	error ("umfpack_zi_triplet_to_col failed") ;
    }

    /* print the column-form of A */
    printf ("\nA: ") ;
    (void) umfpack_zi_report_matrix (n, n, Ap, Ai, Ax, Az, 1, Control) ;

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

    status = umfpack_zi_symbolic (n, n, Ap, Ai, Ax, Az, &Symbolic,
	Control, Info) ;
    if (status < 0)
    {
	umfpack_zi_report_info (Control, Info) ;
	umfpack_zi_report_status (Control, status) ;
	error ("umfpack_zi_symbolic failed") ;
    }

    /* print the symbolic factorization */

    printf ("\nSymbolic factorization of A: ") ;
    (void) umfpack_zi_report_symbolic (Symbolic, Control) ;

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

    status = umfpack_zi_numeric (Ap, Ai, Ax, Az, Symbolic, &Numeric,
	Control, Info) ;
    if (status < 0)
    {
	umfpack_zi_report_info (Control, Info) ;
	umfpack_zi_report_status (Control, status) ;
	error ("umfpack_zi_numeric failed") ;
    }

    /* print the numeric factorization */
    printf ("\nNumeric factorization of A: ") ;
    (void) umfpack_zi_report_numeric (Numeric, Control) ;

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

    status = umfpack_zi_solve (UMFPACK_A, Ap, Ai, Ax, Az, x, xz, b, bz,
	Numeric, Control, Info) ;
    umfpack_zi_report_info (Control, Info) ;
    umfpack_zi_report_status (Control, status) ;
    if (status < 0)
    {
	error ("umfpack_zi_solve failed") ;
    }
    printf ("\nx (solution of Ax=b): ") ;
    (void) umfpack_zi_report_vector (n, x, xz, Control) ;
    rnorm = resid (FALSE, Ap, Ai, Ax, Az) ;
    printf ("maxnorm of residual: %g\n\n", rnorm) ;

    /* ---------------------------------------------------------------------- */
    /* compute the determinant */
    /* ---------------------------------------------------------------------- */

    status = umfpack_zi_get_determinant (x, xz, r, Numeric, Info) ;
    umfpack_zi_report_status (Control, status) ;
    if (status < 0)
    {
	error ("umfpack_zi_get_determinant failed") ;
    }
    printf ("determinant: (%g", x [0]) ;
    printf ("+ (%g)i", xz [0]) ; /* complex */
    printf (") * 10^(%g)\n", r [0]) ;

    /* ---------------------------------------------------------------------- */
    /* solve Ax=b, broken down into steps */
    /* ---------------------------------------------------------------------- */

    /* Rb = R*b */
    Rb  = (double *) malloc (n * sizeof (double)) ;
    Rbz = (double *) malloc (n * sizeof (double)) ;
    y   = (double *) malloc (n * sizeof (double)) ;
    yz  = (double *) malloc (n * sizeof (double)) ;
    if (!Rb || !y) error ("out of memory") ;
    if (!Rbz || !yz) error ("out of memory") ;

    status = umfpack_zi_scale (Rb, Rbz, b, bz, Numeric) ;
    if (status < 0) error ("umfpack_zi_scale failed") ;
    /* solve Ly = P*(Rb) */
    status = umfpack_zi_solve (UMFPACK_Pt_L, Ap, Ai, Ax, Az, y, yz, Rb, Rbz,
	Numeric, Control, Info) ;
    if (status < 0) error ("umfpack_zi_solve failed") ;
    /* solve UQ'x=y */
    status = umfpack_zi_solve (UMFPACK_U_Qt, Ap, Ai, Ax, Az, x, xz, y, yz,
	Numeric, Control, Info) ;
    if (status < 0) error ("umfpack_zi_solve failed") ;
    printf ("\nx (solution of Ax=b, solve is split into 3 steps): ") ;
    (void) umfpack_zi_report_vector (n, x, xz, Control) ;
    rnorm = resid (FALSE, Ap, Ai, Ax, Az) ;
    printf ("maxnorm of residual: %g\n\n", rnorm) ;

    free (Rb) ;
    free (Rbz) ;
    free (y) ;
    free (yz) ;

    /* ---------------------------------------------------------------------- */
    /* solve A'x=b */
    /* ---------------------------------------------------------------------- */

    /* note that this is the complex conjugate transpose, A' */
    status = umfpack_zi_solve (UMFPACK_At, Ap, Ai, Ax, Az, x, xz, b, bz,
	Numeric, Control, Info) ;
    umfpack_zi_report_info (Control, Info) ;
    if (status < 0)
    {
	error ("umfpack_zi_solve failed") ;
    }
    printf ("\nx (solution of A'x=b): ") ;
    (void) umfpack_zi_report_vector (n, x, xz, Control) ;
    rnorm = resid (TRUE, Ap, Ai, Ax, Az) ;
    printf ("maxnorm of residual: %g\n\n", rnorm) ;

    /* ---------------------------------------------------------------------- */
    /* modify one numerical value in the column-form of A */
    /* ---------------------------------------------------------------------- */

    /* change A (1,4), look for row index 1 in column 4. */
    row = 1 ;
    col = 4 ;
    for (p = Ap [col] ; p < Ap [col+1] ; p++)
    {
	if (row == Ai [p])
	{
	    printf ("\nchanging A (%d,%d) to zero\n", row, col) ;
	    Ax [p] = 0.0 ;
	    Az [p] = 0.0 ;
	    break ;
	}
    }
    printf ("\nmodified A: ") ;
    (void) umfpack_zi_report_matrix (n, n, Ap, Ai, Ax, Az, 1, Control) ;

    /* ---------------------------------------------------------------------- */
    /* redo the numeric factorization */
    /* ---------------------------------------------------------------------- */

    /* The pattern (Ap and Ai) hasn't changed, so the symbolic factorization */
    /* doesn't have to be redone, no matter how much we change Ax. */

    /* We don't need the Numeric object any more, so free it. */
    umfpack_zi_free_numeric (&Numeric) ;

    /* Note that a memory leak would have occurred if the old Numeric */
    /* had not been free'd with umfpack_zi_free_numeric above. */
    status = umfpack_zi_numeric (Ap, Ai, Ax, Az, Symbolic, &Numeric,
	Control, Info) ;
    if (status < 0)
    {
	umfpack_zi_report_info (Control, Info) ;
	umfpack_zi_report_status (Control, status) ;
	error ("umfpack_zi_numeric failed") ;
    }
    printf ("\nNumeric factorization of modified A: ") ;
    (void) umfpack_zi_report_numeric (Numeric, Control) ;

    /* ---------------------------------------------------------------------- */
    /* solve Ax=b, with the modified A */
    /* ---------------------------------------------------------------------- */

    status = umfpack_zi_solve (UMFPACK_A, Ap, Ai, Ax, Az, x, xz, b, bz,
	Numeric, Control, Info) ;
    umfpack_zi_report_info (Control, Info) ;
    if (status < 0)
    {
	umfpack_zi_report_status (Control, status) ;
	error ("umfpack_zi_solve failed") ;
    }
    printf ("\nx (with modified A): ") ;
    (void) umfpack_zi_report_vector (n, x, xz, Control) ;
    rnorm = resid (FALSE, Ap, Ai, Ax, Az) ;
    printf ("maxnorm of residual: %g\n\n", rnorm) ;

    /* ---------------------------------------------------------------------- */
    /* modify all of the numerical values of A, but not the pattern */
    /* ---------------------------------------------------------------------- */

    for (col = 0 ; col < n ; col++)
    {
	for (p = Ap [col] ; p < Ap [col+1] ; p++)
	{
	    row = Ai [p] ;
	    printf ("changing ") ;
	    /* complex: */ printf ("real part of ") ;
	    printf ("A (%d,%d) from %g", row, col, Ax [p]) ;
	    Ax [p] = Ax [p] + col*10 - row ;
	    printf (" to %g\n", Ax [p]) ;
	}
    }
    printf ("\ncompletely modified A (same pattern): ") ;
    (void) umfpack_zi_report_matrix (n, n, Ap, Ai, Ax, Az, 1, Control) ;

    /* ---------------------------------------------------------------------- */
    /* save the Symbolic object to file, free it, and load it back in */
    /* ---------------------------------------------------------------------- */

    /* use the default filename, "symbolic.umf" */
    printf ("\nSaving symbolic object:\n") ;
    status = umfpack_zi_save_symbolic (Symbolic, (char *) NULL) ;
    if (status < 0)
    {
	umfpack_zi_report_status (Control, status) ;
	error ("umfpack_zi_save_symbolic failed") ;
    }
    printf ("\nFreeing symbolic object:\n") ;
    umfpack_zi_free_symbolic (&Symbolic) ;
    printf ("\nLoading symbolic object:\n") ;
    status = umfpack_zi_load_symbolic (&Symbolic, (char *) NULL) ;
    if (status < 0)
    {
	umfpack_zi_report_status (Control, status) ;
	error ("umfpack_zi_load_symbolic failed") ;
    }
    printf ("\nDone loading symbolic object\n") ;

    /* ---------------------------------------------------------------------- */
    /* redo the numeric factorization */
    /* ---------------------------------------------------------------------- */

    umfpack_zi_free_numeric (&Numeric) ;
    status = umfpack_zi_numeric (Ap, Ai, Ax, Az, Symbolic, &Numeric,
	Control, Info) ;
    if (status < 0)
    {
	umfpack_zi_report_info (Control, Info) ;
	umfpack_zi_report_status (Control, status) ;
	error ("umfpack_zi_numeric failed") ;
    }
    printf ("\nNumeric factorization of completely modified A: ") ;
    (void) umfpack_zi_report_numeric (Numeric, Control) ;

    /* ---------------------------------------------------------------------- */
    /* solve Ax=b, with the modified A */
    /* ---------------------------------------------------------------------- */

    status = umfpack_zi_solve (UMFPACK_A, Ap, Ai, Ax, Az, x, xz, b, bz,
	Numeric, Control, Info) ;
    umfpack_zi_report_info (Control, Info) ;
    if (status < 0)
    {
	umfpack_zi_report_status (Control, status) ;
	error ("umfpack_zi_solve failed") ;
    }
    printf ("\nx (with completely modified A): ") ;
    (void) umfpack_zi_report_vector (n, x, xz, Control) ;
    rnorm = resid (FALSE, Ap, Ai, Ax, Az) ;
    printf ("maxnorm of residual: %g\n\n", rnorm) ;

    /* ---------------------------------------------------------------------- */
    /* free the symbolic and numeric factorization */
    /* ---------------------------------------------------------------------- */

    umfpack_zi_free_symbolic (&Symbolic) ;
    umfpack_zi_free_numeric (&Numeric) ;

    /* ---------------------------------------------------------------------- */
    /* C = transpose of A */
    /* ---------------------------------------------------------------------- */

    Cp = (int *) malloc ((n+1) * sizeof (int)) ;
    Ci = (int *) malloc (nz1 * sizeof (int)) ;
    Cx = (double *) malloc (nz1 * sizeof (double)) ;
    Cz = (double *) malloc (nz1 * sizeof (double)) ;
    if (!Cp || !Ci || !Cx || !Cz)
    {
	error ("out of memory") ;
    }
    status = umfpack_zi_transpose (n, n, Ap, Ai, Ax, Az,
	(int *) NULL, (int *) NULL, Cp, Ci, Cx, Cz, TRUE) ;
    if (status < 0)
    {
	umfpack_zi_report_status (Control, status) ;
	error ("umfpack_zi_transpose failed: ") ;
    }
    printf ("\nC (transpose of A): ") ;
    (void) umfpack_zi_report_matrix (n, n, Cp, Ci, Cx, Cz, 1, Control) ;

    /* ---------------------------------------------------------------------- */
    /* symbolic factorization of C */
    /* ---------------------------------------------------------------------- */

    status = umfpack_zi_symbolic (n, n, Cp, Ci, Cx, Cz, &Symbolic,
	Control, Info) ;
    if (status < 0)
    {
	umfpack_zi_report_info (Control, Info) ;
	umfpack_zi_report_status (Control, status) ;
	error ("umfpack_zi_symbolic failed") ;
    }
    printf ("\nSymbolic factorization of C: ") ;
    (void) umfpack_zi_report_symbolic (Symbolic, Control) ;

    /* ---------------------------------------------------------------------- */
    /* copy the contents of Symbolic into user arrays print them */
    /* ---------------------------------------------------------------------- */

    printf ("\nGet the contents of the Symbolic object for C:\n") ;
    printf ("(compare with umfpack_zi_report_symbolic output, above)\n") ;
    Pinit = (int *) malloc ((n+1) * sizeof (int)) ;
    Qinit = (int *) malloc ((n+1) * sizeof (int)) ;
    Front_npivcol = (int *) malloc ((n+1) * sizeof (int)) ;
    Front_1strow = (int *) malloc ((n+1) * sizeof (int)) ;
    Front_leftmostdesc = (int *) malloc ((n+1) * sizeof (int)) ;
    Front_parent = (int *) malloc ((n+1) * sizeof (int)) ;
    Chain_start = (int *) malloc ((n+1) * sizeof (int)) ;
    Chain_maxrows = (int *) malloc ((n+1) * sizeof (int)) ;
    Chain_maxcols = (int *) malloc ((n+1) * sizeof (int)) ;
    if (!Pinit || !Qinit || !Front_npivcol || !Front_parent || !Chain_start ||
	!Chain_maxrows || !Chain_maxcols || !Front_1strow ||
	!Front_leftmostdesc)
    {
	error ("out of memory") ;
    }

    status = umfpack_zi_get_symbolic (&nr, &nc, &n1, &anz, &nfr, &nchains,
	Pinit, Qinit, Front_npivcol, Front_parent, Front_1strow,
	Front_leftmostdesc, Chain_start, Chain_maxrows, Chain_maxcols,
	Symbolic) ;

    if (status < 0)
    {
	error ("symbolic factorization invalid") ;
    }

    printf ("From the Symbolic object, C is of dimension %d-by-%d\n", nr, nc);
    printf ("   with nz = %d, number of fronts = %d,\n", nz, nfr) ;
    printf ("   number of frontal matrix chains = %d\n", nchains) ;

    printf ("\nPivot columns in each front, and parent of each front:\n") ;
    k = 0 ;
    for (i = 0 ; i < nfr ; i++)
    {
	fnpiv = Front_npivcol [i] ;
	printf ("    Front %d: parent front: %d number of pivot cols: %d\n",
		i, Front_parent [i], fnpiv) ;
	for (j = 0 ; j < fnpiv ; j++)
	{
	    col = Qinit [k] ;
	    printf (
	    "        %d-th pivot column is column %d in original matrix\n",
		k, col) ;
	    k++ ;
	}
    }

    printf ("\nNote that the column ordering, above, will be refined\n") ;
    printf ("in the numeric factorization below.  The assignment of pivot\n") ;
    printf ("columns to frontal matrices will always remain unchanged.\n") ;

    printf ("\nTotal number of pivot columns in frontal matrices: %d\n", k) ;

    printf ("\nFrontal matrix chains:\n") ;
    for (j = 0 ; j < nchains ; j++)
    {
	printf ("   Frontal matrices %d to %d are factorized in a single\n",
	    Chain_start [j], Chain_start [j+1] - 1) ;
	printf ("        working array of size %d-by-%d\n",
	    Chain_maxrows [j], Chain_maxcols [j]) ;
    }

    /* ---------------------------------------------------------------------- */
    /* numeric factorization of C */
    /* ---------------------------------------------------------------------- */

    status = umfpack_zi_numeric (Cp, Ci, Cx, Cz, Symbolic, &Numeric,
	Control, Info) ;
    if (status < 0)
    {
	error ("umfpack_zi_numeric failed") ;
    }
    printf ("\nNumeric factorization of C: ") ;
    (void) umfpack_zi_report_numeric (Numeric, Control) ;

    /* ---------------------------------------------------------------------- */
    /* extract the LU factors of C and print them */
    /* ---------------------------------------------------------------------- */

    if (umfpack_zi_get_lunz (&lnz, &unz, &nr, &nc, &nzud, Numeric) < 0)
    {
	error ("umfpack_zi_get_lunz failed") ;
    }
    /* ensure arrays are not of zero size */
    lnz1 = MAX (lnz,1) ;
    unz1 = MAX (unz,1) ;
    Lp = (int *) malloc ((n+1) * sizeof (int)) ;
    Lj = (int *) malloc (lnz1 * sizeof (int)) ;
    Lx = (double *) malloc (lnz1 * sizeof (double)) ;
    Lz = (double *) malloc (lnz1 * sizeof (double)) ;
    Up = (int *) malloc ((n+1) * sizeof (int)) ;
    Ui = (int *) malloc (unz1 * sizeof (int)) ;
    Ux = (double *) malloc (unz1 * sizeof (double)) ;
    Uz = (double *) malloc (unz1 * sizeof (double)) ;
    P = (int *) malloc (n * sizeof (int)) ;
    Q = (int *) malloc (n * sizeof (int)) ;
    Dx = (double *) NULL ;	/* D vector not requested */
    Dz = (double *) NULL ;
    Rs  = (double *) malloc (n * sizeof (double)) ;
    if (!Lp || !Lj || !Lx || !Lz || !Up || !Ui || !Ux || !Uz || !P || !Q || !Rs)
    {
	error ("out of memory") ;
    }
    status = umfpack_zi_get_numeric (Lp, Lj, Lx, Lz, Up, Ui, Ux, Uz,
	P, Q, Dx, Dz, &do_recip, Rs, Numeric) ;
    if (status < 0)
    {
	error ("umfpack_zi_get_numeric failed") ;
    }

    printf ("\nL (lower triangular factor of C): ") ;
    (void) umfpack_zi_report_matrix (n, n, Lp, Lj, Lx, Lz, 0, Control) ;
    printf ("\nU (upper triangular factor of C): ") ;
    (void) umfpack_zi_report_matrix (n, n, Up, Ui, Ux, Uz, 1, Control) ;
    printf ("\nP: ") ;
    (void) umfpack_zi_report_perm (n, P, Control) ;
    printf ("\nQ: ") ;
    (void) umfpack_zi_report_perm (n, Q, Control) ;
    printf ("\nScale factors: row i of A is to be ") ;
    if (do_recip)
    {
	printf ("multiplied by the ith scale factor\n") ;
    }
    else
    {
	printf ("divided by the ith scale factor\n") ;
    }
    for (i = 0 ; i < n ; i++) printf ("%d: %g\n", i, Rs [i]) ;

    /* ---------------------------------------------------------------------- */
    /* convert L to triplet form and print it */
    /* ---------------------------------------------------------------------- */

    /* Note that L is in row-form, so it is the row indices that are created */
    /* by umfpack_zi_col_to_triplet. */

    printf ("\nConverting L to triplet form, and printing it:\n") ;
    Li = (int *) malloc (lnz1 * sizeof (int)) ;
    if (!Li)
    {
	error ("out of memory") ;
    }
    if (umfpack_zi_col_to_triplet (n, Lp, Li) < 0)
    {
	error ("umfpack_zi_col_to_triplet failed") ;
    }
    printf ("\nL, in triplet form: ") ;
    (void) umfpack_zi_report_triplet (n, n, lnz, Li, Lj, Lx, Lz, Control) ;

    /* ---------------------------------------------------------------------- */
    /* save the Numeric object to file, free it, and load it back in */
    /* ---------------------------------------------------------------------- */

    /* use the default filename, "numeric.umf" */
    printf ("\nSaving numeric object:\n") ;
    status = umfpack_zi_save_numeric (Numeric, (char *) NULL) ;
    if (status < 0)
    {
	umfpack_zi_report_status (Control, status) ;
	error ("umfpack_zi_save_numeric failed") ;
    }
    printf ("\nFreeing numeric object:\n") ;
    umfpack_zi_free_numeric (&Numeric) ;
    printf ("\nLoading numeric object:\n") ;
    status = umfpack_zi_load_numeric (&Numeric, (char *) NULL) ;
    if (status < 0)
    {
	umfpack_zi_report_status (Control, status) ;
	error ("umfpack_zi_load_numeric failed") ;
    }
    printf ("\nDone loading numeric object\n") ;

    /* ---------------------------------------------------------------------- */
    /* solve C'x=b */
    /* ---------------------------------------------------------------------- */

    status = umfpack_zi_solve (UMFPACK_At, Cp, Ci, Cx, Cz, x, xz, b, bz,
	Numeric, Control, Info) ;
    umfpack_zi_report_info (Control, Info) ;
    if (status < 0)
    {
	umfpack_zi_report_status (Control, status) ;
	error ("umfpack_zi_solve failed") ;
    }
    printf ("\nx (solution of C'x=b): ") ;
    (void) umfpack_zi_report_vector (n, x, xz, Control) ;
    rnorm = resid (TRUE, Cp, Ci, Cx, Cz) ;
    printf ("maxnorm of residual: %g\n\n", rnorm) ;

    /* ---------------------------------------------------------------------- */
    /* solve C'x=b again, using umfpack_zi_wsolve instead */
    /* ---------------------------------------------------------------------- */

    printf ("\nSolving C'x=b again, using umfpack_zi_wsolve instead:\n") ;
    Wi = (int *) malloc (n * sizeof (int)) ;
    W = (double *) malloc (10*n * sizeof (double)) ;
    if (!Wi || !W)
    {
	error ("out of memory") ;
    }

    status = umfpack_zi_wsolve (UMFPACK_At, Cp, Ci, Cx, Cz, x, xz, b, bz,
	Numeric, Control, Info, Wi, W) ;
    umfpack_zi_report_info (Control, Info) ;
    if (status < 0)
    {
	umfpack_zi_report_status (Control, status) ;
	error ("umfpack_zi_wsolve failed") ;
    }
    printf ("\nx (solution of C'x=b): ") ;
    (void) umfpack_zi_report_vector (n, x, xz, Control) ;
    rnorm = resid (TRUE, Cp, Ci, Cx, Cz) ;
    printf ("maxnorm of residual: %g\n\n", rnorm) ;

    /* ---------------------------------------------------------------------- */
    /* free everything */
    /* ---------------------------------------------------------------------- */

    /* This is not strictly required since the process is exiting and the */
    /* system will reclaim the memory anyway.  It's useful, though, just as */
    /* a list of what is currently malloc'ed by this program.  Plus, it's */
    /* always a good habit to explicitly free whatever you malloc. */

    free (Ap) ;
    free (Ai) ;
    free (Ax) ;
    free (Az) ;

    free (Cp) ;
    free (Ci) ;
    free (Cx) ;
    free (Cz) ;

    free (Pinit) ;
    free (Qinit) ;
    free (Front_npivcol) ;
    free (Front_1strow) ;
    free (Front_leftmostdesc) ;
    free (Front_parent) ;
    free (Chain_start) ;
    free (Chain_maxrows) ;
    free (Chain_maxcols) ;

    free (Lp) ;
    free (Lj) ;
    free (Lx) ;
    free (Lz) ;

    free (Up) ;
    free (Ui) ;
    free (Ux) ;
    free (Uz) ;

    free (P) ;
    free (Q) ;

    free (Li) ;

    free (Wi) ;
    free (W) ;

    umfpack_zi_free_symbolic (&Symbolic) ;
    umfpack_zi_free_numeric (&Numeric) ;

    /* ---------------------------------------------------------------------- */
    /* print the total time spent in this demo */
    /* ---------------------------------------------------------------------- */

    umfpack_toc (t) ;
    printf ("\numfpack_zi_demo complete.\nTotal time: %5.2f seconds"
	" (CPU time), %5.2f seconds (wallclock time)\n", t [1], t [0]) ;
    return (0) ;
}
Пример #6
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;
}
Пример #7
0
bool CommonSolverUmfpack::solve(Matrix *mat, cplx *res)
{
    printf("UMFPACK solver - cplx\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();

    // complex components
    double *Axr = new double[nnz];
    double *Axi = new double[nnz];
    cplx *Ax = Acsc->get_Ax_cplx();
    for (int i = 0; i < nnz; i++)
    {
        Axr[i] = Ax[i].real();
        Axi[i] = Ax[i].imag();
    }

    umfpack_zi_defaults(control_array);

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

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

    umfpack_zi_free_symbolic(&symbolic);

    double *xr = new double[size];
    double *xi = new double[size];

    double *resr = new double[size];
    double *resi = new double[size];

    for (int i = 0; i < size; i++)
    {
        resr[i] = res[i].real();
        resi[i] = res[i].imag();
    }

    /* solve system */
    int status_solve = umfpack_zi_solve(UMFPACK_A,
                                        Acsc->get_Ap(), Acsc->get_Ai(), Axr, Axi, xr, xi, resr, resi, numeric,
                                        control_array, info_array);

    print_status(status_solve);

    umfpack_zi_free_numeric(&numeric);

    delete[] resr;
    delete[] resi;
    delete[] Axr;
    delete[] Axi;

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

    for (int i = 0; i < Acsc->get_size(); i++)
        res[i] = cplx(xr[i], xi[i]);

    delete[] xr;
    delete[] xi;

    if (!dynamic_cast<CSCMatrix*>(mat))
        delete Acsc;
}