Используя numpy для решения линейной системы с одним неизвестным? - PullRequest
0 голосов
/ 10 января 2019

Я пытаюсь решить действительно простую проблему программно.

У меня есть одна переменная t, которая должна удовлетворять двум уравнениям одновременно, как указано ниже:

x_v*t = (x_1 - x_2)
y_v*t = (y_1 - y_2)

Моя первая реакция - просто решить ее, разделив правую часть на коэффициент слева, однако этот коэффициент не обязательно будет равен 0.

Таким образом, мы всегда можем использовать алгоритм RREF и представлять систему как:

 a | b
 c | d

, где a = x_v, b = (x_1 - x_2), c = y_v, d = (y_1 - y_2)

После нахождения RREF мы могли бы иметь:

  • Матрица 0 (система разрешима)
  • Первая строка имеет начальную, а вторая - 0 (система совместима)
  • Любая строка имеет начальный 0 и ненулевой конечный номер (система не разрешима)

Несмотря на то, что я мог попытаться кодировать вышеупомянутое сам, я хотел вместо этого использовать библиотеку, где я могу просто настроить систему и спросить API, существует ли решение или нет, поэтому я использовал numpy.

В настоящее время, однако, я даже не могу установить систему, в которой нерасширенная матрица не является квадратной.

Это достижимо?

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Альтернативой является просто выполнить деление. Если обе "стороны" равны нулю, то результатом будет NaN (0/0). Если rhs, т.е. (x_1 - x_2) отличны от нуля, результатом будет inf.

# c1 is np.array([x_1, y_1, z_1, ...])
# c2 is np.array([x_2, y_2, z_2, ...])
c = c1 - c2
# Use this to supress numpy warnings
with np.warnings.catch_warnings():
    np.warnings.filterwarnings('ignore', 'invalid value encountered in true_divide')
    np.warnings.filterwarnings('ignore','divide by zero encountered in true_divide')
    t = c / v
non_nan_t = t[~np.isnan(t)]
if np.isinf(t).any():
    print('unsolvable because rhs is nonzero but v is zero')

elif not np.allclose(non_nan_t, non_nan_t[0]):
    print('no solution because equations disagree')
else:
    print('solution:', non_nan_t[0])
0 голосов
/ 10 января 2019

Это достижимо. Вы можете использовать функцию fsolve библиотеки scipy . Пример

import numpy as np
import scipy.optimize as so

def f(t, x_v, x_1, x_2, y_v, y_1, y_2):
    return np.sum(np.abs([
        x_v*t - (x_1 - x_2),
        y_v*t - (y_1 - y_2),
    ]))

и тогда вы бы сделали

sol_object = so.fsolve(
    func = f,                  # the function that returns the (scalar) 0 you want. 
    x0   = 1,                  # The starting estimate
    args = (1, 2, 3, 1, 2, 3), # Other arguments of f, i.e. x_v, x_1, x_2, y_v, y_1, y_2 
    full_output = True
)
sol        = sol_object[0]
message    = sol_object[-1]

print(sol)
print(message)

Выход

[-1.]
The solution converged.


Как упомянуто в комментарии jdhesa, это можно было бы сделать, используя методы решения с линейными параметрами. Тот, который я использую выше a priori , работает с любым видом преобразования.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...