为了账号安全,请及时绑定邮箱和手机立即绑定

简单线性相关性

简单线性相关性

繁花不似锦 2023-10-06 19:36:31
试图找出两个向量是否线性相关或独立。我不断遇到错误“数组的最后两个维度必须是正方形?有人可以解释一下吗?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 Av1 = 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)
查看完整描述

3 回答

?
米脂

TA贡献1836条经验 获得超3个赞

错误的问题陈述

看来你没有解决正确的问题。正如您所说,它不能像您使用的方法一样工作:

计算已确定的满秩线性矩阵方程 ax = b 的“精确”解 x。

如文档中所定义。

将您的问题写为 是很诱人的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

相反,您想要解决有关线性独立性的更普遍的问题,可以通过评估[v1, v2]T来解决:

在线性代数中,矩阵 A 的秩是由其列生成(或跨越)的向量空间的维数。这对应于 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 分解计算出的空奇异值进行计数,该算法的实现由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]

或者对其执行高斯消元法(假设使用LU 分解)并检查结果。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提供的叉积

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


查看完整回答
反对 回复 2023-10-06
?
忽然笑

TA贡献1806条经验 获得超5个赞

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

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

在哪里 。是点积。

当然,在使用浮点运算时,您必须小心测试相等性。

这可以推广到更多的向量。V[1] .. V[n] 是线性相关的当且仅当它们的 Gramian G 是奇异的,其中

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


查看完整回答
反对 回复 2023-10-06
?
波斯汪

TA贡献1811条经验 获得超4个赞

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


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


查看完整回答
反对 回复 2023-10-06
  • 3 回答
  • 0 关注
  • 70 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信