+++ /dev/null
-// Copyright ©2015 The Gonum Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gonum
-
-import (
- "math"
-
- "gonum.org/v1/gonum/blas/blas64"
-)
-
-// Dlacn2 estimates the 1-norm of an n×n matrix A using sequential updates with
-// matrix-vector products provided externally.
-//
-// Dlacn2 is called sequentially and it returns the value of est and kase to be
-// used on the next call.
-// On the initial call, kase must be 0.
-// In between calls, x must be overwritten by
-// A * X if kase was returned as 1,
-// A^T * X if kase was returned as 2,
-// and all other parameters must not be changed.
-// On the final return, kase is returned as 0, v contains A*W where W is a
-// vector, and est = norm(V)/norm(W) is a lower bound for 1-norm of A.
-//
-// v, x, and isgn must all have length n and n must be at least 1, otherwise
-// Dlacn2 will panic. isave is used for temporary storage.
-//
-// Dlacn2 is an internal routine. It is exported for testing purposes.
-func (impl Implementation) Dlacn2(n int, v, x []float64, isgn []int, est float64, kase int, isave *[3]int) (float64, int) {
- if n < 1 {
- panic("lapack: non-positive n")
- }
- checkVector(n, x, 1)
- checkVector(n, v, 1)
- if len(isgn) < n {
- panic("lapack: insufficient isgn length")
- }
- if isave[0] < 0 || isave[0] > 5 {
- panic("lapack: bad isave value")
- }
- if isave[0] == 0 && kase != 0 {
- panic("lapack: bad isave value")
- }
- itmax := 5
- bi := blas64.Implementation()
- if kase == 0 {
- for i := 0; i < n; i++ {
- x[i] = 1 / float64(n)
- }
- kase = 1
- isave[0] = 1
- return est, kase
- }
- switch isave[0] {
- default:
- panic("unreachable")
- case 1:
- if n == 1 {
- v[0] = x[0]
- est = math.Abs(v[0])
- kase = 0
- return est, kase
- }
- est = bi.Dasum(n, x, 1)
- for i := 0; i < n; i++ {
- x[i] = math.Copysign(1, x[i])
- isgn[i] = int(x[i])
- }
- kase = 2
- isave[0] = 2
- return est, kase
- case 2:
- isave[1] = bi.Idamax(n, x, 1)
- isave[2] = 2
- for i := 0; i < n; i++ {
- x[i] = 0
- }
- x[isave[1]] = 1
- kase = 1
- isave[0] = 3
- return est, kase
- case 3:
- bi.Dcopy(n, x, 1, v, 1)
- estold := est
- est = bi.Dasum(n, v, 1)
- sameSigns := true
- for i := 0; i < n; i++ {
- if int(math.Copysign(1, x[i])) != isgn[i] {
- sameSigns = false
- break
- }
- }
- if !sameSigns && est > estold {
- for i := 0; i < n; i++ {
- x[i] = math.Copysign(1, x[i])
- isgn[i] = int(x[i])
- }
- kase = 2
- isave[0] = 4
- return est, kase
- }
- case 4:
- jlast := isave[1]
- isave[1] = bi.Idamax(n, x, 1)
- if x[jlast] != math.Abs(x[isave[1]]) && isave[2] < itmax {
- isave[2] += 1
- for i := 0; i < n; i++ {
- x[i] = 0
- }
- x[isave[1]] = 1
- kase = 1
- isave[0] = 3
- return est, kase
- }
- case 5:
- tmp := 2 * (bi.Dasum(n, x, 1)) / float64(3*n)
- if tmp > est {
- bi.Dcopy(n, x, 1, v, 1)
- est = tmp
- }
- kase = 0
- return est, kase
- }
- // Iteration complete. Final stage
- altsgn := 1.0
- for i := 0; i < n; i++ {
- x[i] = altsgn * (1 + float64(i)/float64(n-1))
- altsgn *= -1
- }
- kase = 1
- isave[0] = 5
- return est, kase
-}