Skip to content

Commit a31223a

Browse files
committed
Hide scipy imports
1 parent 58f17a8 commit a31223a

File tree

2 files changed

+37
-33
lines changed

2 files changed

+37
-33
lines changed

light-curve/light_curve/light_curve_py/features/rainbow/bolometric.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
from typing import Dict, List, Union
55

66
import numpy as np
7-
from scipy.special import lambertw
87

98
__all__ = [
109
"bolometric_terms",
@@ -225,7 +224,6 @@ def value(t, t0, amplitude, rise_time):
225224

226225
@staticmethod
227226
def initial_guesses(t, m, sigma, band):
228-
229227
A = np.ptp(m)
230228
med_dt = median_dt(t, band)
231229

@@ -328,6 +326,11 @@ def limits(t, m, sigma, band):
328326

329327
@staticmethod
330328
def peak_time(t0, p):
329+
try:
330+
from scipy.special import lambertw
331+
except ImportError:
332+
raise ImportError("scipy is required for DoublexpBolometricTerm.peak_time, please install it")
333+
331334
return t0 + np.real(-lambertw(p * np.exp(1)) + 1)
332335

333336

light-curve/light_curve/light_curve_py/minuit_ml.py

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,10 @@
33
from typing import Callable, Dict, Tuple
44

55
import numpy as np
6-
from scipy.special import erf
7-
8-
9-
def logpdf(x, mu, sigma):
10-
# We do not need second term as it does not depend on parameters
11-
return -(((x - mu) / sigma) ** 2) / 2 # - np.log(np.sqrt(2*np.pi) * sigma)
12-
13-
14-
def barrier(x):
15-
res = np.where(x > 0, 1 / x, np.inf) # FIXME: naive barrier function
16-
17-
return res
18-
19-
20-
def logcdf(x):
21-
# TODO: faster (maybe not so accurate, as we do not need it) implementation
22-
# return norm.logcdf(x)
23-
24-
result = np.zeros(len(x))
25-
26-
idx = x < -5
27-
result[idx] = -x[idx] ** 2 / 2 - 1 / x[idx] ** 2 - 0.9189385336 - np.log(-x[idx])
28-
result[~idx] = np.log(0.5) + np.log1p(erf(x[~idx] / np.sqrt(2)))
29-
30-
return result
31-
326

337
try:
348
from iminuit import Minuit
9+
from scipy.special import erf
3510
except ImportError:
3611
MaximumLikelihood = None
3712
else:
@@ -63,21 +38,47 @@ def __call__(self, *par):
6338
ym = self.model(self.x, *par)
6439

6540
if self.upper_mask is None:
66-
result = -np.sum(logpdf(self.y, ym, self.yerror))
41+
result = -np.sum(self.logpdf(self.y, ym, self.yerror))
6742
else:
6843
# Measurements
69-
result = -np.sum(logpdf(self.y[~self.upper_mask], ym[~self.upper_mask], self.yerror[~self.upper_mask]))
44+
result = -np.sum(
45+
self.logpdf(self.y[~self.upper_mask], ym[~self.upper_mask], self.yerror[~self.upper_mask])
46+
)
7047
# Upper limits, Tobit model
7148
# https://stats.stackexchange.com/questions/49443/how-to-model-this-odd-shaped-distribution-almost-a-reverse-j
7249
result += -np.sum(
73-
logcdf((self.y[self.upper_mask] - ym[self.upper_mask]) / self.yerror[self.upper_mask])
50+
self.logcdf((self.y[self.upper_mask] - ym[self.upper_mask]) / self.yerror[self.upper_mask])
7451
)
7552

7653
# Barriers around parameter ranges
7754
# Scale is selected so that for the most of the range it is much smaller
7855
# than 0.5 which corresponds to 1-sigma errors
79-
result += 0.0001 * np.sum(barrier((par - self.limits0) / self.limits_scale))
80-
result += 0.0001 * np.sum(barrier((self.limits1 - par) / self.limits_scale))
56+
result += 0.0001 * np.sum(self.barrier((par - self.limits0) / self.limits_scale))
57+
result += 0.0001 * np.sum(self.barrier((self.limits1 - par) / self.limits_scale))
58+
59+
return result
60+
61+
@staticmethod
62+
def logpdf(x, mu, sigma):
63+
# We do not need the second term as it does not depend on parameters
64+
return -(((x - mu) / sigma) ** 2) / 2 # - np.log(np.sqrt(2*np.pi) * sigma)
65+
66+
@staticmethod
67+
def barrier(x):
68+
res = np.where(x > 0, 1 / x, np.inf) # FIXME: naive barrier function
69+
70+
return res
71+
72+
@staticmethod
73+
def logcdf(x):
74+
# TODO: faster (maybe not so accurate, as we do not need it) implementation
75+
# return norm.logcdf(x)
76+
77+
result = np.zeros(len(x))
78+
79+
idx = x < -5
80+
result[idx] = -x[idx] ** 2 / 2 - 1 / x[idx] ** 2 - 0.9189385336 - np.log(-x[idx])
81+
result[~idx] = np.log(0.5) + np.log1p(erf(x[~idx] / np.sqrt(2)))
8182

8283
return result
8384

0 commit comments

Comments
 (0)