Ejemplo n.º 1
0
def HansenSengupta(func, J, x0, maxiter=10**3, tol=1e-12):
    def HS(X, c):
        L = asinterval(J(X))

        if L.shape == ():
            LAMBDA = 1 / L.mid
            A = LAMBDA * L
            b = -LAMBDA * func(c)

            if 0 in A:
                raise Exception('Диагональный элемент матрицы содержит нуль!')
            else:
                GS = b / A
            return c + GS

        else:
            LAMBDA = np.linalg.inv(L.mid)
            A = LAMBDA @ L
            b = -LAMBDA @ func(c)

            GS = Gauss_Seidel(A, b, X - c, tol=tol)
            return c + GS

    if not (0 in func(x0)):
        raise Exception('Брус не содержит решений!')

    result = x0
    pre_result = result.copy
    c = result.mid

    error = float('inf')
    nit = 0
    while nit < maxiter and error > tol:
        result = intersection(result, HS(result, c))
        if Interval(float('-inf'), float('-inf'), sortQ=False) in result:
            return result
        c = result.mid
        error = dist(result, pre_result)
        pre_result = result.copy
        nit += 1
    return result
Ejemplo n.º 2
0
def Krawczyk(func, J, x0, maxiter=10**3, tol=1e-12):
    def K(X, c):
        L = asinterval(J(X))

        if L.shape == ():
            LAMBDA = 1 / L.mid

            B = 1 - LAMBDA * L
            return c - LAMBDA * asinterval(func(c)) + B * (X - c)

        else:
            n, m = L.shape
            LAMBDA = np.linalg.inv(L.mid)

            B = np.eye(n) - LAMBDA @ L
            w, _ = np.linalg.eigh(abs(B))
            return c - LAMBDA @ func(c) + B @ (X - c)

    if not (0 in func(x0)):
        raise Exception('Брус не содержит решений!')

    result = x0
    pre_result = result.copy
    c = result.mid

    error = float('inf')
    nit = 0
    while nit < maxiter and error > tol:
        result = intersection(result, K(result, c))
        if Interval(float('-inf'), float('-inf'), sortQ=False) in result:
            return result
        c = result.mid
        error = dist(result, pre_result)
        pre_result = result.copy
        nit += 1

    return result
Ejemplo n.º 3
0
def Gauss_Seidel(A, b, x0=None, P=True, tol=1e-8, maxiter=10**3):
    """
    Итерационный метод Гаусса-Зейделя для решения ИСЛАУ.

    Parameters:
                A: Interval
                    Матрица ИСЛАУ.

                b: Interval
                    Вектор правой части ИСЛАУ.

    Optional Parameters:
                x0: Interval
                    Начальный брус, в котором ищется решение.

                P: Interval
                    Матрица предобуславливания.
                    В случае, если параметр не задан, то берётся обратное среднее.

                tol: float
                    Погрешность для остановки итерационного процесса.

                maxiter: int
                    Максимальное количество итераций.

    Returns:
                out: Interval
                    Возвращается интервальный вектор решений.
    """

    A = asinterval(A).copy
    b = asinterval(b).copy

    if A.shape == () or A.shape == (1, 1):
        if 0 in A:
            raise Exception('Диагональный элемент матрицы содержит нуль!')
        return b / A

    if P:
        P = np.linalg.inv(A.mid)
        A = P @ A
        b = P @ b

    n, _ = A.shape
    mignitude = diag(A).mig
    _abs_A = abs(A)
    for k in range(n):
        if mignitude[k] < sum(_abs_A[k]) - _abs_A[k, k]:
            raise Exception('Матрица А не является H матрицей!')

    error = float("inf")
    result = zeros(n)

    if x0 is None:
        pre_result = zeros(n) + Interval(-1000, 1000, sortQ=False)
    else:
        pre_result = x0.copy

    nit = 0
    while error >= tol and nit <= maxiter:
        for k in range(n):
            tmp = 0
            for l in range(n):
                if l != k:
                    tmp += A[k, l] * pre_result[l]
            result[k] = intersection(pre_result[k], (b[k] - tmp) / A[k, k])

            if float('-inf') in result[k]:
                raise Exception("Интервалы не пересекаются!")

        error = dist(result, pre_result)
        pre_result = result.copy
        nit += 1
    return result