本文整理汇总了Python中pyamg.util.linalg.approximate_spectral_radius函数的典型用法代码示例。如果您正苦于以下问题:Python approximate_spectral_radius函数的具体用法?Python approximate_spectral_radius怎么用?Python approximate_spectral_radius使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了approximate_spectral_radius函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: setup_richardson
def setup_richardson(lvl, iterations=DEFAULT_NITER, omega=1.0):
omega = omega/approximate_spectral_radius(lvl.A)
def smoother(A, x, b):
relaxation.polynomial(A, x, b, coefficients=[omega],
iterations=iterations)
return smoother
示例2: rho_D_inv_A
def rho_D_inv_A(A):
"""Return the (approx.) spectral radius of D^-1 * A.
Parameters
----------
A : sparse-matrix
Returns
-------
approximate spectral radius of diag(A)^{-1} A
Examples
--------
>>> from pyamg.gallery import poisson
>>> from pyamg.relaxation.smoothing import rho_D_inv_A
>>> from scipy.sparse import csr_matrix
>>> import numpy as np
>>> A = csr_matrix(np.array([[1.0,0,0],[0,2.0,0],[0,0,3.0]]))
>>> print rho_D_inv_A(A)
1.0
"""
if not hasattr(A, 'rho_D_inv'):
D_inv = get_diagonal(A, inv=True)
D_inv_A = scale_rows(A, D_inv, copy=True)
A.rho_D_inv = approximate_spectral_radius(D_inv_A)
return A.rho_D_inv
示例3: setup_chebyshev
def setup_chebyshev(lvl, lower_bound=1.0/30.0, upper_bound=1.1, degree=3, iterations=1):
rho = approximate_spectral_radius(lvl.A)
a = rho * lower_bound
b = rho * upper_bound
coefficients = -chebyshev_polynomial_coefficients(a, b, degree)[:-1] # drop the constant coefficient
def smoother(A,x,b):
relaxation.polynomial(A, x, b, coefficients=coefficients, iterations=iterations)
return smoother
示例4: get_aggregate_weights
def get_aggregate_weights(AggOp, A, z, nPDEs, ndof):
"""
Calculate local aggregate quantities
Return a vector of length num_aggregates where entry i is
(card(agg_i)/A.shape[0]) ( <Az, z>/rho(A) )
"""
rho = approximate_spectral_radius(A)
zAz = numpy.dot(z.reshape(1, -1), A*z.reshape(-1, 1))
card = nPDEs*(AggOp.indptr[1:]-AggOp.indptr[:-1])
weights = (numpy.ravel(card)*zAz)/(A.shape[0]*rho)
return weights.reshape(-1, 1)
示例5: eps_convergence_linbp
def eps_convergence_linbp(Hc, W, echo=False, rho_W=None):
"""Calculates eps_convergence with which to multiply Hc, for LinBP (with or w/o echo) to be at convergence boundary.
Returns 0 if the values HC are too small (std < SPECTRAL_TOLERANCE)
Assumes symmetric W and symmetric and doubly stochastic Hc
Uses: degree_matrix()
Parameters
----------
Hc : np.array
Centered coupling matrix (symmetric, doubly stochastic)
W : sparse matrix
Sparse edge matrix (symmetric)
echo : boolean
True to include the echo cancellation term
rho_W : float
the spectral radius of W as optional input to speed up the calculations
"""
if np.std(Hc) < SPECTRAL_TOLERANCE:
return 0
else:
if rho_W is None:
rho_W = approximate_spectral_radius(csr_matrix(W, dtype="f")) # needs to transform from int
rho_H = approximate_spectral_radius(np.array(Hc, dtype="f")) # same here
eps = 1.0 / rho_W / rho_H
# if echo is used, then the above eps value is used as starting point
if echo:
Hc2 = Hc.dot(Hc)
D = degree_matrix(W)
# function for which we need to determine the root: spectral radius minus 1
def radius(eps):
return approximate_spectral_radius(kron(Hc, W).dot(eps) - kron(Hc2, D).dot(eps ** 2)) - 1
# http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.newton.html#scipy.optimize.newton
eps2 = newton(radius, eps, tol=1e-04, maxiter=100)
eps = eps2
return eps
示例6: rho_block_D_inv_A
def rho_block_D_inv_A(A, Dinv):
"""
Return the (approx.) spectral radius of block D^-1 * A
Parameters
----------
A : {sparse-matrix}
size NxN
Dinv : {array}
Inverse of diagonal blocks of A
size (N/blocksize, blocksize, blocksize)
Returns
-------
approximate spectral radius of (Dinv A)
Examples
--------
>>> from pyamg.gallery import poisson
>>> from pyamg.relaxation.smoothing import rho_block_D_inv_A
>>> from pyamg.util.utils import get_block_diag
>>> A = poisson((10,10), format='csr')
>>> Dinv = get_block_diag(A, blocksize=4, inv_flag=True)
"""
if not hasattr(A, 'rho_block_D_inv'):
from scipy.sparse.linalg import LinearOperator
blocksize = Dinv.shape[1]
if Dinv.shape[1] != Dinv.shape[2]:
raise ValueError('Dinv has incorrect dimensions')
elif Dinv.shape[0] != int(A.shape[0]/blocksize):
raise ValueError('Dinv and A have incompatible dimensions')
Dinv = sp.sparse.bsr_matrix((Dinv,
sp.arange(Dinv.shape[0]),
sp.arange(Dinv.shape[0]+1)),
shape=A.shape)
# Don't explicitly form Dinv*A
def matvec(x):
return Dinv*(A*x)
D_inv_A = LinearOperator(A.shape, matvec, dtype=A.dtype)
A.rho_block_D_inv = approximate_spectral_radius(D_inv_A)
return A.rho_block_D_inv
示例7: relax
def relax(A, x):
fn, kwargs = unpack_arg(prepostsmoother)
if fn == 'gauss_seidel':
gauss_seidel(A, x, np.zeros_like(x),
iterations=candidate_iters, sweep='symmetric')
elif fn == 'gauss_seidel_nr':
gauss_seidel_nr(A, x, np.zeros_like(x),
iterations=candidate_iters, sweep='symmetric')
elif fn == 'gauss_seidel_ne':
gauss_seidel_ne(A, x, np.zeros_like(x),
iterations=candidate_iters, sweep='symmetric')
elif fn == 'jacobi':
jacobi(A, x, np.zeros_like(x), iterations=1,
omega=1.0 / rho_D_inv_A(A))
elif fn == 'richardson':
polynomial(A, x, np.zeros_like(x), iterations=1,
coefficients=[1.0/approximate_spectral_radius(A)])
elif fn == 'gmres':
x[:] = (gmres(A, np.zeros_like(x), x0=x,
maxiter=candidate_iters)[0]).reshape(x.shape)
else:
raise TypeError('Unrecognized smoother')
示例8: test_approximate_spectral_radius
def test_approximate_spectral_radius(self):
np.random.seed(3456)
cases = []
cases.append(np.array([[-4]]))
cases.append(np.array([[2, 0], [0, 1]]))
cases.append(np.array([[-2, 0], [0, 1]]))
cases.append(np.array([[100, 0, 0], [0, 101, 0], [0, 0, 99]]))
for i in range(1, 5):
cases.append(np.random.rand(i, i))
# method should be almost exact for small matrices
for A in cases:
A = A.astype(float)
Asp = csr_matrix(A)
[E, V] = linalg.eig(A)
E = np.abs(E)
largest_eig = (E == E.max()).nonzero()[0]
expected_eig = E[largest_eig]
expected_vec = V[:, largest_eig]
assert_almost_equal(approximate_spectral_radius(A), expected_eig)
assert_almost_equal(approximate_spectral_radius(Asp), expected_eig)
vec = approximate_spectral_radius(A, return_vector=True)[1]
minnorm = min(norm(expected_vec + vec), norm(expected_vec - vec))
diff = minnorm / norm(expected_vec)
assert_almost_equal(diff, 0.0, decimal=4)
vec = approximate_spectral_radius(Asp, return_vector=True)[1]
minnorm = min(norm(expected_vec + vec), norm(expected_vec - vec))
diff = minnorm / norm(expected_vec)
assert_almost_equal(diff, 0.0, decimal=4)
# try symmetric matrices
for A in cases:
A = A + A.transpose()
A = A.astype(float)
Asp = csr_matrix(A)
[E, V] = linalg.eig(A)
E = np.abs(E)
largest_eig = (E == E.max()).nonzero()[0]
expected_eig = E[largest_eig]
expected_vec = V[:, largest_eig]
assert_almost_equal(approximate_spectral_radius(A), expected_eig)
assert_almost_equal(approximate_spectral_radius(Asp), expected_eig)
vec = approximate_spectral_radius(A, return_vector=True)[1]
minnorm = min(norm(expected_vec + vec), norm(expected_vec - vec))
diff = minnorm / norm(expected_vec)
assert_almost_equal(diff, 0.0, decimal=4)
vec = approximate_spectral_radius(Asp, return_vector=True)[1]
minnorm = min(norm(expected_vec + vec), norm(expected_vec - vec))
diff = minnorm / norm(expected_vec)
assert_almost_equal(diff, 0.0, decimal=4)
# test a larger matrix, and various parameter choices
cases = []
A1 = gallery.poisson((50, 50), format='csr')
cases.append((A1, 7.99241331495))
A2 = gallery.elasticity.linear_elasticity((32, 32), format='bsr')[0]
cases.append((A2, 536549.922189))
for A, expected in cases:
# test that increasing maxiter increases accuracy
ans1 = approximate_spectral_radius(A, tol=1e-16, maxiter=5,
restart=0)
del A.rho
ans2 = approximate_spectral_radius(A, tol=1e-16, maxiter=15,
restart=0)
del A.rho
assert_equal(abs(ans2 - expected) < 0.5*abs(ans1 - expected), True)
# test that increasing restart increases accuracy
ans1 = approximate_spectral_radius(A, tol=1e-16, maxiter=10,
restart=0)
del A.rho
ans2 = approximate_spectral_radius(A, tol=1e-16, maxiter=10,
restart=1)
del A.rho
assert_equal(abs(ans2 - expected) < 0.8*abs(ans1 - expected), True)
# test tol
ans1 = approximate_spectral_radius(A, tol=0.1, maxiter=15,
restart=5)
del A.rho
assert_equal(abs(ans1 - expected)/abs(expected) < 0.1, True)
ans2 = approximate_spectral_radius(A, tol=0.001, maxiter=15,
restart=5)
del A.rho
assert_equal(abs(ans2 - expected)/abs(expected) < 0.001, True)
assert_equal(abs(ans2 - expected) < 0.1*abs(ans1 - expected), True)
示例9: jacobi_prolongation_smoother
def jacobi_prolongation_smoother(S, T, C, B, omega=4.0/3.0, degree=1, filter=False, weighting='diagonal'):
"""Jacobi prolongation smoother
Parameters
----------
S : {csr_matrix, bsr_matrix}
Sparse NxN matrix used for smoothing. Typically, A.
T : {csr_matrix, bsr_matrix}
Tentative prolongator
C : {csr_matrix, bsr_matrix}
Strength-of-connection matrix
B : {array}
Near nullspace modes for the coarse grid such that T*B
exactly reproduces the fine grid near nullspace modes
omega : {scalar}
Damping parameter
filter : {boolean}
If true, filter S before smoothing T. This option can greatly control
complexity.
weighting : {string}
'block', 'diagonal' or 'local' weighting for constructing the Jacobi D
'local': Uses a local row-wise weight based on the Gershgorin estimate.
Avoids any potential under-damping due to inaccurate spectral radius
estimates.
'block': If A is a BSR matrix, use a block diagonal inverse of A
'diagonal': Classic Jacobi D = diagonal(A)
Returns
-------
P : {csr_matrix, bsr_matrix}
Smoothed (final) prolongator defined by P = (I - omega/rho(K) K) * T
where K = diag(S)^-1 * S and rho(K) is an approximation to the
spectral radius of K.
Notes
-----
If weighting is not 'local', then results using Jacobi prolongation
smoother are not precisely reproducible due to a random initial guess used
for the spectral radius approximation. For precise reproducibility,
set numpy.random.seed(..) to the same value before each test.
Examples
--------
>>> from pyamg.aggregation import jacobi_prolongation_smoother
>>> from pyamg.gallery import poisson
>>> from scipy.sparse import coo_matrix
>>> import numpy
>>> data = numpy.ones((6,))
>>> row = numpy.arange(0,6)
>>> col = numpy.kron([0,1],numpy.ones((3,)))
>>> T = coo_matrix((data,(row,col)),shape=(6,2)).tocsr()
>>> T.todense()
matrix([[ 1., 0.],
[ 1., 0.],
[ 1., 0.],
[ 0., 1.],
[ 0., 1.],
[ 0., 1.]])
>>> A = poisson((6,),format='csr')
>>> P = jacobi_prolongation_smoother(A,T,A,numpy.ones((2,1)))
>>> P.todense()
matrix([[ 0.64930164, 0. ],
[ 1. , 0. ],
[ 0.64930164, 0.35069836],
[ 0.35069836, 0.64930164],
[ 0. , 1. ],
[ 0. , 0.64930164]])
"""
# preprocess weighting
if weighting == 'block':
if isspmatrix_csr(S):
weighting = 'diagonal'
elif isspmatrix_bsr(S):
if S.blocksize[0] == 1:
weighting = 'diagonal'
if filter:
##
# Implement filtered prolongation smoothing for the general case by
# utilizing satisfy constraints
if isspmatrix_bsr(S):
numPDEs = S.blocksize[0]
else:
numPDEs = 1
# Create a filtered S with entries dropped that aren't in C
C = UnAmal(C, numPDEs, numPDEs)
S = S.multiply(C)
S.eliminate_zeros()
if weighting == 'diagonal':
# Use diagonal of S
D_inv = get_diagonal(S, inv=True)
D_inv_S = scale_rows(S, D_inv, copy=True)
D_inv_S = (omega/approximate_spectral_radius(D_inv_S))*D_inv_S
elif weighting == 'block':
# Use block diagonal of S
#.........这里部分代码省略.........
示例10: richardson_prolongation_smoother
def richardson_prolongation_smoother(S, T, omega=4.0/3.0, degree=1):
"""Richardson prolongation smoother
Parameters
----------
S : {csr_matrix, bsr_matrix}
Sparse NxN matrix used for smoothing. Typically, A or the
"filtered matrix" obtained from A by lumping weak connections
onto the diagonal of A.
T : {csr_matrix, bsr_matrix}
Tentative prolongator
omega : {scalar}
Damping parameter
Returns
-------
P : {csr_matrix, bsr_matrix}
Smoothed (final) prolongator defined by P = (I - omega/rho(S) S) * T
where rho(S) is an approximation to the spectral radius of S.
Notes
-----
Results using Richardson prolongation smoother are not precisely
reproducible due to a random initial guess used for the spectral radius
approximation. For precise reproducibility, set numpy.random.seed(..) to
the same value before each test.
Examples
--------
>>> from pyamg.aggregation import richardson_prolongation_smoother
>>> from pyamg.gallery import poisson
>>> from scipy.sparse import coo_matrix
>>> import numpy
>>> data = numpy.ones((6,))
>>> row = numpy.arange(0,6)
>>> col = numpy.kron([0,1],numpy.ones((3,)))
>>> T = coo_matrix((data,(row,col)),shape=(6,2)).tocsr()
>>> T.todense()
matrix([[ 1., 0.],
[ 1., 0.],
[ 1., 0.],
[ 0., 1.],
[ 0., 1.],
[ 0., 1.]])
>>> A = poisson((6,),format='csr')
>>> P = richardson_prolongation_smoother(A,T)
>>> P.todense()
matrix([[ 0.64930164, 0. ],
[ 1. , 0. ],
[ 0.64930164, 0.35069836],
[ 0.35069836, 0.64930164],
[ 0. , 1. ],
[ 0. , 0.64930164]])
"""
weight = omega/approximate_spectral_radius(S)
P = T
for i in range(degree):
P = P - weight*(S*P)
return P
示例11: evolution_strength_of_connection
def evolution_strength_of_connection(A, B='ones', epsilon=4.0, k=2,
proj_type="l2", block_flag=False,
symmetrize_measure=True):
"""
Construct strength of connection matrix using an Evolution-based measure
Parameters
----------
A : {csr_matrix, bsr_matrix}
Sparse NxN matrix
B : {string, array}
If B='ones', then the near nullspace vector used is all ones. If B is
an (NxK) array, then B is taken to be the near nullspace vectors.
epsilon : scalar
Drop tolerance
k : integer
ODE num time steps, step size is assumed to be 1/rho(DinvA)
proj_type : {'l2','D_A'}
Define norm for constrained min prob, i.e. define projection
block_flag : {boolean}
If True, use a block D inverse as preconditioner for A during
weighted-Jacobi
Returns
-------
Atilde : {csr_matrix}
Sparse matrix of strength values
References
----------
.. [1] Olson, L. N., Schroder, J., Tuminaro, R. S.,
"A New Perspective on Strength Measures in Algebraic Multigrid",
submitted, June, 2008.
Examples
--------
>>> import numpy as np
>>> from pyamg.gallery import stencil_grid
>>> from pyamg.strength import evolution_strength_of_connection
>>> n=3
>>> stencil = np.array([[-1.0,-1.0,-1.0],
... [-1.0, 8.0,-1.0],
... [-1.0,-1.0,-1.0]])
>>> A = stencil_grid(stencil, (n,n), format='csr')
>>> S = evolution_strength_of_connection(A, np.ones((A.shape[0],1)))
"""
# local imports for evolution_strength_of_connection
from pyamg.util.utils import scale_rows, get_block_diag, scale_columns
from pyamg.util.linalg import approximate_spectral_radius
# ====================================================================
# Check inputs
if epsilon < 1.0:
raise ValueError("expected epsilon > 1.0")
if k <= 0:
raise ValueError("number of time steps must be > 0")
if proj_type not in ['l2', 'D_A']:
raise ValueError("proj_type must be 'l2' or 'D_A'")
if (not sparse.isspmatrix_csr(A)) and (not sparse.isspmatrix_bsr(A)):
raise TypeError("expected csr_matrix or bsr_matrix")
# ====================================================================
# Format A and B correctly.
# B must be in mat format, this isn't a deep copy
if B == 'ones':
Bmat = np.mat(np.ones((A.shape[0], 1), dtype=A.dtype))
else:
Bmat = np.mat(B)
# Pre-process A. We need A in CSR, to be devoid of explicit 0's and have
# sorted indices
if (not sparse.isspmatrix_csr(A)):
csrflag = False
numPDEs = A.blocksize[0]
D = A.diagonal()
# Calculate Dinv*A
if block_flag:
Dinv = get_block_diag(A, blocksize=numPDEs, inv_flag=True)
Dinv = sparse.bsr_matrix((Dinv, np.arange(Dinv.shape[0]),
np.arange(Dinv.shape[0] + 1)),
shape=A.shape)
Dinv_A = (Dinv * A).tocsr()
else:
Dinv = np.zeros_like(D)
mask = (D != 0.0)
Dinv[mask] = 1.0 / D[mask]
Dinv[D == 0] = 1.0
Dinv_A = scale_rows(A, Dinv, copy=True)
A = A.tocsr()
else:
csrflag = True
numPDEs = 1
D = A.diagonal()
Dinv = np.zeros_like(D)
mask = (D != 0.0)
Dinv[mask] = 1.0 / D[mask]
Dinv[D == 0] = 1.0
Dinv_A = scale_rows(A, Dinv, copy=True)
A.eliminate_zeros()
#.........这里部分代码省略.........
示例12: energy_based_strength_of_connection
def energy_based_strength_of_connection(A, theta=0.0, k=2):
"""
Compute a strength of connection matrix using an energy-based measure.
Parameters
----------
A : {sparse-matrix}
matrix from which to generate strength of connection information
theta : {float}
Threshold parameter in [0,1]
k : {int}
Number of relaxation steps used to generate strength information
Returns
-------
S : {csr_matrix}
Matrix graph defining strong connections. The sparsity pattern
of S matches that of A. For BSR matrices, S is a reduced strength
of connection matrix that describes connections between supernodes.
Notes
-----
This method relaxes with weighted-Jacobi in order to approximate the
matrix inverse. A normalized change of energy is then used to define
point-wise strength of connection values. Specifically, let v be the
approximation to the i-th column of the inverse, then
(S_ij)^2 = <v_j, v_j>_A / <v, v>_A,
where v_j = v, such that entry j in v has been zeroed out. As is common,
larger values imply a stronger connection.
Current implementation is a very slow pure-python implementation for
experimental purposes, only.
References
----------
.. [1] Brannick, Brezina, MacLachlan, Manteuffel, McCormick.
"An Energy-Based AMG Coarsening Strategy",
Numerical Linear Algebra with Applications,
vol. 13, pp. 133-148, 2006.
Examples
--------
>>> import numpy as np
>>> from pyamg.gallery import stencil_grid
>>> from pyamg.strength import energy_based_strength_of_connection
>>> n=3
>>> stencil = np.array([[-1.0,-1.0,-1.0],
... [-1.0, 8.0,-1.0],
... [-1.0,-1.0,-1.0]])
>>> A = stencil_grid(stencil, (n,n), format='csr')
>>> S = energy_based_strength_of_connection(A, 0.0)
"""
if (theta < 0):
raise ValueError('expected a positive theta')
if not sparse.isspmatrix(A):
raise ValueError('expected sparse matrix')
if (k < 0):
raise ValueError('expected positive number of steps')
if not isinstance(k, int):
raise ValueError('expected integer')
if sparse.isspmatrix_bsr(A):
bsr_flag = True
numPDEs = A.blocksize[0]
if A.blocksize[0] != A.blocksize[1]:
raise ValueError('expected square blocks in BSR matrix A')
else:
bsr_flag = False
# Convert A to csc and Atilde to csr
if sparse.isspmatrix_csr(A):
Atilde = A.copy()
A = A.tocsc()
else:
A = A.tocsc()
Atilde = A.copy()
Atilde = Atilde.tocsr()
# Calculate the weighted-Jacobi parameter
from pyamg.util.linalg import approximate_spectral_radius
D = A.diagonal()
Dinv = 1.0 / D
Dinv[D == 0] = 0.0
Dinv = sparse.csc_matrix((Dinv, (np.arange(A.shape[0]),
np.arange(A.shape[1]))), shape=A.shape)
DinvA = Dinv*A
omega = 1.0/approximate_spectral_radius(DinvA)
del DinvA
# Approximate A-inverse with k steps of w-Jacobi and a zero initial guess
S = sparse.csc_matrix(A.shape, dtype=A.dtype) # empty matrix
I = sparse.eye(A.shape[0], A.shape[1], format='csc')
for i in range(k+1):
S = S + omega*(Dinv*(I - A * S))
# Calculate the strength entries in S column-wise, but only strength
# values at the sparsity pattern of A
#.........这里部分代码省略.........
示例13: general_setup_stage
#.........这里部分代码省略.........
# construct R
if symmetry == 'symmetric': # R should reflect A's structure
levels[i].R = levels[i].P.T.asformat(levels[i].P.format)
elif symmetry == 'hermitian':
levels[i].R = levels[i].P.H.asformat(levels[i].P.format)
# construct coarse A
levels[i+1].A = levels[i].R * levels[i].A * levels[i].P
# construct bridging P
T_bridge = make_bridge(levels[i+1].T)
R_bridge = levels[i+2].B
# smooth bridging P
fn, kwargs = unpack_arg(smooth[i+1])
if fn == 'jacobi':
levels[i+1].P = jacobi_prolongation_smoother(levels[i+1].A,
T_bridge,
levels[i+1].C,
R_bridge, **kwargs)
elif fn == 'richardson':
levels[i+1].P = richardson_prolongation_smoother(levels[i+1].A,
T_bridge,
**kwargs)
elif fn == 'energy':
levels[i+1].P = energy_prolongation_smoother(levels[i+1].A,
T_bridge,
levels[i+1].C,
R_bridge, None,
(False, {}), **kwargs)
elif fn is None:
levels[i+1].P = T_bridge
else:
raise ValueError('unrecognized prolongation smoother method %s' %
str(fn))
# construct the "bridging" R
if symmetry == 'symmetric': # R should reflect A's structure
levels[i+1].R = levels[i+1].P.T.asformat(levels[i+1].P.format)
elif symmetry == 'hermitian':
levels[i+1].R = levels[i+1].P.H.asformat(levels[i+1].P.format)
# run solver on candidate
solver = multilevel_solver(levels[i+1:], coarse_solver=coarse_solver)
change_smoothers(solver, presmoother=prepostsmoother,
postsmoother=prepostsmoother)
x = solver.solve(np.zeros_like(x), x0=x,
tol=float(np.finfo(np.float).tiny),
maxiter=candidate_iters)
work[:] += 2 * solver.operator_complexity() * solver.levels[0].A.nnz *\
candidate_iters*2
# update values on next level
levels[i+1].B = R[:, :-1].copy()
levels[i+1].T = T_bridge
# note that we only use the x from the second coarsest level
fn, kwargs = unpack_arg(prepostsmoother)
for lvl in reversed(levels[:-2]):
x = lvl.P * x
work[:] += lvl.A.nnz*candidate_iters*2
if fn == 'gauss_seidel':
# only relax at nonzeros, so as not to mess up any locally dropped
# candidates
indices = np.ravel(x).nonzero()[0]
gauss_seidel_indexed(lvl.A, x, np.zeros_like(x), indices,
iterations=candidate_iters, sweep='symmetric')
elif fn == 'gauss_seidel_ne':
gauss_seidel_ne(lvl.A, x, np.zeros_like(x),
iterations=candidate_iters, sweep='symmetric')
elif fn == 'gauss_seidel_nr':
gauss_seidel_nr(lvl.A, x, np.zeros_like(x),
iterations=candidate_iters, sweep='symmetric')
elif fn == 'jacobi':
jacobi(lvl.A, x, np.zeros_like(x), iterations=1,
omega=1.0 / rho_D_inv_A(lvl.A))
elif fn == 'richardson':
polynomial(lvl.A, x, np.zeros_like(x), iterations=1,
coefficients=[1.0/approximate_spectral_radius(lvl.A)])
elif fn == 'gmres':
x[:] = (gmres(lvl.A, np.zeros_like(x), x0=x,
maxiter=candidate_iters)[0]).reshape(x.shape)
else:
raise TypeError('Unrecognized smoother')
# x will be dense again, so we have to drop locally again
elim, elim_kwargs = unpack_arg(eliminate_local)
if elim is True:
x = x/norm(x, 'inf')
eliminate_local_candidates(x, levels[0].AggOp, levels[0].A, T0,
**elim_kwargs)
return x.reshape(-1, 1)
示例14: reference_evolution_soc
def reference_evolution_soc(A, B, epsilon=4.0, k=2, proj_type="l2"):
"""
All python reference implementation for Evolution Strength of Connection
--> If doing imaginary test, both A and B should be imaginary type upon
entry
--> This does the "unsymmetrized" version of the ode measure
"""
# number of PDEs per point is defined implicitly by block size
csrflag = isspmatrix_csr(A)
if csrflag:
numPDEs = 1
else:
numPDEs = A.blocksize[0]
A = A.tocsr()
# Preliminaries
near_zero = np.finfo(float).eps
sqrt_near_zero = np.sqrt(np.sqrt(near_zero))
Bmat = np.mat(B)
A.eliminate_zeros()
A.sort_indices()
dimen = A.shape[1]
NullDim = Bmat.shape[1]
# Get spectral radius of Dinv*A, this is the time step size for the ODE
D = A.diagonal()
Dinv = np.zeros_like(D)
mask = (D != 0.0)
Dinv[mask] = 1.0 / D[mask]
Dinv[D == 0] = 1.0
Dinv_A = scale_rows(A, Dinv, copy=True)
rho_DinvA = approximate_spectral_radius(Dinv_A)
# Calculate (Atilde^k) naively
S = (scipy.sparse.eye(dimen, dimen, format="csr") - (1.0/rho_DinvA)*Dinv_A)
Atilde = scipy.sparse.eye(dimen, dimen, format="csr")
for i in range(k):
Atilde = S*Atilde
# Strength Info should be row-based, so transpose Atilde
Atilde = Atilde.T.tocsr()
# Construct and apply a sparsity mask for Atilde that restricts Atilde^T to
# the nonzero pattern of A, with the added constraint that row i of
# Atilde^T retains only the nonzeros that are also in the same PDE as i.
mask = A.copy()
# Only consider strength at dofs from your PDE. Use mask to enforce this
# by zeroing out all entries in Atilde that aren't from your PDE.
if numPDEs > 1:
row_length = np.diff(mask.indptr)
my_pde = np.mod(np.arange(dimen), numPDEs)
my_pde = np.repeat(my_pde, row_length)
mask.data[np.mod(mask.indices, numPDEs) != my_pde] = 0.0
del row_length, my_pde
mask.eliminate_zeros()
# Apply mask to Atilde, zeros in mask have already been eliminated at start
# of routine.
mask.data[:] = 1.0
Atilde = Atilde.multiply(mask)
Atilde.eliminate_zeros()
Atilde.sort_indices()
del mask
# Calculate strength based on constrained min problem of
LHS = np.mat(np.zeros((NullDim+1, NullDim+1)), dtype=A.dtype)
RHS = np.mat(np.zeros((NullDim+1, 1)), dtype=A.dtype)
# Choose tolerance for dropping "numerically zero" values later
t = Atilde.dtype.char
eps = np.finfo(np.float).eps
feps = np.finfo(np.single).eps
geps = np.finfo(np.longfloat).eps
_array_precision = {'f': 0, 'd': 1, 'g': 2, 'F': 0, 'D': 1, 'G': 2}
tol = {0: feps*1e3, 1: eps*1e6, 2: geps*1e6}[_array_precision[t]]
for i in range(dimen):
# Get rowptrs and col indices from Atilde
rowstart = Atilde.indptr[i]
rowend = Atilde.indptr[i+1]
length = rowend - rowstart
colindx = Atilde.indices[rowstart:rowend]
# Local diagonal of A is used for scale invariant min problem
D_A = np.mat(np.eye(length, dtype=A.dtype))
if proj_type == "D_A":
for j in range(length):
D_A[j, j] = D[colindx[j]]
# Find row i's position in colindx, matrix must have sorted column
# indices.
iInRow = colindx.searchsorted(i)
if length <= NullDim:
#.........这里部分代码省略.........
示例15: radius
def radius(eps):
return approximate_spectral_radius(kron(Hc, W).dot(eps) - kron(Hc2, D).dot(eps ** 2)) - 1