Files
sjy01-image-proc/vendor/github.com/nuknal/goNum/MatrixEigenJacobiPass.go
2024-10-24 15:46:01 +08:00

97 lines
3.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// MatrixEigenJacobiPass
/*
------------------------------------------------------
作者 : Black Ghost
日期 : 2018-11-30
版本 : 0.0.0
------------------------------------------------------
求解n阶对称矩阵A的全部特征值及其特征向量雅可比过关法
理论:
参考 李信真, 车刚明, 欧阳洁, 等. 计算方法. 西北工业大学
出版社, 2000, pp 90.
------------------------------------------------------
输入 :
A 系数矩阵
tol 最大容许误差
n 最大迭代步数
输出 :
Bbar 主特征值矩阵n阶对角矩阵
Rbar 主特征值所对应的特征向量n维矩阵第i列即对应于
第i个特征值的特征向量
(err) 解出标志false-未解出或达到步数上限;
true-全部解出
------------------------------------------------------
*/
package goNum
// MatrixEigenJacobiPass 求解n阶对称矩阵A的全部特征值及其特征向量雅可比过关法
func MatrixEigenJacobiPass(A Matrix, tol float64, n int) (Matrix, Matrix, bool) {
/*
求解n阶对称矩阵A的全部特征值及其特征向量雅可比过关法
输入 :
A 系数矩阵
tol 最大容许误差
n 最大迭代步数
输出 :
Bbar 主特征值矩阵n阶对角矩阵
Rbar 主特征值所对应的特征向量n维矩阵第i列即对应于
第i个特征值的特征向量
(err) 解出标志false-未解出或达到步数上限;
true-全部解出
*/
//判断A是否对称矩阵
if !isSymMatrix_MatrixEigenClassicalJacobi(A) {
return ZeroMatrix(A.Rows, A.Columns), ZeroMatrix(A.Rows, A.Columns), false
}
//1.
//Rbar最终为特征向量矩阵
Rbar := IdentityE(A.Rows)
//复制A矩阵为BB为迭代过程中逐渐改变的矩阵最终将成为特征值矩阵
B := ZeroMatrix(A.Rows, A.Columns)
Bbar := ZeroMatrix(A.Rows, A.Columns)
for i := 0; i < len(A.Data); i++ {
B.Data[i] = A.Data[i]
}
//2. 计算非对角元素平方和
v0 := sum2Else_MatrixEigenClassicalJacobi(B)
//3. 设置阀值v1
v1 := v0 / float64(B.Rows)
//迭代步
for i := 0; i < n; i++ {
for i0 := 0; i0 < B.Rows-1; i0++ {
for j := i + 1; j < B.Columns; j++ {
//逐个扫描,判断是否大于阀值
if B.GetFromMatrix(i, j) > v1 {
//Jocobi正交相似变换古典Jocobi法
//计算cos(theta)及sin(theta)
cost, sint := cosSinTheta_MatrixEigenClassicalJacobi(B, i, j)
//R为迭代矩阵
R := IdentityE(A.Rows)
R.SetMatrix(i, i, cost)
R.SetMatrix(i, j, sint)
R.SetMatrix(j, i, -1.0*sint)
R.SetMatrix(j, j, cost)
Bbar = DotPruduct(DotPruduct(R, B), R.Transpose()) //A1 = RARt
//Rbar = Rbar*Rt
Rbar = DotPruduct(Rbar, R.Transpose())
}
}
}
//计算并判断v1是否满足误差需求否则迭代
v0 = sum2Else_MatrixEigenClassicalJacobi(Bbar)
if v0 < tol {
return Bbar, Rbar, true
}
v1 = v0 / float64(B.Rows)
//A = A1
for i := 0; i < len(Bbar.Data); i++ {
B.Data[i] = Bbar.Data[i]
}
}
return ZeroMatrix(A.Rows, A.Columns), ZeroMatrix(A.Rows, A.Columns), false
}