Функция исключения Гаусса терпит неудачу, когда я пытаюсь получить неявные уравнения множества

ЦЕЛЬ: Я пытаюсь получить неявные уравнения многообразия, которое задается точками и их остовными векторами. Ну, вы знаете, вы должны исключить Гаусса матрицу этих остовных векторов со столбцом переменных (x1,..., xn) за вычетом точки. Кстати, я использую sympy.

Итак, я реализовал красивую функцию исключения Гаусса, которая отлично работает с нормальными матрицами (я имею в виду, только с числами, без крестиков):

def gauss(matrix):
rows,columns = matrix.shape
n = min(rows,columns)
a = matrix[:,:]
for i in range(n-1):
    k = i
    for j in range(i + 1, rows):
        if abs(a[j,i]) > abs(a[k,i]):
            k = j

    if k != i:
        a[i,:], a[k,:] = a[k,:], a[i,:]

    for j in range(i + 1 , rows):
        t = a[j,i]/a[i,i]
        a[j,i:] -= t*a[i,i:]
return a

И затем я попытался использовать эту функцию в моей матрице остовных векторов с такой точкой X:

point = sympy.Matrix([-1,-3,0,5,3])
generators = sympy.Matrix([[0,0,3,3,0],[-1,4,-3,3,-1],[1,4,-4,-5,-1],[0,8,0,5,-2]]).T
m, n = generators.shape
var_list = sympy.Matrix(variables[:m])
vars = var_list-point
M = generators.col_insert(n, vars)
gauss(M)

ПРОБЛЕМА: И в последней строке я получаю это сообщение:

TypeError: cannot add <class 'sympy.matrices.dense.MutableDenseMatrix'> and <class 'sympy.core.numbers.NaN'>

Я думаю, что это что-то с «минусовой точкой», потому что, когда я пробую эту функцию Гаусса на матрице с числами и столбцом переменных, она работает отлично.

Поэтому я не могу найти, что не так, и я не понимаю ошибку. Был бы очень признателен, если бы мне кто-нибудь помог. Заранее спасибо!


person alienflow    schedule 11.03.2018    source источник


Ответы (1)


В вашей матрице generators недостаточно столбцов, ее ранг меньше количества столбцов. gauss(generators) возвращается

Matrix([
[3, -3,   -4,    0],
[0,  6,   -1,    5],
[0,  0, 14/3, 14/3],
[0,  0,    0,    0],
[0,  0,    0,    0]])

с нулевой точкой опоры в последнем столбце. Это не вызовет ошибок в вашей функции gauss, потому что она не работает с 4-м столбцом, поскольку он является последним столбцом.

Но когда в матрицу добавляется еще один столбец, теперь он будет обрабатывать 4-й столбец. Это приведет к делению на 0/0, что приведет к NaN, и к ошибке при последующей попытке добавить NaN к числу. Вот так выглядит матрица непосредственно перед роковым шагом.

Matrix([
[3, -3,   -4,    0,                                     x2],
[0,  6,   -1,    5,                           -x2 + x3 - 5],
[0,  0, 14/3, 14/3,            x1 + 2*x2/3 - 2*x3/3 + 19/3],
[0,  0,    0,    0, x0 - 5*x1/28 - 2*x2/7 + 2*x3/7 - 27/28],
[0,  0,    0,    0,                        x1/4 + x4 - 9/4]])

Кстати, условное выражение

    if abs(a[j,i]) > abs(a[k,i]):
        k = j

сам выдал бы ошибку, если бы a[j, i] или a[k, i] содержали символы (поскольку неизвестно, выполняется неравенство или нет). Этого не происходит, потому что все ваши символы находятся в последнем столбце.

Лучший подход

Поскольку ваше многообразие (аффинное подпространство) имеет размерность 3 и содержит 5 переменных, оно описывается двумя неявными уравнениями. Вы можете получить их коэффициенты из нулевого пространства транспонированной матрицы генератора (при условии, что коэффициенты действительны, иначе нам нужно эрмитовское транспонирование .H). Это связано с тем, что коэффициенты неявных уравнений исходят из основы ортогонального дополнения, что и дает нулевое пространство транспонирования.

import sympy 
point = sympy.Matrix([-1,-3,0,5,3])
generators = sympy.Matrix([[0,0,3,3,0],[-1,4,-3,3,-1],[1,4,-4,-5,-1],[0,8,0,5,-2]]).T
m, n = generators.shape
variables = sympy.symbols('x0:{}'.format(m))
var_list = sympy.Matrix(variables)
vars = var_list-point
coeffs = generators.T.nullspace()
for c in coeffs:
    print((c.T*vars)[0])

Это печатает два уравнения (с = 0 понятым.)

7*x0/2 - 5*x1/8 - x2 + x3 - 27/8
x1/4 + x4 - 9/4
person Community    schedule 11.03.2018