天天看點

Julia實作克萊姆法則求解線性方程組

      在實際應用中,有時候我們需要求解一組方程。一般來說,基于線性方程組的解空間理論,線性方程組有唯一解當且僅當有效方程數等于未知數的個數。這時,可以運用多種方法來求出唯一的解。而克萊姆法則(Cramer's Rule)就是一種求解線性方程組的方法。

1 克萊姆法則

      針對一個方程組,首先把它的系數改寫成一個行列式,并判斷它的值是否為0,如果為0,則不适用于此規則,否則則說明這個線性方程線有解,可以使用克萊姆法則法則。下面給出一個三元方程組的示例,用于描述克萊姆法則的解題過程:

Julia實作克萊姆法則求解線性方程組

此圖來自網站: http://www.saddlebackmath.com/home/cramer-s-rule

以上述方程組為例,首先需要将方程組按照變量進行對齊,即x的放于前,y放中間,z放後。然後将變量的系數改寫成一個矩陣A,同時将方程組的值寫成一個矩陣B。首先,求出系數的行列式值,用D= det(A)進行求解。其次求x的值時,D1行列式由系數矩陣A的第一列替換為矩陣B的第一列,然後求行列式值,即Dx= det(M1),即x = Dx / D即可。同理,求y的值,首先需要将系數矩陣A的第二列替換為矩陣B的第一列,然後求行列式值Dy。

2 克萊姆法則Julia實作

      根據百度百科,Julia語言是一個面向科學計算的高性能動态進階程式設計語言,其文法與其他科學計算語言相似。在許多情況下擁有能與編譯型語言相媲美的性能。Julia 是個靈活的動态語言,适合科學和數值計算。關于線程代數的知識,可以參考官網: https://docs.julialang.org/en/v1/stdlib/LinearAlgebra

     Julia語言在矩陣的操作上,非常友善,下面給出上述示例的具體代碼實作:

julia> using LinearAlgebra

julia> A = [1 -1 2 ; 1 2 3 ; 2 1 1]
3×3 Array{Int64,2}:
 1  -1  2
 1   2  3
 2   1  1

julia> D = det(A)
-12.0

julia> B = [ -3 ; 4 ; -3 ]
3-element Array{Int64,1}:
 -3
  4
 -3

julia> Mx = deepcopy(A)
3×3 Array{Int64,2}:
 1  -1  2
 1   2  3
 2   1  1

julia> Mx[:,1] = B
3-element Array{Int64,1}:
 -3
  4
 -3

julia> Mx
3×3 Array{Int64,2}:
 -3  -1  2
  4   2  3
 -3   1  1

julia> Dx = det(Mx)
36.0

julia> x = Dx / D
-3.0

julia> My = deepcopy(A)
3×3 Array{Int64,2}:
 1  -1  2
 1   2  3
 2   1  1

julia> My[:,2] = B
3-element Array{Int64,1}:
 -3
  4
 -3

julia> My
3×3 Array{Int64,2}:
 1  -3  2
 1   4  3
 2  -3  1

julia> y = det(My) / D
2.0

julia> Mz = deepcopy(A)
3×3 Array{Int64,2}:
 1  -1  2
 1   2  3
 2   1  1

julia> Mz[:,3] = B
3-element Array{Int64,1}:
 -3
  4
 -3

julia> Mz
3×3 Array{Int64,2}:
 1  -1  -3
 1   2   4
 2   1  -3

julia> z = det(Mz) / D
1.0

julia>        

 由此可見,求出的方程解與示例一緻。其實,利用Julia語言,我們可以直接進行方程組求解,示例如下:

julia> using LinearAlgebra

julia> A = [1 -1 2 ; 1 2 3 ; 2 1 1]
3×3 Array{Int64,2}:
 1  -1  2
 1   2  3
 2   1  1

julia> B = [ -3 ; 4 ; -3 ]
3-element Array{Int64,1}:
 -3
  4
 -3

julia> A \ B
3-element Array{Float64,1}:
 -3.0
  2.0
  1.0

julia>         

最後,需要說的就是,還有很多其他的矩陣操作,比如轉置,求逆矩陣,矩陣乘法等等。示例如下:

julia> using LinearAlgebra

julia> A = [1 -1 2 ; 1 2 3 ; 2 1 1]
3×3 Array{Int64,2}:
 1  -1  2
 1   2  3
 2   1  1

julia> A'
3×3 Adjoint{Int64,Array{Int64,2}}:
  1  1  2
 -1  2  1
  2  3  1

julia> inv(A)
3×3 Array{Float64,2}:
  0.0833333  -0.25   0.583333
 -0.416667    0.25   0.0833333
  0.25        0.25  -0.25

julia> inv(A) * A
3×3 Array{Float64,2}:
 1.0  1.11022e-16  0.0
 0.0  1.0          5.55112e-17
 0.0  0.0          1.0

julia> A' * A
3×3 Array{Int64,2}:
 6  3   7
 3  6   5
 7  5  14

#不是 A + 1
julia> A .+ 1
3×3 Array{Int64,2}:
 2  0  3
 2  3  4
 3  2  2

julia> dot(A,A)
26

julia> ones(3,2)
3×2 Array{Float64,2}:
 1.0  1.0
 1.0  1.0
 1.0  1.0

julia> zeros(3,2)
3×2 Array{Float64,2}:
 0.0  0.0
 0.0  0.0
 0.0  0.0

julia> x = rand(5)
5-element Array{Float64,1}:
 0.09025788794245759
 0.6031193596136584
 0.6252782877091618
 0.43105107636432316
 0.3206800449549978

julia> [2*x[i-1] + 0.5*x[i] + 0.25*x[i+1] for i=2:length(x)-1]
3-element Array{Float64,1}:
 0.6383950276190349
 1.6266406321729785
 1.5462521248392345

julia>         

繼續閱讀