def get_celerite_matrices(self, x, diag): dt = self.delta ar, cr, a, b, c, d = self.term.coefficients # Real part cd = cr * dt delta_diag = 2 * tt.sum(ar * (cd - tt.sinh(cd)) / cd**2) # Complex part cd = c * dt dd = d * dt c2 = c**2 d2 = d**2 c2pd2 = c2 + d2 C1 = a * (c2 - d2) + 2 * b * c * d C2 = b * (c2 - d2) - 2 * a * c * d norm = (dt * c2pd2)**2 sinh = tt.sinh(cd) cosh = tt.cosh(cd) delta_diag += 2 * tt.sum( (C2 * cosh * tt.sin(dd) - C1 * sinh * tt.cos(dd) + (a * c + b * d) * dt * c2pd2) / norm) new_diag = diag + delta_diag # new_diag = diag return super(IntegratedTerm, self).get_celerite_matrices(x, new_diag)
def get_value(self, tau0): dt = self.delta ar, cr, a, b, c, d = self.term.coefficients # Format the lags correctly tau0 = tt.abs_(tau0) tau = tau0[..., None] # Precompute some factors dpt = dt + tau dmt = dt - tau # Real parts: # tau > Delta crd = cr * dt cosh = tt.cosh(crd) norm = 2 * ar / crd ** 2 K_large = tt.sum(norm * (cosh - 1) * tt.exp(-cr * tau), axis=-1) # tau < Delta crdmt = cr * dmt K_small = K_large + tt.sum(norm * (crdmt - tt.sinh(crdmt)), axis=-1) # Complex part cd = c * dt dd = d * dt c2 = c ** 2 d2 = d ** 2 c2pd2 = c2 + d2 C1 = a * (c2 - d2) + 2 * b * c * d C2 = b * (c2 - d2) - 2 * a * c * d norm = 1.0 / (dt * c2pd2) ** 2 k0 = tt.exp(-c * tau) cdt = tt.cos(d * tau) sdt = tt.sin(d * tau) # For tau > Delta cos_term = 2 * (tt.cosh(cd) * tt.cos(dd) - 1) sin_term = 2 * (tt.sinh(cd) * tt.sin(dd)) factor = k0 * norm K_large += tt.sum( (C1 * cos_term - C2 * sin_term) * factor * cdt, axis=-1 ) K_large += tt.sum( (C2 * cos_term + C1 * sin_term) * factor * sdt, axis=-1 ) # tau < Delta edmt = tt.exp(-c * dmt) edpt = tt.exp(-c * dpt) cos_term = ( edmt * tt.cos(d * dmt) + edpt * tt.cos(d * dpt) - 2 * k0 * cdt ) sin_term = ( edmt * tt.sin(d * dmt) + edpt * tt.sin(d * dpt) - 2 * k0 * sdt ) K_small += tt.sum(2 * (a * c + b * d) * c2pd2 * dmt * norm, axis=-1) K_small += tt.sum((C1 * cos_term + C2 * sin_term) * norm, axis=-1) return tt.switch(tt.le(tau0, dt), K_small, K_large)
def get_coefficients(self): ar, cr, a, b, c, d = self.term.coefficients # Real componenets crd = cr * self.delta coeffs = [ar * (tt.exp(crd) + tt.exp(-crd) - 2) / (crd)**2, cr] # Imaginary coefficients cd = c * self.delta dd = d * self.delta c2 = c**2 d2 = d**2 factor = 1. / (self.delta * (c2 + d2))**2 cos_term = tt.cosh(cd) * tt.cos(dd) - 1 sin_term = tt.sinh(cd) * tt.sin(dd) C1 = 2 * (a * (c2 - d2) + 2 * b * c * d) C2 = 2 * (b * (c2 - d2) - 2 * a * c * d) coeffs += [ factor * (C1 * cos_term - C2 * sin_term), factor * (C2 * cos_term + C1 * sin_term), c, d ] return coeffs
def _log_gamma_windschitl(z): """ computes log(gamma(z)) using windschitl's approximation. """ return 0.5 * (T.log(2 * np.pi) - T.log(z) + z * (2 * T.log(z) - 2 + T.log(z * T.sinh(1 / z) + 1 / (810 * (z**6)))))
def value(self, tau0): dt = self.delta ar, cr, a, b, c, d = self.term.coefficients # Format the lags correctly tau0 = tt.abs_(tau0) tau = tt.reshape(tau0, tt.concatenate([tau0.shape, [1]]), ndim=tau0.ndim + 1) # Precompute some factors dpt = dt + tau dmt = dt - tau # Real parts: # tau > Delta crd = cr * dt norm = 1.0 / (crd)**2 factor = (tt.exp(crd) + tt.exp(-crd) - 2) * norm, K_large = tt.sum(ar * tt.exp(-cr * tau) * factor, axis=-1) # tau < Delta K_small = tt.sum((2 * cr * (dmt) + tt.exp(-cr * dmt) + tt.exp(-cr * dpt) - 2 * tt.exp(-cr * tau)) * norm, axis=-1) # Complex part cd = c * dt dd = d * dt c2 = c**2 d2 = d**2 c2pd2 = c2 + d2 C1 = a * (c2 - d2) + 2 * b * c * d C2 = b * (c2 - d2) - 2 * a * c * d norm = 1.0 / (dt * c2pd2)**2 k0 = tt.exp(-c * tau) cdt = tt.cos(d * tau) sdt = tt.sin(d * tau) # For tau > Delta cos_term = 2 * (tt.cosh(cd) * tt.cos(dd) - 1) sin_term = 2 * (tt.sinh(cd) * tt.sin(dd)) factor = k0 * norm K_large += tt.sum((C1 * cos_term - C2 * sin_term) * factor * cdt, axis=-1) K_large += tt.sum((C2 * cos_term + C1 * sin_term) * factor * sdt, axis=-1) # Real part edmt = tt.exp(-c * dmt) edpt = tt.exp(-c * dpt) cos_term = edmt * tt.cos(d * dmt) + edpt * tt.cos( d * dpt) - 2 * k0 * cdt sin_term = edmt * tt.sin(d * dmt) + edpt * tt.sin( d * dpt) - 2 * k0 * sdt K_small += tt.sum(2 * (a * c + b * d) * c2pd2 * dmt * norm, axis=-1) K_small += tt.sum((C1 * cos_term + C2 * sin_term) * norm, axis=-1) return tt.switch(tt.le(tau0, dt), K_small, K_large)
def distmod_constant_curve(Om, Ok, h0, z): """ Distance modulus for a curved universe with a cosmological constant :param Om: matter content :param Ok: curvature :param h0: hubble constant :param z: redshift :return: theano array of dist. mods. """ # Hubble distance dh = sol * 1.e-3 / h0 # Comoving distance dc = dh * gauss_kronrod(integrand_constant_curve, z, parameters=[Om, Ok]) # Pre-compute the sqrt sqrtOk = T.sqrt(T.abs_(Ok)) # Theno does not have exhaustive # control flow, so we have to compute them all # Start here dl = ifelse(T.eq(Ok,0.), (1+z) * dc, 0. * (1+z) * dc) # The above statement is zero if the # condition fails, so we add on to it dl += ifelse(T.gt(Ok,0), (1+z) * dh / sqrtOk * T.sinh(sqrtOk * dc / dh), 0. * (1+z) * dc) # same idea as above dl += ifelse(T.lt(Ok,0), (1+z) * dh / sqrtOk * T.sin(sqrtOk * dc / dh), 0. * (1+z) * dc) return 5. * T.log10(dl) + 25. # dist mod
def distmod_constant_curve(Om, Ok, h0, z): """ Distance modulus for a curved universe with a cosmological constant :param Om: matter content :param Ok: curvature :param h0: hubble constant :param z: redshift :return: theano array of dist. mods. """ # Hubble distance dh = sol * 1.0e-3 / h0 # Comoving distance dc = dh * gauss_kronrod(integrand_constant_curve, z, parameters=[Om, Ok]) # Pre-compute the sqrt sqrtOk = T.sqrt(T.abs_(Ok)) # Theno does not have exhaustive # control flow, so we have to compute them all # Start here dl = ifelse(T.eq(Ok, 0.0), (1 + z) * dc, 0.0 * (1 + z) * dc) # The above statement is zero if the # condition fails, so we add on to it dl += ifelse(T.gt(Ok, 0), (1 + z) * dh / sqrtOk * T.sinh(sqrtOk * dc / dh), 0.0 * (1 + z) * dc) # same idea as above dl += ifelse(T.lt(Ok, 0), (1 + z) * dh / sqrtOk * T.sin(sqrtOk * dc / dh), 0.0 * (1 + z) * dc) return 5.0 * T.log10(dl) + 25.0 # dist mod
def sinh_approx(v_out, i_th=i_th): # approximating function, given preset parameters return i_th * 4.1571e-5 * T.sinh(39.1503 * (v_out - 1.285))
def _log_gamma_windschitl(z): """ computes log(gamma(z)) using windschitl's approximation. """ return 0.5 * (T.log(2*np.pi) - T.log(z) + z * (2 * T.log(z) - 2 + T.log(z * T.sinh(1/z) + 1 / (810*(z**6)))))
def inv(self, y): return tt.sinh(self.shift + self.scale * tt.arcsinh(y))
def __call__(self, x): return tt.sinh((tt.arcsinh(x) - self.shift) / self.scale)
def __call__(self, x): return tt.sinh((x - self.shift) / self.scale)
def sinh(X): return T.sinh(X)
def __call__(self, x): return tt.sinh(self.scale * x) / self.scale - self.shift
def theano_dydt(r, theta, b): R = 2 * b * r s = tt.sinh(R) return (2 * np.sqrt(2) / 7) * r * tt.sqrt(1 + R / s) / (1 - R / s)