当我试图获得各种隐式方程时,高斯消去函数失败
Gauss elimination function fails when I try to get the implicit equations of a variety
目标:我想做的是得到一个变量的隐式方程,它由一个点及其生成向量给出。好吧,你知道的,你必须对这些生成向量的矩阵进行高斯消元,其中有一列变量(x1,...,xn)减去点。顺便说一下,我正在使用 sympy。
所以,我实现了一个漂亮的高斯消去函数,它非常适合普通矩阵(我的意思是,只有数字,没有 X):
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'>
我认为这与 "minus point" 相关,因为当我在包含数字和一列变量的矩阵上尝试这个高斯函数时,它运行得非常好。
所以我找不到问题所在,也不理解错误。如果有人帮助我,将不胜感激。提前致谢!
您的 generators
矩阵是 column-deficient,它的秩小于列数。 gauss(generators)
returns
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 个变量,所以它由两个隐式方程描述。你可以从生成矩阵转置的零空间得到它们的系数(假设系数是实数,否则我们需要 Hermitian 转置 .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
目标:我想做的是得到一个变量的隐式方程,它由一个点及其生成向量给出。好吧,你知道的,你必须对这些生成向量的矩阵进行高斯消元,其中有一列变量(x1,...,xn)减去点。顺便说一下,我正在使用 sympy。
所以,我实现了一个漂亮的高斯消去函数,它非常适合普通矩阵(我的意思是,只有数字,没有 X):
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'>
我认为这与 "minus point" 相关,因为当我在包含数字和一列变量的矩阵上尝试这个高斯函数时,它运行得非常好。
所以我找不到问题所在,也不理解错误。如果有人帮助我,将不胜感激。提前致谢!
您的 generators
矩阵是 column-deficient,它的秩小于列数。 gauss(generators)
returns
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 个变量,所以它由两个隐式方程描述。你可以从生成矩阵转置的零空间得到它们的系数(假设系数是实数,否则我们需要 Hermitian 转置 .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