blob: b401104869f9bea8b446c7d5ff89b52e8584c26e [file] [log] [blame]
// 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
// Ilaenv returns algorithm tuning parameters for the algorithm given by the
// input string. ispec specifies the parameter to return:
// 1: The optimal block size for a blocked algorithm.
// 2: The minimum block size for a blocked algorithm.
// 3: The block size of unprocessed data at which a blocked algorithm should
// crossover to an unblocked version.
// 4: The number of shifts.
// 5: The minimum column dimension for blocking to be used.
// 6: The crossover point for SVD (to use QR factorization or not).
// 7: The number of processors.
// 8: The crossover point for multi-shift in QR and QZ methods for non-symmetric eigenvalue problems.
// 9: Maximum size of the subproblems in divide-and-conquer algorithms.
// 10: ieee NaN arithmetic can be trusted not to trap.
// 11: infinity arithmetic can be trusted not to trap.
// 12...16: parameters for Dhseqr and related functions. See Iparmq for more
// information.
//
// Ilaenv is an internal routine. It is exported for testing purposes.
func (impl Implementation) Ilaenv(ispec int, name string, opts string, n1, n2, n3, n4 int) int {
// TODO(btracey): Replace this with a constant lookup? A list of constants?
sname := name[0] == 'S' || name[0] == 'D'
cname := name[0] == 'C' || name[0] == 'Z'
if !sname && !cname {
panic(badName)
}
c2 := name[1:3]
c3 := name[3:6]
c4 := c3[1:3]
switch ispec {
default:
panic(badIspec)
case 1:
switch c2 {
default:
panic(badName)
case "GE":
switch c3 {
default:
panic(badName)
case "TRF":
if sname {
return 64
}
return 64
case "QRF", "RQF", "LQF", "QLF":
if sname {
return 32
}
return 32
case "HRD":
if sname {
return 32
}
return 32
case "BRD":
if sname {
return 32
}
return 32
case "TRI":
if sname {
return 64
}
return 64
}
case "PO":
switch c3 {
default:
panic(badName)
case "TRF":
if sname {
return 64
}
return 64
}
case "SY":
switch c3 {
default:
panic(badName)
case "TRF":
if sname {
return 64
}
return 64
case "TRD":
return 32
case "GST":
return 64
}
case "HE":
switch c3 {
default:
panic(badName)
case "TRF":
return 64
case "TRD":
return 32
case "GST":
return 64
}
case "OR":
switch c3[0] {
default:
panic(badName)
case 'G':
switch c3[1:] {
default:
panic(badName)
case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR":
return 32
}
case 'M':
switch c3[1:] {
default:
panic(badName)
case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR":
return 32
}
}
case "UN":
switch c3[0] {
default:
panic(badName)
case 'G':
switch c3[1:] {
default:
panic(badName)
case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR":
return 32
}
case 'M':
switch c3[1:] {
default:
panic(badName)
case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR":
return 32
}
}
case "GB":
switch c3 {
default:
panic(badName)
case "TRF":
if sname {
if n4 <= 64 {
return 1
}
return 32
}
if n4 <= 64 {
return 1
}
return 32
}
case "PB":
switch c3 {
default:
panic(badName)
case "TRF":
if sname {
if n2 <= 64 {
return 1
}
return 32
}
if n2 <= 64 {
return 1
}
return 32
}
case "TR":
switch c3 {
default:
panic(badName)
case "TRI":
if sname {
return 64
}
return 64
case "EVC":
if sname {
return 64
}
return 64
}
case "LA":
switch c3 {
default:
panic(badName)
case "UUM":
if sname {
return 64
}
return 64
}
case "ST":
if sname && c3 == "EBZ" {
return 1
}
panic(badName)
}
case 2:
switch c2 {
default:
panic(badName)
case "GE":
switch c3 {
default:
panic(badName)
case "QRF", "RQF", "LQF", "QLF":
if sname {
return 2
}
return 2
case "HRD":
if sname {
return 2
}
return 2
case "BRD":
if sname {
return 2
}
return 2
case "TRI":
if sname {
return 2
}
return 2
}
case "SY":
switch c3 {
default:
panic(badName)
case "TRF":
if sname {
return 8
}
return 8
case "TRD":
if sname {
return 2
}
panic(badName)
}
case "HE":
if c3 == "TRD" {
return 2
}
panic(badName)
case "OR":
if !sname {
panic(badName)
}
switch c3[0] {
default:
panic(badName)
case 'G':
switch c4 {
default:
panic(badName)
case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR":
return 2
}
case 'M':
switch c4 {
default:
panic(badName)
case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR":
return 2
}
}
case "UN":
switch c3[0] {
default:
panic(badName)
case 'G':
switch c4 {
default:
panic(badName)
case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR":
return 2
}
case 'M':
switch c4 {
default:
panic(badName)
case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR":
return 2
}
}
}
case 3:
switch c2 {
default:
panic(badName)
case "GE":
switch c3 {
default:
panic(badName)
case "QRF", "RQF", "LQF", "QLF":
if sname {
return 128
}
return 128
case "HRD":
if sname {
return 128
}
return 128
case "BRD":
if sname {
return 128
}
return 128
}
case "SY":
if sname && c3 == "TRD" {
return 32
}
panic(badName)
case "HE":
if c3 == "TRD" {
return 32
}
panic(badName)
case "OR":
switch c3[0] {
default:
panic(badName)
case 'G':
switch c4 {
default:
panic(badName)
case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR":
return 128
}
}
case "UN":
switch c3[0] {
default:
panic(badName)
case 'G':
switch c4 {
default:
panic(badName)
case "QR", "RQ", "LQ", "QL", "HR", "TR", "BR":
return 128
}
}
}
case 4:
// Used by xHSEQR
return 6
case 5:
// Not used
return 2
case 6:
// Used by xGELSS and xGESVD
return int(float64(min(n1, n2)) * 1.6)
case 7:
// Not used
return 1
case 8:
// Used by xHSEQR
return 50
case 9:
// used by xGELSD and xGESDD
return 25
case 10:
// Go guarantees ieee
return 1
case 11:
// Go guarantees ieee
return 1
case 12, 13, 14, 15, 16:
// Dhseqr and related functions for eigenvalue problems.
return impl.Iparmq(ispec, name, opts, n1, n2, n3, n4)
}
}