<h2>错误的问题陈述</h2>
<p>看来你解决的问题不对。如您所述,它不能像您正在使用的<a href="https://numpy.org/doc/stable/reference/generated/numpy.linalg.solve.html" rel="nofollow noreferrer">method</a>那样工作:</p>
<blockquote>
<p>Computes the “exact” solution, x, of the well-determined, i.e., full
rank, linear matrix equation ax = b.</p>
</blockquote>
<p>如文件中所定义</p>
<p>把你的问题写成<code>Ax = b</code>是很诱人的。但是你需要一个3x3矩阵来测试一个向量<code>b=[0,0,0]T</code>,并找到一个非平凡的解<code>x</code>来声明所有三个向量不是线性独立的。但这意味着矩阵没有满秩</p>
<p>在您的代码中,以下表达式无法实现函数签名:</p>
<pre><code>np.linalg.solve(np.array([v1]), v2)
</code></pre>
<p>并引发以下错误:</p>
<pre><code>LinAlgError: Last 2 dimensions of the array must be square
</code></pre>
<p>根据矩阵形状对<code>numpy.linalg.solve</code>的有效调用是:</p>
<pre><code>np.linalg.solve(np.array([v1, v2, v3]).T, np.zeros(v1.size))
</code></pre>
<p>但在两个方面都失败了:</p>
<pre><code>LinAlgError: Singular matrix
</code></pre>
<p>首先,因为矩阵不是满秩的,因此不可逆。其次,这并不能解决两个向量的问题</p>
<h2>一般解决方案</h2>
<pre><code>import numpy as np
from scipy import linalg
</code></pre>
<p>相反,您希望解决一个关于<a href="https://en.wikipedia.org/wiki/Linear_independence" rel="nofollow noreferrer">linear independence</a>的更一般的问题,这个问题可以通过<strong>评估^{cd5>}的<a href="https://en.wikipedia.org/wiki/Rank_(linear_algebra)" rel="nofollow noreferrer">rank</a></strong>来解决:</p>
<blockquote>
<p>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.</p>
</blockquote>
<p>使用numpy,您可以使用<a href="https://numpy.org/doc/stable/reference/generated/numpy.linalg.matrix_rank.html" rel="nofollow noreferrer">numpy.linalg.matrix_rank</a>执行此操作:</p>
<pre><code>np.linalg.matrix_rank(np.array([v1, v2]).T) # Missing dimension: 1
np.linalg.matrix_rank(np.array([v1, v3]).T) # Full rank: 2
</code></pre>
<p>此方法计算执行<a href="https://en.wikipedia.org/wiki/Singular_value_decomposition" rel="nofollow noreferrer">SVD decomposition</a>计算的空奇异值,该算法的实现由<a href="https://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.svd.html" rel="nofollow noreferrer">scipy.linalg.svd</a>提供:</p>
<pre><code>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]
</code></pre>
<p>或者<strong>执行<a href="https://en.wikipedia.org/wiki/Gaussian_elimination" rel="nofollow noreferrer">Gauss Elimination</a></strong>(比如使用<a href="https://en.wikipedia.org/wiki/LU_decomposition" rel="nofollow noreferrer">LU decomposition</a>)并检查结果。包scipy提供了<a href="https://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.lu.html" rel="nofollow noreferrer">scipy.linalg.lu</a>:</p>
<pre><code>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.]]
</code></pre>
<p>所有这些方法都评估从矩阵列跨越的向量空间的维数。如果矩阵是满秩的,那么向量是线性独立的。如果不是,则至少有两个相关向量</p>
<p>那么解决问题的简单方法是:</p>
<pre><code>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
</code></pre>
<h2>特例</h2>
<p>如果您停留在3D向量空间中,只需要对照两个向量进行检查,您还可以利用<a href="https://numpy.org/doc/stable/reference/generated/numpy.cross.html" rel="nofollow noreferrer">numpy.cross</a>提供的<a href="https://en.wikipedia.org/wiki/Cross_product" rel="nofollow noreferrer">cross product</a>:</p>
<pre><code>np.cross(v1, v2) # Colinear: [0, 0, 0]
np.cross(v1, v3) # Not colinear: [15, 0, -5]
</code></pre>
<p>更具体的备选方案是:</p>
<pre><code>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
</code></pre>
<h2>恒定比率</h2>
<p>正如<code>@MadPhycist</code>所建议的,我们还可以评估共线向量共享标量比例因子(如<code>a = k*b</code>)的事实,然后一种非防弹的测试方法是检查坐标比是否恒定:</p>
<pre><code>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
</code></pre>
<p>如果它比以前的解决方案需要更少的计算量,并且不依赖高水平的线性代数,那么它需要处理特定的情况,并且建议的实现很难闻(不要使用它)</p>
<h2>格拉米安法</h2>
<p>由<code>@dmuir</code>公开的方法可以安全地针对以下两个向量实现:</p>
<pre><code>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
</code></pre>