OSDN Git Service

new repo
[bytom/vapor.git] / vendor / gonum.org / v1 / gonum / lapack / gonum / dgecon.go
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.
4
5 package gonum
6
7 import (
8         "math"
9
10         "gonum.org/v1/gonum/blas"
11         "gonum.org/v1/gonum/blas/blas64"
12         "gonum.org/v1/gonum/lapack"
13 )
14
15 // Dgecon estimates the reciprocal of the condition number of the n×n matrix A
16 // given the LU decomposition of the matrix. The condition number computed may
17 // be based on the 1-norm or the ∞-norm.
18 //
19 // The slice a contains the result of the LU decomposition of A as computed by Dgetrf.
20 //
21 // anorm is the corresponding 1-norm or ∞-norm of the original matrix A.
22 //
23 // work is a temporary data slice of length at least 4*n and Dgecon will panic otherwise.
24 //
25 // iwork is a temporary data slice of length at least n and Dgecon will panic otherwise.
26 func (impl Implementation) Dgecon(norm lapack.MatrixNorm, n int, a []float64, lda int, anorm float64, work []float64, iwork []int) float64 {
27         checkMatrix(n, n, a, lda)
28         if norm != lapack.MaxColumnSum && norm != lapack.MaxRowSum {
29                 panic(badNorm)
30         }
31         if len(work) < 4*n {
32                 panic(badWork)
33         }
34         if len(iwork) < n {
35                 panic(badWork)
36         }
37
38         if n == 0 {
39                 return 1
40         } else if anorm == 0 {
41                 return 0
42         }
43
44         bi := blas64.Implementation()
45         var rcond, ainvnm float64
46         var kase int
47         var normin bool
48         isave := new([3]int)
49         onenrm := norm == lapack.MaxColumnSum
50         smlnum := dlamchS
51         kase1 := 2
52         if onenrm {
53                 kase1 = 1
54         }
55         for {
56                 ainvnm, kase = impl.Dlacn2(n, work[n:], work, iwork, ainvnm, kase, isave)
57                 if kase == 0 {
58                         if ainvnm != 0 {
59                                 rcond = (1 / ainvnm) / anorm
60                         }
61                         return rcond
62                 }
63                 var sl, su float64
64                 if kase == kase1 {
65                         sl = impl.Dlatrs(blas.Lower, blas.NoTrans, blas.Unit, normin, n, a, lda, work, work[2*n:])
66                         su = impl.Dlatrs(blas.Upper, blas.NoTrans, blas.NonUnit, normin, n, a, lda, work, work[3*n:])
67                 } else {
68                         su = impl.Dlatrs(blas.Upper, blas.Trans, blas.NonUnit, normin, n, a, lda, work, work[3*n:])
69                         sl = impl.Dlatrs(blas.Lower, blas.Trans, blas.Unit, normin, n, a, lda, work, work[2*n:])
70                 }
71                 scale := sl * su
72                 normin = true
73                 if scale != 1 {
74                         ix := bi.Idamax(n, work, 1)
75                         if scale == 0 || scale < math.Abs(work[ix])*smlnum {
76                                 return rcond
77                         }
78                         impl.Drscl(n, scale, work, 1)
79                 }
80         }
81 }