├── .gitignore ├── scikits ├── __init__.py └── umfpack │ ├── __init__.py │ ├── setup.py │ ├── info.py │ ├── umfpack.i │ ├── _umfpack.py │ └── umfpack.py ├── site-macports.cfg ├── site.cfg.example ├── README ├── setup.py └── tests ├── test_umfpack.py └── try_umfpack.py /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.pyc 3 | -------------------------------------------------------------------------------- /scikits/__init__.py: -------------------------------------------------------------------------------- 1 | __import__('pkg_resources').declare_namespace(__name__) 2 | -------------------------------------------------------------------------------- /scikits/umfpack/__init__.py: -------------------------------------------------------------------------------- 1 | from scikits.umfpack.info import __doc__ 2 | 3 | from scikits.umfpack.umfpack import * 4 | 5 | __all__ = list(filter(lambda s:not s.startswith('_'),dir())) 6 | 7 | -------------------------------------------------------------------------------- /site-macports.cfg: -------------------------------------------------------------------------------- 1 | [umfpack] 2 | include_dirs = /opt/local/include 3 | library_dirs = /opt/local/lib 4 | umfpack_libs = umfpack 5 | 6 | [amd] 7 | include_dirs = /opt/local/include 8 | library_dirs = /opt/local/lib 9 | amd_libs = amd 10 | 11 | -------------------------------------------------------------------------------- /site.cfg.example: -------------------------------------------------------------------------------- 1 | [umfpack] 2 | include_dirs = /Users/stefan/src/UMFPACK/Include 3 | library_dirs = /Users/stefan/src/UMFPACK/Lib 4 | umfpack_libs = umfpack 5 | 6 | [amd] 7 | include_dirs = /Users/stefan/src/AMD/Include 8 | library_dirs = /Users/stefan/src/AMD/Lib 9 | amd_libs = amd 10 | 11 | -------------------------------------------------------------------------------- /scikits/umfpack/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | def configuration(parent_package='',top_path=None): 4 | import numpy 5 | from numpy.distutils.misc_util import Configuration 6 | from numpy.distutils.system_info import get_info, dict_append 7 | 8 | config = Configuration( 'umfpack', parent_package, top_path ) 9 | config.add_data_dir('tests') 10 | 11 | umf_info = get_info( 'umfpack', notfound_action=2) 12 | 13 | umfpack_i_file = config.paths('umfpack.i')[0] 14 | def umfpack_i(ext, build_dir): 15 | if umf_info: 16 | return umfpack_i_file 17 | 18 | blas_info = get_info('blas_opt') 19 | build_info = {} 20 | dict_append(build_info, **umf_info) 21 | dict_append(build_info, **blas_info) 22 | 23 | config.add_extension( '__umfpack', 24 | sources = [umfpack_i], 25 | depends = ['umfpack.i'], 26 | **build_info) 27 | 28 | return config 29 | 30 | if __name__ == "__main__": 31 | from numpy.distutils.core import setup 32 | setup(**configuration(top_path='').todict()) 33 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | The umfpack scikit provides wrappers of UMFPACK sparse direct solver to SciPy. 2 | 3 | It should work both with the latest SVN, and the last releases versions of 4 | NumPy and SciPy. 5 | 6 | Installation on OSX 7 | =================== 8 | - Download UMFPACK, UFconfig and AMD from 9 | http://www.cise.ufl.edu/research/sparse/umfpack/ 10 | 11 | - Unpack the archives in the same directory, so that you have 12 | src/AMD 13 | /UFconfig 14 | /UMFPACK 15 | 16 | - Edit src/UFconfig/UFconfig.mk and remove -lgfortranbegin and -lg2c from 17 | BLAS:: 18 | 19 | BLAS = -lblas -lgfortran #-lgfortranbegin -lg2c 20 | 21 | - Go into src/UMFPACK and run "make" 22 | 23 | - Copy src/UFconfig/UFconfig.h to src/UMFPACK/Includes 24 | 25 | - Create a site.cfg in this directory (the root of the scikit), with:: 26 | 27 | umfpack] 28 | include_dirs = /Users/stefan/src/UMFPACK/Include 29 | library_dirs = /Users/stefan/src/UMFPACK/Lib 30 | umfpack_libs = umfpack 31 | 32 | [amd] 33 | include_dirs = /Users/stefan/src/AMD/Include 34 | library_dirs = /Users/stefan/src/AMD/Lib 35 | amd_libs = amd 36 | 37 | - Compile and install the scikit, using 38 | 39 | :: 40 | 41 | python setup.py install 42 | 43 | or 44 | 45 | python setup.py install --prefix=${HOME} # for local install 46 | 47 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | subpackage = 'umfpack' 4 | version = '5.2.0' 5 | 6 | def configuration(parent_package = '', top_path = None): 7 | from numpy.distutils.misc_util import Configuration 8 | from numpy.distutils.system_info import get_info, dict_append 9 | 10 | config = Configuration( None, parent_package, top_path, 11 | namespace_packages = ['scikits'] ) 12 | config.set_options( 13 | ignore_setup_xxx_py = True, 14 | assume_default_configuration = True, 15 | delegate_options_to_subpackages = True, 16 | quiet = True, 17 | ) 18 | 19 | config.add_subpackage('scikits.umfpack') 20 | config.add_data_files('scikits/__init__.py') 21 | 22 | return config 23 | 24 | def setup_package(): 25 | 26 | from numpy.distutils.core import setup 27 | 28 | setup( 29 | name = 'scikits.' + subpackage, 30 | version = version, 31 | author = "Robert Cimrman", 32 | maintainer = "Paul Nation", 33 | maintainer_email = "nonhermitian@gmail.com", 34 | description = "Python interface to the UMFPACK sparse linear solver.", 35 | url = "http://www.scipy.org", 36 | license = 'BSD', 37 | configuration = configuration, 38 | install_requires = [ 39 | 'numpy', 40 | 'scipy', 41 | ], 42 | ) 43 | return 44 | 45 | if __name__ == '__main__': 46 | setup_package() 47 | -------------------------------------------------------------------------------- /scikits/umfpack/info.py: -------------------------------------------------------------------------------- 1 | """ 2 | :Interface to the UMFPACK library: 3 | ================================== 4 | 5 | :Contains: UmfpackContext class 6 | 7 | :Description: 8 | ------------- 9 | Routines for symbolic and numeric LU factorization of sparse 10 | matrices and for solving systems of linear equations with sparse matrices. 11 | 12 | Tested with UMFPACK V4.4 (Jan. 28, 2005), V5.0 (May 5, 2006) 13 | Copyright (c) 2005 by Timothy A. Davis. All Rights Reserved. 14 | UMFPACK homepage: http://www.cise.ufl.edu/research/sparse/umfpack 15 | 16 | Use 'print UmfpackContext().funs' to see all UMFPACK library functions the 17 | module exposes, if you need something not covered by the examples below. 18 | 19 | :Installation: 20 | -------------- 21 | 22 | Example site.cfg entry: 23 | 24 | 25 | UMFPACK v4.4 in : 26 | 27 | [amd] 28 | library_dirs = /UMFPACK/AMD/Lib 29 | include_dirs = /UMFPACK/AMD/Include 30 | amd_libs = amd 31 | 32 | [umfpack] 33 | library_dirs = /UMFPACK/UMFPACK/Lib 34 | include_dirs = /UMFPACK/UMFPACK/Include 35 | umfpack_libs = umfpack 36 | 37 | UMFPACK v5.0 (as part of UFsparse package) in : 38 | 39 | [amd] 40 | library_dirs = /UFsparse/AMD/Lib 41 | include_dirs = /UFsparse/AMD/Include, /UFsparse/UFconfig 42 | amd_libs = amd 43 | 44 | [umfpack] 45 | library_dirs = /UFsparse/UMFPACK/Lib 46 | include_dirs = /UFsparse/UMFPACK/Include, /UFsparse/UFconfig 47 | umfpack_libs = umfpack 48 | 49 | 50 | :Examples: 51 | ---------- 52 | 53 | Assuming this module imported as um (import scipy.linsolve.umfpack as um) 54 | 55 | Sparse matrix in CSR or CSC format: mtx 56 | Righthand-side: rhs 57 | Solution: sol 58 | 59 | 60 | # Contruct the solver. 61 | umfpack = um.UmfpackContext() # Use default 'di' family of UMFPACK routines. 62 | 63 | # One-shot solution. 64 | sol = umfpack( um.UMFPACK_A, mtx, rhs, autoTranspose = True ) 65 | # same as: 66 | sol = umfpack.linsolve( um.UMFPACK_A, mtx, rhs, autoTranspose = True ) 67 | 68 | 69 | -or- 70 | 71 | 72 | # Make LU decomposition. 73 | umfpack.numeric( mtx ) 74 | ... 75 | # Use already LU-decomposed matrix. 76 | sol1 = umfpack( um.UMFPACK_A, mtx, rhs1, autoTranspose = True ) 77 | sol2 = umfpack( um.UMFPACK_A, mtx, rhs2, autoTranspose = True ) 78 | # same as: 79 | sol1 = umfpack.solve( um.UMFPACK_A, mtx, rhs1, autoTranspose = True ) 80 | sol2 = umfpack.solve( um.UMFPACK_A, mtx, rhs2, autoTranspose = True ) 81 | 82 | 83 | -or- 84 | 85 | 86 | # Make symbolic decomposition. 87 | umfpack.symbolic( mtx0 ) 88 | # Print statistics. 89 | umfpack.report_symbolic() 90 | 91 | # ... 92 | 93 | # Make LU decomposition of mtx1 which has same structure as mtx0. 94 | umfpack.numeric( mtx1 ) 95 | # Print statistics. 96 | umfpack.report_numeric() 97 | 98 | # Use already LU-decomposed matrix. 99 | sol1 = umfpack( um.UMFPACK_A, mtx1, rhs1, autoTranspose = True ) 100 | 101 | # ... 102 | 103 | # Make LU decomposition of mtx2 which has same structure as mtx0. 104 | umfpack.numeric( mtx2 ) 105 | sol2 = umfpack.solve( um.UMFPACK_A, mtx2, rhs2, autoTranspose = True ) 106 | 107 | # Print all statistics. 108 | umfpack.report_info() 109 | 110 | 111 | -or- 112 | 113 | 114 | # Get LU factors and permutation matrices of a matrix. 115 | L, U, P, Q, R, do_recip = umfpack.lu( mtx ) 116 | 117 | 118 | :Returns: 119 | - `L` : Lower triangular m-by-min(m,n) CSR matrix 120 | - `U` : Upper triangular min(m,n)-by-n CSC matrix 121 | - `P` : Vector of row permuations 122 | - `Q` : Vector of column permuations 123 | - `R` : Vector of diagonal row scalings 124 | - `do_recip` : boolean 125 | 126 | :Note: 127 | For a given matrix A, the decomposition satisfies: 128 | $LU = PRAQ$ when do_recip is true, 129 | $LU = P(R^{-1})AQ$ when do_recip is false 130 | 131 | :UmfpackContext solution methods: 132 | --------------------------------- 133 | 134 | umfpack(), umfpack.linsolve(), umfpack.solve() 135 | 136 | :Parameters: 137 | - `sys` : constant, 138 | one of UMFPACK system description constants, like 139 | UMFPACK_A, UMFPACK_At, see umfSys list and UMFPACK docs 140 | - `mtx` : sparse matrix (CSR or CSC) 141 | - `rhs` : right hand side vector 142 | - `autoTranspose` : bool 143 | automatically changes 'sys' to the transposed type, if 'mtx' is in CSR, 144 | since UMFPACK assumes CSC internally 145 | 146 | :Setting control parameters: 147 | ---------------------------- 148 | 149 | Assuming this module imported as um: 150 | 151 | List of control parameter names is accessible as 'um.umfControls' - their 152 | meaning and possible values are described in the UMFPACK documentation. 153 | To each name corresponds an attribute of the 'um' module, such as, 154 | for example 'um.UMFPACK_PRL' (controlling the verbosity of umfpack report 155 | functions). These attributes are in fact indices into the control array 156 | - to set the corresponding control array value, just do the following: 157 | 158 | 159 | umfpack = um.UmfpackContext() 160 | umfpack.control[um.UMFPACK_PRL] = 4 # Let's be more verbose. 161 | 162 | 163 | -- 164 | :Author: Robert Cimrman 165 | :Other contributors: Nathan Bell (lu() method wrappers) 166 | :License: BSD-style license. See LICENSE.txt in the scipy source directory. 167 | """ 168 | 169 | postpone_import = 1 170 | global_symbols = ['UmfpackContext'] 171 | -------------------------------------------------------------------------------- /scikits/umfpack/umfpack.i: -------------------------------------------------------------------------------- 1 | /* -*- C -*- */ 2 | #ifdef SWIGPYTHON 3 | 4 | %module _umfpack 5 | 6 | /* 7 | See umfpack.py for more information. 8 | 9 | Created by: Robert Cimrman 10 | */ 11 | 12 | %{ 13 | #include 14 | #include "numpy/arrayobject.h" 15 | %} 16 | 17 | %feature("autodoc", "1"); 18 | 19 | #include 20 | 21 | %init %{ 22 | import_array(); 23 | %} 24 | 25 | %{ 26 | /*! 27 | Appends @a what to @a where. On input, @a where need not to be a tuple, but on 28 | return it always is. 29 | 30 | @par Revision history: 31 | - 17.02.2005, c 32 | */ 33 | PyObject *helper_appendToTuple( PyObject *where, PyObject *what ) { 34 | PyObject *o2, *o3; 35 | 36 | if ((!where) || (where == Py_None)) { 37 | where = what; 38 | } else { 39 | if (!PyTuple_Check( where )) { 40 | o2 = where; 41 | where = PyTuple_New( 1 ); 42 | PyTuple_SetItem( where, 0, o2 ); 43 | } 44 | o3 = PyTuple_New( 1 ); 45 | PyTuple_SetItem( o3, 0, what ); 46 | o2 = where; 47 | where = PySequence_Concat( o2, o3 ); 48 | Py_DECREF( o2 ); 49 | Py_DECREF( o3 ); 50 | } 51 | return where; 52 | } 53 | 54 | /*! 55 | Gets PyArrayObject from a PyObject. 56 | 57 | @par Revision history: 58 | - 22.02.2005, c 59 | - 03.03.2005 60 | - 25.11.2005 61 | - 30.11.2005 62 | - 01.12.2005 63 | */ 64 | PyArrayObject *helper_getCArrayObject( PyObject *input, int type, 65 | int minDim, int maxDim ) { 66 | PyArrayObject *obj; 67 | 68 | if (PyArray_Check( input )) { 69 | obj = (PyArrayObject *) input; 70 | if (!PyArray_ISCARRAY( obj )) { 71 | PyErr_SetString( PyExc_TypeError, "not a C array" ); 72 | return NULL; 73 | } 74 | obj = (PyArrayObject *) 75 | PyArray_ContiguousFromAny( input, type, minDim, maxDim ); 76 | if (!obj) return NULL; 77 | } else { 78 | PyErr_SetString( PyExc_TypeError, "not an array" ); 79 | return NULL; 80 | } 81 | return obj; 82 | } 83 | %} 84 | 85 | /*! 86 | Use for arrays as input arguments. Could be also used for changing an array 87 | in place. 88 | 89 | @a rtype ... return this C data type 90 | @a ctype ... C data type of the C function 91 | @a atype ... PyArray_* suffix 92 | 93 | @par Revision history: 94 | - 30.11.2005, c 95 | */ 96 | #define ARRAY_IN( rtype, ctype, atype ) \ 97 | %typemap( in ) (ctype *array) { \ 98 | PyArrayObject *obj; \ 99 | obj = helper_getCArrayObject( $input, PyArray_##atype, 1, 1 ); \ 100 | if (!obj) return NULL; \ 101 | $1 = (rtype *) obj->data; \ 102 | Py_DECREF( obj ); \ 103 | }; 104 | 105 | /*! 106 | @par Revision history: 107 | - 30.11.2005, c 108 | */ 109 | #define CONF_IN( arSize ) \ 110 | %typemap( in ) (double conf [arSize]) { \ 111 | PyArrayObject *obj; \ 112 | obj = helper_getCArrayObject( $input, PyArray_DOUBLE, 1, 1 ); \ 113 | if (!obj) return NULL; \ 114 | if ((obj->nd != 1) || (obj->dimensions[0] != arSize)) { \ 115 | PyErr_SetString( PyExc_ValueError, "wrong Control/Info array size" ); \ 116 | Py_DECREF( obj ); \ 117 | return NULL; \ 118 | } \ 119 | $1 = (double *) obj->data; \ 120 | Py_DECREF( obj ); \ 121 | }; 122 | 123 | /*! 124 | @par Revision history: 125 | - 01.12.2005, c 126 | - 02.12.2005 127 | */ 128 | #define OPAQUE_ARGOUT( ttype ) \ 129 | %typemap( in, numinputs=0 ) ttype* opaque_argout( ttype tmp ) { \ 130 | $1 = &tmp; \ 131 | }; \ 132 | %typemap( argout ) ttype* opaque_argout { \ 133 | PyObject *obj; \ 134 | obj = SWIG_NewPointerObj( (ttype) (*$1), $*1_descriptor, 0 ); \ 135 | $result = helper_appendToTuple( $result, obj ); \ 136 | }; 137 | 138 | /*! 139 | @par Revision history: 140 | - 02.12.2005, c 141 | */ 142 | #define OPAQUE_ARGINOUT( ttype ) \ 143 | %typemap( in ) ttype* opaque_arginout( ttype tmp ) { \ 144 | if ((SWIG_ConvertPtr( $input,(void **) &tmp, $*1_descriptor, \ 145 | SWIG_POINTER_EXCEPTION)) == -1) return NULL; \ 146 | $1 = &tmp; \ 147 | }; \ 148 | %typemap( argout ) ttype* opaque_arginout { \ 149 | PyObject *obj; \ 150 | obj = SWIG_NewPointerObj( (ttype) (*$1), $*1_descriptor, 0 ); \ 151 | $result = helper_appendToTuple( $result, obj ); \ 152 | }; 153 | 154 | ARRAY_IN( int, const int, INT ) 155 | %apply const int *array { 156 | const int Ap [ ], 157 | const int Ai [ ] 158 | }; 159 | 160 | ARRAY_IN( long, const long, LONG ) 161 | %apply const long *array { 162 | const long Ap [ ], 163 | const long Ai [ ] 164 | }; 165 | 166 | ARRAY_IN( double, const double, DOUBLE ) 167 | %apply const double *array { 168 | const double Ax [ ], 169 | const double Az [ ], 170 | const double B [ ], 171 | const double Bx [ ], 172 | const double Bz [ ] 173 | }; 174 | 175 | ARRAY_IN( double, double, DOUBLE ) 176 | %apply double *array { 177 | double X [ ], 178 | double Xx [ ], 179 | double Xz [ ] 180 | }; 181 | 182 | CONF_IN( UMFPACK_CONTROL ) 183 | %apply (double conf [UMFPACK_CONTROL]) { 184 | double Control [ANY] 185 | }; 186 | 187 | CONF_IN( UMFPACK_INFO ) 188 | %apply double conf [UMFPACK_INFO] { 189 | double Info [ANY] 190 | }; 191 | 192 | %include 193 | %include 194 | %include 195 | %include 196 | %include 197 | %include 198 | %include 199 | 200 | %include 201 | %include 202 | %include 203 | %include 204 | 205 | /* 206 | The order is important below! 207 | */ 208 | 209 | OPAQUE_ARGOUT( void * ) 210 | %apply void ** opaque_argout { 211 | void **Symbolic, 212 | void **Numeric 213 | } 214 | 215 | %include 216 | %include 217 | 218 | 219 | OPAQUE_ARGINOUT( void * ) 220 | %apply void ** opaque_arginout { 221 | void **Symbolic, 222 | void **Numeric 223 | } 224 | 225 | %include 226 | %include 227 | 228 | 229 | 230 | /* 231 | * wnbell - attempt to get L,U,P,Q out 232 | */ 233 | %include "typemaps.i" 234 | %apply int *OUTPUT { 235 | int *lnz, 236 | int *unz, 237 | int *n_row, 238 | int *n_col, 239 | int *nz_udiag 240 | }; 241 | %apply long *OUTPUT { 242 | long *lnz, 243 | long *unz, 244 | long *n_row, 245 | long *n_col, 246 | long *nz_udiag 247 | }; 248 | %include 249 | 250 | 251 | ARRAY_IN( double, double, DOUBLE ) 252 | %apply double *array { 253 | double Lx [ ], 254 | double Lz [ ], 255 | double Ux [ ], 256 | double Uz [ ], 257 | double Dx [ ], 258 | double Dz [ ], 259 | double Rs [ ] 260 | }; 261 | 262 | ARRAY_IN( int, int, INT ) 263 | %apply int *array { 264 | int Lp [ ], 265 | int Lj [ ], 266 | int Up [ ], 267 | int Ui [ ], 268 | int P [ ], 269 | int Q [ ] 270 | }; 271 | %apply int *OUTPUT { int *do_recip}; 272 | %include 273 | 274 | #endif 275 | -------------------------------------------------------------------------------- /tests/test_umfpack.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | 4 | """ 5 | Test functions for UMFPACK solver. The solver is accessed via spsolve(), 6 | so the built-in SuperLU solver is tested too, in single precision. 7 | """ 8 | 9 | import warnings 10 | import nose 11 | from numpy import transpose, array, arange 12 | 13 | import random 14 | from numpy.testing import * 15 | 16 | from scipy import rand, matrix, diag, eye 17 | from scipy.sparse import csc_matrix, dok_matrix, spdiags, SparseEfficiencyWarning 18 | 19 | import scipy 20 | try: 21 | import scipy.sparse.linalg.dsolve.linsolve as linsolve 22 | except (ImportError, AttributeError): 23 | raise ImportError( "Cannot import linsolve!" ) 24 | 25 | warnings.simplefilter('ignore',SparseEfficiencyWarning) 26 | 27 | import numpy as nm 28 | try: 29 | import scikits.umfpack as um 30 | _have_umfpack = True 31 | except: 32 | raise Exception('UMFPACK library not found.') 33 | 34 | # Allow disabling of nose tests if umfpack not present 35 | # See end of file for application 36 | _umfpack_skip = dec.skipif(not _have_umfpack, 37 | 'UMFPACK appears not to be compiled') 38 | 39 | class TestSolvers(TestCase): 40 | """Tests inverting a sparse linear system""" 41 | 42 | def test_solve_complex_without_umfpack(self): 43 | """Solve: single precision complex""" 44 | linsolve.use_solver( useUmfpack = False ) 45 | a = self.a 46 | a.data = a.data.astype('F',casting='unsafe') 47 | b = self.b 48 | b = b.astype('F') 49 | x = linsolve.spsolve(a, b) 50 | #print x 51 | #print "Error: ", a*x-b 52 | assert_array_almost_equal(a*x, b) 53 | 54 | 55 | def test_solve_without_umfpack(self): 56 | """Solve: single precision""" 57 | linsolve.use_solver( useUmfpack = False ) 58 | a = self.a.astype('f') 59 | b = self.b 60 | x = linsolve.spsolve(a, b.astype('f')) 61 | #print x 62 | #print "Error: ", a*x-b 63 | # single precision: be more generous... 64 | assert_array_almost_equal(a*x, b, decimal = 5) 65 | 66 | 67 | def test_solve_complex_umfpack(self): 68 | """Solve with UMFPACK: double precision complex""" 69 | linsolve.use_solver( useUmfpack = True ) 70 | a = self.a.astype('D') 71 | b = self.b 72 | x = linsolve.spsolve(a, b) 73 | #print x 74 | #print "Error: ", a*x-b 75 | assert_array_almost_equal(a*x, b) 76 | 77 | def test_solve_umfpack(self): 78 | """Solve with UMFPACK: double precision""" 79 | linsolve.use_solver( useUmfpack = True ) 80 | a = self.a.astype('d') 81 | b = self.b 82 | x = linsolve.spsolve(a, b) 83 | #print x 84 | #print "Error: ", a*x-b 85 | assert_array_almost_equal(a*x, b) 86 | 87 | def test_solve_sparse_rhs(self): 88 | """Solve with UMFPACK: double precision, sparse rhs""" 89 | linsolve.use_solver( useUmfpack = True ) 90 | a = self.a.astype('d') 91 | b = csc_matrix( self.b.reshape((5,1)) ) 92 | x = linsolve.spsolve(a, b) 93 | #print x 94 | #print "Error: ", a*x-b 95 | assert_array_almost_equal(a*x, self.b) 96 | 97 | def test_factorized_umfpack(self): 98 | """Prefactorize (with UMFPACK) matrix for solving with multiple rhs""" 99 | linsolve.use_solver( useUmfpack = True ) 100 | a = self.a.astype('d') 101 | solve = linsolve.factorized( a ) 102 | 103 | x1 = solve( self.b ) 104 | assert_array_almost_equal(a*x1, self.b) 105 | x2 = solve( self.b2 ) 106 | assert_array_almost_equal(a*x2, self.b2) 107 | 108 | def test_factorized_without_umfpack(self): 109 | """Prefactorize matrix for solving with multiple rhs""" 110 | linsolve.use_solver( useUmfpack = False ) 111 | a = self.a.astype('d') 112 | solve = linsolve.factorized( a ) 113 | 114 | x1 = solve( self.b ) 115 | assert_array_almost_equal(a*x1, self.b) 116 | x2 = solve( self.b2 ) 117 | assert_array_almost_equal(a*x2, self.b2) 118 | 119 | def setUp(self): 120 | self.a = spdiags([[1, 2, 3, 4, 5], [6, 5, 8, 9, 10]], [0, 1], 5, 5) 121 | #print "The sparse matrix (constructed from diagonals):" 122 | #print self.a 123 | self.b = array([1, 2, 3, 4, 5]) 124 | self.b2 = array([5, 4, 3, 2, 1]) 125 | 126 | 127 | 128 | class TestFactorization(TestCase): 129 | """Tests factorizing a sparse linear system""" 130 | 131 | def test_complex_lu(self): 132 | """Getting factors of complex matrix""" 133 | umfpack = um.UmfpackContext("zi") 134 | 135 | for A in self.complex_matrices: 136 | umfpack.numeric(A) 137 | 138 | (L,U,P,Q,R,do_recip) = umfpack.lu(A) 139 | 140 | L = L.todense() 141 | U = U.todense() 142 | A = A.todense() 143 | if not do_recip: R = 1.0/R 144 | R = matrix(diag(R)) 145 | P = eye(A.shape[0])[P,:] 146 | Q = eye(A.shape[1])[:,Q] 147 | 148 | assert_array_almost_equal(P*R*A*Q,L*U) 149 | 150 | def test_real_lu(self): 151 | """Getting factors of real matrix""" 152 | umfpack = um.UmfpackContext("di") 153 | 154 | for A in self.real_matrices: 155 | umfpack.numeric(A) 156 | 157 | (L,U,P,Q,R,do_recip) = umfpack.lu(A) 158 | 159 | L = L.todense() 160 | U = U.todense() 161 | A = A.todense() 162 | if not do_recip: R = 1.0/R 163 | R = matrix(diag(R)) 164 | P = eye(A.shape[0])[P,:] 165 | Q = eye(A.shape[1])[:,Q] 166 | 167 | assert_array_almost_equal(P*R*A*Q,L*U) 168 | 169 | 170 | def setUp(self): 171 | random.seed(0) #make tests repeatable 172 | self.real_matrices = [] 173 | self.real_matrices.append(spdiags([[1, 2, 3, 4, 5], [6, 5, 8, 9, 10]], 174 | [0, 1], 5, 5) ) 175 | self.real_matrices.append(spdiags([[1, 2, 3, 4, 5], [6, 5, 8, 9, 10]], 176 | [0, 1], 4, 5) ) 177 | self.real_matrices.append(spdiags([[1, 2, 3, 4, 5], [6, 5, 8, 9, 10]], 178 | [0, 2], 5, 5) ) 179 | self.real_matrices.append(rand(3,3)) 180 | self.real_matrices.append(rand(5,4)) 181 | self.real_matrices.append(rand(4,5)) 182 | 183 | self.real_matrices = [csc_matrix(x).astype('float') for x \ 184 | in self.real_matrices] 185 | self.complex_matrices = [x.astype('complex') 186 | for x in self.real_matrices] 187 | 188 | # Skip methods if umfpack not present 189 | for cls in [TestSolvers, TestFactorization]: 190 | decorate_methods(cls, _umfpack_skip) 191 | 192 | if __name__ == "__main__": 193 | nose.run(argv=['', __file__]) 194 | -------------------------------------------------------------------------------- /tests/try_umfpack.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by: Robert Cimrman, 05.12.2005 3 | 4 | """Benchamrks for umfpack module""" 5 | 6 | from optparse import OptionParser 7 | import scikits.umfpack as um 8 | import numpy as nm 9 | #import scipy.io as io 10 | import scipy.sparse as sp 11 | import scipy.linalg as nla 12 | #import pylab 13 | import time 14 | import urllib 15 | import gzip 16 | 17 | defaultURL = 'http://www.cise.ufl.edu/research/sparse/HBformat/' 18 | 19 | usage = """%%prog [options] [, ...] 20 | 21 | can be a local or distant (gzipped) file 22 | 23 | default url is: 24 | %s 25 | 26 | supported formats are: 27 | triplet .. [nRow, nCol, nItem] followed by 'nItem' * [ir, ic, value] 28 | hb .. Harwell-Boeing format N/A 29 | """ % defaultURL 30 | 31 | 32 | ## 33 | # 05.12.2005, c 34 | def read_triplet( fd ): 35 | nRow, nCol = map( int, fd.readline().split() ) 36 | nItem = int( fd.readline() ) 37 | 38 | ij = nm.zeros( (nItem,2), nm.int32 ) 39 | val = nm.zeros( (nItem,), nm.float64 ) 40 | for ii, row in enumerate( fd.readlines() ): 41 | aux = row.split() 42 | ij[ii] = int( aux[0] ), int( aux[1] ) 43 | val[ii] = float( aux[2] ) 44 | 45 | mtx = sp.csc_matrix( (val, ij), dims = (nRow, nCol), nzmax = nItem ) 46 | 47 | return mtx 48 | 49 | ## 50 | # 06.12.2005, c 51 | def read_triplet2( fd ): 52 | nRow, nCol = map( int, fd.readline().split() ) 53 | nItem = int( fd.readline() ) 54 | 55 | ij, val = io.read_array( fd, 56 | columns = [(0,1), (2,)], 57 | atype = (nm.int32, nm.float64), 58 | rowsize = nItem ) 59 | 60 | mtx = sp.csc_matrix( (val, ij), dims = (nRow, nCol), nzmax = nItem ) 61 | 62 | return mtx 63 | 64 | 65 | formatMap = {'triplet' : read_triplet} 66 | ## 67 | # 05.12.2005, c 68 | def readMatrix( matrixName, options ): 69 | 70 | if options.default_url: 71 | matrixName = defaultURL + matrixName 72 | 73 | print('url:', matrixName) 74 | 75 | if matrixName[:7] == 'http://': 76 | fileName, status = urllib.urlretrieve( matrixName ) 77 | ## print status 78 | else: 79 | fileName = matrixName 80 | 81 | print('file:', fileName) 82 | 83 | try: 84 | readMatrix = formatMap[options.format] 85 | except: 86 | raise ValueError('unsupported format: %s' % options.format) 87 | 88 | print('format:', options.format) 89 | 90 | print('reading...') 91 | if fileName[-3:] == '.gz': 92 | fd = gzip.open( fileName ) 93 | else: 94 | fd = open( fileName ) 95 | 96 | mtx = readMatrix( fd ) 97 | 98 | fd.close() 99 | 100 | print('ok') 101 | 102 | return mtx 103 | 104 | ## 105 | # 05.12.2005, c 106 | def main(): 107 | parser = OptionParser( usage = usage ) 108 | parser.add_option( "-c", "--compare", 109 | action = "store_true", dest = "compare", 110 | default = False, 111 | help = "compare with default scipy.sparse solver [default: %default]" ) 112 | parser.add_option( "-p", "--plot", 113 | action = "store_true", dest = "plot", 114 | default = False, 115 | help = "plot time statistics [default: %default]" ) 116 | parser.add_option( "-d", "--default-url", 117 | action = "store_true", dest = "default_url", 118 | default = False, 119 | help = "use default url [default: %default]" ) 120 | parser.add_option( "-f", "--format", type = type( '' ), 121 | dest = "format", default = 'triplet', 122 | help = "matrix format [default: %default]" ) 123 | (options, args) = parser.parse_args() 124 | 125 | if (len( args ) >= 1): 126 | matrixNames = args; 127 | else: 128 | parser.print_help(), 129 | return 130 | 131 | sizes, nnzs, times, errors = [], [], [], [] 132 | legends = ['umfpack', 'sparse.solve'] 133 | for ii, matrixName in enumerate( matrixNames ): 134 | 135 | print('*' * 50) 136 | mtx = readMatrix( matrixName, options ) 137 | 138 | sizes.append( mtx.shape ) 139 | nnzs.append( mtx.nnz ) 140 | tts = nm.zeros( (2,), dtype = nm.double ) 141 | times.append( tts ) 142 | err = nm.zeros( (2,2), dtype = nm.double ) 143 | errors.append( err ) 144 | 145 | print('size : %s (%d nnz)' % (mtx.shape, mtx.nnz)) 146 | 147 | sol0 = nm.ones( (mtx.shape[0],), dtype = nm.double ) 148 | rhs = mtx * sol0 149 | 150 | umfpack = um.UmfpackContext() 151 | 152 | tt = time.clock() 153 | sol = umfpack( um.UMFPACK_A, mtx, rhs, autoTranspose = True ) 154 | tts[0] = time.clock() - tt 155 | print("umfpack : %.2f s" % tts[0]) 156 | 157 | error = mtx * sol - rhs 158 | err[0,0] = nla.norm( error ) 159 | print('||Ax-b|| :', err[0,0]) 160 | 161 | error = sol0 - sol 162 | err[0,1] = nla.norm( error ) 163 | print('||x - x_{exact}|| :', err[0,1]) 164 | 165 | if options.compare: 166 | tt = time.clock() 167 | sol = sp.solve( mtx, rhs ) 168 | tts[1] = time.clock() - tt 169 | print("sparse.solve : %.2f s" % tts[1]) 170 | 171 | error = mtx * sol - rhs 172 | err[1,0] = nla.norm( error ) 173 | print('||Ax-b|| :', err[1,0]) 174 | 175 | error = sol0 - sol 176 | err[1,1] = nla.norm( error ) 177 | print('||x - x_{exact}|| :', err[1,1]) 178 | 179 | if options.plot: 180 | try: 181 | import pylab 182 | except: 183 | raise ImportError("could not import pylab") 184 | times = nm.array( times ) 185 | print(times) 186 | pylab.plot( times[:,0], 'b-o' ) 187 | if options.compare: 188 | pylab.plot( times[:,1], 'r-s' ) 189 | else: 190 | del legends[1] 191 | 192 | print(legends) 193 | 194 | ax = pylab.axis() 195 | y2 = 0.5 * (ax[3] - ax[2]) 196 | xrng = range( len( nnzs ) ) 197 | for ii in xrng: 198 | yy = y2 + 0.4 * (ax[3] - ax[2])\ 199 | * nm.sin( ii * 2 * nm.pi / (len( xrng ) - 1) ) 200 | 201 | if options.compare: 202 | pylab.text( ii+0.02, yy, 203 | '%s\n%.2e err_umf\n%.2e err_sp' 204 | % (sizes[ii], nm.sum( errors[ii][0,:] ), 205 | nm.sum( errors[ii][1,:] )) ) 206 | else: 207 | pylab.text( ii+0.02, yy, 208 | '%s\n%.2e err_umf' 209 | % (sizes[ii], nm.sum( errors[ii][0,:] )) ) 210 | pylab.plot( [ii, ii], [ax[2], ax[3]], 'k:' ) 211 | 212 | pylab.xticks( xrng, ['%d' % (nnzs[ii] ) for ii in xrng] ) 213 | pylab.xlabel( 'nnz' ) 214 | pylab.ylabel( 'time [s]' ) 215 | pylab.legend( legends ) 216 | pylab.axis( [ax[0] - 0.05, ax[1] + 1, ax[2], ax[3]] ) 217 | pylab.show() 218 | 219 | if __name__ == '__main__': 220 | main() 221 | -------------------------------------------------------------------------------- /scikits/umfpack/_umfpack.py: -------------------------------------------------------------------------------- 1 | # This file was automatically generated by SWIG (http://www.swig.org). 2 | # Version 1.3.31 3 | # 4 | # Don't modify this file, modify the SWIG interface instead. 5 | # This file is compatible with both classic and new-style classes. 6 | 7 | import scikits.umfpack.__umfpack 8 | import new 9 | new_instancemethod = new.instancemethod 10 | try: 11 | _swig_property = property 12 | except NameError: 13 | pass # Python < 2.2 doesn't have 'property'. 14 | def _swig_setattr_nondynamic(self,class_type,name,value,static=1): 15 | if (name == "thisown"): return self.this.own(value) 16 | if (name == "this"): 17 | if type(value).__name__ == 'PySwigObject': 18 | self.__dict__[name] = value 19 | return 20 | method = class_type.__swig_setmethods__.get(name,None) 21 | if method: return method(self,value) 22 | if (not static) or hasattr(self,name): 23 | self.__dict__[name] = value 24 | else: 25 | raise AttributeError("You cannot add attributes to %s" % self) 26 | 27 | def _swig_setattr(self,class_type,name,value): 28 | return _swig_setattr_nondynamic(self,class_type,name,value,0) 29 | 30 | def _swig_getattr(self,class_type,name): 31 | if (name == "thisown"): return self.this.own() 32 | method = class_type.__swig_getmethods__.get(name,None) 33 | if method: return method(self) 34 | raise AttributeError(name) 35 | 36 | def _swig_repr(self): 37 | try: strthis = "proxy of " + self.this.__repr__() 38 | except: strthis = "" 39 | return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) 40 | 41 | import types 42 | try: 43 | _object = types.ObjectType 44 | _newclass = 1 45 | except AttributeError: 46 | class _object : pass 47 | _newclass = 0 48 | del types 49 | 50 | 51 | UMFPACK_INFO = __umfpack.UMFPACK_INFO 52 | UMFPACK_CONTROL = __umfpack.UMFPACK_CONTROL 53 | UMFPACK_VERSION = __umfpack.UMFPACK_VERSION 54 | UMFPACK_COPYRIGHT = __umfpack.UMFPACK_COPYRIGHT 55 | UMFPACK_LICENSE_PART1 = __umfpack.UMFPACK_LICENSE_PART1 56 | UMFPACK_LICENSE_PART2 = __umfpack.UMFPACK_LICENSE_PART2 57 | UMFPACK_LICENSE_PART3 = __umfpack.UMFPACK_LICENSE_PART3 58 | UMFPACK_DATE = __umfpack.UMFPACK_DATE 59 | UMFPACK_MAIN_VERSION = __umfpack.UMFPACK_MAIN_VERSION 60 | UMFPACK_SUB_VERSION = __umfpack.UMFPACK_SUB_VERSION 61 | UMFPACK_SUBSUB_VERSION = __umfpack.UMFPACK_SUBSUB_VERSION 62 | UMFPACK_VER = __umfpack.UMFPACK_VER 63 | UMFPACK_STATUS = __umfpack.UMFPACK_STATUS 64 | UMFPACK_NROW = __umfpack.UMFPACK_NROW 65 | UMFPACK_NCOL = __umfpack.UMFPACK_NCOL 66 | UMFPACK_NZ = __umfpack.UMFPACK_NZ 67 | UMFPACK_SIZE_OF_UNIT = __umfpack.UMFPACK_SIZE_OF_UNIT 68 | UMFPACK_SIZE_OF_INT = __umfpack.UMFPACK_SIZE_OF_INT 69 | UMFPACK_SIZE_OF_LONG = __umfpack.UMFPACK_SIZE_OF_LONG 70 | UMFPACK_SIZE_OF_POINTER = __umfpack.UMFPACK_SIZE_OF_POINTER 71 | UMFPACK_SIZE_OF_ENTRY = __umfpack.UMFPACK_SIZE_OF_ENTRY 72 | UMFPACK_NDENSE_ROW = __umfpack.UMFPACK_NDENSE_ROW 73 | UMFPACK_NEMPTY_ROW = __umfpack.UMFPACK_NEMPTY_ROW 74 | UMFPACK_NDENSE_COL = __umfpack.UMFPACK_NDENSE_COL 75 | UMFPACK_NEMPTY_COL = __umfpack.UMFPACK_NEMPTY_COL 76 | UMFPACK_SYMBOLIC_DEFRAG = __umfpack.UMFPACK_SYMBOLIC_DEFRAG 77 | UMFPACK_SYMBOLIC_PEAK_MEMORY = __umfpack.UMFPACK_SYMBOLIC_PEAK_MEMORY 78 | UMFPACK_SYMBOLIC_SIZE = __umfpack.UMFPACK_SYMBOLIC_SIZE 79 | UMFPACK_SYMBOLIC_TIME = __umfpack.UMFPACK_SYMBOLIC_TIME 80 | UMFPACK_SYMBOLIC_WALLTIME = __umfpack.UMFPACK_SYMBOLIC_WALLTIME 81 | UMFPACK_STRATEGY_USED = __umfpack.UMFPACK_STRATEGY_USED 82 | UMFPACK_ORDERING_USED = __umfpack.UMFPACK_ORDERING_USED 83 | UMFPACK_QFIXED = __umfpack.UMFPACK_QFIXED 84 | UMFPACK_DIAG_PREFERRED = __umfpack.UMFPACK_DIAG_PREFERRED 85 | UMFPACK_PATTERN_SYMMETRY = __umfpack.UMFPACK_PATTERN_SYMMETRY 86 | UMFPACK_NZ_A_PLUS_AT = __umfpack.UMFPACK_NZ_A_PLUS_AT 87 | UMFPACK_NZDIAG = __umfpack.UMFPACK_NZDIAG 88 | UMFPACK_SYMMETRIC_LUNZ = __umfpack.UMFPACK_SYMMETRIC_LUNZ 89 | UMFPACK_SYMMETRIC_FLOPS = __umfpack.UMFPACK_SYMMETRIC_FLOPS 90 | UMFPACK_SYMMETRIC_NDENSE = __umfpack.UMFPACK_SYMMETRIC_NDENSE 91 | UMFPACK_SYMMETRIC_DMAX = __umfpack.UMFPACK_SYMMETRIC_DMAX 92 | UMFPACK_2BY2_NWEAK = __umfpack.UMFPACK_2BY2_NWEAK 93 | UMFPACK_2BY2_UNMATCHED = __umfpack.UMFPACK_2BY2_UNMATCHED 94 | UMFPACK_2BY2_PATTERN_SYMMETRY = __umfpack.UMFPACK_2BY2_PATTERN_SYMMETRY 95 | UMFPACK_2BY2_NZ_PA_PLUS_PAT = __umfpack.UMFPACK_2BY2_NZ_PA_PLUS_PAT 96 | UMFPACK_2BY2_NZDIAG = __umfpack.UMFPACK_2BY2_NZDIAG 97 | UMFPACK_COL_SINGLETONS = __umfpack.UMFPACK_COL_SINGLETONS 98 | UMFPACK_ROW_SINGLETONS = __umfpack.UMFPACK_ROW_SINGLETONS 99 | UMFPACK_N2 = __umfpack.UMFPACK_N2 100 | UMFPACK_S_SYMMETRIC = __umfpack.UMFPACK_S_SYMMETRIC 101 | UMFPACK_NUMERIC_SIZE_ESTIMATE = __umfpack.UMFPACK_NUMERIC_SIZE_ESTIMATE 102 | UMFPACK_PEAK_MEMORY_ESTIMATE = __umfpack.UMFPACK_PEAK_MEMORY_ESTIMATE 103 | UMFPACK_FLOPS_ESTIMATE = __umfpack.UMFPACK_FLOPS_ESTIMATE 104 | UMFPACK_LNZ_ESTIMATE = __umfpack.UMFPACK_LNZ_ESTIMATE 105 | UMFPACK_UNZ_ESTIMATE = __umfpack.UMFPACK_UNZ_ESTIMATE 106 | UMFPACK_VARIABLE_INIT_ESTIMATE = __umfpack.UMFPACK_VARIABLE_INIT_ESTIMATE 107 | UMFPACK_VARIABLE_PEAK_ESTIMATE = __umfpack.UMFPACK_VARIABLE_PEAK_ESTIMATE 108 | UMFPACK_VARIABLE_FINAL_ESTIMATE = __umfpack.UMFPACK_VARIABLE_FINAL_ESTIMATE 109 | UMFPACK_MAX_FRONT_SIZE_ESTIMATE = __umfpack.UMFPACK_MAX_FRONT_SIZE_ESTIMATE 110 | UMFPACK_MAX_FRONT_NROWS_ESTIMATE = __umfpack.UMFPACK_MAX_FRONT_NROWS_ESTIMATE 111 | UMFPACK_MAX_FRONT_NCOLS_ESTIMATE = __umfpack.UMFPACK_MAX_FRONT_NCOLS_ESTIMATE 112 | UMFPACK_NUMERIC_SIZE = __umfpack.UMFPACK_NUMERIC_SIZE 113 | UMFPACK_PEAK_MEMORY = __umfpack.UMFPACK_PEAK_MEMORY 114 | UMFPACK_FLOPS = __umfpack.UMFPACK_FLOPS 115 | UMFPACK_LNZ = __umfpack.UMFPACK_LNZ 116 | UMFPACK_UNZ = __umfpack.UMFPACK_UNZ 117 | UMFPACK_VARIABLE_INIT = __umfpack.UMFPACK_VARIABLE_INIT 118 | UMFPACK_VARIABLE_PEAK = __umfpack.UMFPACK_VARIABLE_PEAK 119 | UMFPACK_VARIABLE_FINAL = __umfpack.UMFPACK_VARIABLE_FINAL 120 | UMFPACK_MAX_FRONT_SIZE = __umfpack.UMFPACK_MAX_FRONT_SIZE 121 | UMFPACK_MAX_FRONT_NROWS = __umfpack.UMFPACK_MAX_FRONT_NROWS 122 | UMFPACK_MAX_FRONT_NCOLS = __umfpack.UMFPACK_MAX_FRONT_NCOLS 123 | UMFPACK_NUMERIC_DEFRAG = __umfpack.UMFPACK_NUMERIC_DEFRAG 124 | UMFPACK_NUMERIC_REALLOC = __umfpack.UMFPACK_NUMERIC_REALLOC 125 | UMFPACK_NUMERIC_COSTLY_REALLOC = __umfpack.UMFPACK_NUMERIC_COSTLY_REALLOC 126 | UMFPACK_COMPRESSED_PATTERN = __umfpack.UMFPACK_COMPRESSED_PATTERN 127 | UMFPACK_LU_ENTRIES = __umfpack.UMFPACK_LU_ENTRIES 128 | UMFPACK_NUMERIC_TIME = __umfpack.UMFPACK_NUMERIC_TIME 129 | UMFPACK_UDIAG_NZ = __umfpack.UMFPACK_UDIAG_NZ 130 | UMFPACK_RCOND = __umfpack.UMFPACK_RCOND 131 | UMFPACK_WAS_SCALED = __umfpack.UMFPACK_WAS_SCALED 132 | UMFPACK_RSMIN = __umfpack.UMFPACK_RSMIN 133 | UMFPACK_RSMAX = __umfpack.UMFPACK_RSMAX 134 | UMFPACK_UMIN = __umfpack.UMFPACK_UMIN 135 | UMFPACK_UMAX = __umfpack.UMFPACK_UMAX 136 | UMFPACK_ALLOC_INIT_USED = __umfpack.UMFPACK_ALLOC_INIT_USED 137 | UMFPACK_FORCED_UPDATES = __umfpack.UMFPACK_FORCED_UPDATES 138 | UMFPACK_NUMERIC_WALLTIME = __umfpack.UMFPACK_NUMERIC_WALLTIME 139 | UMFPACK_NOFF_DIAG = __umfpack.UMFPACK_NOFF_DIAG 140 | UMFPACK_ALL_LNZ = __umfpack.UMFPACK_ALL_LNZ 141 | UMFPACK_ALL_UNZ = __umfpack.UMFPACK_ALL_UNZ 142 | UMFPACK_NZDROPPED = __umfpack.UMFPACK_NZDROPPED 143 | UMFPACK_IR_TAKEN = __umfpack.UMFPACK_IR_TAKEN 144 | UMFPACK_IR_ATTEMPTED = __umfpack.UMFPACK_IR_ATTEMPTED 145 | UMFPACK_OMEGA1 = __umfpack.UMFPACK_OMEGA1 146 | UMFPACK_OMEGA2 = __umfpack.UMFPACK_OMEGA2 147 | UMFPACK_SOLVE_FLOPS = __umfpack.UMFPACK_SOLVE_FLOPS 148 | UMFPACK_SOLVE_TIME = __umfpack.UMFPACK_SOLVE_TIME 149 | UMFPACK_SOLVE_WALLTIME = __umfpack.UMFPACK_SOLVE_WALLTIME 150 | UMFPACK_ORDERING_COLAMD = __umfpack.UMFPACK_ORDERING_COLAMD 151 | UMFPACK_ORDERING_AMD = __umfpack.UMFPACK_ORDERING_AMD 152 | UMFPACK_ORDERING_GIVEN = __umfpack.UMFPACK_ORDERING_GIVEN 153 | UMFPACK_PRL = __umfpack.UMFPACK_PRL 154 | UMFPACK_DENSE_ROW = __umfpack.UMFPACK_DENSE_ROW 155 | UMFPACK_DENSE_COL = __umfpack.UMFPACK_DENSE_COL 156 | UMFPACK_BLOCK_SIZE = __umfpack.UMFPACK_BLOCK_SIZE 157 | UMFPACK_STRATEGY = __umfpack.UMFPACK_STRATEGY 158 | UMFPACK_2BY2_TOLERANCE = __umfpack.UMFPACK_2BY2_TOLERANCE 159 | UMFPACK_FIXQ = __umfpack.UMFPACK_FIXQ 160 | UMFPACK_AMD_DENSE = __umfpack.UMFPACK_AMD_DENSE 161 | UMFPACK_AGGRESSIVE = __umfpack.UMFPACK_AGGRESSIVE 162 | UMFPACK_PIVOT_TOLERANCE = __umfpack.UMFPACK_PIVOT_TOLERANCE 163 | UMFPACK_ALLOC_INIT = __umfpack.UMFPACK_ALLOC_INIT 164 | UMFPACK_SYM_PIVOT_TOLERANCE = __umfpack.UMFPACK_SYM_PIVOT_TOLERANCE 165 | UMFPACK_SCALE = __umfpack.UMFPACK_SCALE 166 | UMFPACK_FRONT_ALLOC_INIT = __umfpack.UMFPACK_FRONT_ALLOC_INIT 167 | UMFPACK_DROPTOL = __umfpack.UMFPACK_DROPTOL 168 | UMFPACK_IRSTEP = __umfpack.UMFPACK_IRSTEP 169 | UMFPACK_COMPILED_WITH_BLAS = __umfpack.UMFPACK_COMPILED_WITH_BLAS 170 | UMFPACK_COMPILED_FOR_MATLAB = __umfpack.UMFPACK_COMPILED_FOR_MATLAB 171 | UMFPACK_COMPILED_WITH_GETRUSAGE = __umfpack.UMFPACK_COMPILED_WITH_GETRUSAGE 172 | UMFPACK_COMPILED_IN_DEBUG_MODE = __umfpack.UMFPACK_COMPILED_IN_DEBUG_MODE 173 | UMFPACK_STRATEGY_AUTO = __umfpack.UMFPACK_STRATEGY_AUTO 174 | UMFPACK_STRATEGY_UNSYMMETRIC = __umfpack.UMFPACK_STRATEGY_UNSYMMETRIC 175 | UMFPACK_STRATEGY_2BY2 = __umfpack.UMFPACK_STRATEGY_2BY2 176 | UMFPACK_STRATEGY_SYMMETRIC = __umfpack.UMFPACK_STRATEGY_SYMMETRIC 177 | UMFPACK_SCALE_NONE = __umfpack.UMFPACK_SCALE_NONE 178 | UMFPACK_SCALE_SUM = __umfpack.UMFPACK_SCALE_SUM 179 | UMFPACK_SCALE_MAX = __umfpack.UMFPACK_SCALE_MAX 180 | UMFPACK_DEFAULT_PRL = __umfpack.UMFPACK_DEFAULT_PRL 181 | UMFPACK_DEFAULT_DENSE_ROW = __umfpack.UMFPACK_DEFAULT_DENSE_ROW 182 | UMFPACK_DEFAULT_DENSE_COL = __umfpack.UMFPACK_DEFAULT_DENSE_COL 183 | UMFPACK_DEFAULT_PIVOT_TOLERANCE = __umfpack.UMFPACK_DEFAULT_PIVOT_TOLERANCE 184 | UMFPACK_DEFAULT_2BY2_TOLERANCE = __umfpack.UMFPACK_DEFAULT_2BY2_TOLERANCE 185 | UMFPACK_DEFAULT_SYM_PIVOT_TOLERANCE = __umfpack.UMFPACK_DEFAULT_SYM_PIVOT_TOLERANCE 186 | UMFPACK_DEFAULT_BLOCK_SIZE = __umfpack.UMFPACK_DEFAULT_BLOCK_SIZE 187 | UMFPACK_DEFAULT_ALLOC_INIT = __umfpack.UMFPACK_DEFAULT_ALLOC_INIT 188 | UMFPACK_DEFAULT_FRONT_ALLOC_INIT = __umfpack.UMFPACK_DEFAULT_FRONT_ALLOC_INIT 189 | UMFPACK_DEFAULT_IRSTEP = __umfpack.UMFPACK_DEFAULT_IRSTEP 190 | UMFPACK_DEFAULT_SCALE = __umfpack.UMFPACK_DEFAULT_SCALE 191 | UMFPACK_DEFAULT_STRATEGY = __umfpack.UMFPACK_DEFAULT_STRATEGY 192 | UMFPACK_DEFAULT_FIXQ = __umfpack.UMFPACK_DEFAULT_FIXQ 193 | UMFPACK_DEFAULT_AGGRESSIVE = __umfpack.UMFPACK_DEFAULT_AGGRESSIVE 194 | UMFPACK_DEFAULT_DROPTOL = __umfpack.UMFPACK_DEFAULT_DROPTOL 195 | UMFPACK_OK = __umfpack.UMFPACK_OK 196 | UMFPACK_WARNING_singular_matrix = __umfpack.UMFPACK_WARNING_singular_matrix 197 | UMFPACK_WARNING_determinant_underflow = __umfpack.UMFPACK_WARNING_determinant_underflow 198 | UMFPACK_WARNING_determinant_overflow = __umfpack.UMFPACK_WARNING_determinant_overflow 199 | UMFPACK_ERROR_out_of_memory = __umfpack.UMFPACK_ERROR_out_of_memory 200 | UMFPACK_ERROR_invalid_Numeric_object = __umfpack.UMFPACK_ERROR_invalid_Numeric_object 201 | UMFPACK_ERROR_invalid_Symbolic_object = __umfpack.UMFPACK_ERROR_invalid_Symbolic_object 202 | UMFPACK_ERROR_argument_missing = __umfpack.UMFPACK_ERROR_argument_missing 203 | UMFPACK_ERROR_n_nonpositive = __umfpack.UMFPACK_ERROR_n_nonpositive 204 | UMFPACK_ERROR_invalid_matrix = __umfpack.UMFPACK_ERROR_invalid_matrix 205 | UMFPACK_ERROR_different_pattern = __umfpack.UMFPACK_ERROR_different_pattern 206 | UMFPACK_ERROR_invalid_system = __umfpack.UMFPACK_ERROR_invalid_system 207 | UMFPACK_ERROR_invalid_permutation = __umfpack.UMFPACK_ERROR_invalid_permutation 208 | UMFPACK_ERROR_internal_error = __umfpack.UMFPACK_ERROR_internal_error 209 | UMFPACK_ERROR_file_IO = __umfpack.UMFPACK_ERROR_file_IO 210 | UMFPACK_A = __umfpack.UMFPACK_A 211 | UMFPACK_At = __umfpack.UMFPACK_At 212 | UMFPACK_Aat = __umfpack.UMFPACK_Aat 213 | UMFPACK_Pt_L = __umfpack.UMFPACK_Pt_L 214 | UMFPACK_L = __umfpack.UMFPACK_L 215 | UMFPACK_Lt_P = __umfpack.UMFPACK_Lt_P 216 | UMFPACK_Lat_P = __umfpack.UMFPACK_Lat_P 217 | UMFPACK_Lt = __umfpack.UMFPACK_Lt 218 | UMFPACK_Lat = __umfpack.UMFPACK_Lat 219 | UMFPACK_U_Qt = __umfpack.UMFPACK_U_Qt 220 | UMFPACK_U = __umfpack.UMFPACK_U 221 | UMFPACK_Q_Ut = __umfpack.UMFPACK_Q_Ut 222 | UMFPACK_Q_Uat = __umfpack.UMFPACK_Q_Uat 223 | UMFPACK_Ut = __umfpack.UMFPACK_Ut 224 | UMFPACK_Uat = __umfpack.UMFPACK_Uat 225 | 226 | def umfpack_di_solve(*args): 227 | """ 228 | umfpack_di_solve(int sys, int Ap, int Ai, double Ax, double X, double B, 229 | void Numeric, double Control, double Info) -> int 230 | """ 231 | return __umfpack.umfpack_di_solve(*args) 232 | 233 | def umfpack_dl_solve(*args): 234 | """ 235 | umfpack_dl_solve(UF_long sys, UF_long Ap, UF_long Ai, double Ax, double X, 236 | double B, void Numeric, double Control, 237 | double Info) -> UF_long 238 | """ 239 | return __umfpack.umfpack_dl_solve(*args) 240 | 241 | def umfpack_zi_solve(*args): 242 | """ 243 | umfpack_zi_solve(int sys, int Ap, int Ai, double Ax, double Az, double Xx, 244 | double Xz, double Bx, double Bz, void Numeric, 245 | double Control, double Info) -> int 246 | """ 247 | return __umfpack.umfpack_zi_solve(*args) 248 | 249 | def umfpack_zl_solve(*args): 250 | """ 251 | umfpack_zl_solve(UF_long sys, UF_long Ap, UF_long Ai, double Ax, double Az, 252 | double Xx, double Xz, double Bx, double Bz, 253 | void Numeric, double Control, double Info) -> UF_long 254 | """ 255 | return __umfpack.umfpack_zl_solve(*args) 256 | 257 | def umfpack_di_defaults(*args): 258 | """umfpack_di_defaults(double Control)""" 259 | return __umfpack.umfpack_di_defaults(*args) 260 | 261 | def umfpack_dl_defaults(*args): 262 | """umfpack_dl_defaults(double Control)""" 263 | return __umfpack.umfpack_dl_defaults(*args) 264 | 265 | def umfpack_zi_defaults(*args): 266 | """umfpack_zi_defaults(double Control)""" 267 | return __umfpack.umfpack_zi_defaults(*args) 268 | 269 | def umfpack_zl_defaults(*args): 270 | """umfpack_zl_defaults(double Control)""" 271 | return __umfpack.umfpack_zl_defaults(*args) 272 | 273 | def umfpack_di_triplet_to_col(*args): 274 | """ 275 | umfpack_di_triplet_to_col(int n_row, int n_col, int nz, int Ti, int Tj, double Tx, 276 | int Ap, int Ai, double Ax, int Map) -> int 277 | """ 278 | return __umfpack.umfpack_di_triplet_to_col(*args) 279 | 280 | def umfpack_dl_triplet_to_col(*args): 281 | """ 282 | umfpack_dl_triplet_to_col(UF_long n_row, UF_long n_col, UF_long nz, UF_long Ti, 283 | UF_long Tj, double Tx, UF_long Ap, UF_long Ai, 284 | double Ax, UF_long Map) -> UF_long 285 | """ 286 | return __umfpack.umfpack_dl_triplet_to_col(*args) 287 | 288 | def umfpack_zi_triplet_to_col(*args): 289 | """ 290 | umfpack_zi_triplet_to_col(int n_row, int n_col, int nz, int Ti, int Tj, double Tx, 291 | double Tz, int Ap, int Ai, double Ax, double Az, 292 | int Map) -> int 293 | """ 294 | return __umfpack.umfpack_zi_triplet_to_col(*args) 295 | 296 | def umfpack_zl_triplet_to_col(*args): 297 | """ 298 | umfpack_zl_triplet_to_col(UF_long n_row, UF_long n_col, UF_long nz, UF_long Ti, 299 | UF_long Tj, double Tx, double Tz, UF_long Ap, 300 | UF_long Ai, double Ax, double Az, UF_long Map) -> UF_long 301 | """ 302 | return __umfpack.umfpack_zl_triplet_to_col(*args) 303 | 304 | def umfpack_di_col_to_triplet(*args): 305 | """umfpack_di_col_to_triplet(int n_col, int Ap, int Tj) -> int""" 306 | return __umfpack.umfpack_di_col_to_triplet(*args) 307 | 308 | def umfpack_dl_col_to_triplet(*args): 309 | """umfpack_dl_col_to_triplet(UF_long n_col, UF_long Ap, UF_long Tj) -> UF_long""" 310 | return __umfpack.umfpack_dl_col_to_triplet(*args) 311 | 312 | def umfpack_zi_col_to_triplet(*args): 313 | """umfpack_zi_col_to_triplet(int n_col, int Ap, int Tj) -> int""" 314 | return __umfpack.umfpack_zi_col_to_triplet(*args) 315 | 316 | def umfpack_zl_col_to_triplet(*args): 317 | """umfpack_zl_col_to_triplet(UF_long n_col, UF_long Ap, UF_long Tj) -> UF_long""" 318 | return __umfpack.umfpack_zl_col_to_triplet(*args) 319 | 320 | def umfpack_di_transpose(*args): 321 | """ 322 | umfpack_di_transpose(int n_row, int n_col, int Ap, int Ai, double Ax, int P, 323 | int Q, int Rp, int Ri, double Rx) -> int 324 | """ 325 | return __umfpack.umfpack_di_transpose(*args) 326 | 327 | def umfpack_dl_transpose(*args): 328 | """ 329 | umfpack_dl_transpose(UF_long n_row, UF_long n_col, UF_long Ap, UF_long Ai, 330 | double Ax, UF_long P, UF_long Q, UF_long Rp, 331 | UF_long Ri, double Rx) -> UF_long 332 | """ 333 | return __umfpack.umfpack_dl_transpose(*args) 334 | 335 | def umfpack_zi_transpose(*args): 336 | """ 337 | umfpack_zi_transpose(int n_row, int n_col, int Ap, int Ai, double Ax, double Az, 338 | int P, int Q, int Rp, int Ri, double Rx, 339 | double Rz, int do_conjugate) -> int 340 | """ 341 | return __umfpack.umfpack_zi_transpose(*args) 342 | 343 | def umfpack_zl_transpose(*args): 344 | """ 345 | umfpack_zl_transpose(UF_long n_row, UF_long n_col, UF_long Ap, UF_long Ai, 346 | double Ax, double Az, UF_long P, UF_long Q, 347 | UF_long Rp, UF_long Ri, double Rx, double Rz, 348 | UF_long do_conjugate) -> UF_long 349 | """ 350 | return __umfpack.umfpack_zl_transpose(*args) 351 | 352 | def umfpack_di_scale(*args): 353 | """umfpack_di_scale(double X, double B, void Numeric) -> int""" 354 | return __umfpack.umfpack_di_scale(*args) 355 | 356 | def umfpack_dl_scale(*args): 357 | """umfpack_dl_scale(double X, double B, void Numeric) -> UF_long""" 358 | return __umfpack.umfpack_dl_scale(*args) 359 | 360 | def umfpack_zi_scale(*args): 361 | """umfpack_zi_scale(double Xx, double Xz, double Bx, double Bz, void Numeric) -> int""" 362 | return __umfpack.umfpack_zi_scale(*args) 363 | 364 | def umfpack_zl_scale(*args): 365 | """umfpack_zl_scale(double Xx, double Xz, double Bx, double Bz, void Numeric) -> UF_long""" 366 | return __umfpack.umfpack_zl_scale(*args) 367 | 368 | def umfpack_di_report_symbolic(*args): 369 | """umfpack_di_report_symbolic(void Symbolic, double Control) -> int""" 370 | return __umfpack.umfpack_di_report_symbolic(*args) 371 | 372 | def umfpack_dl_report_symbolic(*args): 373 | """umfpack_dl_report_symbolic(void Symbolic, double Control) -> UF_long""" 374 | return __umfpack.umfpack_dl_report_symbolic(*args) 375 | 376 | def umfpack_zi_report_symbolic(*args): 377 | """umfpack_zi_report_symbolic(void Symbolic, double Control) -> int""" 378 | return __umfpack.umfpack_zi_report_symbolic(*args) 379 | 380 | def umfpack_zl_report_symbolic(*args): 381 | """umfpack_zl_report_symbolic(void Symbolic, double Control) -> UF_long""" 382 | return __umfpack.umfpack_zl_report_symbolic(*args) 383 | 384 | def umfpack_di_report_numeric(*args): 385 | """umfpack_di_report_numeric(void Numeric, double Control) -> int""" 386 | return __umfpack.umfpack_di_report_numeric(*args) 387 | 388 | def umfpack_dl_report_numeric(*args): 389 | """umfpack_dl_report_numeric(void Numeric, double Control) -> UF_long""" 390 | return __umfpack.umfpack_dl_report_numeric(*args) 391 | 392 | def umfpack_zi_report_numeric(*args): 393 | """umfpack_zi_report_numeric(void Numeric, double Control) -> int""" 394 | return __umfpack.umfpack_zi_report_numeric(*args) 395 | 396 | def umfpack_zl_report_numeric(*args): 397 | """umfpack_zl_report_numeric(void Numeric, double Control) -> UF_long""" 398 | return __umfpack.umfpack_zl_report_numeric(*args) 399 | 400 | def umfpack_di_report_info(*args): 401 | """umfpack_di_report_info(double Control, double Info)""" 402 | return __umfpack.umfpack_di_report_info(*args) 403 | 404 | def umfpack_dl_report_info(*args): 405 | """umfpack_dl_report_info(double Control, double Info)""" 406 | return __umfpack.umfpack_dl_report_info(*args) 407 | 408 | def umfpack_zi_report_info(*args): 409 | """umfpack_zi_report_info(double Control, double Info)""" 410 | return __umfpack.umfpack_zi_report_info(*args) 411 | 412 | def umfpack_zl_report_info(*args): 413 | """umfpack_zl_report_info(double Control, double Info)""" 414 | return __umfpack.umfpack_zl_report_info(*args) 415 | 416 | def umfpack_di_report_control(*args): 417 | """umfpack_di_report_control(double Control)""" 418 | return __umfpack.umfpack_di_report_control(*args) 419 | 420 | def umfpack_dl_report_control(*args): 421 | """umfpack_dl_report_control(double Control)""" 422 | return __umfpack.umfpack_dl_report_control(*args) 423 | 424 | def umfpack_zi_report_control(*args): 425 | """umfpack_zi_report_control(double Control)""" 426 | return __umfpack.umfpack_zi_report_control(*args) 427 | 428 | def umfpack_zl_report_control(*args): 429 | """umfpack_zl_report_control(double Control)""" 430 | return __umfpack.umfpack_zl_report_control(*args) 431 | 432 | def umfpack_di_symbolic(*args): 433 | """ 434 | umfpack_di_symbolic(int n_row, int n_col, int Ap, int Ai, double Ax, void Symbolic, 435 | double Control, double Info) -> int 436 | """ 437 | return __umfpack.umfpack_di_symbolic(*args) 438 | 439 | def umfpack_dl_symbolic(*args): 440 | """ 441 | umfpack_dl_symbolic(UF_long n_row, UF_long n_col, UF_long Ap, UF_long Ai, 442 | double Ax, void Symbolic, double Control, 443 | double Info) -> UF_long 444 | """ 445 | return __umfpack.umfpack_dl_symbolic(*args) 446 | 447 | def umfpack_zi_symbolic(*args): 448 | """ 449 | umfpack_zi_symbolic(int n_row, int n_col, int Ap, int Ai, double Ax, double Az, 450 | void Symbolic, double Control, double Info) -> int 451 | """ 452 | return __umfpack.umfpack_zi_symbolic(*args) 453 | 454 | def umfpack_zl_symbolic(*args): 455 | """ 456 | umfpack_zl_symbolic(UF_long n_row, UF_long n_col, UF_long Ap, UF_long Ai, 457 | double Ax, double Az, void Symbolic, double Control, 458 | double Info) -> UF_long 459 | """ 460 | return __umfpack.umfpack_zl_symbolic(*args) 461 | 462 | def umfpack_di_numeric(*args): 463 | """ 464 | umfpack_di_numeric(int Ap, int Ai, double Ax, void Symbolic, void Numeric, 465 | double Control, double Info) -> int 466 | """ 467 | return __umfpack.umfpack_di_numeric(*args) 468 | 469 | def umfpack_dl_numeric(*args): 470 | """ 471 | umfpack_dl_numeric(UF_long Ap, UF_long Ai, double Ax, void Symbolic, void Numeric, 472 | double Control, double Info) -> UF_long 473 | """ 474 | return __umfpack.umfpack_dl_numeric(*args) 475 | 476 | def umfpack_zi_numeric(*args): 477 | """ 478 | umfpack_zi_numeric(int Ap, int Ai, double Ax, double Az, void Symbolic, 479 | void Numeric, double Control, double Info) -> int 480 | """ 481 | return __umfpack.umfpack_zi_numeric(*args) 482 | 483 | def umfpack_zl_numeric(*args): 484 | """ 485 | umfpack_zl_numeric(UF_long Ap, UF_long Ai, double Ax, double Az, void Symbolic, 486 | void Numeric, double Control, double Info) -> UF_long 487 | """ 488 | return __umfpack.umfpack_zl_numeric(*args) 489 | 490 | def umfpack_di_free_symbolic(*args): 491 | """umfpack_di_free_symbolic(void Symbolic)""" 492 | return __umfpack.umfpack_di_free_symbolic(*args) 493 | 494 | def umfpack_dl_free_symbolic(*args): 495 | """umfpack_dl_free_symbolic(void Symbolic)""" 496 | return __umfpack.umfpack_dl_free_symbolic(*args) 497 | 498 | def umfpack_zi_free_symbolic(*args): 499 | """umfpack_zi_free_symbolic(void Symbolic)""" 500 | return __umfpack.umfpack_zi_free_symbolic(*args) 501 | 502 | def umfpack_zl_free_symbolic(*args): 503 | """umfpack_zl_free_symbolic(void Symbolic)""" 504 | return __umfpack.umfpack_zl_free_symbolic(*args) 505 | 506 | def umfpack_di_free_numeric(*args): 507 | """umfpack_di_free_numeric(void Numeric)""" 508 | return __umfpack.umfpack_di_free_numeric(*args) 509 | 510 | def umfpack_dl_free_numeric(*args): 511 | """umfpack_dl_free_numeric(void Numeric)""" 512 | return __umfpack.umfpack_dl_free_numeric(*args) 513 | 514 | def umfpack_zi_free_numeric(*args): 515 | """umfpack_zi_free_numeric(void Numeric)""" 516 | return __umfpack.umfpack_zi_free_numeric(*args) 517 | 518 | def umfpack_zl_free_numeric(*args): 519 | """umfpack_zl_free_numeric(void Numeric)""" 520 | return __umfpack.umfpack_zl_free_numeric(*args) 521 | 522 | def umfpack_di_get_lunz(*args): 523 | """ 524 | umfpack_di_get_lunz(int lnz, int unz, int n_row, int n_col, int nz_udiag, 525 | void Numeric) -> int 526 | """ 527 | return __umfpack.umfpack_di_get_lunz(*args) 528 | 529 | def umfpack_dl_get_lunz(*args): 530 | """ 531 | umfpack_dl_get_lunz(UF_long lnz, UF_long unz, UF_long n_row, UF_long n_col, 532 | UF_long nz_udiag, void Numeric) -> UF_long 533 | """ 534 | return __umfpack.umfpack_dl_get_lunz(*args) 535 | 536 | def umfpack_zi_get_lunz(*args): 537 | """ 538 | umfpack_zi_get_lunz(int lnz, int unz, int n_row, int n_col, int nz_udiag, 539 | void Numeric) -> int 540 | """ 541 | return __umfpack.umfpack_zi_get_lunz(*args) 542 | 543 | def umfpack_zl_get_lunz(*args): 544 | """ 545 | umfpack_zl_get_lunz(UF_long lnz, UF_long unz, UF_long n_row, UF_long n_col, 546 | UF_long nz_udiag, void Numeric) -> UF_long 547 | """ 548 | return __umfpack.umfpack_zl_get_lunz(*args) 549 | 550 | def umfpack_di_get_numeric(*args): 551 | """ 552 | umfpack_di_get_numeric(int Lp, int Lj, double Lx, int Up, int Ui, double Ux, 553 | int P, int Q, double Dx, int do_recip, double Rs, 554 | void Numeric) -> int 555 | """ 556 | return __umfpack.umfpack_di_get_numeric(*args) 557 | 558 | def umfpack_dl_get_numeric(*args): 559 | """ 560 | umfpack_dl_get_numeric(UF_long Lp, UF_long Lj, double Lx, UF_long Up, UF_long Ui, 561 | double Ux, UF_long P, UF_long Q, double Dx, 562 | UF_long do_recip, double Rs, void Numeric) -> UF_long 563 | """ 564 | return __umfpack.umfpack_dl_get_numeric(*args) 565 | 566 | def umfpack_zi_get_numeric(*args): 567 | """ 568 | umfpack_zi_get_numeric(int Lp, int Lj, double Lx, double Lz, int Up, int Ui, 569 | double Ux, double Uz, int P, int Q, double Dx, 570 | double Dz, int do_recip, double Rs, void Numeric) -> int 571 | """ 572 | return __umfpack.umfpack_zi_get_numeric(*args) 573 | 574 | def umfpack_zl_get_numeric(*args): 575 | """ 576 | umfpack_zl_get_numeric(UF_long Lp, UF_long Lj, double Lx, double Lz, UF_long Up, 577 | UF_long Ui, double Ux, double Uz, UF_long P, 578 | UF_long Q, double Dx, double Dz, UF_long do_recip, 579 | double Rs, void Numeric) -> UF_long 580 | """ 581 | return __umfpack.umfpack_zl_get_numeric(*args) 582 | 583 | 584 | -------------------------------------------------------------------------------- /scikits/umfpack/umfpack.py: -------------------------------------------------------------------------------- 1 | """ 2 | Interface to the UMFPACK library. 3 | 4 | -- 5 | Author: Robert Cimrman 6 | """ 7 | 8 | from __future__ import division, print_function, absolute_import 9 | 10 | import re 11 | import warnings 12 | 13 | from scipy.lib.six import iteritems 14 | 15 | import numpy as np 16 | import scipy.sparse as sp 17 | try: # Silence import error. 18 | from . import _umfpack as _um 19 | except: 20 | _um = None 21 | 22 | assumeSortedIndices = False 23 | 24 | 25 | class UmfpackWarning(UserWarning): 26 | pass 27 | 28 | 29 | ## 30 | # 10.01.2006, c 31 | def configure(**kwargs): 32 | """ 33 | Valid keyword arguments with defaults (other ignored): 34 | assumeSortedIndices = False 35 | 36 | Umfpack requires a CSR/CSC matrix to have sorted column/row indices. If 37 | sure that the matrix fulfills this, pass assumeSortedIndices = 38 | True to gain some speed. 39 | """ 40 | if 'assumeSortedIndices' in kwargs: 41 | globals()['assumeSortedIndices'] = kwargs['assumeSortedIndices'] 42 | 43 | 44 | ## 45 | # 30.11.2005, c 46 | def updateDictWithVars(adict, module, pattern, group=None): 47 | match = re.compile(pattern).match 48 | 49 | for name in [ii for ii in vars(module) 50 | if match(ii)]: 51 | if group is not None: 52 | outName = match(name).group(group) 53 | else: 54 | outName = name 55 | 56 | adict[outName] = module.__dict__[name] 57 | 58 | return adict 59 | 60 | ## 61 | # How to list these automagically? 62 | umfControls = [ 63 | 'UMFPACK_PRL', 64 | 'UMFPACK_DENSE_ROW', 65 | 'UMFPACK_DENSE_COL', 66 | 'UMFPACK_BLOCK_SIZE', 67 | 'UMFPACK_STRATEGY', 68 | 'UMFPACK_2BY2_TOLERANCE', 69 | 'UMFPACK_FIXQ', 70 | 'UMFPACK_AMD_DENSE', 71 | 'UMFPACK_AGGRESSIVE', 72 | 'UMFPACK_PIVOT_TOLERANCE', 73 | 'UMFPACK_ALLOC_INIT', 74 | 'UMFPACK_SYM_PIVOT_TOLERANCE', 75 | 'UMFPACK_SCALE', 76 | 'UMFPACK_FRONT_ALLOC_INIT', 77 | 'UMFPACK_DROPTOL', 78 | 'UMFPACK_IRSTEP', 79 | 'UMFPACK_COMPILED_WITH_BLAS', 80 | 'UMFPACK_COMPILED_FOR_MATLAB', 81 | 'UMFPACK_COMPILED_WITH_GETRUSAGE', 82 | 'UMFPACK_COMPILED_IN_DEBUG_MODE', 83 | 'UMFPACK_STRATEGY_AUTO', 84 | 'UMFPACK_STRATEGY_UNSYMMETRIC', 85 | 'UMFPACK_STRATEGY_2BY2', 86 | 'UMFPACK_STRATEGY_SYMMETRIC', 87 | 'UMFPACK_SCALE_NONE', 88 | 'UMFPACK_SCALE_SUM', 89 | 'UMFPACK_SCALE_MAX', 90 | ] 91 | 92 | umfInfo = [ 93 | 'UMFPACK_STATUS', 94 | 'UMFPACK_NROW', 95 | 'UMFPACK_NCOL', 96 | 'UMFPACK_NZ', 97 | 'UMFPACK_SIZE_OF_UNIT', 98 | 'UMFPACK_SIZE_OF_INT', 99 | 'UMFPACK_SIZE_OF_LONG', 100 | 'UMFPACK_SIZE_OF_POINTER', 101 | 'UMFPACK_SIZE_OF_ENTRY', 102 | 'UMFPACK_NDENSE_ROW', 103 | 'UMFPACK_NEMPTY_ROW', 104 | 'UMFPACK_NDENSE_COL', 105 | 'UMFPACK_NEMPTY_COL', 106 | 'UMFPACK_SYMBOLIC_DEFRAG', 107 | 'UMFPACK_SYMBOLIC_PEAK_MEMORY', 108 | 'UMFPACK_SYMBOLIC_SIZE', 109 | 'UMFPACK_SYMBOLIC_TIME', 110 | 'UMFPACK_SYMBOLIC_WALLTIME', 111 | 'UMFPACK_STRATEGY_USED', 112 | 'UMFPACK_ORDERING_USED', 113 | 'UMFPACK_QFIXED', 114 | 'UMFPACK_DIAG_PREFERRED', 115 | 'UMFPACK_PATTERN_SYMMETRY', 116 | 'UMFPACK_NZ_A_PLUS_AT', 117 | 'UMFPACK_NZDIAG', 118 | 'UMFPACK_SYMMETRIC_LUNZ', 119 | 'UMFPACK_SYMMETRIC_FLOPS', 120 | 'UMFPACK_SYMMETRIC_NDENSE', 121 | 'UMFPACK_SYMMETRIC_DMAX', 122 | 'UMFPACK_2BY2_NWEAK', 123 | 'UMFPACK_2BY2_UNMATCHED', 124 | 'UMFPACK_2BY2_PATTERN_SYMMETRY', 125 | 'UMFPACK_2BY2_NZ_PA_PLUS_PAT', 126 | 'UMFPACK_2BY2_NZDIAG', 127 | 'UMFPACK_COL_SINGLETONS', 128 | 'UMFPACK_ROW_SINGLETONS', 129 | 'UMFPACK_N2', 130 | 'UMFPACK_S_SYMMETRIC', 131 | 'UMFPACK_NUMERIC_SIZE_ESTIMATE', 132 | 'UMFPACK_PEAK_MEMORY_ESTIMATE', 133 | 'UMFPACK_FLOPS_ESTIMATE', 134 | 'UMFPACK_LNZ_ESTIMATE', 135 | 'UMFPACK_UNZ_ESTIMATE', 136 | 'UMFPACK_VARIABLE_INIT_ESTIMATE', 137 | 'UMFPACK_VARIABLE_PEAK_ESTIMATE', 138 | 'UMFPACK_VARIABLE_FINAL_ESTIMATE', 139 | 'UMFPACK_MAX_FRONT_SIZE_ESTIMATE', 140 | 'UMFPACK_MAX_FRONT_NROWS_ESTIMATE', 141 | 'UMFPACK_MAX_FRONT_NCOLS_ESTIMATE', 142 | 'UMFPACK_NUMERIC_SIZE', 143 | 'UMFPACK_PEAK_MEMORY', 144 | 'UMFPACK_FLOPS', 145 | 'UMFPACK_LNZ', 146 | 'UMFPACK_UNZ', 147 | 'UMFPACK_VARIABLE_INIT', 148 | 'UMFPACK_VARIABLE_PEAK', 149 | 'UMFPACK_VARIABLE_FINAL', 150 | 'UMFPACK_MAX_FRONT_SIZE', 151 | 'UMFPACK_MAX_FRONT_NROWS', 152 | 'UMFPACK_MAX_FRONT_NCOLS', 153 | 'UMFPACK_NUMERIC_DEFRAG', 154 | 'UMFPACK_NUMERIC_REALLOC', 155 | 'UMFPACK_NUMERIC_COSTLY_REALLOC', 156 | 'UMFPACK_COMPRESSED_PATTERN', 157 | 'UMFPACK_LU_ENTRIES', 158 | 'UMFPACK_NUMERIC_TIME', 159 | 'UMFPACK_UDIAG_NZ', 160 | 'UMFPACK_RCOND', 161 | 'UMFPACK_WAS_SCALED', 162 | 'UMFPACK_RSMIN', 163 | 'UMFPACK_RSMAX', 164 | 'UMFPACK_UMIN', 165 | 'UMFPACK_UMAX', 166 | 'UMFPACK_ALLOC_INIT_USED', 167 | 'UMFPACK_FORCED_UPDATES', 168 | 'UMFPACK_NUMERIC_WALLTIME', 169 | 'UMFPACK_NOFF_DIAG', 170 | 'UMFPACK_ALL_LNZ', 171 | 'UMFPACK_ALL_UNZ', 172 | 'UMFPACK_NZDROPPED', 173 | 'UMFPACK_IR_TAKEN', 174 | 'UMFPACK_IR_ATTEMPTED', 175 | 'UMFPACK_OMEGA1', 176 | 'UMFPACK_OMEGA2', 177 | 'UMFPACK_SOLVE_FLOPS', 178 | 'UMFPACK_SOLVE_TIME', 179 | 'UMFPACK_SOLVE_WALLTIME', 180 | 'UMFPACK_ORDERING_COLAMD', 181 | 'UMFPACK_ORDERING_AMD', 182 | 'UMFPACK_ORDERING_GIVEN', 183 | ] 184 | 185 | if _um: 186 | ## 187 | # Export UMFPACK constants from _um. 188 | umfDefines = updateDictWithVars({}, _um, 'UMFPACK_.*') 189 | locals().update(umfDefines) 190 | 191 | umfStatus = { 192 | UMFPACK_OK: 'UMFPACK_OK', 193 | UMFPACK_WARNING_singular_matrix: 'UMFPACK_WARNING_singular_matrix', 194 | UMFPACK_WARNING_determinant_underflow: 'UMFPACK_WARNING_determinant_underflow', 195 | UMFPACK_WARNING_determinant_overflow: 'UMFPACK_WARNING_determinant_overflow', 196 | UMFPACK_ERROR_out_of_memory: 'UMFPACK_ERROR_out_of_memory', 197 | UMFPACK_ERROR_invalid_Numeric_object: 'UMFPACK_ERROR_invalid_Numeric_object', 198 | UMFPACK_ERROR_invalid_Symbolic_object: 'UMFPACK_ERROR_invalid_Symbolic_object', 199 | UMFPACK_ERROR_argument_missing: 'UMFPACK_ERROR_argument_missing', 200 | UMFPACK_ERROR_n_nonpositive: 'UMFPACK_ERROR_n_nonpositive', 201 | UMFPACK_ERROR_invalid_matrix: 'UMFPACK_ERROR_invalid_matrix', 202 | UMFPACK_ERROR_different_pattern: 'UMFPACK_ERROR_different_pattern', 203 | UMFPACK_ERROR_invalid_system: 'UMFPACK_ERROR_invalid_system', 204 | UMFPACK_ERROR_invalid_permutation: 'UMFPACK_ERROR_invalid_permutation', 205 | UMFPACK_ERROR_internal_error: 'UMFPACK_ERROR_internal_error', 206 | UMFPACK_ERROR_file_IO: 'UMFPACK_ERROR_file_IO', 207 | } 208 | 209 | umfSys = [ 210 | UMFPACK_A, 211 | UMFPACK_At, 212 | UMFPACK_Aat, 213 | UMFPACK_Pt_L, 214 | UMFPACK_L, 215 | UMFPACK_Lt_P, 216 | UMFPACK_Lat_P, 217 | UMFPACK_Lt, 218 | UMFPACK_U_Qt, 219 | UMFPACK_U, 220 | UMFPACK_Q_Ut, 221 | UMFPACK_Q_Uat, 222 | UMFPACK_Ut, 223 | UMFPACK_Uat, 224 | ] 225 | 226 | # Real, complex. 227 | umfSys_transposeMap = [ 228 | {UMFPACK_A: UMFPACK_At, 229 | UMFPACK_At: UMFPACK_A, 230 | UMFPACK_Aat: UMFPACK_A}, 231 | {UMFPACK_A: UMFPACK_Aat, 232 | UMFPACK_Aat: UMFPACK_A} 233 | ] 234 | 235 | umfFamilyTypes = {'di': int, 'dl': int, 'zi': int, 'zl': int} 236 | umfRealTypes = ('di', 'dl') 237 | umfComplexTypes = ('zi', 'zl') 238 | 239 | ## 240 | # 02.01.2005 241 | 242 | 243 | class Struct(object): 244 | # 03.10.2005, c 245 | # 26.10.2005 246 | def __init__(self, **kwargs): 247 | if kwargs: 248 | self.__dict__.update(kwargs) 249 | 250 | # 08.03.2005 251 | def __str__(self): 252 | ss = "%s\n" % self.__class__ 253 | for key, val in iteritems(self.__dict__): 254 | if (issubclass(self.__dict__[key].__class__, Struct)): 255 | ss += " %s:\n %s\n" % (key, self.__dict__[key].__class__) 256 | else: 257 | aux = "\n" + str(val) 258 | aux = aux.replace("\n", "\n ") 259 | ss += " %s:\n%s\n" % (key, aux[1:]) 260 | return(ss.rstrip()) 261 | 262 | ## 263 | # 30.11.2005, c 264 | 265 | 266 | class UmfpackContext(Struct): 267 | 268 | ## 269 | # 30.11.2005, c 270 | # 01.12.2005 271 | # 21.12.2005 272 | # 01.03.2006 273 | def __init__(self, family='di', **kwargs): 274 | """ 275 | Arguments: 276 | 277 | family .. family of UMFPACK functions ('di', 'dl', 'zi', 'zl') 278 | 279 | Keyword arguments: 280 | 281 | maxCond .. if extimated condition number is greater than maxCond, 282 | a warning is issued (default: 1e12)""" 283 | if _um is None: 284 | raise ImportError('Scipy was built without UMFPACK support. ' 285 | 'You need to install the UMFPACK library and ' 286 | 'header files before building scipy.') 287 | 288 | self.maxCond = 1e12 289 | Struct.__init__(self, **kwargs) 290 | 291 | if family not in umfFamilyTypes: 292 | raise TypeError('wrong family: %s' % family) 293 | 294 | self.family = family 295 | self.control = np.zeros((UMFPACK_CONTROL,), dtype=np.double) 296 | self.info = np.zeros((UMFPACK_INFO,), dtype=np.double) 297 | self._symbolic = None 298 | self._numeric = None 299 | self.mtx = None 300 | self.isReal = self.family in umfRealTypes 301 | 302 | ## 303 | # Functions corresponding to are stored in self.funs. 304 | pattern = 'umfpack_' + family + '_(.*)' 305 | fn = updateDictWithVars({}, _um, pattern, group=1) 306 | self.funs = Struct(**fn) 307 | 308 | self.funs.defaults(self.control) 309 | self.control[UMFPACK_PRL] = 3 310 | 311 | def __del__(self): 312 | if _um is not None: 313 | self.free() 314 | 315 | ## 316 | # 30.11.2005, c 317 | def strControl(self): 318 | maxLen = max([len(name) for name in umfControls]) 319 | format = '%%-%ds : %%d' % maxLen 320 | aux = [format % (name, self.control[umfDefines[name]]) 321 | for name in umfControls if name in umfDefines] 322 | return '\n'.join(aux) 323 | 324 | ## 325 | # 01.12.2005, c 326 | def strInfo(self): 327 | maxLen = max([len(name) for name in umfInfo]) 328 | format = '%%-%ds : %%d' % maxLen 329 | aux = [format % (name, self.info[umfDefines[name]]) 330 | for name in umfInfo if name in umfDefines] 331 | return '\n'.join(aux) 332 | 333 | ## 334 | # 30.11.2005, c 335 | # 01.12.2005 336 | # 14.12.2005 337 | # 01.03.2006 338 | def _getIndx(self, mtx): 339 | 340 | if sp.isspmatrix_csc(mtx): 341 | indx = mtx.indices 342 | self.isCSR = 0 343 | elif sp.isspmatrix_csr(mtx): 344 | indx = mtx.indices 345 | self.isCSR = 1 346 | else: 347 | raise TypeError('must be a CSC/CSR matrix (is %s)' % mtx.__class__) 348 | 349 | ## 350 | # Should check types of indices to correspond to familyTypes. 351 | if self.family[1] == 'i': 352 | if (indx.dtype != np.dtype('i')) \ 353 | or mtx.indptr.dtype != np.dtype('i'): 354 | raise ValueError('matrix must have int indices') 355 | else: 356 | if (indx.dtype != np.dtype('l')) \ 357 | or mtx.indptr.dtype != np.dtype('l'): 358 | raise ValueError('matrix must have long indices') 359 | 360 | if self.isReal: 361 | if mtx.data.dtype != np.dtype('f8'): 362 | raise ValueError('matrix must have float64 values') 363 | else: 364 | if mtx.data.dtype != np.dtype('c16'): 365 | raise ValueError('matrix must have complex128 values') 366 | 367 | return indx 368 | 369 | ## 370 | # 30.11.2005, c 371 | # last revision: 10.01.2007 372 | def symbolic(self, mtx): 373 | """Symbolic object (symbolic LU decomposition) computation for a given 374 | sparsity pattern.""" 375 | self.free_symbolic() 376 | 377 | indx = self._getIndx(mtx) 378 | 379 | if not assumeSortedIndices: 380 | # row/column indices cannot be assumed to be sorted 381 | mtx.sort_indices() 382 | 383 | if self.isReal: 384 | status, self._symbolic\ 385 | = self.funs.symbolic(mtx.shape[0], mtx.shape[1], 386 | mtx.indptr, indx, mtx.data, 387 | self.control, self.info) 388 | else: 389 | real, imag = mtx.data.real.copy(), mtx.data.imag.copy() 390 | status, self._symbolic\ 391 | = self.funs.symbolic(mtx.shape[0], mtx.shape[1], 392 | mtx.indptr, indx, 393 | real, imag, 394 | self.control, self.info) 395 | 396 | if status != UMFPACK_OK: 397 | raise RuntimeError('%s failed with %s' % (self.funs.symbolic, 398 | umfStatus[status])) 399 | 400 | self.mtx = mtx 401 | 402 | ## 403 | # 30.11.2005, c 404 | # 01.12.2005 405 | # 02.12.2005 406 | # 01.03.2006 407 | def numeric(self, mtx): 408 | """Numeric object (LU decomposition) computation using the 409 | symbolic decomposition. The symbolic decomposition is (re)computed 410 | if necessary.""" 411 | 412 | self.free_numeric() 413 | 414 | if self._symbolic is None: 415 | self.symbolic(mtx) 416 | 417 | indx = self._getIndx(mtx) 418 | 419 | failCount = 0 420 | while 1: 421 | if self.isReal: 422 | status, self._numeric\ 423 | = self.funs.numeric(mtx.indptr, indx, mtx.data, 424 | self._symbolic, 425 | self.control, self.info) 426 | else: 427 | real, imag = mtx.data.real.copy(), mtx.data.imag.copy() 428 | status, self._numeric\ 429 | = self.funs.numeric(mtx.indptr, indx, 430 | real, imag, 431 | self._symbolic, 432 | self.control, self.info) 433 | 434 | if status != UMFPACK_OK: 435 | if status == UMFPACK_WARNING_singular_matrix: 436 | warnings.warn('Singular matrix', UmfpackWarning) 437 | break 438 | elif status in (UMFPACK_ERROR_different_pattern, 439 | UMFPACK_ERROR_invalid_Symbolic_object): 440 | # Try again. 441 | warnings.warn('Recomputing symbolic', UmfpackWarning) 442 | self.symbolic(mtx) 443 | failCount += 1 444 | else: 445 | failCount += 100 446 | else: 447 | break 448 | if failCount >= 2: 449 | raise RuntimeError('%s failed with %s' % (self.funs.numeric, 450 | umfStatus[status])) 451 | 452 | ## 453 | # 14.12.2005, c 454 | def report_symbolic(self): 455 | """Print information about the symbolic object. Output depends on 456 | self.control[UMFPACK_PRL].""" 457 | self.funs.report_symbolic(self._symbolic, self.control) 458 | 459 | ## 460 | # 14.12.2005, c 461 | def report_numeric(self): 462 | """Print information about the numeric object. Output depends on 463 | self.control[UMFPACK_PRL].""" 464 | self.funs.report_numeric(self._numeric, self.control) 465 | 466 | ## 467 | # 14.12.2005, c 468 | def report_control(self): 469 | """Print control values.""" 470 | self.funs.report_control(self.control) 471 | 472 | ## 473 | # 14.12.2005, c 474 | def report_info(self): 475 | """Print all status information. Output depends on 476 | self.control[UMFPACK_PRL].""" 477 | self.funs.report_info(self.control, self.info) 478 | 479 | ## 480 | # 30.11.2005, c 481 | # 01.12.2005 482 | def free_symbolic(self): 483 | if self._symbolic is not None: 484 | self.funs.free_symbolic(self._symbolic) 485 | self._symbolic = None 486 | self.mtx = None 487 | 488 | ## 489 | # 30.11.2005, c 490 | # 01.12.2005 491 | def free_numeric(self): 492 | if self._numeric is not None: 493 | self.funs.free_numeric(self._numeric) 494 | self._numeric = None 495 | self.free_symbolic() 496 | 497 | ## 498 | # 30.11.2005, c 499 | def free(self): 500 | self.free_symbolic() 501 | self.free_numeric() 502 | 503 | ## 504 | # 30.11.2005, c 505 | # 01.12.2005 506 | # 02.12.2005 507 | # 21.12.2005 508 | # 01.03.2006 509 | def solve(self, sys, mtx, rhs, autoTranspose=False): 510 | """ 511 | Solution of system of linear equation using the Numeric object. 512 | 513 | Arguments: 514 | sys - one of UMFPACK system description constants, like 515 | UMFPACK_A, UMFPACK_At, see umfSys list and UMFPACK 516 | docs 517 | mtx - sparse matrix (CSR or CSC) 518 | rhs - right hand side vector 519 | autoTranspose - automatically changes 'sys' to the 520 | transposed type, if 'mtx' is in CSR, since UMFPACK 521 | assumes CSC internally 522 | """ 523 | if sys not in umfSys: 524 | raise ValueError('sys must be in' % umfSys) 525 | 526 | if autoTranspose and self.isCSR: 527 | ## 528 | # UMFPACK uses CSC internally... 529 | if self.family in umfRealTypes: 530 | ii = 0 531 | else: 532 | ii = 1 533 | if sys in umfSys_transposeMap[ii]: 534 | sys = umfSys_transposeMap[ii][sys] 535 | else: 536 | raise RuntimeError('autoTranspose ambiguous, switch it off') 537 | 538 | if self._numeric is not None: 539 | if self.mtx is not mtx: 540 | raise ValueError('must be called with same matrix as numeric()') 541 | else: 542 | raise RuntimeError('numeric() not called') 543 | 544 | indx = self._getIndx(mtx) 545 | 546 | if self.isReal: 547 | rhs = rhs.astype(np.float64) 548 | sol = np.zeros((mtx.shape[1],), dtype=np.float64) 549 | status = self.funs.solve(sys, mtx.indptr, indx, mtx.data, sol, rhs, 550 | self._numeric, self.control, self.info) 551 | else: 552 | rhs = rhs.astype(np.complex128) 553 | sol = np.zeros((mtx.shape[1],), dtype=np.complex128) 554 | mreal, mimag = mtx.data.real.copy(), mtx.data.imag.copy() 555 | sreal, simag = sol.real.copy(), sol.imag.copy() 556 | rreal, rimag = rhs.real.copy(), rhs.imag.copy() 557 | status = self.funs.solve(sys, mtx.indptr, indx, 558 | mreal, mimag, sreal, simag, rreal, rimag, 559 | self._numeric, self.control, self.info) 560 | sol.real, sol.imag = sreal, simag 561 | 562 | # self.funs.report_info( self.control, self.info ) 563 | # pause() 564 | if status != UMFPACK_OK: 565 | if status == UMFPACK_WARNING_singular_matrix: 566 | ## Change inf, nan to zeros. 567 | warnings.warn('Zeroing nan and inf entries...', UmfpackWarning) 568 | sol[~np.isfinite(sol)] = 0.0 569 | else: 570 | raise RuntimeError('%s failed with %s' % (self.funs.solve, 571 | umfStatus[status])) 572 | econd = 1.0 / self.info[UMFPACK_RCOND] 573 | if econd > self.maxCond: 574 | msg = '(almost) singular matrix! '\ 575 | + '(estimated cond. number: %.2e)' % econd 576 | warnings.warn(msg, UmfpackWarning) 577 | 578 | return sol 579 | 580 | ## 581 | # 30.11.2005, c 582 | # 01.12.2005 583 | def linsolve(self, sys, mtx, rhs, autoTranspose=False): 584 | """ 585 | One-shot solution of system of linear equation. Reuses Numeric object 586 | if possible. 587 | 588 | Arguments: 589 | sys - one of UMFPACK system description constants, like 590 | UMFPACK_A, UMFPACK_At, see umfSys list and UMFPACK 591 | docs 592 | mtx - sparse matrix (CSR or CSC) 593 | rhs - right hand side vector 594 | autoTranspose - automatically changes 'sys' to the 595 | transposed type, if 'mtx' is in CSR, since UMFPACK 596 | assumes CSC internally 597 | """ 598 | 599 | if sys not in umfSys: 600 | raise ValueError('sys must be in' % umfSys) 601 | 602 | if self._numeric is None: 603 | self.numeric(mtx) 604 | else: 605 | if self.mtx is not mtx: 606 | self.numeric(mtx) 607 | 608 | sol = self.solve(sys, mtx, rhs, autoTranspose) 609 | self.free_numeric() 610 | 611 | return sol 612 | 613 | ## 614 | # 30.11.2005, c 615 | # 01.12.2005 616 | def __call__(self, sys, mtx, rhs, autoTranspose=False): 617 | """ 618 | Uses solve() or linsolve() depending on the presence of the Numeric 619 | object. 620 | 621 | Arguments: 622 | sys - one of UMFPACK system description constants, like 623 | UMFPACK_A, UMFPACK_At, see umfSys list and UMFPACK 624 | docs 625 | mtx - sparse matrix (CSR or CSC) 626 | rhs - right hand side vector 627 | autoTranspose - automatically changes 'sys' to the 628 | transposed type, if 'mtx' is in CSR, since UMFPACK 629 | assumes CSC internally 630 | """ 631 | 632 | if self._numeric is not None: 633 | return self.solve(sys, mtx, rhs, autoTranspose) 634 | else: 635 | return self.linsolve(sys, mtx, rhs, autoTranspose) 636 | 637 | ## 638 | # 21.09.2006, added by Nathan Bell 639 | def lu(self, mtx): 640 | """ 641 | Returns an LU decomposition of an m-by-n matrix in the form 642 | (L, U, P, Q, R, do_recip): 643 | 644 | L - Lower triangular m-by-min(m,n) CSR matrix 645 | U - Upper triangular min(m,n)-by-n CSC matrix 646 | P - Vector of row permuations 647 | Q - Vector of column permuations 648 | R - Vector of diagonal row scalings 649 | do_recip - boolean 650 | 651 | For a given matrix A, the decomposition satisfies: 652 | LU = PRAQ when do_recip is true 653 | LU = P(R^-1)AQ when do_recip is false 654 | """ 655 | 656 | # this should probably be changed 657 | mtx = mtx.tocsc() 658 | self.numeric(mtx) 659 | 660 | # first find out how much space to reserve 661 | (status, lnz, unz, n_row, n_col, nz_udiag)\ 662 | = self.funs.get_lunz(self._numeric) 663 | 664 | if status != UMFPACK_OK: 665 | raise RuntimeError('%s failed with %s' % (self.funs.get_lunz, 666 | umfStatus[status])) 667 | 668 | # allocate storage for decomposition data 669 | i_type = mtx.indptr.dtype 670 | 671 | Lp = np.zeros((n_row+1,), dtype=i_type) 672 | Lj = np.zeros((lnz,), dtype=i_type) 673 | Lx = np.zeros((lnz,), dtype=np.double) 674 | 675 | Up = np.zeros((n_col+1,), dtype=i_type) 676 | Ui = np.zeros((unz,), dtype=i_type) 677 | Ux = np.zeros((unz,), dtype=np.double) 678 | 679 | P = np.zeros((n_row,), dtype=i_type) 680 | Q = np.zeros((n_col,), dtype=i_type) 681 | 682 | Dx = np.zeros((min(n_row,n_col),), dtype=np.double) 683 | 684 | Rs = np.zeros((n_row,), dtype=np.double) 685 | 686 | if self.isReal: 687 | (status,do_recip) = self.funs.get_numeric(Lp,Lj,Lx,Up,Ui,Ux, 688 | P,Q,Dx,Rs, 689 | self._numeric) 690 | 691 | if status != UMFPACK_OK: 692 | raise RuntimeError('%s failed with %s' 693 | % (self.funs.get_numeric, umfStatus[status])) 694 | 695 | L = sp.csr_matrix((Lx,Lj,Lp),(n_row,min(n_row,n_col))) 696 | U = sp.csc_matrix((Ux,Ui,Up),(min(n_row,n_col),n_col)) 697 | R = Rs 698 | 699 | return (L,U,P,Q,R,bool(do_recip)) 700 | 701 | else: 702 | # allocate additional storage for imaginary parts 703 | Lz = np.zeros((lnz,), dtype=np.double) 704 | Uz = np.zeros((unz,), dtype=np.double) 705 | Dz = np.zeros((min(n_row,n_col),), dtype=np.double) 706 | 707 | (status,do_recip) = self.funs.get_numeric(Lp,Lj,Lx,Lz,Up,Ui,Ux,Uz, 708 | P,Q,Dx,Dz,Rs, 709 | self._numeric) 710 | 711 | if status != UMFPACK_OK: 712 | raise RuntimeError('%s failed with %s' 713 | % (self.funs.get_numeric, umfStatus[status])) 714 | 715 | Lxz = np.zeros((lnz,), dtype=np.complex128) 716 | Uxz = np.zeros((unz,), dtype=np.complex128) 717 | Dxz = np.zeros((min(n_row,n_col),), dtype=np.complex128) 718 | 719 | Lxz.real,Lxz.imag = Lx,Lz 720 | Uxz.real,Uxz.imag = Ux,Uz 721 | Dxz.real,Dxz.imag = Dx,Dz 722 | 723 | L = sp.csr_matrix((Lxz,Lj,Lp),(n_row,min(n_row,n_col))) 724 | U = sp.csc_matrix((Uxz,Ui,Up),(min(n_row,n_col),n_col)) 725 | R = Rs 726 | 727 | return (L,U,P,Q,R,bool(do_recip)) 728 | --------------------------------------------------------------------------------