~ubuntu-branches/ubuntu/saucy/python-scipy/saucy

« back to all changes in this revision

Viewing changes to Lib/sandbox/pysparse/src/umfpackmodule.c

  • Committer: Bazaar Package Importer
  • Author(s): Ondrej Certik
  • Date: 2008-06-16 22:58:01 UTC
  • mfrom: (2.1.24 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080616225801-irdhrpcwiocfbcmt
Tags: 0.6.0-12
* The description updated to match the current SciPy (Closes: #489149).
* Standards-Version bumped to 3.8.0 (no action needed)
* Build-Depends: netcdf-dev changed to libnetcdf-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
This module provides an interface to the UMFPACK library. The
3
 
license of the UMFPACK library is available below.
4
 
 
5
 
UMFPACK Version 4.1 (Apr. 30, 2003),  Copyright (c) 2003 by Timothy A.
6
 
Davis.  All Rights Reserved.
7
 
 
8
 
UMFPACK License:
9
 
 
10
 
    Your use or distribution of UMFPACK or any modified version of
11
 
    UMFPACK implies that you agree to this License.
12
 
 
13
 
    THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
14
 
    EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
15
 
 
16
 
    Permission is hereby granted to use or copy this program, provided
17
 
    that the Copyright, this License, and the Availability of the original
18
 
    version is retained on all copies.  User documentation of any code that
19
 
    uses UMFPACK or any modified version of UMFPACK code must cite the
20
 
    Copyright, this License, the Availability note, and "Used by permission."
21
 
    Permission to modify the code and to distribute modified code is granted,
22
 
    provided the Copyright, this License, and the Availability note are
23
 
    retained, and a notice that the code was modified is included.  This
24
 
    software was developed with support from the National Science Foundation,
25
 
    and is provided to you free of charge.
26
 
 
27
 
Availability:
28
 
 
29
 
    http://www.cise.ufl.edu/research/sparse/umfpack
30
 
 
31
 
--------------------------------------------------------------------------------
32
 
 
33
 
AMD Version 1.0 (Apr. 30, 2003),  Copyright (c) 2003 by Timothy A.
34
 
Davis, Patrick R. Amestoy, and Iain S. Duff.  All Rights Reserved.
35
 
 
36
 
AMD License:
37
 
 
38
 
    Your use or distribution of AMD or any modified version of
39
 
    AMD implies that you agree to this License.
40
 
 
41
 
    THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
42
 
    EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
43
 
 
44
 
    Permission is hereby granted to use or copy this program, provided
45
 
    that the Copyright, this License, and the Availability of the original
46
 
    version is retained on all copies.  User documentation of any code that
47
 
    uses AMD or any modified version of AMD code must cite the
48
 
    Copyright, this License, the Availability note, and "Used by permission."
49
 
    Permission to modify the code and to distribute modified code is granted,
50
 
    provided the Copyright, this License, and the Availability note are
51
 
    retained, and a notice that the code was modified is included.  This
52
 
    software was developed with support from the National Science Foundation,
53
 
    and is provided to you free of charge.
54
 
 
55
 
Availability:
56
 
 
57
 
    http://www.cise.ufl.edu/research/sparse/amd
58
 
*/
59
 
#include <stdio.h>
60
 
#include <string.h>
61
 
#include "Python.h"
62
 
#define PY_ARRAY_UNIQUE_SYMBOL umfpack
63
 
#include "numpy/arrayobject.h"
64
 
#include "umfpack.h"
65
 
#include "pysparse/spmatrix.h"
66
 
 
67
 
/***********************************************************************
68
 
 * UMFPackObject definition
69
 
 */
70
 
 
71
 
typedef struct UMFPackObject {
72
 
  PyObject_VAR_HEAD
73
 
  int n;
74
 
  int nnz;
75
 
  double *val;          /* pointer to array of values */
76
 
  int *row;                     /* pointer to array of indices */
77
 
  int *ind;                     /* pointer to array of indices */
78
 
  void *Numeric;
79
 
  double *Control;
80
 
  double *Info;
81
 
} UMFPackObject;
82
 
 
83
 
/***********************************************************************
84
 
 * UMFPackObject methods
85
 
 */
86
 
 
87
 
static char getlists_doc[] = "";
88
 
 
89
 
static PyObject *
90
 
UMFPack_getlists(UMFPackObject *self, PyObject *args) {
91
 
  PyObject *ind=NULL, *row=NULL, *val=NULL, *tupleret=NULL;
92
 
  int i;
93
 
 
94
 
  if (!PyArg_ParseTuple(args, ""))
95
 
    return NULL;
96
 
 
97
 
  ind = PyList_New(self->n+1);
98
 
  if (ind == NULL)
99
 
    goto failmemory;
100
 
 
101
 
  PyList_SetItem(ind, 0, Py_BuildValue("i", 0));
102
 
  for (i=1; i < (self->n + 1); i++) {
103
 
    PyList_SetItem(ind, i, Py_BuildValue("i", self->ind[i] ));
104
 
  }
105
 
 
106
 
  row = PyList_New(self->nnz);
107
 
  if (row == NULL)
108
 
    goto failmemory;
109
 
 
110
 
  for (i=0; i < self->nnz; i++) {
111
 
    PyList_SetItem(row, i, Py_BuildValue("i", self->row[i]));
112
 
  }
113
 
 
114
 
  val = PyList_New(self->nnz);
115
 
  if (val == NULL)
116
 
    goto failmemory;
117
 
 
118
 
  for (i=0; i < self->nnz; i++) {
119
 
    PyList_SetItem(val, i, Py_BuildValue("d", self->val[i]));
120
 
  }
121
 
 
122
 
  tupleret = PyTuple_New(3);
123
 
  if (tupleret == NULL)
124
 
    goto failmemory;
125
 
 
126
 
  PyTuple_SetItem(tupleret, 0, ind);
127
 
  PyTuple_SetItem(tupleret, 1, row);
128
 
  PyTuple_SetItem(tupleret, 2, val);
129
 
 
130
 
  return tupleret;
131
 
 
132
 
  failmemory:
133
 
    if (ind != NULL)
134
 
      PyObject_Del(ind);
135
 
    if (row != NULL)
136
 
      PyObject_Del(row);
137
 
    if (val != NULL)
138
 
      PyObject_Del(val);
139
 
    if (tupleret != NULL)
140
 
      PyObject_Del(tupleret);
141
 
    return PyErr_NoMemory();
142
 
}
143
 
 
144
 
static char solve_doc[] = "self.solve(b, x, systype)\n\
145
 
\n\
146
 
solves linear system of equations.\n\
147
 
\n\
148
 
parameters\n\
149
 
----------\n\
150
 
\n\
151
 
b        array, right hand side of equation\n\
152
 
x        array, solution vector\n\
153
 
systype  'UMFPACK_A': solve A   * x == b\n\
154
 
         'UMFPACK_At': solve A^T * x == b\n\
155
 
         'UMFPACK_Pt_L': solve P^T * L * x == b\n\
156
 
         'UMFPACK_L': solve L * x == b\n\
157
 
         'UMFPACK_Lt_P': solve L^T * P * x == b\n\
158
 
         'UMFPACK_Lt': solve L^T * x == b\n\
159
 
         'UMFPACK_U_Qt': solve U * Q^T * x == b\n\
160
 
         'UMFPACK_U': solve U * x == b\n\
161
 
         'UMFPACK_Q_Ut': solve Q * U^T * x == b\n\
162
 
         'UMFPACK_Ut': solve U^T * x == b\n\
163
 
";
164
 
 
165
 
static PyObject *
166
 
UMFPack_solve(UMFPackObject *self, PyObject *args) {
167
 
  PyArrayObject *b, *x;
168
 
  char *systype = "UMFPACK_A";
169
 
  int sys, status;
170
 
 
171
 
  if (!PyArg_ParseTuple(args, "O!O!|s",
172
 
                        &PyArray_Type, &b,
173
 
                        &PyArray_Type, &x,
174
 
                        &systype))
175
 
    return NULL;
176
 
 
177
 
  SPMATRIX_CHECK_ARR_DIM_SIZE(b, 1, self->n);
178
 
  SPMATRIX_CHECK_ARR_DIM_SIZE(x, 1, self->n);
179
 
 
180
 
  if (strcmp(systype, "UMFPACK_A") == 0)
181
 
      sys = UMFPACK_A;
182
 
  else if (strcmp(systype, "UMFPACK_At") == 0)
183
 
      sys = UMFPACK_At;
184
 
  else if (strcmp(systype, "UMFPACK_Pt_L") == 0)
185
 
      sys = UMFPACK_Pt_L;
186
 
  else if (strcmp(systype, "UMFPACK_L") == 0)
187
 
      sys = UMFPACK_L;
188
 
  else if (strcmp(systype, "UMFPACK_Lt_P") == 0)
189
 
      sys = UMFPACK_Lt_P;
190
 
  else if (strcmp(systype, "UMFPACK_Lt") == 0)
191
 
      sys = UMFPACK_Lt;
192
 
  else if (strcmp(systype, "UMFPACK_U_Qt") == 0)
193
 
      sys = UMFPACK_U_Qt;
194
 
  else if (strcmp(systype, "UMFPACK_U") == 0)
195
 
      sys = UMFPACK_U;
196
 
  else if (strcmp(systype, "UMFPACK_Q_Ut") == 0)
197
 
      sys = UMFPACK_Q_Ut;
198
 
  else if (strcmp(systype, "UMFPACK_Ut") == 0)
199
 
      sys = UMFPACK_Ut;
200
 
  else {
201
 
      PyErr_SetString(PyExc_ValueError, "systype");
202
 
      return NULL;
203
 
  }
204
 
 
205
 
  status = umfpack_di_solve(sys, self->ind, self->row, self->val,
206
 
                             (double *)x->data, (double *)b->data, self->Numeric,
207
 
                             self->Control, self->Info);
208
 
 
209
 
  switch(status) {
210
 
    case UMFPACK_WARNING_singular_matrix:
211
 
      PyErr_SetString(PyExc_SystemError, "singular matrix");
212
 
      return NULL;
213
 
    case UMFPACK_ERROR_out_of_memory:
214
 
      PyErr_SetString(PyExc_SystemError, "insufficient memory");
215
 
      return NULL;
216
 
    case UMFPACK_ERROR_argument_missing:
217
 
      PyErr_SetString(PyExc_SystemError, "one or more argument missing");
218
 
      return NULL;
219
 
    case UMFPACK_ERROR_invalid_system:
220
 
      PyErr_SetString(PyExc_SystemError, "matrix is not square");
221
 
      return NULL;
222
 
    case UMFPACK_ERROR_invalid_Numeric_object:
223
 
      PyErr_SetString(PyExc_SystemError, "invalid Numeric object");
224
 
      return NULL;
225
 
  }
226
 
 
227
 
  Py_INCREF(Py_None);
228
 
  return Py_None;
229
 
}
230
 
 
231
 
/** table of object methods
232
 
 */
233
 
PyMethodDef UMFPack_methods[] = {
234
 
  {"solve", (PyCFunction)UMFPack_solve, METH_VARARGS, solve_doc},
235
 
  {"getlists", (PyCFunction)UMFPack_getlists, METH_VARARGS, getlists_doc},
236
 
  {NULL, NULL}                  /* sentinel */
237
 
};
238
 
 
239
 
 
240
 
/***********************************************************************
241
 
 * UMFPackType methods
242
 
 */
243
 
 
244
 
static void
245
 
UMFPack_dealloc(UMFPackObject *self)
246
 
{
247
 
  umfpack_di_free_numeric(&(self->Numeric));
248
 
  PyMem_Free(self->val);
249
 
  PyMem_Free(self->row);
250
 
  PyMem_Free(self->ind);
251
 
  PyMem_Free(self->Control);
252
 
  PyMem_Free(self->Info);
253
 
  PyObject_Del(self);
254
 
}
255
 
 
256
 
static PyObject *
257
 
UMFPack_getattr(UMFPackObject *self, char *name)
258
 
{
259
 
  if (strcmp(name, "shape") == 0)
260
 
    return Py_BuildValue("(i,i)", self->n, self->n);
261
 
  if (strcmp(name, "nnz") == 0)
262
 
    return Py_BuildValue("i", self->nnz);
263
 
  if (strcmp(name, "__members__") == 0) {
264
 
    char *members[] = {"shape", "nnz"};
265
 
    int i;
266
 
 
267
 
    PyObject *list = PyList_New(sizeof(members)/sizeof(char *));
268
 
    if (list != NULL) {
269
 
      for (i = 0; i < sizeof(members)/sizeof(char *); i ++)
270
 
        PyList_SetItem(list, i, PyString_FromString(members[i]));
271
 
      if (PyErr_Occurred()) {
272
 
        Py_DECREF(list);
273
 
        list = NULL;
274
 
      }
275
 
    }
276
 
    return list;
277
 
  }
278
 
  return Py_FindMethod(UMFPack_methods, (PyObject *)self, name);
279
 
}
280
 
 
281
 
 
282
 
/***********************************************************************
283
 
 * UMFPackType structure
284
 
 */
285
 
 
286
 
PyTypeObject UMFPackType = {
287
 
  PyObject_HEAD_INIT(NULL)
288
 
  0,
289
 
  "umfpack_context",
290
 
  sizeof(UMFPackObject),
291
 
  0,
292
 
  (destructor)UMFPack_dealloc,   /* tp_dealloc */
293
 
  0,                            /* tp_print */
294
 
  (getattrfunc)UMFPack_getattr,  /* tp_getattr */
295
 
  0,                            /* tp_setattr */
296
 
  0,                            /* tp_compare */
297
 
  0,                            /* tp_repr */
298
 
  0,                            /* tp_as_number*/
299
 
  0,                            /* tp_as_sequence*/
300
 
  0,                            /* tp_as_mapping*/
301
 
  0,                            /* tp_hash */
302
 
};
303
 
 
304
 
/***********************************************************************
305
 
 * Object construction functions
306
 
 */
307
 
 
308
 
/***********************************************************************
309
 
 * Module functions
310
 
 */
311
 
 
312
 
static void sortcol(int *row, double *val, int n)
313
 
{
314
 
  int i, j, tmpint;
315
 
  double tmpdbl;
316
 
 
317
 
  for (i=n-1; i > 0; i--) {
318
 
 
319
 
    for (j=0; j < i; j++) {
320
 
      if (row[j] > row[j+1]) {
321
 
 
322
 
        /* swap row indices */
323
 
        tmpint = row[j+1];
324
 
        row[j+1] = row[j];
325
 
        row[j] = tmpint;
326
 
        
327
 
        /* swap values */
328
 
        tmpdbl = val[j+1];
329
 
        val[j+1] = val[j];
330
 
        val[j] = tmpdbl;
331
 
 
332
 
      }
333
 
    }
334
 
  }
335
 
 
336
 
  return;
337
 
}
338
 
 
339
 
static PyObject *
340
 
newUMFPackObject(LLMatObject *matrix, int strategy, double tol2by2, int scale,
341
 
                  double tolpivot, double tolsympivot, int irstep)
342
 
{
343
 
  UMFPackObject *self;
344
 
  void *Symbolic;
345
 
  struct llColIndex *colidx;
346
 
  int i, validx, curridx, status;
347
 
 
348
 
  if (SpMatrix_LLMatBuildColIndex(&colidx, matrix, 1) == 1)
349
 
    return NULL;
350
 
 
351
 
  self = PyObject_New(UMFPackObject, &UMFPackType);
352
 
  if (self == NULL)
353
 
    return PyErr_NoMemory();
354
 
 
355
 
  /* initialize pointers to arrays */
356
 
  self->val = NULL;
357
 
  self->row = NULL;
358
 
  self->ind = NULL;
359
 
  self->Control = NULL;
360
 
  self->Info = NULL;
361
 
  self->Numeric = NULL;
362
 
 
363
 
  self->n = matrix->dim[0];
364
 
  if (matrix->issym)
365
 
    self->nnz = 2 * colidx->nzLo + colidx->nzDiag + 2 * colidx->nzUp;
366
 
  else
367
 
    self->nnz = matrix->nnz;
368
 
 
369
 
  self->val = (double *)PyMem_Malloc(self->nnz * sizeof(double));
370
 
  if (self->val == NULL)
371
 
    goto failmemory;
372
 
 
373
 
  self->row = (int *)PyMem_Malloc(self->nnz * sizeof(int));
374
 
  if (self->row == NULL) {
375
 
    goto failmemory;
376
 
  }
377
 
  self->ind = (int *)PyMem_Malloc((self->n + 1) * sizeof(int) );
378
 
  if (self->ind == NULL) {
379
 
    goto failmemory;
380
 
  }
381
 
  self->ind[self->n] = self->nnz;
382
 
 
383
 
  self->Control = (double *)PyMem_Malloc(UMFPACK_CONTROL * sizeof(double));
384
 
  if (self->Control == NULL) {
385
 
    goto failmemory;
386
 
  }
387
 
 
388
 
  umfpack_di_defaults(self->Control);
389
 
 
390
 
  if (strategy != -1)
391
 
    self->Control[UMFPACK_STRATEGY] = strategy;
392
 
 
393
 
  if (tol2by2 != -1)
394
 
    self->Control[UMFPACK_2BY2_TOLERANCE] = tol2by2;
395
 
 
396
 
  if (scale != -1)
397
 
    self->Control[UMFPACK_SCALE] = scale;
398
 
 
399
 
  if (tolpivot != -1)
400
 
    self->Control[UMFPACK_PIVOT_TOLERANCE] = tolpivot;
401
 
 
402
 
  if (tolsympivot != -1)
403
 
    self->Control[UMFPACK_SYM_PIVOT_TOLERANCE] = tolsympivot;
404
 
 
405
 
  if (irstep != -1)
406
 
    self->Control[UMFPACK_IRSTEP] = irstep;
407
 
 
408
 
  self->Info = (double *)PyMem_Malloc(UMFPACK_INFO * sizeof(double));
409
 
  if (self->Info == NULL) {
410
 
    goto failmemory;
411
 
  }
412
 
 
413
 
  validx = 0;
414
 
  for (i=0; i < self->n; i++) {
415
 
    self->ind[i] = validx;
416
 
    for (curridx=colidx->root[i]; curridx != -1; curridx = colidx->link[curridx]) {
417
 
      self->val[validx] = matrix->val[curridx];
418
 
      self->row[validx++] = colidx->row[curridx];
419
 
    }
420
 
 
421
 
    if (matrix->issym) {
422
 
      for (curridx=matrix->root[i]; curridx != -1; curridx = matrix->link[curridx]) {
423
 
        if (i != matrix->col[curridx]) {
424
 
          self->val[validx] = matrix->val[curridx];
425
 
          self->row[validx++] = matrix->col[curridx];
426
 
        }
427
 
      }
428
 
    }
429
 
 
430
 
    sortcol(&(self->row[self->ind[i]]), &(self->val[self->ind[i]]), validx - self->ind[i]);
431
 
  }
432
 
 
433
 
  status = umfpack_di_symbolic(self->n, self->n, self->ind, self->row, self->val, &Symbolic, self->Control, self->Info);
434
 
 
435
 
  switch(status) {
436
 
    case UMFPACK_ERROR_n_nonpositive:
437
 
      PyErr_SetString(PyExc_SystemError, "n must be positive");
438
 
      return NULL;
439
 
    case UMFPACK_ERROR_out_of_memory:
440
 
      PyErr_SetString(PyExc_SystemError, "insufficient memory");
441
 
      return NULL;
442
 
    case UMFPACK_ERROR_argument_missing:
443
 
      PyErr_SetString(PyExc_SystemError, "one or more argument missing");
444
 
      return NULL;
445
 
    case UMFPACK_ERROR_invalid_matrix:
446
 
      PyErr_SetString(PyExc_SystemError, "invalid matrix");
447
 
      return NULL;
448
 
    case UMFPACK_ERROR_internal_error:
449
 
      PyErr_SetString(PyExc_SystemError, "bug in umfpack");
450
 
      return NULL;
451
 
  }
452
 
 
453
 
  status = umfpack_di_numeric(self->ind, self->row, self->val, Symbolic, &(self->Numeric), self->Control, self->Info);
454
 
 
455
 
  switch(status) {
456
 
 
457
 
    case UMFPACK_WARNING_singular_matrix:
458
 
      PyErr_SetString(PyExc_SystemError, "singular matrix");
459
 
      return NULL;
460
 
    case UMFPACK_ERROR_out_of_memory:
461
 
      PyErr_SetString(PyExc_SystemError, "insufficient memory");
462
 
      return NULL;
463
 
    case UMFPACK_ERROR_argument_missing:
464
 
      PyErr_SetString(PyExc_SystemError, "one or more argument missing");
465
 
      return NULL;
466
 
    case UMFPACK_ERROR_invalid_Symbolic_object:
467
 
      PyErr_SetString(PyExc_SystemError, "invalid symbolic object");
468
 
      return NULL;
469
 
    case UMFPACK_ERROR_different_pattern:
470
 
      PyErr_SetString(PyExc_SystemError, "matrix has changed since last factorization");
471
 
      return NULL;
472
 
  }
473
 
 
474
 
  umfpack_di_free_symbolic(&Symbolic);
475
 
 
476
 
  return self;
477
 
 
478
 
  failmemory:
479
 
    SpMatrix_LLMatDestroyColIndex(&colidx);
480
 
    if (self->val != NULL)
481
 
      PyMem_Free(self->val);
482
 
    if (self->row != NULL)
483
 
      PyMem_Free(self->row);
484
 
    if (self->ind != NULL)
485
 
      PyMem_Free(self->ind);
486
 
    if (self->Control != NULL)
487
 
      PyMem_Free(self->Control);
488
 
    if (self->Info != NULL)
489
 
      PyMem_Free(self->Info);
490
 
    PyObject_Del(self);
491
 
    return PyErr_NoMemory();
492
 
 
493
 
}
494
 
 
495
 
static char factorize_doc[] = "factorize(A, ...)\n\
496
 
\n\
497
 
performs a factorization of the sparse matrix A (which is a ll_mat object) and \n\
498
 
return a umfpack_context object.\n\
499
 
\n\
500
 
arguments\n\
501
 
---------\n\
502
 
\n\
503
 
A    spmatrix.ll_mat object.\n\
504
 
     Matrix to be factorized\n\
505
 
\n\
506
 
additional keyword arguments:\n\
507
 
-----------------------------\n\
508
 
\n\
509
 
strategy            determines what kind of ordering and\n\
510
 
                    pivoting strategy that UMFPACK should use.\n\
511
 
                    \"UMFPACK_STRATEGY_AUTO\"\n\
512
 
                    \"UMFPACK_STRATEGY_UNSYMMETRIC\"\n\
513
 
                    \"UMFPACK_STRATEGY_SYMMETRIC\"\n\
514
 
                    \"UMFPACK_STRATEGY_2BY2\"\n\
515
 
\n\
516
 
tol2by2             tolerance for the 2 by 2 strategy\n\
517
 
\n\
518
 
scale               scaling UMFPACK would use\n\
519
 
                    \"UMFPACK_SCALE_NONE\"\n\
520
 
                    \"UMFPACK_SCALE_SUM\"\n\
521
 
                    \"UMFPACK_SCALE_MAX\"\n\
522
 
\n\
523
 
tolpivot            relative pivot tolerance for threshold partial\n\
524
 
                    pivoting with row interchanges.\n\
525
 
\n\
526
 
tolsympivot         if diagonal pivoting is attempted then this\n\
527
 
                    parameter is used to control when the diagonal\n\
528
 
                    is selected in a given pivot column.\n\
529
 
\n\
530
 
irstep              number of iterative refinement steps to attempt.\
531
 
";
532
 
 
533
 
static PyObject *
534
 
factorize(PyObject *self, PyObject *args, PyObject *keywds) {
535
 
  LLMatObject *matrix;
536
 
  char *strategy="UMFPACK_STRATEGY_AUTO";
537
 
  double tol2by2 = 0.1;
538
 
  char *scale="UMFPACK_SCALE_SUM";
539
 
  double tolpivot = 0.1;
540
 
  double tolsympivot = 0.0;
541
 
  int irstep = 2;
542
 
  int res;
543
 
  int strategyval, scaleval;
544
 
 
545
 
  static char *kwlist[] = {"", "strategy", "tol2by2", "scale", "tolpivot", "tolsympivot", "irstep", NULL};
546
 
 
547
 
  res = PyArg_ParseTupleAndKeywords(args, keywds, "O!|sdsddi", kwlist, 
548
 
                                        &LLMatType, &matrix,
549
 
                                        &strategy,
550
 
                                        &tol2by2,
551
 
                                        &scale,
552
 
                                        &tolpivot,
553
 
                                        &tolsympivot,
554
 
                              &irstep);
555
 
  if (!res)
556
 
    return NULL;
557
 
 
558
 
  if (strcmp("UMFPACK_STRATEGY_AUTO", strategy) == 0)
559
 
    strategyval = UMFPACK_STRATEGY_AUTO;
560
 
  else if (strcmp("UMFPACK_STRATEGY_UNSYMMETRIC", strategy) == 0)
561
 
    strategyval = UMFPACK_STRATEGY_UNSYMMETRIC;
562
 
  else if (strcmp("UMFPACK_STRATEGY_SYMMETRIC", strategy) == 0)
563
 
    strategyval = UMFPACK_STRATEGY_SYMMETRIC;
564
 
  else if (strcmp("UMFPACK_STRATEGY_2BY2", strategy) == 0)
565
 
    strategyval = UMFPACK_STRATEGY_2BY2;
566
 
 
567
 
  if (strcmp("UMFPACK_SCALE_NONE", scale) == 0)
568
 
    scaleval = UMFPACK_SCALE_NONE;
569
 
  else if (strcmp("UMFPACK_SCALE_SUM", scale) == 0)
570
 
    scaleval = UMFPACK_SCALE_SUM;
571
 
  if (strcmp("UMFPACK_SCALE_MAX", scale) == 0)
572
 
    scaleval = UMFPACK_SCALE_MAX;
573
 
 
574
 
  return newUMFPackObject(matrix, strategyval, tol2by2, scaleval, tolpivot, tolsympivot, irstep);
575
 
}
576
 
 
577
 
 
578
 
/** table of module functions
579
 
 */
580
 
static PyMethodDef precon_methods[] = {
581
 
  {"factorize", (PyCFunction)factorize, METH_VARARGS|METH_KEYWORDS, factorize_doc},
582
 
  {NULL, NULL}  /* sentinel */
583
 
};
584
 
 
585
 
 
586
 
PyMODINIT_FUNC
587
 
initumfpack(void)
588
 
{
589
 
  PyObject *m, *d;
590
 
  
591
 
  UMFPackType.ob_type = &PyType_Type;
592
 
 
593
 
  m = Py_InitModule("umfpack", precon_methods);
594
 
  d = PyModule_GetDict(m);
595
 
 
596
 
  PyDict_SetItemString(d, "UMFPackType", (PyObject *)&UMFPackType);
597
 
 
598
 
  /* initialize Numeric array module */
599
 
  import_array();
600
 
  /* initialize spmatrix module */
601
 
  import_spmatrix();
602
 
 
603
 
  /* No need to check the error here, the caller will do that */
604
 
}