github.com/gonum/lapack@v0.0.0-20181123203213-e4cdc5a0bff9/native/dgebak.go (about) 1 // Copyright ©2016 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 native 6 7 import ( 8 "github.com/gonum/blas/blas64" 9 "github.com/gonum/lapack" 10 ) 11 12 // Dgebak updates an n×m matrix V as 13 // V = P D V, if side == lapack.RightEV, 14 // V = P D^{-1} V, if side == lapack.LeftEV, 15 // where P and D are n×n permutation and scaling matrices, respectively, 16 // implicitly represented by job, scale, ilo and ihi as returned by Dgebal. 17 // 18 // Typically, columns of the matrix V contain the right or left (determined by 19 // side) eigenvectors of the balanced matrix output by Dgebal, and Dgebak forms 20 // the eigenvectors of the original matrix. 21 // 22 // Dgebak is an internal routine. It is exported for testing purposes. 23 func (impl Implementation) Dgebak(job lapack.Job, side lapack.EVSide, n, ilo, ihi int, scale []float64, m int, v []float64, ldv int) { 24 switch job { 25 default: 26 panic(badJob) 27 case lapack.None, lapack.Permute, lapack.Scale, lapack.PermuteScale: 28 } 29 switch side { 30 default: 31 panic(badSide) 32 case lapack.LeftEV, lapack.RightEV: 33 } 34 checkMatrix(n, m, v, ldv) 35 switch { 36 case ilo < 0 || max(0, n-1) < ilo: 37 panic(badIlo) 38 case ihi < min(ilo, n-1) || n <= ihi: 39 panic(badIhi) 40 } 41 42 // Quick return if possible. 43 if n == 0 || m == 0 || job == lapack.None { 44 return 45 } 46 47 bi := blas64.Implementation() 48 if ilo != ihi && job != lapack.Permute { 49 // Backward balance. 50 if side == lapack.RightEV { 51 for i := ilo; i <= ihi; i++ { 52 bi.Dscal(m, scale[i], v[i*ldv:], 1) 53 } 54 } else { 55 for i := ilo; i <= ihi; i++ { 56 bi.Dscal(m, 1/scale[i], v[i*ldv:], 1) 57 } 58 } 59 } 60 if job == lapack.Scale { 61 return 62 } 63 // Backward permutation. 64 for i := ilo - 1; i >= 0; i-- { 65 k := int(scale[i]) 66 if k == i { 67 continue 68 } 69 bi.Dswap(m, v[i*ldv:], 1, v[k*ldv:], 1) 70 } 71 for i := ihi + 1; i < n; i++ { 72 k := int(scale[i]) 73 if k == i { 74 continue 75 } 76 bi.Dswap(m, v[i*ldv:], 1, v[k*ldv:], 1) 77 } 78 }