简单线性依赖

2024-06-16 10:16:36 发布

您现在位置:Python中文网/ 问答频道 /正文

试图找出两个向量是线性相关的还是独立的。我经常遇到这样的错误:“数组的最后两个维度必须是正方形?有人能解释一下吗?”

def Indy2Vec(v1, v2):
    
    A = np.array([v1])
    B = np.array([v2])
    print(A)
    #A =np.linalg.matrix_rank(A)
    A=np.linalg.solve(A,B)
    
    return A


v1 = np.array([0, 5, 0])
v2 = np.array([0, -10, 0])
v3 = np.array([1, 2, 3])
v4 = np.array([-2, -4, -6])
Indy2Vec(v1,v2)

Tags: def错误np数组array向量matrixv2
3条回答

错误的问题陈述

看来你解决的问题不对。如您所述,它不能像您正在使用的method那样工作:

Computes the “exact” solution, x, of the well-determined, i.e., full rank, linear matrix equation ax = b.

如文件中所定义

把你的问题写成Ax = b是很诱人的。但是你需要一个3x3矩阵来测试一个向量b=[0,0,0]T,并找到一个非平凡的解x来声明所有三个向量不是线性独立的。但这意味着矩阵没有满秩

在您的代码中,以下表达式无法实现函数签名:

np.linalg.solve(np.array([v1]), v2)

并引发以下错误:

LinAlgError: Last 2 dimensions of the array must be square

根据矩阵形状对numpy.linalg.solve的有效调用是:

np.linalg.solve(np.array([v1, v2, v3]).T, np.zeros(v1.size))

但在两个方面都失败了:

LinAlgError: Singular matrix

首先,因为矩阵不是满秩的,因此不可逆。其次,这并不能解决两个向量的问题

一般解决方案

import numpy as np
from scipy import linalg

相反,您希望解决一个关于linear independence的更一般的问题,这个问题可以通过评估^{cd5>}的rank来解决:

In linear algebra, the rank of a matrix A is the dimension of the vector space generated (or spanned) by its columns. This corresponds to the maximal number of linearly independent columns of A.

使用numpy,您可以使用numpy.linalg.matrix_rank执行此操作:

np.linalg.matrix_rank(np.array([v1, v2]).T) # Missing dimension: 1
np.linalg.matrix_rank(np.array([v1, v3]).T) # Full rank: 2

此方法计算执行SVD decomposition计算的空奇异值,该算法的实现由scipy.linalg.svd提供:

U, s, V = linalg.svd(np.array([v1, v2]).T) # s = [11.18033989, 0.]
U, s, V = linalg.svd(np.array([v1, v3]).T) # s = [5.55992016, 2.84381571]

或者执行Gauss Elimination(比如使用LU decomposition)并检查结果。包scipy提供了scipy.linalg.lu

p, l, u = linalg.lu(np.array([v1, v2]).T) # Null pivot: u = [[5., -10.], [0., 0.]]
p, l, u = linalg.lu(np.array([v1, v3]).T) # Full rank:  u = [[5., 2.], [0., 3.]]

所有这些方法都评估从矩阵列跨越的向量空间的维数。如果矩阵是满秩的,那么向量是线性独立的。如果不是,则至少有两个相关向量

那么解决问题的简单方法是:

def indep1(*args):
    A = np.array(args).T
    return np.linalg.matrix_rank(A) == len(args)

indep1(v1, v2) # False
indep1(v1, v3) # True
indep1(v1, v2, v3) # False
indep1(v1, np.zeros(v1.size)) # False

特例

如果您停留在3D向量空间中,只需要对照两个向量进行检查,您还可以利用numpy.cross提供的cross product

np.cross(v1, v2) # Colinear: [0, 0, 0]
np.cross(v1, v3) # Not colinear: [15,  0, -5]

更具体的备选方案是:

def indep2(a, b):
    return not np.allclose(np.cross(a, b), 0.)

indep2(v1, v2) # False
indep2(v1, v3) # True
# indep2(v1, v2, v3) # TypeError
indep2(v1, np.zeros(v1.size)) # False

恒定比率

正如@MadPhycist所建议的,我们还可以评估共线向量共享标量比例因子(如a = k*b)的事实,然后一种非防弹的测试方法是检查坐标比是否恒定:

def indep3(a, b):
    r = a/b                                 # Ratio of coordinates
    q = np.isfinite(r)                      # Filter bad ratio (zero division)
    return not np.allclose(r[q], r[q][0])   # Assess all ratio are equal

indep3(v1, v2) # False
indep3(v1, v3) # True
# indep3(v3, np.zeros(v1.size)) # IndexError

如果它比以前的解决方案需要更少的计算量,并且不依赖高水平的线性代数,那么它需要处理特定的情况,并且建议的实现很难闻(不要使用它)

格拉米安法

@dmuir公开的方法可以安全地针对以下两个向量实现:

def indep4(a, b):
    return not np.isclose(np.dot(a,b)*np.dot(b,a), np.dot(a,a)*np.dot(b,b))

indep4(v1, v2) # False
indep4(v1, v3) # True
indep4(v3, v4) # False
indep4(v3, np.zeros(v1.size)) # False

两个向量的简单测试为: A和B是线性相关的

(A.B)*(A.B) == (A.A) * (B.B)

在哪里。是点积

当然,在使用浮点运算时,必须小心测试等式

这可以推广到更多的向量。V[1]。。当其Gramian G为单数时,V[n]是线性相关的,其中

G[i,j] = V[i].V[j] (i,j=1..N)

为什么不使用更简单的算法:

def is_linearly_dependent(a, b):
    non_zero = b != 0
    if len(np.unique(a[non_zero]/b[non_zero])) > 1:
        return False
    else:
        zero = np.logical_not(b)
        if np.any(a[zero] != 0):
            return False
    return True

相关问题 更多 >