mirror of
https://github.com/gonum/gonum.git
synced 2025-10-27 17:21:18 +08:00
native: restructure dsterqr.go part 1
Remove gotos.
This commit is contained in:
140
native/dsteqr.go
140
native/dsteqr.go
@@ -88,7 +88,6 @@ func (impl Implementation) Dsteqr(compz lapack.EigComp, n int, d, e, z []float64
|
||||
|
||||
// Determine where the matrix splits and choose QL or QR iteration for each
|
||||
// block, according to whether top or bottom diagonal element is smaller.
|
||||
// TODO(btracey): Reformat the gotos to use structural flow techniques.
|
||||
// TODO(btracey): Move these variables closer to actual usage when
|
||||
// gotos are removed.
|
||||
l1 := 0
|
||||
@@ -104,9 +103,31 @@ func (impl Implementation) Dsteqr(compz lapack.EigComp, n int, d, e, z []float64
|
||||
)
|
||||
var iscale scaletype
|
||||
|
||||
Ten:
|
||||
for {
|
||||
if l1 > n-1 {
|
||||
goto OneSixty
|
||||
// Order eigenvalues and eigenvectors.
|
||||
if icompz == 0 {
|
||||
impl.Dlasrt(lapack.SortIncreasing, n, d)
|
||||
} else {
|
||||
// TODO(btracey): Consider replacing this sort with a call to sort.Sort.
|
||||
for ii := 1; ii < n; ii++ {
|
||||
i := ii - 1
|
||||
k := i
|
||||
p := d[i]
|
||||
for j := ii; j < n; j++ {
|
||||
if d[j] < p {
|
||||
k = j
|
||||
p = d[j]
|
||||
}
|
||||
}
|
||||
if k != i {
|
||||
d[k] = d[i]
|
||||
d[i] = p
|
||||
bi.Dswap(n, z[i:], ldz, z[k:], ldz)
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
if l1 > 0 {
|
||||
e[l1-1] = 0
|
||||
@@ -115,30 +136,28 @@ Ten:
|
||||
for m = l1; m < nm1; m++ {
|
||||
test := math.Abs(e[m])
|
||||
if test == 0 {
|
||||
goto Thirty
|
||||
break
|
||||
}
|
||||
if test <= (math.Sqrt(math.Abs(d[m]))*math.Sqrt(math.Abs(d[m+1])))*eps {
|
||||
e[m] = 0
|
||||
goto Thirty
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
m = n - 1
|
||||
Thirty:
|
||||
l = l1
|
||||
lsv = l
|
||||
lend = m
|
||||
lendsv = lend
|
||||
l1 = m + 1
|
||||
if lend == l {
|
||||
goto Ten
|
||||
continue
|
||||
}
|
||||
|
||||
// Scale submatrix in rows and columns L to Lend
|
||||
anorm = impl.Dlanst(lapack.MaxAbs, lend-l+1, d[l:], e[l:])
|
||||
switch {
|
||||
case anorm == 0:
|
||||
goto Ten
|
||||
continue
|
||||
case anorm > ssfmax:
|
||||
iscale = down
|
||||
// TODO(btracey): Why is lda n?
|
||||
@@ -158,24 +177,29 @@ Thirty:
|
||||
}
|
||||
if lend > l {
|
||||
// QL Iteration. Look for small subdiagonal element.
|
||||
Fourty:
|
||||
for {
|
||||
if l != lend {
|
||||
lendm1 := lend - 1
|
||||
for m = l; m <= lendm1; m++ {
|
||||
for m = l; m < lend; m++ {
|
||||
v := math.Abs(e[m])
|
||||
if v*v <= (eps2*math.Abs(d[m]))*math.Abs(d[m+1])+safmin {
|
||||
goto Sixty
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m = lend
|
||||
Sixty:
|
||||
}
|
||||
if m < lend {
|
||||
e[m] = 0
|
||||
}
|
||||
p = d[l]
|
||||
if m == l {
|
||||
goto Eighty
|
||||
// Eigenvalue found.
|
||||
d[l] = p
|
||||
l++
|
||||
if l > lend {
|
||||
break
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// If remaining matrix is 2×2, use Dlae2 to compute its eigensystem.
|
||||
@@ -189,14 +213,14 @@ Thirty:
|
||||
}
|
||||
e[l] = 0
|
||||
l += 2
|
||||
if l <= lend {
|
||||
goto Fourty
|
||||
if l > lend {
|
||||
break
|
||||
}
|
||||
goto OneFourty
|
||||
continue
|
||||
}
|
||||
|
||||
if jtot == nmaxit {
|
||||
goto OneFourty
|
||||
break
|
||||
}
|
||||
jtot++
|
||||
|
||||
@@ -236,37 +260,33 @@ Thirty:
|
||||
}
|
||||
d[l] -= p
|
||||
e[l] = g
|
||||
goto Fourty
|
||||
|
||||
// Eigenvalue found.
|
||||
Eighty:
|
||||
d[l] = p
|
||||
l++
|
||||
if l <= lend {
|
||||
goto Fourty
|
||||
}
|
||||
goto OneFourty
|
||||
} else {
|
||||
// QR Iteration.
|
||||
// Look for small superdiagonal element.
|
||||
Ninety:
|
||||
for {
|
||||
if l != lend {
|
||||
lendp1 := lend + 1
|
||||
for m = l; m >= lendp1; m-- {
|
||||
for m = l; m > lend; m-- {
|
||||
v := math.Abs(e[m-1])
|
||||
if v*v <= (eps2*math.Abs(d[m])*math.Abs(d[m-1]) + safmin) {
|
||||
goto OneTen
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m = lend
|
||||
OneTen:
|
||||
}
|
||||
if m > lend {
|
||||
e[m-1] = 0
|
||||
}
|
||||
p = d[l]
|
||||
if m == l {
|
||||
goto OneThirty
|
||||
// Eigenvalue found
|
||||
d[l] = p
|
||||
l--
|
||||
if l < lend {
|
||||
break
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// If remaining matrix is 2×2, use Dlae2 to compute its eigenvalues.
|
||||
@@ -280,13 +300,13 @@ Thirty:
|
||||
}
|
||||
e[l-1] = 0
|
||||
l -= 2
|
||||
if l >= lend {
|
||||
goto Ninety
|
||||
if l < lend {
|
||||
break
|
||||
}
|
||||
goto OneFourty
|
||||
continue
|
||||
}
|
||||
if jtot == nmaxit {
|
||||
goto OneFourty
|
||||
break
|
||||
}
|
||||
jtot++
|
||||
|
||||
@@ -328,20 +348,10 @@ Thirty:
|
||||
}
|
||||
d[l] -= p
|
||||
e[l-1] = g
|
||||
goto Ninety
|
||||
|
||||
// Eigenvalue found
|
||||
OneThirty:
|
||||
d[l] = p
|
||||
l--
|
||||
if l >= lend {
|
||||
goto Ninety
|
||||
}
|
||||
goto OneFourty
|
||||
}
|
||||
|
||||
// Undo scaling if necessary.
|
||||
OneFourty:
|
||||
switch iscale {
|
||||
case down:
|
||||
impl.Dlascl(lapack.General, 0, 0, ssfmax, anorm, lendsv-lsv+1, 1, d[lsv:], n)
|
||||
@@ -352,8 +362,9 @@ OneFourty:
|
||||
}
|
||||
|
||||
// Check for no convergence to an eigenvalue after a total of n*maxit iterations.
|
||||
if jtot < nmaxit {
|
||||
goto Ten
|
||||
if jtot >= nmaxit {
|
||||
break
|
||||
}
|
||||
}
|
||||
for i := 0; i < n-1; i++ {
|
||||
if e[i] != 0 {
|
||||
@@ -361,29 +372,4 @@ OneFourty:
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
||||
// Order eigenvalues and eigenvectors.
|
||||
OneSixty:
|
||||
if icompz == 0 {
|
||||
impl.Dlasrt(lapack.SortIncreasing, n, d)
|
||||
} else {
|
||||
// TODO(btracey): Consider replacing this sort with a call to sort.Sort.
|
||||
for ii := 1; ii < n; ii++ {
|
||||
i := ii - 1
|
||||
k := i
|
||||
p := d[i]
|
||||
for j := ii; j < n; j++ {
|
||||
if d[j] < p {
|
||||
k = j
|
||||
p = d[j]
|
||||
}
|
||||
}
|
||||
if k != i {
|
||||
d[k] = d[i]
|
||||
d[i] = p
|
||||
bi.Dswap(n, z[i:], ldz, z[k:], ldz)
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user