예제 #1
0
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
예제 #3
0
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)
예제 #4
0
 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
예제 #5
0
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
예제 #6
0
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]
예제 #7
0
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")
예제 #8
0
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
예제 #9
0
        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
예제 #10
0
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"