22from mumps import Context
33
44class Mumps (Base ):
5- """
6- Mumps solver
5+ """The MUMPS direct solver.
6+
7+ This solver uses the python-mumps wrappers to factorize a sparse matrix, and use that factorization for solving.
8+
9+ Parameters
10+ ----------
11+ A
12+ Matrix to solve with.
13+ ordering : str, default 'metis'
14+ Which ordering algorithm to use. See the `python-mumps` documentation for more details.
15+ is_symmetric : bool, optional
16+ Whether the matrix is symmetric. By default, it will perform some simple tests to check for symmetry, and
17+ default to ``False`` if those fail.
18+ is_positive_definite : bool, optional
19+ Whether the matrix is positive definite.
20+ check_accuracy : bool, optional
21+ Whether to check the accuracy of the solution.
22+ check_rtol : float, optional
23+ The relative tolerance to check against for accuracy.
24+ check_atol : float, optional
25+ The absolute tolerance to check against for accuracy.
26+ accuracy_tol : float, optional
27+ Relative accuracy tolerance.
28+ .. deprecated:: 0.3.0
29+ `accuracy_tol` will be removed in pymatsolver 0.4.0. Use `check_rtol` and `check_atol` instead.
30+ **kwargs
31+ Extra keyword arguments. If there are any left here a warning will be raised.
732 """
833 _transposed = False
9- ordering = ''
1034
11- def __init__ (self , A , ** kwargs ):
12- self .set_kwargs (** kwargs )
35+ def __init__ (self , A , ordering = None , is_symmetric = None , is_positive_definite = False , check_accuracy = False , check_rtol = 1e-6 , check_atol = 0 , accuracy_tol = None , ** kwargs ):
36+ is_hermitian = kwargs .pop ('is_hermitian' , False )
37+ super ().__init__ (A , is_symmetric = is_symmetric , is_positive_definite = is_positive_definite , is_hermitian = is_hermitian , check_accuracy = check_accuracy , check_rtol = check_rtol , check_atol = check_atol , accuracy_tol = accuracy_tol , ** kwargs )
38+ if ordering is None :
39+ ordering = "metis"
40+ self .ordering = ordering
1341 self .solver = Context ()
14- self ._set_A (A )
15- self .A = A
42+ self ._set_A (self .A )
1643
1744 def _set_A (self , A ):
1845 self .solver .set_matrix (
1946 A ,
2047 symmetric = self .is_symmetric ,
21- # positive_definite=self.is_positive_definite # doesn't (yet) support setting positive definiteness
2248 )
2349
2450 @property
2551 def ordering (self ):
26- return getattr (self , '_ordering' , "metis" )
52+ """The ordering algorithm to use.
53+
54+ Returns
55+ -------
56+ str
57+ """
58+ return self ._ordering
2759
2860 @ordering .setter
2961 def ordering (self , value ):
30- self ._ordering = value
62+ self ._ordering = str ( value )
3163
3264 @property
3365 def _factored (self ):
3466 return self .solver .factored
3567
36- @property
68+ def get_attributes (self ):
69+ attrs = super ().get_attributes ()
70+ attrs ['ordering' ] = self .ordering
71+ return attrs
72+
3773 def transpose (self ):
3874 trans_obj = Mumps .__new__ (Mumps )
39- trans_obj .A = self .A
75+ trans_obj ._A = self .A
76+ for attr , value in self .get_attributes ().items ():
77+ setattr (trans_obj , attr , value )
4078 trans_obj .solver = self .solver
41- trans_obj .is_symmetric = self .is_symmetric
42- trans_obj .is_positive_definite = self .is_positive_definite
43- trans_obj .ordering = self .ordering
4479 trans_obj ._transposed = not self ._transposed
4580 return trans_obj
4681
47- T = transpose
48-
4982 def factor (self , A = None ):
50- reuse_analysis = False
51- if A is not None :
52- self ._set_A (A )
53- self .A = A
83+ """(Re)factor the A matrix.
84+
85+ Parameters
86+ ----------
87+ A : scipy.sparse.spmatrix
88+ The matrix to be factorized. If a previous factorization has been performed, this will
89+ reuse the previous factorization's analysis.
90+ """
91+ reuse_analysis = self ._factored
92+ do_factor = not self ._factored
93+ if A is not None and A is not self .A :
5494 # if it was previously factored then re-use the analysis.
55- reuse_analysis = self ._factored
56- if not self ._factored :
95+ self ._set_A (A )
96+ self ._A = A
97+ do_factor = True
98+ if do_factor :
5799 pivot_tol = 0.0 if self .is_positive_definite else 0.01
58100 self .solver .factor (
59101 ordering = self .ordering , reuse_analysis = reuse_analysis , pivot_tol = pivot_tol
60102 )
61103
62- def _solveM (self , rhs ):
104+ def _solve_multiple (self , rhs ):
63105 self .factor ()
64106 if self ._transposed :
65107 self .solver .mumps_instance .icntl [9 ] = 0
@@ -68,4 +110,4 @@ def _solveM(self, rhs):
68110 sol = self .solver .solve (rhs )
69111 return sol
70112
71- _solve1 = _solveM
113+ _solve_single = _solve_multiple
0 commit comments