mirror of
https://github.com/gonum/gonum.git
synced 2025-10-05 23:26:52 +08:00
44 lines
1.2 KiB
Go
44 lines
1.2 KiB
Go
// 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 native
|
||
|
||
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)
|
||
}
|