1 // Copyright ©2015 The Gonum Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
10 "gonum.org/v1/gonum/blas/blas64"
13 // Dlacn2 estimates the 1-norm of an n×n matrix A using sequential updates with
14 // matrix-vector products provided externally.
16 // Dlacn2 is called sequentially and it returns the value of est and kase to be
17 // used on the next call.
18 // On the initial call, kase must be 0.
19 // In between calls, x must be overwritten by
20 // A * X if kase was returned as 1,
21 // A^T * X if kase was returned as 2,
22 // and all other parameters must not be changed.
23 // On the final return, kase is returned as 0, v contains A*W where W is a
24 // vector, and est = norm(V)/norm(W) is a lower bound for 1-norm of A.
26 // v, x, and isgn must all have length n and n must be at least 1, otherwise
27 // Dlacn2 will panic. isave is used for temporary storage.
29 // Dlacn2 is an internal routine. It is exported for testing purposes.
30 func (impl Implementation) Dlacn2(n int, v, x []float64, isgn []int, est float64, kase int, isave *[3]int) (float64, int) {
32 panic("lapack: non-positive n")
37 panic("lapack: insufficient isgn length")
39 if isave[0] < 0 || isave[0] > 5 {
40 panic("lapack: bad isave value")
42 if isave[0] == 0 && kase != 0 {
43 panic("lapack: bad isave value")
46 bi := blas64.Implementation()
48 for i := 0; i < n; i++ {
65 est = bi.Dasum(n, x, 1)
66 for i := 0; i < n; i++ {
67 x[i] = math.Copysign(1, x[i])
74 isave[1] = bi.Idamax(n, x, 1)
76 for i := 0; i < n; i++ {
84 bi.Dcopy(n, x, 1, v, 1)
86 est = bi.Dasum(n, v, 1)
88 for i := 0; i < n; i++ {
89 if int(math.Copysign(1, x[i])) != isgn[i] {
94 if !sameSigns && est > estold {
95 for i := 0; i < n; i++ {
96 x[i] = math.Copysign(1, x[i])
105 isave[1] = bi.Idamax(n, x, 1)
106 if x[jlast] != math.Abs(x[isave[1]]) && isave[2] < itmax {
108 for i := 0; i < n; i++ {
117 tmp := 2 * (bi.Dasum(n, x, 1)) / float64(3*n)
119 bi.Dcopy(n, x, 1, v, 1)
125 // Iteration complete. Final stage
127 for i := 0; i < n; i++ {
128 x[i] = altsgn * (1 + float64(i)/float64(n-1))