blob: 40a4b9c3ee2465c9ac847fd5eedba94242ba3459 [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
import "math"
// Dlas2 computes the singular values of the 2×2 matrix defined by
// [F G]
// [0 H]
// The smaller and larger singular values are returned in that order.
//
// Dlas2 is an internal routine. It is exported for testing purposes.
func (impl Implementation) Dlas2(f, g, h float64) (ssmin, ssmax float64) {
fa := math.Abs(f)
ga := math.Abs(g)
ha := math.Abs(h)
fhmin := math.Min(fa, ha)
fhmax := math.Max(fa, ha)
if fhmin == 0 {
if fhmax == 0 {
return 0, ga
}
v := math.Min(fhmax, ga) / math.Max(fhmax, ga)
return 0, math.Max(fhmax, ga) * math.Sqrt(1+v*v)
}
if ga < fhmax {
as := 1 + fhmin/fhmax
at := (fhmax - fhmin) / fhmax
au := (ga / fhmax) * (ga / fhmax)
c := 2 / (math.Sqrt(as*as+au) + math.Sqrt(at*at+au))
return fhmin * c, fhmax / c
}
au := fhmax / ga
if au == 0 {
return fhmin * fhmax / ga, ga
}
as := 1 + fhmin/fhmax
at := (fhmax - fhmin) / fhmax
c := 1 / (math.Sqrt(1+(as*au)*(as*au)) + math.Sqrt(1+(at*au)*(at*au)))
return 2 * (fhmin * c) * au, ga / (c + c)
}