math_utils.py | math_utils.py | |||
---|---|---|---|---|
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | |||
import numpy as np | import numpy as np | |||
import math | import math | |||
from scipy import special | ||||
# Mandatory TAU = 6.283185307179586... | # Mandatory TAU = 6.283185307179586... | |||
math.tau = 2 * math.pi | math.tau = 2 * math.pi | |||
def merge_where_nan(target, filler): | def merge_where_nan(target, filler): | |||
""" | """ | |||
Procedurally mutates target by replacing its nan values by values from filler. | Procedurally mutates target by replacing its nan values by values from filler. | |||
This is a very simple polyfill for numpy.copyto (for numpy < 1.7). | This is a very simple polyfill for numpy.copyto (for numpy < 1.7). | |||
""" | """ | |||
try: | #try: | |||
# np.copyto(target, filler, where=np.isnan(target)) | ||||
#except AttributeError: | ||||
# isnan = np.isnan(target) | ||||
# target[isnan] = filler[isnan] | ||||
if target.size == filler.size: | ||||
np.copyto(target, filler, where=np.isnan(target)) | np.copyto(target, filler, where=np.isnan(target)) | |||
except AttributeError: | else: | |||
isnan = np.isnan(target) | try: | |||
target[isnan] = filler[isnan] | for k in target.names: | |||
if k in filler.names: | ||||
target[k] = np.where(np.isnan(target[k]), filler[k], ta | ||||
rget[k]) | ||||
except ValueError: | ||||
raise ValueError(" merge failed ") | ||||
def safe_exp(x): | def safe_exp(x): | |||
""" | """ | |||
Should not throw during Underflows (and return 0) and Overflows (and re turn inf). | Should not throw during Underflows (and return 0) and Overflows (and re turn inf). | |||
This code is a hack, and may be cause of future bugs. | This code is a hack, and may be cause of future bugs. | |||
Oddly enough, it passes a few basic tests in `math_utils_test.py`. | Oddly enough, it passes a few basic tests in `math_utils_test.py`. | |||
""" | """ | |||
try: | try: | |||
a = math.exp(x) | a = math.exp(x) | |||
except OverflowError: | except OverflowError: | |||
skipping to change at line 99 | skipping to change at line 109 | |||
median = np.median(data) | median = np.median(data) | |||
sigma = np.std(data) | sigma = np.std(data) | |||
return median, sigma, iteration | return median, sigma, iteration | |||
def flux_gaussian(radius, rhwhm): | def flux_gaussian(radius, rhwhm): | |||
""" | """ | |||
Disk Gaussian profile with Gaussian thickness | Disk Gaussian profile with Gaussian thickness | |||
""" | """ | |||
energy = np.exp(-radius ** 2 / 2. / (2. * rhwhm / 2.35) ** 2) #* np | #energy = np.exp(-radius ** 2 / 2. / (2. * rhwhm / 2.35) ** 2) #* n | |||
.exp(-nz ** 2 / 2. / hz ** 2) | p.exp(-nz ** 2 / 2. / hz ** 2) | |||
return energy #DizkModel.flux_sersic(radius, size, 0.5) | return flux_sersic(radius, rhwhm, 0.5) | |||
def flux_sersic(radius, size, index): | def flux_sersic(radius, size, index, normalize=False): | |||
""" | """ | |||
Sersic profile with Gaussian thickness | Sersic profile with Gaussian thickness | |||
See http://en.wikipedia.org/wiki/Sersic_profile | See http://en.wikipedia.org/wiki/Sersic_profile | |||
""" | """ | |||
beta = 1.9992 * index - 0.3271 | beta = 1.9992 * index - 0.3271 | |||
energy = np.exp(-beta * (radius / size) ** (1. / index)) | energy = np.exp(-beta * ((radius / size) ** (1. / index) -1) ) | |||
if normalize: | ||||
#Graham Driver 2005 | ||||
Norm = size**2 * 2 * np.pi * index * np.exp(beta) / beta**(2*in | ||||
dex) | ||||
energy = energy / Norm | ||||
#energy = np.exp(-beta * (radius / size) ** (1. / index)) * np.exp( -nz ** 2 / 2. / hz ** 2) | #energy = np.exp(-beta * (radius / size) ** (1. / index)) * np.exp( -nz ** 2 / 2. / hz ** 2) | |||
#energy = np.exp(-beta * (radius / size) ** (1. / index)) * np.exp( -np.sqrt(nz ** 2) / hz ) #exponential z-profile | #energy = np.exp(-beta * (radius / size) ** (1. / index)) * np.exp( -np.sqrt(nz ** 2) / hz ) #exponential z-profile | |||
#energy = np.exp(-beta * (radius / size) ** (1. / index)) * np.cosh (-nz / hz )**(-2.) #sech^2 z-profile | #energy = np.exp(-beta * (radius / size) ** (1. / index)) * np.cosh (-nz / hz )**(-2.) #sech^2 z-profile | |||
return energy | return energy | |||
def flux_exponential(radius, size): | def flux_exponential(radius, size): | |||
""" | """ | |||
Disk exponential profile with Gaussian thickness | Disk exponential profile with Gaussian thickness | |||
This is merely a Sérsic profile with index = 1 | This is merely a Sérsic profile with index = 1 | |||
""" | """ | |||
return flux_sersic(radius, size, 1.) | return flux_sersic(radius, size, 1.) | |||
def flux_de_vaucouleurs(radius, size): | def flux_de_vaucouleurs(radius, size): | |||
""" | """ | |||
De Vaucouleurs profile with Gaussian thickness | De Vaucouleurs profile with Gaussian thickness | |||
See http://en.wikipedia.org/wiki/De_Vaucouleurs%27_law | See http://en.wikipedia.org/wiki/De_Vaucouleurs%27_law | |||
This is merely a Sérsic profile with index = 4 | This is merely a Sérsic profile with index = 4 | |||
""" | """ | |||
return flux_sersic(radius, size, 4.) | return flux_sersic(radius, size, 4.) | |||
def Phi_ppf(q, loc=0, scale=1.): | ||||
""" | ||||
normal ppf | ||||
:param q: | ||||
:param loc: | ||||
:param scale: | ||||
:return: | ||||
""" | ||||
#https://stackoverflow.com/questions/38754423/drawing-gaussian-random-v | ||||
ariables-using-scipy-erfinv | ||||
return loc+2**0.5*scale*special.erfinv(2*q-1) | ||||
End of changes. 7 change blocks. | ||||
9 lines changed or deleted | 26 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |