Исполняющая роль домохозяина Отражение вектора для QR-разложения - PullRequest
0 голосов
/ 31 марта 2020

Этот вопрос был задан до меня на здесь .

Однако решение для меня не было удовлетворительным, я все еще застрял на 33% несоответствии, поэтому я чувствовал необходимость повторно откройте эту топи c (а также автор этой темы не добавил соответствующий ответ после решения проблемы для себя).

Код, который я написал, находится здесь:

def householder(vec):
    vec = np.asarray(vec, dtype=float)
    if vec.ndim != 1:
        raise ValueError("vec.ndim = %s, expected 1" % vec.ndim)

    n = len(vec)
    I = np.eye(n)
    e1 = np.zeros_like(vec).astype(float)
    e1[0] = 1.0
    V1 = e1 * np.linalg.norm(vec)
    print("V1:", V1)
    u = vec
    u[0] = -(np.sum(np.square(u[1:]))) / (vec[0] + np.linalg.norm(vec))
    u = u / np.linalg.norm(u)
    H = I - 2 * (np.outer(u, u))
    return V1 , H

Вот тестовый пример, который должен пройти этот код:

v = np.array([1, 2, 3])
v1, h = householder(v)

assert_allclose(np.dot(h, v1), v)
assert_allclose(np.dot(h, v), v1)

Первое утверждение успешно пройдено, однако второе дает мне несоответствие на 33%:

AssertionError: 
Not equal to tolerance rtol=1e-07, atol=0

Mismatch: 33.3%
Max absolute difference: 4.4408921e-16
Max relative difference: 1.18687834e-16
 x: array([3.741657e+00, 2.220446e-16, 0.000000e+00])
 y: array([3.741657, 0.      , 0.      ])

Я пробовал все около 5 часов, и мне кажется, что я трачу на это слишком много времени. Я очень ценю любую помощь в прохождении этого кода тестом.

1 Ответ

1 голос
/ 31 марта 2020

Ну, это выглядит правильно для меня.

Проблема заключается в параметрах функции assert_allclose. В частности, он сообщает, действительно ли

absolute(a - b) <= (atol + rtol * absolute(b))

для каждой пары записей a и b. Согласно документам абсолютный допуск составляет 1e-8 для обычной allclose функции. Однако параметр assert_allclose для atol равен 0 при по умолчанию .

Поскольку ваша цель b равна нулю, любое значение! = 0 не является близким по отношению к этой функции, даже если эти два значения безусловно разумно закрыты.

Я рекомендую установить atol на 1e-8, то есть

assert_allclose(np.dot(h, v), v1, atol=1e-8)

Я не совсем уверен, почему люди numpy выбрали разные параметры для обычных allclose и assert_allclose, хотя ...

...