def plotFilter(b, a, mag_type='abs', fs=2, ax1=None): w1, h = sig.freqz(b, a, fs=fs) w2, gd = sig.group_delay((b, a), fs=fs) if ax1 is None: fig, ax1 = plt.subplots() ax1.set_title('Digital filter frequency response') # ax1.plot(w1, 20 * np.log10(abs(h)), 'b') # ax1.plot(w1[:-1], (abs(h[:-1]) - abs(h[1:]))/(w1[1]-w1[0]), 'b') if mag_type == 'abs': mag = np.abs(h) mag_label = 'Magnitude' elif mag_type == 'dB': mag = 20 * np.log10(np.abs(h)) mag_label = 'Magnitude [dB]' elif mag_type == 'loss': mag = 20 * np.log10(1 / np.abs(h)) mag_label = 'Attenuation [dB]' ax1.plot(w1, mag, 'b') ax1.set_ylabel(mag_label, color='b') ax1.set_xlabel('Frequency [normalized]') ax2 = ax1.twinx() ax2.plot(w2, gd, 'g') ax2.set_ylabel('Group delay', color='g') ax2.grid() ax2.axis('tight') if mag_type == 'loss': ax2.set_ylim(-5, 5)
def loss(theta, X, y): y_hat = self.sigmoid(np.dot(X, theta)) y_hat = np.squeeze(y_hat) y = np.squeeze(y) res = -np.sum( y.dot(np.log10(y_hat)) + (1 - y).dot(np.log10(1 - y_hat))) res = res / X.shape[0] return res
def loss(theta, X, y): y_hat = self.sigmoid(np.dot(X, theta)) y_hat = np.squeeze(y_hat) y = np.squeeze(y) error = -np.sum( y.dot(np.log10(y_hat)) + (1 - y).dot(np.log10(1 - y_hat))) error = error / X.shape[0] error += self.l2_coef / (2 * X.shape[0]) * np.sum(np.square(theta)) return error
def speciation(dic, pH, totals, k_constants): """Calculate the full chemical speciation of seawater given DIC and pH. Based on CalculateAlkParts by Ernie Lewis. """ h_scale = 10.0**-pH # on the pH scale declared by the user sw = {} # Carbonate sw["HCO3"] = HCO3fromTCH(dic, h_scale, totals, k_constants) sw["CO3"] = CarbfromTCH(dic, h_scale, totals, k_constants) sw["CO2"] = dic - sw["HCO3"] - sw["CO3"] # Borate sw["BOH4"] = sw["BAlk"] = (totals["TB"] * k_constants["KB"] / (k_constants["KB"] + h_scale)) sw["BOH3"] = totals["TB"] - sw["BOH4"] # Water sw["OH"] = k_constants["KW"] / h_scale sw["Hfree"] = h_scale * k_constants["pHfactor_to_Free"] # Phosphate sw.update(phosphate_components(h_scale, totals, k_constants)) sw["PAlk"] = sw["HPO4"] + 2 * sw["PO4"] - sw["H3PO4"] # Silicate sw["H3SiO4"] = sw["SiAlk"] = (totals["TSi"] * k_constants["KSi"] / (k_constants["KSi"] + h_scale)) sw["H4SiO4"] = totals["TSi"] - sw["H3SiO4"] # Ammonium sw["NH3"] = sw["NH3Alk"] = (totals["TNH3"] * k_constants["KNH3"] / (k_constants["KNH3"] + h_scale)) sw["NH4"] = totals["TNH3"] - sw["NH3"] # Sulfide sw["HS"] = sw["H2SAlk"] = (totals["TH2S"] * k_constants["KH2S"] / (k_constants["KH2S"] + h_scale)) sw["H2S"] = totals["TH2S"] - sw["HS"] # KSO4 and KF are always on the Free scale, so: # Sulfate sw["HSO4"] = totals["TSO4"] / (1 + k_constants["KSO4"] / sw["Hfree"]) sw["SO4"] = totals["TSO4"] - sw["HSO4"] # Fluoride sw["HF"] = totals["TF"] / (1 + k_constants["KF"] / sw["Hfree"]) sw["F"] = totals["TF"] - sw["HF"] # Extra alkalinity components (added in v1.6.0) sw["alpha"] = (totals["alpha"] * k_constants["alpha"] / (k_constants["alpha"] + h_scale)) sw["alphaH"] = totals["alpha"] - sw["alpha"] sw["beta"] = totals["beta"] * k_constants["beta"] / (k_constants["beta"] + h_scale) sw["betaH"] = totals["beta"] - sw["beta"] zlp = 4.5 # pK of 'zero level of protons' [WZK07] sw["alk_alpha"] = np.where(-np.log10(k_constants["alpha"]) <= zlp, -sw["alphaH"], sw["alpha"]) sw["alk_beta"] = np.where(-np.log10(k_constants["beta"]) <= zlp, -sw["betaH"], sw["beta"]) # Total alkalinity sw["alk_total"] = (sw["HCO3"] + 2 * sw["CO3"] + sw["BAlk"] + sw["OH"] + sw["PAlk"] + sw["SiAlk"] + sw["NH3Alk"] + sw["H2SAlk"] - sw["Hfree"] - sw["HSO4"] - sw["HF"] + sw["alk_alpha"] + sw["alk_beta"]) return sw
def loss(self, theta, x, y): assert (x.shape[0] == y.shape[0]) pred = self.predicition(theta, x) pred = np.squeeze(pred) y = np.squeeze(y) res = -np.sum(y.dot(np.log10(pred)) + (1 - y).dot(np.log10(1 - pred))) res = res / x.shape[0] res += self.l2_coef / (2 * x.shape[0]) * np.sum(np.square(theta)) res += self.l1_coef / (2 * x.shape[0]) * np.sum(np.abs(theta)) # print(res) return res
def sgn_annotate(ax, df, idx, color, s=r"$\ast$"): row = df.iloc[idx] sgn = row["sgn"] ylims = np.log10(ax.get_ylim()) y_pos = (np.log10(sgn) - ylims[0]) / (ylims[1] - ylims[0]) ax.annotate(s, (1.01, y_pos), color=color, size="x-large", xycoords=ax.transAxes, verticalalignment="center") return
def lead_dioxide_ocp_Bode1977(m): """ Dimensional open-circuit voltage in the positive (lead-dioxide) electrode [V], from [1]_, as a function of the molar mass m [mol.kg-1]. References ---------- .. [1] H Bode. Lead-acid batteries. John Wiley and Sons, Inc., New York, NY, 1977. """ U = (1.628 + 0.074 * np.log10(m) + 0.033 * np.log10(m)**2 + 0.043 * np.log10(m)**3 + 0.022 * np.log10(m)**4) return U
def lead_ocp_Bode1977(m): """ Dimensional open-circuit voltage in the negative (lead) electrode [V], from [1]_, as a function of the molar mass m [mol.kg-1]. References ---------- .. [1] H Bode. Lead-acid batteries. John Wiley and Sons, Inc., New York, NY, 1977. """ U = (-0.294 - 0.074 * np.log10(m) - 0.030 * np.log10(m)**2 - 0.031 * np.log10(m)**3 - 0.012 * np.log10(m)**4) return U
def ess(samples): """ Computing Effective Sample Size Parameters ---------- samples : `numpy.ndarray(n_chains, n_iters)` An array containing samples Returns ------- ess : `real` effective sample size of the given sample """ n_chain, n_draw = samples.shape if (n_chain > 1): ValueError("Number of chains must be 1") acov = autocov(samples, axis=1) #chain_mean = samples.mean(axis=1) mean_var = np.mean(acov[:, 0]) * n_draw / (n_draw - 1.0) var_plus = mean_var * (n_draw - 1.0) / n_draw #if n_chain > 1: # var_plus += _numba_var(svar, np.var, chain_mean, axis=None, ddof=1) rho_hat_t = np.zeros(n_draw) rho_hat_even = 1.0 rho_hat_t[0] = rho_hat_even rho_hat_odd = 1.0 - (mean_var - np.mean(acov[:, 1])) / var_plus rho_hat_t[1] = rho_hat_odd # Geyer's initial positive sequence t = 1 while t < (n_draw - 3) and (rho_hat_even + rho_hat_odd) > 0.0: rho_hat_even = 1.0 - (mean_var - np.mean(acov[:, t + 1])) / var_plus rho_hat_odd = 1.0 - (mean_var - np.mean(acov[:, t + 2])) / var_plus if (rho_hat_even + rho_hat_odd) >= 0: rho_hat_t[t + 1] = rho_hat_even rho_hat_t[t + 2] = rho_hat_odd t += 2 max_t = t - 2 # improve estimation if rho_hat_even > 0: rho_hat_t[max_t + 1] = rho_hat_even # Geyer's initial monotone sequence t = 1 while t <= max_t - 2: if (rho_hat_t[t + 1] + rho_hat_t[t + 2]) > (rho_hat_t[t - 1] + rho_hat_t[t]): rho_hat_t[t + 1] = (rho_hat_t[t - 1] + rho_hat_t[t]) / 2.0 rho_hat_t[t + 2] = rho_hat_t[t + 1] t += 2 ess = n_chain * n_draw tau_hat = -1.0 + 2.0 * np.sum(rho_hat_t[: max_t + 1]) + np.sum(rho_hat_t[max_t + 1 : max_t + 2]) tau_hat = max(tau_hat, 1 / np.log10(ess)) ess = ess / tau_hat if np.isnan(rho_hat_t).any(): ess = np.nan return ess
def _overridekwargs(co2dict, co2kwargs_plus, kwarg, wrt, dx, dx_scaling, dx_func): """Generate `co2kwargs_plus` and scale `dx` for internal override derivatives.""" # Reformat variable names for the kwargs dicts ispK = wrt.startswith("pK") if ispK: wrt = wrt[1:] if kwarg == "equilibria_in": wrt_stem = wrt.replace("input", "") elif kwarg == "equilibria_out": wrt_stem = wrt.replace("output", "") else: wrt_stem = wrt # If there isn't yet a dict, create one if co2kwargs_plus[kwarg] is None: co2kwargs_plus[kwarg] = {wrt_stem: co2dict[wrt]} # If there is a dict, add the field if it's not already there if wrt not in co2kwargs_plus[kwarg]: co2kwargs_plus[kwarg].update({wrt_stem: co2dict[wrt]}) # Scale dx and add it to the `co2kwargs_plus` dict if ispK: pKvalues = -np.log10(co2kwargs_plus[kwarg][wrt_stem]) dx_wrt = _get_dx_wrt(dx, pKvalues, dx_scaling, dx_func=dx_func) pKvalues_plus = pKvalues + dx_wrt co2kwargs_plus[kwarg][wrt_stem] = 10.0**-pKvalues_plus else: Kvalues = co2kwargs_plus[kwarg][wrt_stem] dx_wrt = _get_dx_wrt(dx, Kvalues, dx_scaling, dx_func=dx_func) co2kwargs_plus[kwarg][wrt_stem] = Kvalues + dx_wrt return co2kwargs_plus, dx_wrt
def callback(weights, iteration, g): it = iteration + 1 if it % self.checkpoint == 0 or it in {1, self.num_iters}: obj = objective(weights, iteration) padding = int(np.log10(self.num_iters) + 1) print( f"[Iteration {it:{padding}d}] Sum of squared errors: {obj:.6f}" )
def default_file_name(self): fn = self.model.default_model_name() fn += "_M%03d" % list(self.reg.fs.values())[-1].M fn += "_ns%03d" % self.nsleep fn += "_nw%03d" % self.nwake fn += "_s%s" % self.s_type fn += "_g%s" % self.g_type fn += "_lr%d" % (int(np.log10(self.opt.lr))) if self.niter is not None: fn += "_ni%d" % (int(np.log10(self.niter))) if self.seed is not None: fn += "_%02d" % self.seed return fn
def kH2CO3_NBS_MCHP73(TempK, Sal): """Carbonic acid dissociation constants following MCHP73.""" # === CO2SYS.m comments: ======= # GEOSECS and Peng et al use K1, K2 from Mehrbach et al, # Limnology and Oceanography, 18(6):897-907, 1973. # I.e., these are the original Mehrbach dissociation constants. # The 2s precision in pK1 is .005, or 1.2% in K1. # The 2s precision in pK2 is .008, or 2% in K2. pK1 = (-13.7201 + 0.031334 * TempK + 3235.76 / TempK + 1.3e-5 * Sal * TempK - 0.1032 * Sal**0.5) K1 = 10.0**-pK1 # this is on the NBS scale pK2 = (5371.9645 + 1.671221 * TempK + 0.22913 * Sal + 18.3802 * np.log10(Sal) - 128375.28 / TempK - 2194.3055 * np.log10(TempK) - 8.0944e-4 * Sal * TempK - 5617.11 * np.log10(Sal) / TempK + 2.136 * Sal / TempK ) # pK2 is not defined for Sal=0, since log10(0)=-inf K2 = 10.0**-pK2 # this is on the NBS scale return K1, K2
def k_calcite_P0_I75(TempK, Sal): """Calcite solubility constant following ICHP73/I75 with no pressure correction. For use with GEOSECS constants. """ return 0.0000001 * ( -34.452 - 39.866 * Sal ** (1 / 3) + 110.21 * np.log10(Sal) - 0.0000075752 * TempK ** 2 )
def fromCO3(CBAlk, CARB, TB, K1, K2, KB): """Find initial value for TA-pH solver with carbonate ion as the second variable. Inspired by M13, section 3.2.2. """ H0 = np.where( CBAlk > 2 * CARB + TB, _goodH0_CO3(CBAlk, CARB, TB, K1, K2, KB), 1e-10, # default pH=10 for low alkalinity ) return -np.log10(H0)
def loss(self, theta, x, y): assert (x.shape[0] == y.shape[0]) pred = self.predicition(theta, x) assert (pred.shape == (x.shape[0], self.num_classes)) res = 0 y = y.squeeze() for i in range(x.shape[0]): res -= np.log10(pred[i][int(y[i])]) res = res / x.shape[0] # print(res) return res
def fromHCO3(CBAlk, HCO3, TB, K1, K2, KB): """Find initial value for TA-pH solver with bicarbonate ion as the second variable. Inspired by M13, section 3.2.2. """ H0 = np.where( CBAlk > HCO3, _goodH0_HCO3(CBAlk, HCO3, TB, K1, K2, KB), 1e-3, # default pH=3 for low alkalinity ) return -np.log10(H0)
def fromCO2(CBAlk, CO2, TB, K1, K2, KB): """Find initial value for TA-pH solver with fCO2 as the second variable. Inspired by M13, section 3.2.2. """ H0 = np.where( CBAlk > 0, _goodH0_CO2(CBAlk, CO2, TB, K1, K2, KB), 1e-3, # default pH=3 for negative alkalinity ) return -np.log10(H0)
def visit_Function(self, node): f = node.value if f == EXP: return np.exp(self.visit(node.expr)) if (f == LOG) or (f == LN): return np.log(self.visit(node.expr)) if f == LOG10: return np.log10(self.visit(node.expr)) if f == SQRT: return np.sqrt(self.visit(node.expr)) if f == ABS: return np.abs(self.visit(node.expr)) if f == SIGN: return np.sign(self.visit(node.expr)) if f == SIN: return np.sin(self.visit(node.expr)) if f == COS: return np.cos(self.visit(node.expr)) if f == TAN: return np.tan(self.visit(node.expr)) if f == ASIN: return np.arcsin(self.visit(node.expr)) if f == ACOS: return np.arccos(self.visit(node.expr)) if f == ATAN: return np.arctan(self.visit(node.expr)) if f == MAX: raise NotImplementedError(MAX) if f == MIN: raise NotImplementedError(MIN) if f == NORMCDF: raise NotImplementedError(NORMCDF) if f == NORMPDF: raise NotImplementedError(NORMPDF) if f == ERF: return erf(self.visit(node.expr))
def k_calcite_M83(TempK, Sal, Pbar, RGas): """Calcite solubility following M83.""" logKCa = -171.9065 - 0.077993 * TempK + 2839.319 / TempK logKCa = logKCa + 71.595 * np.log10(TempK) logKCa = logKCa + (-0.77712 + 0.0028426 * TempK + 178.34 / TempK) * np.sqrt(Sal) logKCa = logKCa - 0.07711 * Sal + 0.0041249 * np.sqrt(Sal) * Sal # sd fit = .01 (for Sal part, not part independent of Sal) KCa = 10.0 ** logKCa # this is in (mol/kg-SW)^2 at zero pressure # Add pressure correction for calcite [I75, M79] TempC = convert.TempK2C(TempK) deltaVKCa, KappaKCa = _deltaKappaCalcite_I75(TempC) lnKCafac = (-deltaVKCa + 0.5 * KappaKCa * Pbar) * Pbar / (RGas * TempK) KCa = KCa * np.exp(lnKCafac) return KCa
def pHfromfCO2Carb(fCO2, CARB, totals, k_constants): """Calculate pH from CO2 fugacity and carbonate ion. This calculates pH from Carbonate and fCO2 using K0, K1, and K2 by solving the equation in H: fCO2 * K0 * K1* K2 = Carb * H * H Based on CalculatepHfromfCO2Carb, version 01.00, 06-12-2019, by Denis Pierrot. """ K0 = k_constants["K0"] K1 = k_constants["K1"] K2 = k_constants["K2"] H = np.sqrt(K0 * K1 * K2 * fCO2 / CARB) return -np.log10(H)
def fromTC(CBAlk, TC, TB, K1, K2, KB): """Find initial value for TA-pH solver with TC as the second variable. Follows M13 section 3.2.2 and its implementation in mocsy (OE15). """ # Logical conditions and defaults from mocsy phsolvers.f90 H0 = np.where( CBAlk <= 0, 1e-3, # default pH=3 for negative alkalinity 1e-10, # default pH=10 for very high alkalinity relative to DIC ) # Use better estimate if alkalinity in suitable range H0 = np.where((CBAlk > 0) & (CBAlk < 2 * TC + TB), _goodH0_TC(CBAlk, TC, TB, K1, K2, KB), H0) return -np.log10(H0)
def _threshold(morph): """Find the threshold value for a given morphology """ _morph = morph[morph > 0] _bins = 50 # Decrease the bin size for sources with a small number of pixels if _morph.size < 500: _bins = max(np.int(_morph.size / 10), 1) if _bins == 1: return 0, _bins hist, bins = np.histogram(np.log10(_morph).reshape(-1), _bins) cutoff = np.where(hist == 0)[0] # If all of the pixels are used there is no need to threshold if len(cutoff) == 0: return 0, _bins return 10**bins[cutoff[-1]], _bins
def flow_in_tube_Gnielinski(Re, Prf, Prw=-1, dl=0.): """ turbulent flow in circular tube, by Gnielinski 2300 < Re < 1e6, 0.6 < Pr < 1e5 dl: d/l return Nu """ f = (1.82 * np.log10(Re) - 1.64)**(-2) if Prw <= 0: ct = 1. else: ct = (Prf / Prw)**0.11 t1 = f / 8 Nu = t1 * (Re - 1000.) * Prf * (1 + (dl)**0.6667) * ct / (1 + 12.7 * (t1**0.5) * (Prf**0.6667 - 1)) return Nu
def objective(self, params, _): # print(X.shape) # print(y.shape) """ Compute the multi-class cross-entropy loss """ preds = self.forward_pass(params, self.X_batch) # print(preds.shape) preds = np.exp(preds) predsum = np.sum(preds, axis=1, keepdims=True) preds /= predsum # print(np.sum(preds,axis=1)) res = 0 self.y_batch = self.y_batch.squeeze() for i in range(preds.shape[0]): res -= np.log10(preds[i][int(self.y_batch[i])]) res = res / preds.shape[0] # print(res) return res
def k_aragonite_M83(TempK, Sal, Pbar, RGas): """Aragonite solubility following M83 with pressure correction of I75.""" logKAr = -171.945 - 0.077993 * TempK + 2903.293 / TempK logKAr = logKAr + 71.595 * np.log10(TempK) logKAr = logKAr + (-0.068393 + 0.0017276 * TempK + 88.135 / TempK) * np.sqrt(Sal) logKAr = logKAr - 0.10018 * Sal + 0.0059415 * np.sqrt(Sal) * Sal # sd fit = .009 (for Sal part, not part independent of Sal) KAr = 10.0 ** logKAr # this is in (mol/kg-SW)^2 # Add pressure correction for aragonite [M79]: TempC = convert.TempK2C(TempK) deltaVKCa, KappaKCa = _deltaKappaCalcite_I75(TempC) # Same as Millero, GCA 1995 except for typos (-.5304, -.3692, # and 10^3 for Kappa factor) deltaVKAr = deltaVKCa + 2.8 KappaKAr = KappaKCa lnKArfac = (-deltaVKAr + 0.5 * KappaKAr * Pbar) * Pbar / (RGas * TempK) KAr = KAr * np.exp(lnKArfac) return KAr
def pHfromTCHCO3(TC, HCO3, totals, k_constants): """Calculate pH from dissolved inorganic carbon and carbonate ion. Follows ZW01 Appendix B (12). """ K1 = k_constants["K1"] K2 = k_constants["K2"] a = HCO3 / K1 b = HCO3 - TC c = HCO3 * K2 bsq_4ac = b**2 - 4 * a * c F = (HCO3 >= TC) | (bsq_4ac <= 0) if np.any(F): print( "Some input HCO3 values are impossibly high given the input DIC;") print("returning np.nan.") H = np.where(F, np.nan, (-b - np.sqrt(bsq_4ac)) / (2 * a)) return -np.log10(H)
def pHfromTCCarb(TC, CARB, totals, k_constants): """Calculate pH from dissolved inorganic carbon and carbonate ion. This calculates pH from Carbonate and TC using K1, and K2 by solving the quadratic in H: TC * K1 * K2= Carb * (H * H + K1 * H + K1 * K2). Based on CalculatepHfromTCCarb, version 01.00, 06-12-2019, by Denis Pierrot. """ K1 = k_constants["K1"] K2 = k_constants["K2"] RR = 1 - TC / CARB Discr = K1**2 - 4 * K1 * K2 * RR F = (CARB >= TC) | (Discr <= 0) if np.any(F): print("Some input CO3 values are impossibly high given the input DIC;") print("returning np.nan.") H = np.where(F, np.nan, (-K1 + np.sqrt(Discr)) / 2) return -np.log10(H)
def objective(W, B, X, y, activations): # print(X.shape) # print(y.shape) """ Compute the multi-class cross-entropy loss """ preds = forward_pass(W, B, X, activations) preds = np.array(preds).astype(float) # print(type(preds)) # print(preds.shape) preds = np.exp(preds) predsum = np.sum(preds, axis=1, keepdims=True) preds /= predsum # print(np.sum(preds,axis=1)) res = 0 y = y.squeeze() for i in range(preds.shape[0]): res -= np.log10(preds[i][int(y[i])]) res = res / preds.shape[0] # print(res) return res
def plot_relres_ecdf(point_df, gfp_cutoff=GFP_CUTOFF, sgn_cutoff=SGN_CUTOFF, log_transform=False, xlabel="", ylabel="", ax=None): if ax is None: _, ax = plt.subplots(figsize=(12, 6)) relres, sgns = point_df["relres"], point_df["sgn"] if log_transform: relres = np.log10(relres) relres = relres.sort_values() other_relres = relres[relres < gfp_cutoff] gfp_relres = relres[relres >= gfp_cutoff] gfp_fraction = len(gfp_relres) / len(relres) ax.step(other_relres, np.linspace(0, 1 - gfp_fraction, len(other_relres)), lw=2, color=COLORS["other"]) ax.hlines(1 - gfp_fraction, other_relres.iloc[-1], gfp_relres.iloc[0], lw=2, color=COLORS["other"]) ax.step(gfp_relres, np.linspace(1 - gfp_fraction, 1, len(gfp_relres)), lw=2, color=COLORS["gfp"]) ax.vlines(relres[sgns < sgn_cutoff], 0, 0.15, lw=3, color=COLORS["cp"]) ax.set_ylabel(ylabel, size=fmt.LABELSIZE) ax.set_xlabel(xlabel) ax.set_ylim([0, 1]) ax.set_xlim([0, 1]) return ax
def test_log10(): fun = lambda x : 3.0 * np.log10(x) d_fun = grad(fun) check_grads(fun, abs(npr.randn())) check_grads(d_fun, abs(npr.randn()))
def nanomaggies2mags(self, nanos): return (-2.5)*np.log10(nanos) + 22.5
def test_log10(): fun = lambda x : 3.0 * np.log10(x) check_grads(fun)(abs(npr.randn()))
def ilqr_iterate(self, x0, u_init, n_itrs=50, tol=1e-6, verbose=True): #initialize the regularization term self.reg = 1 #derive the initial guess trajectory from the initial guess of u x_array = self.forward_propagation(x0, u_init) u_array = np.copy(u_init) #initialize current trajectory cost J_opt = self.evaluate_trajectory_cost(x_array, u_init) J_hist = [J_opt] #iterates... converged = False for i in range(n_itrs): k_array, K_array = self.back_propagation(x_array, u_array) norm_k = np.mean(np.linalg.norm(k_array, axis=1)) #apply the control to update the trajectory by trying different alpha accept = False for alpha in self.alpha_array: x_array_new, u_array_new = self.apply_control(x_array, u_array, k_array, K_array, alpha) #evaluate the cost of this trial J_new = self.evaluate_trajectory_cost(x_array_new, u_array_new) if J_new < J_opt: #see if it is converged if np.abs((J_opt - J_new )/J_opt) < tol: #replacement for the next iteration J_opt = J_new x_array = x_array_new u_array = u_array_new converged = True break else: #replacement for the next iteration J_opt = J_new x_array = x_array_new u_array = u_array_new #successful step, decrease the regularization term #momentum like adaptive regularization self.reg = np.max([self.reg_min, self.reg / self.reg_factor]) accept = True print 'Iteration {0}:\tJ = {1};\tnorm_k = {2};\treg = {3}'.format(i+1, J_opt, norm_k, np.log10(self.reg)) break else: #don't accept this accept = False J_hist.append(J_opt) #exit if converged... if converged: print 'Converged at iteration {0}; J = {1}; reg = {2}'.format(i+1, J_opt, self.reg) break #see if all the trials are rejected if not accept: #need to increase regularization #check if the regularization term is too large if self.reg > self.reg_max: print 'Exceeds regularization limit at iteration {0}; terminate the iterations'.format(i+1) break self.reg = self.reg * self.reg_factor if verbose: print 'Reject the control perturbation. Increase the regularization term.' #prepare result dictionary res_dict = { 'J_hist':np.array(J_hist), 'x_array_opt':np.array(x_array), 'u_array_opt':np.array(u_array), 'k_array_opt':np.array(k_array), 'K_array_opt':np.array(K_array) } return res_dict