def Beta(B, n, margin, x0): """ this function executes a recursion with the aid of a for-loop ON INPUT: *B (float): it is very important that we keep the star. ON OUTPUT: x (list) or x[-1] (float) or conv: {x[-1]} (string) """ c, x = [0.2, 5], [x0] for i in range(n): x_new = c[0] * x[-1] - B * (x[-1]**2 - c[1]) x.append(x_new) if np.abs(x[-1] - x[-2]) < margin: break if p == "x_lastval_sring": return f"""conv: {x[-1]}""" elif p == "x_lastval": return x[-1] elif p == "x": return x
def test_lin(num_pwle= 5): def FuelCell(El_prod): return 0.11 + 1.2 * El_prod + 0.99 * El_prod ** 2 def Electrolysis(Output): return (Output/(-0.0498658434302489*Output**3 + 0.302140545845083*Output**2 + 0.715060196682739*Output + 0.0326651009024266))*0.629761721491849*Output def Sin_test(test_in): return math.cos((test_in*math.pi)) x = list() y = list() pwlm = {} breakpoints = [i/num_pwle for i in range(num_pwle+1)] for i in np.linspace(0,1.6,num_pwle+1): x.append(i) y.append(Electrolysis(i)) ######### hier Funktion einfügen for i in range(len(x)-1): pwlm["Lin_el" + str(i)] = {} pwlm["Lin_el"+ str(i)]["start/endpoint"] = [x[i],x[i+1]] pwlm["Lin_el" + str(i)]["slope"] = (y[i + 1]-y[i])/(x[i + 1]-x[i]) pwlm["Lin_el" + str(i)]["intersect"] = y[i] - x[i]*pwlm["Lin_el" + str(i)]["slope"] fig, ax = plt.subplots() ax.plot(x, y) plt.show() return pwlm
def iter_(f, max_iter, margin=1.e-9): x = [f(0)] for i in range(1, max_iter): x_new = f(i) x.append(x_new) if np.abs(x[-1]) < margin: break return x, min(x), len(x)
def Beta_moderator(B, max_iter=30): """ denna funktion genomför n rekusrion under en for-loop ON INPUT: B (float) """ for i in range(max_iter + 1): x_new = c[0] * x[-1] - B * (x[-1]**2 - c[1]) x.append(x_new) if np.abs(x[-1] - x[-2]) < margin: break return True else: return False
def solve_congruence_set(a: list, b: list, m: list, silent=True): """ 同余方程组求解 .. math:: a_i x ≡ b_i mod m_i 若有解 x0 mod m0 则返回(x0, m0);若无解则返回None """ k = min([len(a), len(b), len(m)]) x = [] new_m = [] for i in range(k): d_i = gcd(a[i], m[i]) if b[i] % d_i != 0: if not silent: print(f"{a}x ≡ {b} mod {m} 无解") return None else: x_i, m_i = solve_congruence(a[i], b[i], m[i]) x.append(x_i) new_m.append(m_i) def solve_2(x_i, x_j, m_i, m_j): """解两个方程的方程组,返回解 x≡x_ij mod m_ij 或 None(无解)""" m_ij, k_i, k_j = euclidean_algorithm(m_i, m_j) k_i = -k_i c_i = m_i // m_ij # c_j=m_j//m_ij if (x_i - x_j) % m_ij != 0: return None else: return (x_i - x_j ) * k_i * c_i + x_i, m_i * m_j // m_ij # 第二项即lcm(m_i,m_j) x0, m0 = x[0], new_m[0] for i in range(1, k): # 可以用functool.reduce(),这里手动实现 tmp = solve_2(x0, x[i], m0, new_m[i]) if tmp: x0, m0 = tmp[0], tmp[1] else: if not silent: print(f"{a}x ≡ {b} mod {m} 无解") return None x0 = x0 % m0 # 取0~m0-1之间的主值 if not silent: print(f"{a}x ≡ {b} mod {m} 解集为 {x0} mod {m0}") return x0, m0
def newton(f, fp, x0, max_iter=400, div_deterrent=10**(10), margin=1.e-9, slope_near_zero=1.e-9, step=10**9, climb_steps=10**(4)): x = [x0] def check_slope(fp, X, Where_): SLOPE = fp(X) if np.abs(SLOPE) < slope_near_zero: for j in range(climb_steps): X += step Yp = fp(X) if Yp > slope_near_zero: x[-1] = X return x if Where_ == "start of code": raise Exception("slope near zero at initial evaluation") elif Where_ == "middle of code": raise Exception("slope near zero at later evaluations") check_slope(fp, x0, Where_="start_of_code") for i in range(max_iter): x_new = x[-1] - f(x[-1]) / fp(x[-1]) x.append(x_new) delta = np.abs(x[-1] - x[-2]) travel_len = np.abs(x[0] - x[-1]) check_slope(fp, x[-1], Where_="middle of code") if travel_len < div_deterrent: if i < max_iter: if delta < margin: return x[-1], f"convergent, {x[-1]} = x[-1] < margin" elif i == max_iter: if delta > margin: return f"divergent, {x[-1]} = x[-1] > margin" elif travel_len >= div_deterrent: raise Exception(f"x-values are travelling too far away {x[-1]}") return x[-1]
def Newton(f, fp, x0, max_iter=400, div_deterrent=10**(10), margin=1.e-9): x = [x0] for i in range(max_iter): x_new = x[-1] - f(x[-1]) / fp(x[-1]) x.append(x_new) delta = np.abs(x[-1] - x[-2]) travel_len = np.abs(x[0] - x[-1]) if travel_len < div_deterrent: if i < max_iter: if delta < margin: return x[-1], "convergent, x[-1] < margin" elif i == max_iter: if delta > margin: return x[-1], "divergent, x[-1] > margin" elif travel_len > div_deterrent: raise Exception("x-values are travelling too far away")
def Beta_bool(B, n, max_iter=30, margin=1.e-9, x0=1): """ denna funktion genomför n rekusrion under en for-loop ON INPUT: B (float) """ c = [0.2, 5] x = [x0] for i in range(n): x_new = c[0] * x[-1] - B * (x[-1]**2 - c[1]) x.append(x_new) delta = np.abs(x[-1] - x[-2]) if i < max_iter: if delta < margin: return True, x elif i == max_iter: if delta > margin: return False, x
def Beta(B): """ denna funktion genomför n rekusrion under en for-loop ON INPUT: B (float) """ for i in range(n): x_new = c[0] * x[-1] - B * (x[-1]**2 - c[1]) x.append(x_new) if np.abs(x[-1] - x[-2]) < margin: break if p == "x_lastval_sring": return f"""conv: {x[-1]}""" elif p == "x_lastval": return x[-1] elif p == "x": return x
def fix_point(f, x0, max_iter, margin=1.e-10, MARGIN=1.e-7, min_iter=30): """ This function takes a function and an initiat guess on the the first x-value and returns a fixed point with the property x = f(x) """ N = max_iter * 2 x = [x0] if c == "index": for i in range(max_iter): x.append((f(x[i - 1]))) delta = np.abs(x[-1] - x[-2]) if delta <= margin and i > min_iter: break return x[-1], delta, f"""delta < {margin}""".format(margin=margin) elif c == "claus_method": for i in range(max_iter): x_new = f(x[-1]) x.append(x_new) DELTA = np.abs(x[-1] - x[-2]) if margin <= DELTA <= MARGIN: for i in range(max_iter, N): x.append((f(x[i - 1]))) D = np.abs(x[-1] - x[-2]) if D < margin and i > min_iter: break return x[-1], """fixed DELTA to delta""", D elif DELTA >= MARGIN: return x[-1], DELTA, "DELTA" else: D = np.abs(x[-1] - x[-2]) return x, D, "D"