native: restructure dsterqr.go part 1

Remove gotos.
This commit is contained in:
kortschak
2016-03-12 09:49:34 +10:30
parent a58b813a93
commit fc65060520

View File

@@ -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
}