github.com/gonum/lapack@v0.0.0-20181123203213-e4cdc5a0bff9/native/iparmq.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 "math" 8 9 // Iparmq returns problem and machine dependent parameters useful for Dhseqr and 10 // related subroutines for eigenvalue problems. 11 // 12 // ispec specifies the parameter to return: 13 // 12: Crossover point between Dlahqr and Dlaqr0. Will be at least 11. 14 // 13: Deflation window size. 15 // 14: Nibble crossover point. Determines when to skip a multi-shift QR sweep. 16 // 15: Number of simultaneous shifts in a multishift QR iteration. 17 // 16: Select structured matrix multiply. 18 // For other values of ispec Iparmq will panic. 19 // 20 // name is the name of the calling function. name must be in uppercase but this 21 // is not checked. 22 // 23 // opts is not used and exists for future use. 24 // 25 // n is the order of the Hessenberg matrix H. 26 // 27 // ilo and ihi specify the block [ilo:ihi+1,ilo:ihi+1] that is being processed. 28 // 29 // lwork is the amount of workspace available. 30 // 31 // Except for ispec input parameters are not checked. 32 // 33 // Iparmq is an internal routine. It is exported for testing purposes. 34 func (Implementation) Iparmq(ispec int, name, opts string, n, ilo, ihi, lwork int) int { 35 nh := ihi - ilo + 1 36 ns := 2 37 switch { 38 case nh >= 30: 39 ns = 4 40 case nh >= 60: 41 ns = 10 42 case nh >= 150: 43 ns = max(10, nh/int(math.Log(float64(nh))/math.Ln2)) 44 case nh >= 590: 45 ns = 64 46 case nh >= 3000: 47 ns = 128 48 case nh >= 6000: 49 ns = 256 50 } 51 ns = max(2, ns-(ns%2)) 52 53 switch ispec { 54 default: 55 panic("lapack: bad ispec") 56 57 case 12: 58 // Matrices of order smaller than nmin get sent to Dlahqr, the 59 // classic double shift algorithm. This must be at least 11. 60 const nmin = 75 61 return nmin 62 63 case 13: 64 const knwswp = 500 65 if nh <= knwswp { 66 return ns 67 } 68 return 3 * ns / 2 69 70 case 14: 71 // Skip a computationally expensive multi-shift QR sweep with 72 // Dlaqr5 whenever aggressive early deflation finds at least 73 // nibble*(window size)/100 deflations. The default, small, 74 // value reflects the expectation that the cost of looking 75 // through the deflation window with Dlaqr3 will be 76 // substantially smaller. 77 const nibble = 14 78 return nibble 79 80 case 15: 81 return ns 82 83 case 16: 84 if len(name) != 6 { 85 panic("lapack: bad name") 86 } 87 const ( 88 k22min = 14 89 kacmin = 14 90 ) 91 var acc22 int 92 switch { 93 case name[1:] == "GGHRD" || name[1:] == "GGHD3": 94 acc22 = 1 95 if nh >= k22min { 96 acc22 = 2 97 } 98 case name[3:] == "EXC": 99 if nh >= kacmin { 100 acc22 = 1 101 } 102 if nh >= k22min { 103 acc22 = 2 104 } 105 case name[1:] == "HSEQR" || name[1:5] == "LAQR": 106 if ns >= kacmin { 107 acc22 = 1 108 } 109 if ns >= k22min { 110 acc22 = 2 111 } 112 } 113 return acc22 114 } 115 }