fortran快速排序算法,示例对一维数组进行排序
![](https://i-blog.csdnimg.cn/blog_migrate/4c24ba10cac007c377b859ab713a3466.png)
0. 引言
Gram-Schmidt过程
是一种用于将一组线性无关的向量转换为一组正交或标准正交向量的算法。这个过程通常用于线性代数和数值计算中。
假设我们有一组线性无关的向量
v
1
,
v
2
,
…
,
v
n
{v_1, v_2, \ldots, v_n}
v1,v2,…,vn 。Gram-Schmidt
过程的目标是生成一组正交向量
q
1
,
q
2
,
…
,
q
n
{q_1, q_2, \ldots, q_n}
q1,q2,…,qn,它们仍然在原始向量的线性空间中,但是彼此之间是正交的(或标准正交的,即彼此之间的内积为0,且每个向量的范数为1)。
Gram-Schmidt过程的步骤:
a) 初始化:
将第一个向量作为新的正交向量的第一个成员:
q
1
=
v
1
q_1 = v_1
q1=v1
b 递归构建正交向量:
对于每个
i
=
2
,
3
,
…
,
n
i = 2, 3, \ldots, n
i=2,3,…,n,执行以下步骤:
- 正交化处理:
计算当前向量
v
i
v_i
vi 在前
i
−
1
i-1
i−1 个已经确定的正交向量
[
q
1
,
q
2
,
…
,
q
i
−
1
]
[q_1, q_2, \ldots, q_{i-1}]
[q1,q2,…,qi−1] 上的投影。投影的计算方式为:
proj
q
i
−
1
v
i
=
⟨
v
i
,
q
i
−
1
⟩
⟨
q
i
−
1
,
q
i
−
1
⟩
q
i
−
1
\text{proj}{ q_{i-1} }{v_i} = \frac{\langle v_i, q_{i-1} \rangle}{\langle q_{i-1}, q_{i-1} \rangle} q_{i-1}
projqi−1vi=⟨qi−1,qi−1⟩⟨vi,qi−1⟩qi−1
其中
(
⟨
⋅
,
⋅
⟩
)
(\langle \cdot, \cdot \rangle)
(⟨⋅,⋅⟩) 表示内积(或点积)。
- 更新向量:
将投影向量从 (v_i) 中减去,得到一个新的向量
(
v
i
′
)
(v_i^\prime)
(vi′):
v
i
′
=
v
i
−
proj
q
i
−
1
(
v
i
)
v_i^\prime = v_i - \text{proj}{q_{i-1}}(v_i)
vi′=vi−projqi−1(vi)
- 正则化:
将 v i ′ v_i^\prime vi′ 归一化为单位向量 q i q_i qi:
q
i
=
v
i
′
∣
v
i
′
∣
q_i = \frac{v_i^\prime}{|v_i^\prime|}
qi=∣vi′∣vi′
其中
∣
v
i
′
∣
|v_i^\prime|
∣vi′∣表示向量
v
i
′
v_i^\prime
vi′ 的范数(或长度)。
- 输出结果:
最终得到一组正交向量
q
1
,
q
2
,
…
,
q
n
{q_1, q_2, \ldots, q_n}
q1,q2,…,qn,它们满足以下两个条件:
(1)
q
i
⋅
q
j
=
0
q_i \cdot q_j = 0
qi⋅qj=0 对于所有
i
≠
j
i \neq j
i=j,即彼此正交。
(2)
∣
q
i
∣
=
1
|q_i| = 1
∣qi∣=1 对于所有
i
i
i,即每个向量的范数为1。
这样,Gram-Schmidt
过程能够有效地将一个线性无关的向量集合转换为一组正交或标准正交的向量集合,为许多数学和计算问题提供了便利。
本篇用fortran实现了Gram-Schmidt正交化过程,过程参考了matlab
的相关资料。
1. Fortran实现Gram-Schmidt过程
下面是示例程序,用简单案例测试Gram-Schmidt
方法计算过程。
%%调用主程序
program t
use math
real(8),allocatable :: aa(:,:),oaa(:,:)
allocate(aa(3,3))
aa(1,:) = [8d0,1d0,8d0];
aa(2,:) = [8d0,1d0,4d0]
aa(3,:) = [6d0,0d0,5d0]
oaa = orths(aa)
print *,oaa
end program
执行结果:
![](https://i-blog.csdnimg.cn/blog_migrate/c277ae64c2c6291c54bab4c948eb002a.png)
%% 主调函数,输入向量 输出正交基向量
module math2
implicit none
contains
function orths(A)result(ou)
real(8),allocatable,intent(in) :: A(:,:)
real(8),dimension(3) :: bt,at,at2,bt2
integer :: N, i,ind
real(8),allocatable,dimension(:,:) :: b,ou
N = size(A,1)
allocate( b(N,3) )
do i = 1, N
if(i == 1)then
b(i,:) = A(i,:)
cycle
endif
at(:) = A(i,:)
at2 = at
ind = 0
do
ind = ind + 1
if(ind >= i)then
exit
endif
bt(:) = b(ind,:)
at2 = at2 - ( dot_product(at, bt)/dot_product(bt,bt) )* bt
enddo
b(i,:) = at2(:)
enddo
allocate(ou(N,3))
ou = 0d0
!> 归一化
do i = 1, N
bt2(:) = b(i,:)
ou(i,:) = norm( bt2 )
enddo
contains
! norm
function norm(a)result(b)
real(8),intent(in) :: a(:)
real(8) :: b(3)
real(8) :: no
no = sqrt( a(1)**2 + a(2)**2 + a(3)**2 )
b = a / no
end function
end function
end module
2. 结语
本篇分享了基于fortran
的Gram-Schmidt方法,能够求解输入矩阵的正交基。希望有所帮助
😜
😜😜
😜😜😜😜