def gauss_lobatto_points(p): """ Returns the list of Gauss-Lobatto points of the order 'p'. """ x = Symbol("x") print "creating" e = legendre(p, x).diff(x) e = Poly(e, x) print "polydone" if e == 0: return [] print "roots" if e == 1: r = [] else: with workdps(40): r, err = polyroots(e.all_coeffs(), error=True) #if err > 1e-40: # raise Exception("Internal Error: Root is not precise") print "done" p = [] p.append("-1.0") for x in r: if abs(x) < 1e-40: x = 0 p.append(str(x)) p.append("1.0") return p
def mc_compute_stationary(P, precision=None, tol=None): n = P.shape[0] if precision is None: # Compute eigenvalues and eigenvectors eigvals, eigvecs = la.eig(P, left=True, right=False) # Find the index for unit eigenvalues index = np.where(abs(eigvals - 1.) < 1e-12)[0] # Pull out the eigenvectors that correspond to unit eig-vals uniteigvecs = eigvecs[:, index] stationary_dists = uniteigvecs / np.sum(uniteigvecs, axis=0) else: # Create a list to store eigvals stationary_dists_list = [] if tol is None: # If tolerance isn't specified then use 2*precision tol = mp.mpf(2 * 10**(-precision + 1)) with mp.workdps(precision): eigvals, eigvecs = mp.eig(mp.matrix(P), left=True, right=False) for ind, el in enumerate(eigvals): if el >= (mp.mpf(1) - mp.mpf(tol)) and el <= (mp.mpf(1) + mp.mpf(tol)): stationary_dists_list.append(eigvecs[ind, :]) stationary_dists = np.asarray(stationary_dists_list).T stationary_dists = (stationary_dists / sum(stationary_dists)).astype(np.float) # Check to make sure all of the elements of invar_dist are positive if np.any(stationary_dists < -1e-16): warn("Elements of your invariant distribution were negative; " + "Re-trying with additional precision") if precision is None: stationary_dists = mc_compute_stationary(P, precision=18, tol=tol) elif precision is not None: raise ValueError("Elements of your stationary distribution were" + "negative. Try computing with higher precision") # Since we will be accessing the columns of this matrix, we # might consider adding .astype(np.float, order='F') to make it # column major at beginning return stationary_dists.squeeze()
def mc_compute_stationary(P, precision=None, tol=None): n = P.shape[0] if precision is None: # Compute eigenvalues and eigenvectors eigvals, eigvecs = la.eig(P, left=True, right=False) # Find the index for unit eigenvalues index = np.where(abs(eigvals - 1.) < 1e-12)[0] # Pull out the eigenvectors that correspond to unit eig-vals uniteigvecs = eigvecs[:, index] stationary_dists = uniteigvecs/np.sum(uniteigvecs, axis=0) else: # Create a list to store eigvals stationary_dists_list = [] if tol is None: # If tolerance isn't specified then use 2*precision tol = mp.mpf(2 * 10**(-precision + 1)) with mp.workdps(precision): eigvals, eigvecs = mp.eig(mp.matrix(P), left=True, right=False) for ind, el in enumerate(eigvals): if el>=(mp.mpf(1)-mp.mpf(tol)) and el<=(mp.mpf(1)+mp.mpf(tol)): stationary_dists_list.append(eigvecs[ind, :]) stationary_dists = np.asarray(stationary_dists_list).T stationary_dists = (stationary_dists/sum(stationary_dists)).astype(np.float) # Check to make sure all of the elements of invar_dist are positive if np.any(stationary_dists < -1e-16): warn("Elements of your invariant distribution were negative; " + "Re-trying with additional precision") if precision is None: stationary_dists = mc_compute_stationary(P, precision=18, tol=tol) elif precision is not None: raise ValueError("Elements of your stationary distribution were" + "negative. Try computing with higher precision") # Since we will be accessing the columns of this matrix, we # might consider adding .astype(np.float, order='F') to make it # column major at beginning return stationary_dists.squeeze()
def improve_mu_m(self, beam_type, mode, decimal_precision=DEFAULT_DECIMAL_PRECISION, **kwargs): f = self._get_f(beam_type, decimal_precision) with mpmath.workdps(decimal_precision): # If not converted to `sympy.Float` precision will be lost after the # original `mpmath` context is restored return Float( mpmath.findroot(f=f, x0=self.x0(beam_type, mode, decimal_precision), solver=self.solver_name, maxsteps=self.max_iterations, verify=False, **kwargs), decimal_precision)
def gauss_lobatto_points(p): """ Returns the list of Gauss-Lobatto points of the order 'p'. """ x = Symbol("x") e = (1-x**2)*legendre(p, x).diff(x) e = Poly(e, x) if e == 0: return [] with workdps(40): r, err = polyroots(e.all_coeffs(), error=True) if err > 1e-40: raise Exception("Internal Error: Root is not precise") p = [] for x in r: if abs(x) < 1e-40: x = 0 p.append(str(x)) return p
def integrate(integral, beam_type, a, m=None, t=None, v=None, n=None, decimal_precision=DEFAULT_DECIMAL_PRECISION, **kwargs): cached_subs = integral(beam_type, m, t, v, n, decimal_precision).subs('a', a) f = lambda y: cached_subs.evalf(n=decimal_precision, subs={'y': y}) with mpmath.workdps(decimal_precision): result = mpmath.quad(f, (0., a), **kwargs) # If not converted to `sympy.Float` precision will be lost after the # original `mpmath` context is restored if isinstance(result, tuple): # Integration error included return tuple(Float(x, decimal_precision) for x in result) else: return Float(result, decimal_precision)
def voigt_slow(a, u): with mp.workdps(581): z = mp.mpc(u, a) result = mp.exp(-z * z) * mp.erfc(-1j * z) return result.real