def m_step(self, expectations, datas, inputs, masks, tags, **kwargs): from sklearn.linear_model import LinearRegression D, M = self.D, self.M for k in range(self.K): xs, ys, weights = [], [], [] for (Ez, _), data, input in zip(expectations, datas, inputs): xs.append( np.hstack([ data[self.lags - l - 1:-l - 1] for l in range(self.lags) ] + [input[self.lags:]])) ys.append(data[self.lags:]) weights.append(Ez[self.lags:, k]) xs = np.concatenate(xs) ys = np.concatenate(ys) weights = np.concatenate(weights) # Fit a weighted linear regression lr = LinearRegression() lr.fit(xs, ys, sample_weight=weights) self.As[k], self.Vs[k], self.bs[ k] = lr.coef_[:, :D * self.lags], lr.coef_[:, D * self.lags:], lr.intercept_ assert np.all(np.isfinite(self.As)) assert np.all(np.isfinite(self.Vs)) assert np.all(np.isfinite(self.bs)) # Update the variances yhats = lr.predict(xs) sqerr = (ys - yhats)**2 self.inv_sigmas[k] = np.log( np.average(sqerr, weights=weights, axis=0))
def sample_prior(kld_sampler, n_layers, n_hid_units, is_ResNet, n_inv_steps=20, alpha=.00005): ### DEFINE FUNCTIONS # define E[KLD] function def expected_KLD(log_tau, prev_log_taus, n_layers, mc_samples=3, sigma2_y=1.): tau = softplus(log_tau) prev_taus = softplus(prev_log_taus) kld_accum = 0. for s_idx in range(mc_samples): if is_ResNet: f0 = fprop(0., prev_taus, n_layers, n_hid_units, is_ResNet) else: f0 = fprop(-1, prev_taus, n_layers, n_hid_units, is_ResNet) f1 = fprop(tau, prev_taus, n_layers, n_hid_units, is_ResNet) kld_accum += np.mean((f0 - f1)**2 / (2 * sigma2_y)) return kld_accum / mc_samples # define grad dEKLD_dTau = grad(expected_KLD) ### RUN ITERATIVE SAMPLING log_tau_samples = np.random.uniform(low=-2, high=-1, size=(n_layers, )) for layer_idx in range(n_layers): k_hat = kld_sampler() for t_idx in range(n_inv_steps): ekld = expected_KLD(log_tau=log_tau_samples[layer_idx], prev_log_taus=log_tau_samples[:layer_idx], n_layers=n_layers) if not np.isfinite(ekld): continue ekld_prime = dEKLD_dTau(log_tau_samples[layer_idx], log_tau_samples[:layer_idx], n_layers) if not np.isfinite(ekld_prime): continue if np.abs(ekld_prime) < .1: ekld_prime = np.sign(ekld_prime) * .1 log_tau_samples[layer_idx] = log_tau_samples[layer_idx] - alpha / ( ekld_prime) * (ekld - k_hat) return softplus(log_tau_samples)
def test_generate_all_predictions(): """Spot-check that the predicted free energies are reasonable (right shape, finite, RMSE (in kcal/mol) in a reasonable range)""" theta = np.ones(2 * n_types) from time import time print('predicting hydration free energies with theta=ones...') t0 = time() predictions = generate_all_predictions(theta) t1 = time() print('that took {:.3f} s'.format(t1 - t0)) # sanity check that the predictions are finite and that there's the right number of them assert (len(predictions) == len(molecules)) assert (np.isfinite(predictions).all()) # sanity check that the numerical values of the predictions aren't grossly wrong... pred_kcal_mol = unreduce(predictions) expt_kcal_mol = unreduce(expt_means) rmse = np.sqrt(np.mean((pred_kcal_mol - expt_kcal_mol)**2)) print('RMSE for theta all ones: {:.3f} kcal/mol'.format(rmse)) # first time I ran this test, it was ~7.154 kcal/mol assert (rmse < 10.) assert (rmse > 2.) # check that running with mbondi radii and scales gives an RMSE closer to like 2.5 kcal/mol theta = pack(radii=mbondi_model.get_radii(), scales=mbondi_model.get_scale_factors()) print('predicting hydration free energies with theta from mbondi model...') t0 = time() predictions = generate_all_predictions(theta) t1 = time() print('that took {:.3f} s'.format(t1 - t0)) # sanity check that the predictions are finite and that there's the right number of them assert (len(predictions) == len(molecules)) assert (np.isfinite(predictions).all()) # sanity check that the numerical values of the predictions aren't grossly wrong... pred_kcal_mol = unreduce(predictions) expt_kcal_mol = unreduce(expt_means) rmse = np.sqrt(np.mean((pred_kcal_mol - expt_kcal_mol)**2)) print('RMSE for mbondi model: {:.3f} kcal/mol'.format(rmse)) # I think it's around 2.4 kcal/mol, but this test is saying something like 2.628 kcal/mol assert (rmse > 2.) assert (rmse < 3.)
def elbo(self, variational_params, datas, inputs=None, masks=None, tags=None, n_samples=1): """ Lower bound on the marginal likelihood p(y | theta) using variational posterior q(x; phi) where phi = variational_params """ elbo = 0 for data, input, mask, tag, (q_mu, q_sigma_inv) in \ zip(datas, inputs, masks, tags, variational_params): q_sigma = np.exp(q_sigma_inv) for sample in range(n_samples): # log p(theta) elbo += self.log_prior() # Sample x from the variational posterior x = q_mu + np.sqrt(q_sigma) * npr.randn(data.shape[0], self.D) # Compute log p(x | theta) = log \sum_z p(x, z | theta) # The "mask" for x is all ones x_mask = np.ones_like(x, dtype=bool) log_pi0 = self.init_state_distn.log_initial_state_distn(x, input, x_mask, tag) log_Ps = self.transitions.log_transition_matrices(x, input, x_mask, tag) log_likes = self.dynamics.log_likelihoods(x, input, x_mask, tag) log_likes += self.emissions.log_likelihoods(data, input, mask, tag, x) elbo += hmm_normalizer(log_pi0, log_Ps, log_likes) # -log q(x) elbo -= np.sum(-0.5 * np.log(2 * np.pi * q_sigma)) elbo -= np.sum(-0.5 * (x - q_mu)**2 / q_sigma) assert np.isfinite(elbo) return elbo / n_samples
def initialize(self, datas, inputs=None, masks=None, tags=None): data = np.concatenate(datas) ddata = np.concatenate([np.gradient(d, axis=0) for d in datas]) ddata = (ddata - ddata.mean(0)) / ddata.std(0) input = np.concatenate(inputs) T = data.shape[0] # Cluster the data and its gradient before initializing from sklearn.cluster import KMeans km = KMeans(self.K) # km.fit(np.column_stack((data, ddata))) km.fit(data) z = km.labels_[:-self.lags] from sklearn.linear_model import LinearRegression for k in range(self.K): ts = np.where(z == k)[0] x = np.column_stack([data[ts + l] for l in range(self.lags)] + [input[ts]]) y = data[ts + self.lags] lr = LinearRegression().fit(x, y) self.As[k] = lr.coef_[:, :self.D * self.lags] self.Vs[k] = lr.coef_[:, self.D * self.lags:] self.bs[k] = lr.intercept_ resid = y - lr.predict(x) sigmas = np.var(resid, axis=0) self.inv_sigmas[k] = np.log(sigmas + 1e-16) assert np.all(np.isfinite(self.inv_sigmas))
def elbo(self, variational_params, datas, inputs=None, masks=None, tags=None, n_samples=1): """ Lower bound on the marginal likelihood p(y | theta) using variational posterior q(x; phi) where phi = variational_params """ elbo = 0 for data, input, mask, tag, (q_mu, q_sigma_inv) in \ zip(datas, inputs, masks, tags, variational_params): q_sigma = np.exp(q_sigma_inv) for sample in range(n_samples): # log p(theta) elbo += self.log_prior() # Sample x from the variational posterior x = q_mu + np.sqrt(q_sigma) * npr.randn(data.shape[0], self.D) x_mask = np.ones_like(x, dtype=bool) # Compute log p(y, x | theta) elbo += np.sum(self.dynamics.log_likelihoods(x, input, x_mask, tag)) elbo += np.sum(self.emissions.log_likelihoods(data, input, mask, tag, x)) # -log q(x) elbo -= np.sum(-0.5 * np.log(2 * np.pi * q_sigma)) elbo -= np.sum(-0.5 * (x - q_mu)**2 / q_sigma) assert np.isfinite(elbo) return elbo / n_samples
def nll(p, y, gp): # Update the kernel parameters: gp.set_parameter_vector(p) # Compute the loglikelihood: ll = gp.log_likelihood(y, quiet=True) # The scipy optimizer doesn’t play well with infinities: return -ll if np.isfinite(ll) else 1e25
def elbo(self, variational_posterior, datas, inputs=None, masks=None, tags=None, n_samples=1): """ Lower bound on the marginal likelihood p(y | theta) using variational posterior q(x; phi) where phi = variational_params """ elbo = 0 for sample in range(n_samples): # Sample x from the variational posterior xs = variational_posterior.sample() # log p(theta) elbo += self.log_prior() # Compute log p(y, x | theta) for x, data, input, mask, tag in zip(xs, datas, inputs, masks, tags): x_mask = np.ones_like(x, dtype=bool) elbo += np.sum( self.dynamics.log_likelihoods(x, input, x_mask, tag)) elbo += np.sum( self.emissions.log_likelihoods(data, input, mask, tag, x)) # -log q(x) elbo -= variational_posterior.log_density(xs) assert np.isfinite(elbo) return elbo / n_samples
def expected_log_likelihood(self, expectations, datas, inputs=None, masks=None, tags=None): """ Compute log-likelihood given current model parameters. :param datas: single array or list of arrays of data. :return total log probability of the data. """ ell = 0.0 for (Ez, Ezzp1, _), data, input, mask, tag in \ zip(expectations, datas, inputs, masks, tags): pi0 = self.init_state_distn.initial_state_distn log_Ps = self.transitions.log_transition_matrices( data, input, mask, tag) log_likes = self.observations.log_likelihoods( data, input, mask, tag) ell += np.sum(Ez[0] * np.log(pi0)) ell += np.sum(Ezzp1 * log_Ps) ell += np.sum(Ez * log_likes) assert np.isfinite(ell) return ell
def standardize(X): mx = np.mean(X, 0) stdx = np.std(X, axis=0) # Assume standard deviations are not 0 Zx = old_div((X-mx),stdx) assert np.all(np.isfinite(Zx)) return Zx
def _objective(params, itr): # Grab a minibatch of data data, input, mask, tag = _get_minibatch(itr) Ti = data.shape[0] # E step: compute expected latent states with current parameters Ez, Ezzp1, _ = self.expected_states(data, input, mask, tag) # M step: set the parameter and compute the (normalized) objective function self.params = params log_pi0 = self.init_state_distn.log_initial_state_distn( data, input, mask, tag) log_Ps = self.transitions.log_transition_matrices( data, input, mask, tag) log_likes = self.observations.log_likelihoods( data, input, mask, tag) # Compute the expected log probability # (Scale by number of length of this minibatch.) obj = self.log_prior() obj += np.sum(Ez[0] * log_pi0) * M obj += np.sum(Ezzp1 * log_Ps) * (T - M) / (Ti - 1) obj += np.sum(Ez * log_likes) * T / Ti assert np.isfinite(obj) return -obj / T
def expected_log_probability(self, expectations, datas, inputs=None, masks=None, tags=None): """ Compute the log probability of the data under the current model parameters. :param datas: single array or list of arrays of data. :return total log probability of the data. """ elp = self.log_prior() for (Ez, Ezzp1, _), data, input, mask, tag in \ zip(expectations, datas, inputs, masks, tags): log_pi0 = self.init_state_distn.log_initial_state_distn( data, input, mask, tag) log_Ps = self.transitions.log_transition_matrices( data, input, mask, tag) log_likes = self.observations.log_likelihoods( data, input, mask, tag) # Compute the expected log probability elp += np.sum(Ez[0] * log_pi0) elp += np.sum(Ezzp1 * log_Ps) elp += np.sum(Ez * log_likes) assert np.isfinite(elp) return elp
def elbo(self, variational_posterior, datas, inputs=None, masks=None, tags=None, n_samples=1): """ Lower bound on the marginal likelihood p(y | theta) using variational posterior q(x; phi) where phi = variational_params """ elbo = 0 for sample in range(n_samples): # Sample x from the variational posterior xs = variational_posterior.sample() # log p(theta) elbo += self.log_prior() # log p(x, y | theta) = log \sum_z p(x, y, z | theta) for x, data, input, mask, tag in zip(xs, datas, inputs, masks, tags): # The "mask" for x is all ones x_mask = np.ones_like(x, dtype=bool) pi0 = self.init_state_distn.initial_state_distn Ps = self.transitions.transition_matrices(x, input, x_mask, tag) log_likes = self.dynamics.log_likelihoods(x, input, x_mask, tag) log_likes += self.emissions.log_likelihoods(data, input, mask, tag, x) elbo += hmm_normalizer(pi0, Ps, log_likes) # -log q(x) elbo -= variational_posterior.log_density(xs) assert np.isfinite(elbo) return elbo / n_samples
def renyii(pk0, pk1, a): """ Compute the renyii divergence between two Gaussian distributions. """ # Check dimensions assert (pk0.S.shape == pk1.S.shape) # Check diagonal p0S_is_diag = np.all(np.diag(np.diag(pk0.S)) == pk0.S) p1S_is_diag = np.all(np.diag(np.diag(pk1.S)) == pk1.S) Sa = (1 - a) * pk0.S + a * pk1.S # make sure eigenvalues are positive if np.any(np.isfinite(Sa) == 0): print(Sa) w, v = np.linalg.eig(Sa) #assert(np.all(w > 0)) assert np.linalg.det(Sa) != 0 #if np.linalg.det(Sa) == 0: # print Sa # return float('Inf') dm = pk1.m - pk0.m # Use precise computation for diagonal covariance matrices if p0S_is_diag and p1S_is_diag: r = a / 2. * np.dot(np.dot(dm, np.linalg.inv(Sa)), dm) + \ (np.sum(np.log(np.diag(Sa))) - (1-a)*np.sum(np.log(np.diag(pk0.S))) - a*np.sum(np.log(np.diag(pk1.S)))) \ / (1 - a) / 2. else: r = a / 2. * np.dot(np.dot(dm, np.linalg.inv(Sa)), dm) + \ (np.log(np.linalg.det(Sa)) - (1-a)*np.log(np.linalg.det(pk0.S)) - a*np.log(np.linalg.det(pk1.S))) \ / (1 - a) / 2. #assert(r > -1e-10) return max(r, 0)
def make_frame(request, hyper_params=default_hyper_params): frame = resample(request) print('resample', frame) frame = make_pandas_frame(frame) print('pandas', frame) frame["delta"] = frame["glucose"] - frame["glucose"].shift(1) print('delta', frame['delta']) maxdelta = hyper_params.get("maxdelta", 10) delta = frame["delta"] frame.loc[(delta > maxdelta) | (delta < -maxdelta), "delta"] = hyper_params.get("maxdelta_replace", math.nan) if hyper_params.get("delta_window", 1) > 0: frame["delta"] = (frame["delta"].rolling( window=hyper_params["delta_window"], min_periods=1).mean()) print('delta33', frame['delta']) win = hyper_params.get("rolling_window") if win > 1: # Compute endpoint deltas directly so we have more data points to # work with (fewer will get filtered out by the NaN filter). # frame['delta'] = (frame['sgv'] - frame['sgv'].shift(win)) / (win+1) # frame['ca'] = frame['ca'].rolling(window=win).mean() # frame['ia'] = frame['ia'].rolling(window=win).mean() frame = frame.rolling(window=win).mean() rows = (np.isfinite(frame["delta"]) & np.isfinite(frame["carb"]) & np.isfinite(frame["insulin"])) frame = frame[rows] print('finite', frame) insulin_quantile = frame["insulin"].quantile(0.90) print('iq', insulin_quantile) # Filter carb and insulin outliers. # frame = frame[(frame["insulin"] > 0) & (frame["insulin"] <= insulin_quantile)] # print('filter insulin', frame) # (frame["insulin"] >= frame["insulin"].quantile(0.05)) # & (frame["insulin"] <= frame["insulin"].quantile(0.85)) # ] carb_quantile = frame[frame["carb"] > 0.0]["carb"].quantile(0.90) print('cq', carb_quantile) #frame = frame[frame["carb"] <= carb_quantile] return frame
def log_probability(self, theta, x, y): lp = self.log_prior(theta) if not np.isfinite(lp): return -np.inf return lp + self.log_likelihood(theta, x, y)
def molecular_eval_norm(t, mag, w, tau, phi=None, L=128.0, norm_method='analytic', verbose=0, **kwargs): """ Nearly the same as for atoms, but we no longer broadcast generally. One molecule, many time steps. """ # verbose = kwargs.get('verbose', 0) mol_norm = molecular_mag(t, mag, w, tau, phi=phi, L=L, norm_method=norm_method, verbose=verbose, **kwargs) if np.any(mol_norm <= 0.0) and verbose > 1: # Null molecules should be removed before we get to this stage # but occasionally my logic misses them warnings.warn("magnitude of mol norm vanished {}".format( (mag, w, tau, phi))) mol_norm = np.maximum(mol_norm, 1e-12) mol_ev = molecular_eval(t, mag, w, tau, phi=None, L=128.0, **kwargs) if not np.all(np.isfinite(mol_ev)) and verbose >= 1: warnings.warn("raw molecule exploded {} giving \n{}".format( [mag, w, tau, phi], mol_ev, )) normed_eval = mol_ev / mol_norm if not np.all(np.isfinite(normed_eval)): warnings.warn("raw molecule exploded {} giving \n{}".format( [mag, w, tau, phi], normed_eval, )) return normed_eval
def log_transition_matrix(self): Ps_dist = np.sum((self.ell[None, :, :] - self.ell[:, None, :])**2, axis=2) log_Ps = -Ps_dist / self.L log_Ps += np.diag(self.log_p) assert np.all(np.isfinite(log_Ps)) # Normalize and return return log_Ps - logsumexp(log_Ps, axis=1, keepdims=True)
def logsumexp(a, axis=None, keepdims=False): """Modified from scipy : Compute the log of the sum of exponentials of input elements. Parameters ---------- a : array_like Input array. axis : None or int or tuple of ints, optional Axis or axes over which the sum is taken. By default `axis` is None, and all elements are summed. .. versionadded:: 0.11.0 keepdims : bool, optional If this is set to True, the axes which are reduced are left in the result as dimensions with size one. With this option, the result will broadcast correctly against the original array. .. versionadded:: 0.15.0 Returns ------- res : ndarray The result, ``np.log(np.sum(np.exp(a)))`` calculated in a numerically more stable way. If `b` is given then ``np.log(np.sum(b*np.exp(a)))`` is returned. sgn : ndarray If return_sign is True, this will be an array of floating-point numbers matching res and +1, 0, or -1 depending on the sign of the result. If False, only one result is returned. """ a_max = np.amax(a, axis=axis, keepdims=True) # Cutting the max if infinite a_max = np.where(~np.isfinite(a_max), 0, a_max) assert np.sum(~np.isfinite(a_max)) == 0 tmp = np.exp(a - a_max) # suppress warnings about log of zero with np.errstate(divide='ignore'): s = np.sum(tmp, axis=axis, keepdims=keepdims) out = np.log(s) if not keepdims: a_max = np.squeeze(a_max, axis=axis) out += a_max return out
def _parameter_initialiser(self, x, c=None, n=None, offset=False): # x, c, n = xcn_handler(x, c, n) # c = (c == 0).astype(np.int64) rate = 1. / x[np.isfinite(x)].mean() if offset: return np.min(x) - (np.max(x) - np.min(x)) / 10., rate else: return np.array([rate])
def standardize(data, mask): data[~mask] = np.nan m = np.nanmean(data, axis=0) s = np.nanstd(data, axis=0) s[~np.any(mask, axis=0)] = 1 y = (data - m) / s assert np.all(np.isfinite(y)) return y
def log_prob(params, fit_y, gp, logperiod): gp.set_parameter_vector(params) p_current = gp.get_parameter_dict()['kernel:terms[2]:log_P'] lp = gp.log_prior() + additional_prior(params, p_current, logperiod) if not np.isfinite(lp): return -np.inf return lp + gp.log_likelihood(fit_y)
def lnlike(p, x, y, gp): ln_a = p[0] ln_b = p[1] p0 = np.array([ln_a, ln_b]) # update kernel parameters: gp.set_parameter_vector(p0) # calculate the likelihood: ll = gp.log_likelihood(y, quiet=True) # return return ll if np.isfinite(ll) else 1e25
def __init__(self, X): """ :param X: n x d numpy array for dataset X """ self.X = X if not np.all(np.isfinite(X)): print 'X:' print util.fullprint(X) raise ValueError('Not all elements in X are finite.')
def mse(model): """ MSE: Mean Square Error This is simply fitting the curve to the best estimate from a non-parametric estimate. This is slightly different in that it fits it to untransformed data on the x and y axis. The MPP method fits the curve to the transformed data. This is simply fitting a the CDF sigmoid to the nonparametric estimate. """ dist = model.dist x, c, n, t = (model.data['x'], model.data['c'], model.data['n'], model.data['t']) const = model.fitting_info['const'] inv_trans = model.fitting_info['inv_trans'] init = model.fitting_info['init'] if (-1 in c) or (2 in c): out = nonp.turnbull(x, c, n, t, estimator='Fleming-Harrington') else: out = nonp.fleming_harrington(x, c, n, t) F = 1 - out['R'] mask = np.isfinite(out['x']) F = F[mask] x = out['x'][mask] jac = jacobian(mse_fun) hess = hessian(mse_fun) old_err_state = np.seterr(all='ignore') res = minimize(mse_fun, init, method='Newton-CG', jac=jac, hess=hess, args=(dist, x, F, inv_trans, const)) if (res.success is False) or (np.isnan(res.x).any()): res = minimize(mse_fun, init, method='BFGS', jac=jac, args=(dist, x, F, inv_trans, const)) if (res.success is False) or (np.isnan(res.x).any()): res = minimize(mse_fun, init, args=(dist, x, F, inv_trans, const)) results = {} results['res'] = res results['params'] = inv_trans(const(res.x)) np.seterr(**old_err_state) return results
def check_parameters(self): """Check that all parameters have finite elements Raises ------ `ArithmeticError` when non-finite elements are present """ for k, p in enumerate(self._parameters): if not np.isfinite(p).all(): msg = "Component {} Parameter {} is not finite:\n{}".format( self, k, p) raise ArithmeticError(msg)
def _log_prob_noderivatives(self, x): """ Computes the log-probability of an action $\mathbf u$ without computing derivatives. This is here only to facilitate unit testing of the `.log_prob` method by comparison against `autograd`. """ # Compute logits self.logits = self.inverse_softmax_temp*x # Compute log-probability of actions LSE = fu.logsumexp(self.logits) if not np.isfinite(LSE): LSE = 0. return self.logits - LSE
def log_prob(self, x): """ Computes the log-probability of an action $\mathbf u$ $$ \log p(\mathbf u|\mathbf v, \mathbf u_{t-1}) = \\big(\\beta \mathbf v + \\beta^\\rho \mathbf u_{t-1}) - \log \sum_{v_i} e^{\\beta \mathbf v_i + \\beta^\\rho u_{t-1}^{(i)}} $$ Arguments: x: State vector of type `ndarray((nactions,))` Returns: Scalar log-probability """ # Compute logits Bx = self.inverse_softmax_temp*x stickiness = self.perseveration*self.a_last self.logits = Bx + stickiness # Hessians HB, Hp, HBp, Hx, _ = hess.log_stickysoftmax(self.inverse_softmax_temp, self.perseveration, x, self.a_last) self.hess_logprob['inverse_softmax_temp'] = HB self.hess_logprob['perseveration'] = Hp self.hess_logprob['action_values'] = Hx self.hess_logprob['inverse_softmax_temp_perseveration'] = HBp # Derivatives # Grad LSE wrt Logits Dlse = grad.logsumexp(self.logits) # Grad logprob wrt logits self.d_logprob['logits'] = np.eye(x.size) - Dlse # Partial derivative with respect to inverse softmax temp self.d_logits['inverse_softmax_temp'] = x self.d_logits['perseveration'] = self.a_last self.d_logprob['inverse_softmax_temp'] = x - np.dot(Dlse, x) self.d_logprob['perseveration'] = self.a_last - np.dot(Dlse, self.a_last) # Gradient with respect to x B = np.eye(x.size)*self.inverse_softmax_temp Dlsetile = np.tile(self.inverse_softmax_temp*Dlse, [x.size, 1]) self.d_logprob['action_values'] = B - Dlsetile LSE = fu.logsumexp(self.logits) if not np.isfinite(LSE): LSE = 0. return self.logits - LSE
def multi_objective(rates): """ normalised inner product for each rate """ molecules = [molecular_scale( code_coef, 1, rate, ) for rate in rates] normecules = np.array([ molecular_eval_norm(t, *molecule, norm_method=norm_method, verbose=verbose) for molecule in molecules ]) if not np.all(np.isfinite(normecules)) and verbose >= 1: exploded = np.isfinite(normecules.sum(1)) warnings.warn( "{} normed molecules {} exploded with\n{} at rates\n{}".format( np.sum(exploded), normecules.shape, code_coef, rates[exploded])) obj = np.array([np.dot(normecule, target) for normecule in normecules]) return np.nan_to_num(obj)
def jitchol(A, maxtries=5): diagA = np.diag(A) if np.any(diagA <= 0.): raise np.linalg.LinAlgError("not pd: non-positive diagonal elements") jitter = diagA.mean() * 1e-6 num_tries = 1 while num_tries <= maxtries and np.isfinite(jitter): try: L = np.linalg.cholesky(A + np.eye(A.shape[0]) * jitter, lower=True) return L except: jitter *= 10 finally: num_tries += 1 raise np.linalg.LinAlgError("not positive definite, even with jitter.")
def fit_gaussian_draw(X, J, seed=28, reg=1e-7, eig_pow=1.0): """ Fit a multivariate normal to the data X (n x d) and draw J points from the fit. - reg: regularizer to use with the covariance matrix - eig_pow: raise eigenvalues of the covariance matrix to this power to construct a new covariance matrix before drawing samples. Useful to shrink the spread of the variance. """ with NumpySeedContext(seed=seed): d = X.shape[1] mean_x = np.mean(X, 0) cov_x = np.cov(X.T) if d==1: cov_x = np.array([[cov_x]]) [evals, evecs] = np.linalg.eig(cov_x) evals = np.maximum(0, np.real(evals)) assert np.all(np.isfinite(evals)) evecs = np.real(evecs) shrunk_cov = evecs.dot(np.diag(evals**eig_pow)).dot(evecs.T) + reg*np.eye(d) V = np.random.multivariate_normal(mean_x, shrunk_cov, J) return V
def compute_rotated_map(self, rotation): """ Compute stellar maps projected on the plane of the sky for a given rotation of the star Args: rotation (float) : rotation around the star in degrees given as [longitude, latitude] in degrees Returns: pixel_unique (int) : vector with the "active" healpix pixels pixel_map (int) : map showing the healpix pixel projected on the plane of the sky mu_pixel (float): map of the astrocentric angle for each pixel on the plane of the sky (zero for pixels not in the star) T_pixel (float): map of temperatures for each pixel on the plane of the sky """ mu_pixel = np.zeros_like(self.mu_angle) T_pixel = np.zeros_like(self.mu_angle) # Get the projection of the healpix pixel indices on the plane of the sky pixel_map = self.projector.projmap(self.indices, self.f_vec2pix, rot=rotation)[:,0:int(self.npix/2)] # Get the unique elements in the vector pixel_unique = np.unique(pixel_map) # Now loop over all unique pixels, filling up the array of the projected map with the mu and temeperature values for j in range(len(pixel_unique)): ind = np.where(pixel_map == pixel_unique[j]) if (np.all(np.isfinite(self.mu_angle[ind[0],ind[1]]))): if (self.mu_angle[ind[0],ind[1]].size == 0): value = 0.0 else: value = np.nanmean(self.mu_angle[ind[0],ind[1]]) mu_pixel[ind[0],ind[1]] = value T_pixel[ind[0],ind[1]] = self.temperature_map[int(pixel_unique[j])] else: mu_pixel[ind[0],ind[1]] = 0.0 T_pixel[ind[0],ind[1]] = 0.0 return pixel_unique, pixel_map, mu_pixel, T_pixel
def precompute_rotation_maps(self, rotations=None): """ Compute the averaged spectrum on the star for a given temperature map and for a given rotation Args: rotations (float) : [N_phases x 2] giving [longitude, latitude] in degrees for each phase Returns: None """ if (rotations is None): print("Use some angles for the rotations") return self.n_phases = rotations.shape[0] self.avg_mu = [None] * self.n_phases self.avg_v = [None] * self.n_phases self.velocity = [None] * self.n_phases self.n_pixel_unique = [None] * self.n_phases self.n_pixels = [None] * self.n_phases self.pixel_unique = [None] * self.n_phases for loop in range(self.n_phases): mu_pixel = np.zeros_like(self.mu_angle) v_pixel = np.zeros_like(self.vel_projection) pixel_map = self.projector.projmap(self.indices, self.f_vec2pix, rot=rotations[loop,:])[:,0:int(self.npix/2)] pixel_unique = np.unique(pixel_map[np.isfinite(pixel_map)]) for j in range(len(pixel_unique)): ind = np.where(pixel_map == pixel_unique[j]) if (np.all(np.isfinite(self.mu_angle[ind[0],ind[1]]))): if (self.mu_angle[ind[0],ind[1]].size == 0): mu_pixel[ind[0],ind[1]] = 0.0 v_pixel[ind[0],ind[1]] = 0.0 else: if (self.clv): value = np.nanmean(self.mu_angle[ind[0],ind[1]]) else: value = 1.0 mu_pixel[ind[0],ind[1]] = value value = np.nanmean(self.vel_projection[ind[0],ind[1]]) v_pixel[ind[0],ind[1]] = value else: mu_pixel[ind[0],ind[1]] = 0.0 v_pixel[ind[0],ind[1]] = 0.0 self.n_pixel_unique[loop] = len(pixel_unique) self.avg_mu[loop] = np.zeros(self.n_pixel_unique[loop]) self.avg_v[loop] = np.zeros(self.n_pixel_unique[loop]) self.velocity[loop] = np.zeros(self.n_pixel_unique[loop]) self.n_pixels[loop] = np.zeros(self.n_pixel_unique[loop], dtype='int') self.pixel_unique[loop] = pixel_unique.astype('int') for i in range(len(pixel_unique)): ind = np.where(pixel_map == pixel_unique[i]) self.n_pixels[loop][i] = len(ind[0]) self.avg_mu[loop][i] = np.unique(mu_pixel[ind[0], ind[1]]) self.avg_v[loop][i] = np.unique(v_pixel[ind[0], ind[1]]) self.velocity[loop][i] = self.avg_mu[loop][i] * self.avg_v[loop][i]