线性代数Python计算:无关向量组的正交化

将ℝ n ^n n的一个无关组 α 1 , α 2 , ⋯   , α k \boldsymbol{\alpha}_1,\boldsymbol{\alpha}_2,\cdots,\boldsymbol{\alpha}_k α1,α2,,αk正交化为 β 1 , β 2 , ⋯   , β k \boldsymbol{\beta}_1,\boldsymbol{\beta}_2,\cdots,\boldsymbol{\beta}_k β1,β2,,βk的计算公式为:
{ β 1 = α 1 β 2 = − β 1 ∘ α 2 β 1 ∘ β 1 β 1 + α 2 ⋯ ⋯ ⋯ β k = − β 1 ∘ α k β 1 ∘ β 1 β 1 − β 2 ∘ α k β 2 ∘ β 2 β 2 − ⋯ − β k − 1 ∘ α k β k − 1 ∘ β k − 1 β k − 1 + α k . \begin{cases}\boldsymbol{\beta}_1=\boldsymbol{\alpha}_1\\ \boldsymbol{\beta}_2=-\frac{\boldsymbol{\beta}_1\circ\boldsymbol{\alpha}_2}{\boldsymbol{\beta}_1\circ\boldsymbol{\beta}_1}\boldsymbol{\beta}_1+\boldsymbol{\alpha}_2\\ \quad\quad\cdots\cdots\cdots\\ \boldsymbol{\beta}_k=-\frac{\boldsymbol{\beta}_1\circ\boldsymbol{\alpha}_k}{\boldsymbol{\beta}_1\circ\boldsymbol{\beta}_1}\boldsymbol{\beta}_1-\frac{\boldsymbol{\beta}_2\circ\boldsymbol{\alpha}_k}{\boldsymbol{\beta}_2\circ\boldsymbol{\beta}_2}\boldsymbol{\beta}_2-\cdots-\frac{\boldsymbol{\beta}_{k-1}\circ\boldsymbol{\alpha}_k}{\boldsymbol{\beta}_{k-1}\circ\boldsymbol{\beta}_{k-1}}\boldsymbol{\beta}_{k-1}+\boldsymbol{\alpha}_k \end{cases}. β1=α1β2=β1β1β1α2β1+α2βk=β1β1β1αkβ1β2β2β2αkβ2βk1βk1βk1αkβk1+αk.
将上述公式写成下列的Python函数:

import numpy as np                      #导入numpy
def orthogonalize(A):                   #计算存储在A中的向量组正交化
    _,k=A.shape                         #读取向量个数k
    B=A.copy()                          #将A拷贝为B
    for i in range(1,k):                #计算B的第1~k-1列
        for j in range(i):              #计算B[:,i]
            B[:,i]-=(np.dot(B[:,j],A[:,i])/np.dot(B[:,j],B[:,j]))*B[:,j]
    return B                            #正交化结果

程序的第2~8行定义无关向量组正交化函数orthogonalize,无关向量组以列的形式存储于参数A。第3行读取存储在A中的向量个数k。第4行将A的副本拷贝为B,作为正交化向量的初始值。第5~7行的两重for循环完成正交化向量组B的计算,外层for循环扫描B中从第2列(下标为1)开始的每一列(下标为0的第1列存储的是 α 1 \boldsymbol{\alpha}_1 α1,不用处理),内层的for循环对B的当前列(下标为i)按公式
β i = − β 1 ∘ α i β 1 ∘ β 1 β 1 − β 2 ∘ α i β 2 ∘ β 2 β 2 − ⋯ − β i − 1 ∘ α i β i − 1 ∘ β i − 1 β i − 1 + α i \boldsymbol{\beta}_i=-\frac{\boldsymbol{\beta}_1\circ\boldsymbol{\alpha}_i}{\boldsymbol{\beta}_1\circ\boldsymbol{\beta}_1}\boldsymbol{\beta}_1-\frac{\boldsymbol{\beta}_2\circ\boldsymbol{\alpha}_i}{\boldsymbol{\beta}_2\circ\boldsymbol{\beta}_2}\boldsymbol{\beta}_2-\cdots-\frac{\boldsymbol{\beta}_{i-1}\circ\boldsymbol{\alpha}_i}{\boldsymbol{\beta}_{i-1}\circ\boldsymbol{\beta}_{i-1}}\boldsymbol{\beta}_{i-1}+\boldsymbol{\alpha}_i βi=β1β1β1αiβ1β2β2β2αiβ2βi1βi1βi1αiβi1+αi
计算 β i \boldsymbol{\beta}_i βi。注意,Python用复合赋值运算符x-=a表示x=x-a。由于B在第4行拷贝为A的副本,故B[:,i]的初始值就是 α i \boldsymbol{\alpha}_i αi。而B[:,[1:i]]中存储的是在当前的 β i \boldsymbol{\beta}_i βi计算前已经计算完毕的诸 β j \boldsymbol{\beta}_j βj,注意numpy的dot函数完成向量的内积运算。循环完成,B中存储的就是正交化后的向量组。
对正交换后的向量组,可以用下列定义的函数作单位化处理。

import numpy as np                      #导入numpy
def unitization(A):                     #A中存储各列向量
    _,k=A.shape                         #读取向量个数
    for i in range(k):                  #对每一个向量
        A[:,i]/=np.linalg.norm(A[:,i])  #单位化

待单位化的向量以列的形式组织于函数unitization的参数A中。第3行读取向量个数k。第4~5行的for循环对A的每一列A[:,i](i取遍0~k-1),用自身的模(调用np.linalg的norm函数计算)除该列元素,即 α i / ∣ α i ∣ \boldsymbol{\alpha}_i/|\boldsymbol{\alpha}_i| αi/αi。循环结束,A中各列均完成单位化操作。
例1 用Python计算向量组 α 1 = ( 1 0 − 1 1 ) , α 2 = ( 1 − 1 0 1 ) , α 3 = ( − 1 1 1 0 ) ∈ \boldsymbol{\alpha}_1=\begin{pmatrix}1\\0\\-1\\1\end{pmatrix},\boldsymbol{\alpha}_2=\begin{pmatrix}1\\-1\\0\\1\end{pmatrix},\boldsymbol{\alpha}_3=\begin{pmatrix}-1\\1\\1\\0\end{pmatrix}\in α1=1011,α2=1101,α3=1110 4 ^4 4的正交化及单位化。

import numpy as np                              #导入numpy
np.set_printoptions(precision=4, suppress=True) #设置输出精度
A=np.array([[1,1,-1],                           #向量组矩阵
            [0,-1,1],
            [-1,0,1],
            [1,1,0]],dtype='float')
B=orthogonalize(A)                              #正交化
print(B)
unitization(B)                                  #单位化
print(B)

程序的第3~6行设置由向量作为列构成的矩阵A。第7行调用以上定义的正交化函数orthogonalize对存储在A中的列向量正交化,得保存在B中的正交化后的向量组。第8行调用上述定义的单位化函数unitization将存储在B中的两两正交向量组单位化。运行程序,输出

[[ 1.      0.3333 -0.2   ]
 [ 0.     -1.      0.6   ]
 [-1.      0.6667  0.6   ]
 [ 1.      0.3333  0.8   ]]
[[ 0.5774  0.2582 -0.169 ]
 [ 0.     -0.7746  0.5071]
 [-0.5774  0.5164  0.5071]
 [ 0.5774  0.2582  0.6761]]

前四行表示 α 1 , α 2 , α 3 \boldsymbol{\alpha}_1,\boldsymbol{\alpha}_2,\boldsymbol{\alpha}_3 α1,α2,α3正交化后的结果 β 1 = ( 1 0 − 1 1 ) , β 2 = ( 1 3 − 1 2 3 1 3 ) , β 3 = ( − 1 5 3 5 3 5 4 5 ) \boldsymbol{\beta}_1=\begin{pmatrix}1\\0\\-1\\1\end{pmatrix},\boldsymbol{\beta}_2=\begin{pmatrix}\frac{1}{3}\\-1\\\frac{2}{3}\\\frac{1}{3}\end{pmatrix},\boldsymbol{\beta}_3=\begin{pmatrix}-\frac{1}{5}\\\frac{3}{5}\\\frac{3}{5}\\\frac{4}{5}\end{pmatrix} β1=1011,β2=3113231,β3=51535354精确到万分位的近似值。后四行表示对 β 1 , β 2 , β 3 \boldsymbol{\beta}_1,\boldsymbol{\beta}_2,\boldsymbol{\beta}_3 β1,β2,β3单位化后的结果。
写博不易,敬请支持:
如果阅读本文于您有所获,敬请点赞、评论、收藏,谢谢大家的支持!

你可能感兴趣的:(线性代数,线性代数,python,机器学习)