// 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)
}
