Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1__docformat__ = "restructuredtext en" 

2 

3__all__ = [] 

4 

5 

6from numpy import asanyarray, asarray, array, matrix, zeros 

7from scipy.sparse.sputils import asmatrix 

8 

9from scipy.sparse.linalg.interface import aslinearoperator, LinearOperator, \ 

10 IdentityOperator 

11 

12_coerce_rules = {('f','f'):'f', ('f','d'):'d', ('f','F'):'F', 

13 ('f','D'):'D', ('d','f'):'d', ('d','d'):'d', 

14 ('d','F'):'D', ('d','D'):'D', ('F','f'):'F', 

15 ('F','d'):'D', ('F','F'):'F', ('F','D'):'D', 

16 ('D','f'):'D', ('D','d'):'D', ('D','F'):'D', 

17 ('D','D'):'D'} 

18 

19 

20def coerce(x,y): 

21 if x not in 'fdFD': 

22 x = 'd' 

23 if y not in 'fdFD': 

24 y = 'd' 

25 return _coerce_rules[x,y] 

26 

27 

28def id(x): 

29 return x 

30 

31 

32def make_system(A, M, x0, b): 

33 """Make a linear system Ax=b 

34 

35 Parameters 

36 ---------- 

37 A : LinearOperator 

38 sparse or dense matrix (or any valid input to aslinearoperator) 

39 M : {LinearOperator, Nones} 

40 preconditioner 

41 sparse or dense matrix (or any valid input to aslinearoperator) 

42 x0 : {array_like, None} 

43 initial guess to iterative method 

44 b : array_like 

45 right hand side 

46 

47 Returns 

48 ------- 

49 (A, M, x, b, postprocess) 

50 A : LinearOperator 

51 matrix of the linear system 

52 M : LinearOperator 

53 preconditioner 

54 x : rank 1 ndarray 

55 initial guess 

56 b : rank 1 ndarray 

57 right hand side 

58 postprocess : function 

59 converts the solution vector to the appropriate 

60 type and dimensions (e.g. (N,1) matrix) 

61 

62 """ 

63 A_ = A 

64 A = aslinearoperator(A) 

65 

66 if A.shape[0] != A.shape[1]: 

67 raise ValueError('expected square matrix, but got shape=%s' % (A.shape,)) 

68 

69 N = A.shape[0] 

70 

71 b = asanyarray(b) 

72 

73 if not (b.shape == (N,1) or b.shape == (N,)): 

74 raise ValueError('A and b have incompatible dimensions') 

75 

76 if b.dtype.char not in 'fdFD': 

77 b = b.astype('d') # upcast non-FP types to double 

78 

79 def postprocess(x): 

80 if isinstance(b,matrix): 

81 x = asmatrix(x) 

82 return x.reshape(b.shape) 

83 

84 if hasattr(A,'dtype'): 

85 xtype = A.dtype.char 

86 else: 

87 xtype = A.matvec(b).dtype.char 

88 xtype = coerce(xtype, b.dtype.char) 

89 

90 b = asarray(b,dtype=xtype) # make b the same type as x 

91 b = b.ravel() 

92 

93 if x0 is None: 

94 x = zeros(N, dtype=xtype) 

95 else: 

96 x = array(x0, dtype=xtype) 

97 if not (x.shape == (N,1) or x.shape == (N,)): 

98 raise ValueError('A and x have incompatible dimensions') 

99 x = x.ravel() 

100 

101 # process preconditioner 

102 if M is None: 

103 if hasattr(A_,'psolve'): 

104 psolve = A_.psolve 

105 else: 

106 psolve = id 

107 if hasattr(A_,'rpsolve'): 

108 rpsolve = A_.rpsolve 

109 else: 

110 rpsolve = id 

111 if psolve is id and rpsolve is id: 

112 M = IdentityOperator(shape=A.shape, dtype=A.dtype) 

113 else: 

114 M = LinearOperator(A.shape, matvec=psolve, rmatvec=rpsolve, 

115 dtype=A.dtype) 

116 else: 

117 M = aslinearoperator(M) 

118 if A.shape != M.shape: 

119 raise ValueError('matrix and preconditioner have different shapes') 

120 

121 return A, M, x, b, postprocess