def quad(func, a, b, args=(), full_output=0, epsabs=1.49e-08, epsrel=1.49e-08, limit=50, points=None, weight=None, wvar=None, wopts=None, maxp1=50, limlst=50): 'units wrapped scipy.integrate.quad' def wrappedfunc(x, *args): return float(func(x, *args)) # get the units on the integral INTEGRAND = func(a, *args) U = INTEGRAND*a if full_output: (y, abserr, infodict, message, explain) = _quad(wrappedfunc, float(a), float(b), args, full_output, epsabs, epsrel, limit, points, weight, wvar, wopts, maxp1, limlst) return (Unit(y, U.exponents, U.label), Unit(abserr, U.exponents, U.label), infodict, message, explain) else: (y, abserr) = _quad(wrappedfunc, float(a), float(b), args, full_output, epsabs, epsrel, limit, points, weight, wvar, wopts, maxp1, limlst) return (Unit(y, U.exponents, U.label), Unit(abserr, U.exponents, U.label))
def external_count(self, atomic_mass): mu = self.mass * atomic_mass / (self.mass + atomic_mass) self.pmax = _np.sqrt(2 * mu * self.emax) self.momentum = [_np.sqrt(2 * mu * e) for e in self.energies] self.int_value, self.int_error = _quad(self._function, 0, self.pmax.magnitude)
def norm_func(self, *args): # reads in some function and returns its # area-normalized version (as a function object) inst_func = _partial(func, self) ToT = _quad(inst_func, ave_range[0], ave_range[1], args=args[1:])[0] return func(self, *args) / ToT
def _python_integral(d, e1, e2, sigma1, sigma2, k1, k2, tau): """ Use Gaussian quadrature to integrate the BIASD integrand across df between f = 0 ... 1 """ return _quad(_python_integrand, 0., 1., args=(d, e1, e2, sigma1, sigma2, k1, k2, tau), limit=1000)[0]
def integrate(bpf, bounds=None): """ integrate the given bpf between the given bounds (or use the bpf bounds if not given) It uses the quad algorithm in scipy.integrate """ if bounds is None: x0, x1 = bpf.bounds() else: x0, x1 = bounds return _quad(bpf, x0, x1)[0]
def _get_erfcx_integral_gl_order(y_th, y_r, start_order, epsrel, maxiter): """Determine order of Gauss-Legendre quadrature for erfcx integral.""" # determine maximal integration range a = min(np.abs(y_th).min(), np.abs(y_r).min()) b = max(np.abs(y_th).max(), np.abs(y_r).max()) # adaptive quadrature from scipy.integrate for comparison I_quad = _quad(_erfcx, a, b, epsabs=0, epsrel=epsrel)[0] # increase order to reach desired accuracy order = start_order for _ in range(maxiter): I_gl = _erfcx_integral(a, b, order=order)[0] rel_error = np.abs(I_gl / I_quad - 1) if rel_error < epsrel: return order else: order *= 2 msg = f'Quadrature search failed to converge after {maxiter} iterations. ' msg += f'Last relative error {rel_error:e}, desired {epsrel:e}.' raise RuntimeError(msg)
def scattering( cls, kinetic_energy: _ureg.Quantity, thickness: _ureg.Quantity, model: _ScatteringModelType = _DifferentialMoliere ) -> Mapping[str, float]: """ Compute the Fermi-Eyges parameters A0, A1, A2 and B (emittance). Args: kinetic_energy: thickness: model: Returns: """ if not cls.valid_data: """ TODO """ "Set a warning message" return { 'A': (0.0, 0.0, 0.0), 'B': 0.0, 'TWISS_ALPHA': _np.nan, 'TWISS_BETA': _np.nan, 'TWISS_GAMMA': _np.nan, } thickness = thickness.m_as('cm') def integrand(u: float, initial_energy: _ureg.Quantity, thickness: float, material: MaterialType, scattering_model: _ScatteringModelType, n: int): return (thickness - u)**n * scattering_model.t( _ekin_to_pv(cls.stopping(u * _ureg.cm, initial_energy).ekin).m_as('MeV'), _ekin_to_pv(initial_energy).m_as('MeV'), material=material) a = [ _quad(integrand, 0, thickness, args=(kinetic_energy, thickness, cls, model, 0))[0], # Order 0 1e-2 * _quad( integrand, 0, thickness, args=(kinetic_energy, thickness, cls, model, 1))[0], # Order 1 1e-4 * _quad( integrand, 0, thickness, args=(kinetic_energy, thickness, cls, model, 2))[0], # Order 2 ] b = _np.sqrt(a[0] * a[2] - a[1]**2) # Emittance in m.rad return { 'A': a, 'B': b, 'TWISS_ALPHA': -a[1] / b, 'TWISS_BETA': a[2] / b, 'TWISS_GAMMA': a[0] / b, }