예제 #1
0
파일: _superlumodule.c 프로젝트: 87/scipy
static PyObject *
Py_gstrf(PyObject *self, PyObject *args, PyObject *keywds)
{
    /* default value for SuperLU parameters*/
    int N, nnz;
    PyArrayObject *rowind, *colptr, *nzvals;
    SuperMatrix A;
    PyObject *result;
    PyObject *option_dict = NULL;
    int type;
    int ilu = 0;

    static char *kwlist[] = {"N","nnz","nzvals","colind","rowptr",
                             "options", "ilu",
                             NULL};

    int res = PyArg_ParseTupleAndKeywords(
        args, keywds, "iiO!O!O!|Oi", kwlist, 
        &N, &nnz,
        &PyArray_Type, &nzvals,
        &PyArray_Type, &rowind,
        &PyArray_Type, &colptr,
        &option_dict,
        &ilu);

    if (!res)
        return NULL;

    if (!_CHECK_INTEGER(colptr) || !_CHECK_INTEGER(rowind)) {
        PyErr_SetString(PyExc_TypeError,
                        "rowind and colptr must be of type cint");
        return NULL;
    }

    type = PyArray_TYPE(nzvals);
    if (!CHECK_SLU_TYPE(type)) {
        PyErr_SetString(PyExc_TypeError,
                        "nzvals is not of a type supported by SuperLU");
        return NULL;
    }

    if (NCFormat_from_spMatrix(&A, N, N, nnz, nzvals, rowind, colptr,
                               type)) {
        goto fail;
    }

    result = newSciPyLUObject(&A, option_dict, type, ilu);
    if (result == NULL) {
        goto fail;
    }

    /* arrays of input matrix will not be freed */  
    Destroy_SuperMatrix_Store(&A);
    return result;
  
fail:
    /* arrays of input matrix will not be freed */
    Destroy_SuperMatrix_Store(&A); 
    return NULL;
}
예제 #2
0
int DenseSuper_from_Numeric(SuperMatrix *X, PyObject *PyX)
{
    PyArrayObject *aX;
    int m, n, ldx, nd;

    if (!PyArray_Check(PyX)) {
        PyErr_SetString(PyExc_TypeError,
                        "argument is not an array.");
        return -1;
    }

    aX = (PyArrayObject*)PyX;

    if (!CHECK_SLU_TYPE(aX->descr->type_num)) {
        PyErr_SetString(PyExc_ValueError, "unsupported array data type");
        return -1;
    }

    if (!(aX->flags & NPY_F_CONTIGUOUS)) {
        PyErr_SetString(PyExc_ValueError, "array is not fortran contiguous");
        return -1;
    }

    nd = aX->nd;

    if (nd == 1) {
	m = aX->dimensions[0];
	n = 1;
	ldx = m;
    }
    else if (nd == 2) {
	m = aX->dimensions[0];
	n = aX->dimensions[1];
	ldx = m;
    }
    else {
        PyErr_SetString(PyExc_ValueError, "wrong number of dimensions in array");
        return -1;
    }

    if (setjmp(_superlu_py_jmpbuf))
	return -1;
    else {
	Create_Dense_Matrix(aX->descr->type_num, X, m, n,
			    aX->data, ldx, SLU_DN,
			    NPY_TYPECODE_TO_SLU(aX->descr->type_num),
			    SLU_GE);
    }
    return 0;
}
예제 #3
0
int NCFormat_from_spMatrix(SuperMatrix * A, int m, int n, int nnz,
			   PyArrayObject * nzvals, PyArrayObject * rowind,
			   PyArrayObject * colptr, int typenum)
{
    int ok = 0;

    ok = (PyArray_EquivTypenums(PyArray_DESCR(nzvals)->type_num, typenum) &&
          PyArray_EquivTypenums(PyArray_DESCR(rowind)->type_num, NPY_INT) &&
          PyArray_EquivTypenums(PyArray_DESCR(colptr)->type_num, NPY_INT) &&
          PyArray_NDIM(nzvals) == 1 &&
          PyArray_NDIM(rowind) == 1 &&
          PyArray_NDIM(colptr) == 1 &&
          PyArray_IS_C_CONTIGUOUS(nzvals) &&
          PyArray_IS_C_CONTIGUOUS(rowind) &&
          PyArray_IS_C_CONTIGUOUS(colptr) &&
          nnz <= PyArray_DIM(nzvals, 0) &&
          nnz <= PyArray_DIM(rowind, 0) &&
          n+1 <= PyArray_DIM(colptr, 0));
    if (!ok) {
	PyErr_SetString(PyExc_ValueError,
			"sparse matrix arrays must be 1-D C-contiguous and of proper "
                        "sizes and types");
	return -1;
    }


    if (setjmp(_superlu_py_jmpbuf))
	return -1;
    else {
	if (!CHECK_SLU_TYPE(nzvals->descr->type_num)) {
	    PyErr_SetString(PyExc_TypeError, "Invalid type for array.");
	    return -1;
	}
	Create_CompCol_Matrix(nzvals->descr->type_num,
			      A, m, n, nnz, nzvals->data,
			      (int *) rowind->data, (int *) colptr->data,
			      SLU_NC,
			      NPY_TYPECODE_TO_SLU(nzvals->descr->type_num),
			      SLU_GE);
    }

    return 0;
}
예제 #4
0
파일: _superlumodule.c 프로젝트: 87/scipy
static PyObject *
Py_gssv(PyObject *self, PyObject *args, PyObject *kwdict)
{
    PyObject *Py_B=NULL, *Py_X=NULL;
    PyArrayObject *nzvals=NULL;
    PyArrayObject *colind=NULL, *rowptr=NULL;
    int N, nnz;
    int info;
    int csc=0;
    int *perm_r=NULL, *perm_c=NULL;
    SuperMatrix A, B, L, U;
    superlu_options_t options;
    SuperLUStat_t stat;
    PyObject *option_dict = NULL;
    int type;
    int ssv_finished = 0;

    static char *kwlist[] = {"N","nnz","nzvals","colind","rowptr","B", "csc",
                             "options",NULL};
    
    /* Get input arguments */
    if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO!O!O!O|iO", kwlist,
                                     &N, &nnz, &PyArray_Type, &nzvals,
                                     &PyArray_Type, &colind, &PyArray_Type,
                                     &rowptr, &Py_B, &csc, &option_dict)) {
        return NULL;
    }

    if (!_CHECK_INTEGER(colind) || !_CHECK_INTEGER(rowptr)) {
        PyErr_SetString(PyExc_TypeError,
                        "colind and rowptr must be of type cint");
        return NULL;
    }

    type = PyArray_TYPE(nzvals);
    if (!CHECK_SLU_TYPE(type)) {
        PyErr_SetString(PyExc_TypeError,
                        "nzvals is not of a type supported by SuperLU");
        return NULL;
    }

    if (!set_superlu_options_from_dict(&options, 0, option_dict, NULL, NULL)) {
        return NULL;
    }

    /* Create Space for output */
    Py_X = PyArray_CopyFromObject(Py_B, type, 1, 2);
    if (Py_X == NULL) return NULL;

    if (csc) {
        if (NCFormat_from_spMatrix(&A, N, N, nnz, nzvals, colind, rowptr,
                                   type)) {
            Py_DECREF(Py_X);
            return NULL;
        }
    }
    else {
        if (NRFormat_from_spMatrix(&A, N, N, nnz, nzvals, colind, rowptr,
                                   type)) {
            Py_DECREF(Py_X);
            return NULL;
        }
    }
    
    if (DenseSuper_from_Numeric(&B, Py_X)) {
        Destroy_SuperMatrix_Store(&A);  
        Py_DECREF(Py_X);
        return NULL;
    }

    /* B and Py_X  share same data now but Py_X "owns" it */
    
    /* Setup options */
    
    if (setjmp(_superlu_py_jmpbuf)) {
        goto fail;
    }
    else {
        perm_c = intMalloc(N);
        perm_r = intMalloc(N);
        StatInit(&stat);

        /* Compute direct inverse of sparse Matrix */
        gssv(type, &options, &A, perm_c, perm_r, &L, &U, &B, &stat, &info);
    }
    ssv_finished = 1;

    SUPERLU_FREE(perm_r);
    SUPERLU_FREE(perm_c);
    Destroy_SuperMatrix_Store(&A);  /* holds just a pointer to the data */
    Destroy_SuperMatrix_Store(&B);
    Destroy_SuperNode_Matrix(&L);
    Destroy_CompCol_Matrix(&U);
    StatFree(&stat);
 
    return Py_BuildValue("Ni", Py_X, info);

fail:
    SUPERLU_FREE(perm_r);
    SUPERLU_FREE(perm_c);
    Destroy_SuperMatrix_Store(&A);  /* holds just a pointer to the data */
    Destroy_SuperMatrix_Store(&B);
    if (ssv_finished) {
        /* Avoid trying to free partially initialized matrices;
           might leak some memory, but avoids a crash */
        Destroy_SuperNode_Matrix(&L);
        Destroy_CompCol_Matrix(&U);
    }
    StatFree(&stat);  
    Py_XDECREF(Py_X);
    return NULL;
}
예제 #5
0
PyObject *newSuperLUObject(SuperMatrix * A, PyObject * option_dict,
                           int intype, int ilu)
{

    /* A must be in SLU_NC format used by the factorization routine. */
    SuperLUObject *self;
    SuperMatrix AC = { 0 };	/* Matrix postmultiplied by Pc */
    int lwork = 0;
    int *etree = NULL;
    int info;
    int n;
    superlu_options_t options;
    SuperLUStat_t stat = { 0 };
    int panel_size, relax;

    n = A->ncol;

    if (!set_superlu_options_from_dict(&options, ilu, option_dict,
				       &panel_size, &relax)) {
	return NULL;
    }

    /* Create SLUObject */
    self = PyObject_New(SuperLUObject, &SuperLUType);
    if (self == NULL)
	return PyErr_NoMemory();
    self->m = A->nrow;
    self->n = n;
    self->perm_r = NULL;
    self->perm_c = NULL;
    self->L.Store = NULL;
    self->U.Store = NULL;
    self->cached_U = NULL;
    self->cached_L = NULL;
    self->type = intype;

    if (setjmp(_superlu_py_jmpbuf))
	goto fail;

    /* Calculate and apply minimum degree ordering */
    etree = intMalloc(n);
    self->perm_r = intMalloc(n);
    self->perm_c = intMalloc(n);
    StatInit(&stat);

    get_perm_c(options.ColPerm, A, self->perm_c);	/* calc column permutation */
    sp_preorder(&options, A, self->perm_c, etree, &AC);	/* apply column
							 * permutation */

    /* Perform factorization */
    if (!CHECK_SLU_TYPE(SLU_TYPECODE_TO_NPY(A->Dtype))) {
	PyErr_SetString(PyExc_ValueError, "Invalid type in SuperMatrix.");
	goto fail;
    }
    if (ilu) {
	gsitrf(SLU_TYPECODE_TO_NPY(A->Dtype),
	       &options, &AC, relax, panel_size,
	       etree, NULL, lwork, self->perm_c, self->perm_r,
	       &self->L, &self->U, &stat, &info);
    }
    else {
	gstrf(SLU_TYPECODE_TO_NPY(A->Dtype),
	      &options, &AC, relax, panel_size,
	      etree, NULL, lwork, self->perm_c, self->perm_r,
	      &self->L, &self->U, &stat, &info);
    }

    if (info) {
	if (info < 0)
	    PyErr_SetString(PyExc_SystemError,
			    "gstrf was called with invalid arguments");
	else {
	    if (info <= n)
		PyErr_SetString(PyExc_RuntimeError,
				"Factor is exactly singular");
	    else
		PyErr_NoMemory();
	}
	goto fail;
    }

    /* free memory */
    SUPERLU_FREE(etree);
    Destroy_CompCol_Permuted(&AC);
    StatFree(&stat);

    return (PyObject *) self;

  fail:
    SUPERLU_FREE(etree);
    XDestroy_CompCol_Permuted(&AC);
    XStatFree(&stat);
    Py_DECREF(self);
    return NULL;
}
예제 #6
0
static PyObject *SuperLU_solve(SuperLUObject * self, PyObject * args,
			       PyObject * kwds)
{
    PyArrayObject *b, *x = NULL;
    SuperMatrix B = { 0 };
#ifndef NPY_PY3K
    char itrans = 'N';
#else
    int itrans = 'N';
#endif
    int info;
    trans_t trans;
    SuperLUStat_t stat = { 0 };

    static char *kwlist[] = { "rhs", "trans", NULL };

    if (!CHECK_SLU_TYPE(self->type)) {
	PyErr_SetString(PyExc_ValueError, "unsupported data type");
	return NULL;
    }

#ifndef NPY_PY3K
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|c", kwlist,
				     &PyArray_Type, &b, &itrans))
#else
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|C", kwlist,
				     &PyArray_Type, &b, &itrans))
#endif
	return NULL;

    /* solve transposed system: matrix was passed row-wise instead of
     * column-wise */
    if (itrans == 'n' || itrans == 'N')
	trans = NOTRANS;
    else if (itrans == 't' || itrans == 'T')
	trans = TRANS;
    else if (itrans == 'h' || itrans == 'H')
	trans = CONJ;
    else {
	PyErr_SetString(PyExc_ValueError, "trans must be N, T, or H");
	return NULL;
    }

    x = (PyArrayObject*)PyArray_FROMANY(
        (PyObject*)b, self->type, 1, 2,
        NPY_F_CONTIGUOUS | NPY_ENSURECOPY);
    if (x == NULL) {
        goto fail;
    }

    if (x->dimensions[0] != self->n) {
        PyErr_SetString(PyExc_ValueError, "b is of incompatible size");
	goto fail;
    }

    if (setjmp(_superlu_py_jmpbuf))
	goto fail;

    if (DenseSuper_from_Numeric(&B, (PyObject *)x))
	goto fail;

    StatInit(&stat);

    /* Solve the system, overwriting vector x. */
    gstrs(self->type,
	  trans, &self->L, &self->U, self->perm_c, self->perm_r, &B,
	  &stat, &info);

    if (info) {
	PyErr_SetString(PyExc_SystemError,
			"gstrs was called with invalid arguments");
	goto fail;
    }

    /* free memory */
    Destroy_SuperMatrix_Store(&B);
    StatFree(&stat);
    return (PyObject *) x;

  fail:
    XDestroy_SuperMatrix_Store(&B);
    XStatFree(&stat);
    Py_XDECREF(x);
    return NULL;
}