github.com/gonum/lapack@v0.0.0-20181123203213-e4cdc5a0bff9/native/dlas2.go (about)

     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 native
     6  
     7  import "math"
     8  
     9  // Dlas2 computes the singular values of the 2×2 matrix defined by
    10  //  [F G]
    11  //  [0 H]
    12  // The smaller and larger singular values are returned in that order.
    13  //
    14  // Dlas2 is an internal routine. It is exported for testing purposes.
    15  func (impl Implementation) Dlas2(f, g, h float64) (ssmin, ssmax float64) {
    16  	fa := math.Abs(f)
    17  	ga := math.Abs(g)
    18  	ha := math.Abs(h)
    19  	fhmin := math.Min(fa, ha)
    20  	fhmax := math.Max(fa, ha)
    21  	if fhmin == 0 {
    22  		if fhmax == 0 {
    23  			return 0, ga
    24  		}
    25  		v := math.Min(fhmax, ga) / math.Max(fhmax, ga)
    26  		return 0, math.Max(fhmax, ga) * math.Sqrt(1+v*v)
    27  	}
    28  	if ga < fhmax {
    29  		as := 1 + fhmin/fhmax
    30  		at := (fhmax - fhmin) / fhmax
    31  		au := (ga / fhmax) * (ga / fhmax)
    32  		c := 2 / (math.Sqrt(as*as+au) + math.Sqrt(at*at+au))
    33  		return fhmin * c, fhmax / c
    34  	}
    35  	au := fhmax / ga
    36  	if au == 0 {
    37  		return fhmin * fhmax / ga, ga
    38  	}
    39  	as := 1 + fhmin/fhmax
    40  	at := (fhmax - fhmin) / fhmax
    41  	c := 1 / (math.Sqrt(1+(as*au)*(as*au)) + math.Sqrt(1+(at*au)*(at*au)))
    42  	return 2 * (fhmin * c) * au, ga / (c + c)
    43  }