+++ /dev/null
-// 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"
-
-// Dlasv2 computes the singular value decomposition of a 2×2 matrix.
-// [ csl snl] [f g] [csr -snr] = [ssmax 0]
-// [-snl csl] [0 h] [snr csr] = [ 0 ssmin]
-// ssmax is the larger absolute singular value, and ssmin is the smaller absolute
-// singular value. [cls, snl] and [csr, snr] are the left and right singular vectors.
-//
-// Dlasv2 is an internal routine. It is exported for testing purposes.
-func (impl Implementation) Dlasv2(f, g, h float64) (ssmin, ssmax, snr, csr, snl, csl float64) {
- ft := f
- fa := math.Abs(ft)
- ht := h
- ha := math.Abs(h)
- // pmax points to the largest element of the matrix in terms of absolute value.
- // 1 if F, 2 if G, 3 if H.
- pmax := 1
- swap := ha > fa
- if swap {
- pmax = 3
- ft, ht = ht, ft
- fa, ha = ha, fa
- }
- gt := g
- ga := math.Abs(gt)
- var clt, crt, slt, srt float64
- if ga == 0 {
- ssmin = ha
- ssmax = fa
- clt = 1
- crt = 1
- slt = 0
- srt = 0
- } else {
- gasmall := true
- if ga > fa {
- pmax = 2
- if (fa / ga) < dlamchE {
- gasmall = false
- ssmax = ga
- if ha > 1 {
- ssmin = fa / (ga / ha)
- } else {
- ssmin = (fa / ga) * ha
- }
- clt = 1
- slt = ht / gt
- srt = 1
- crt = ft / gt
- }
- }
- if gasmall {
- d := fa - ha
- l := d / fa
- if d == fa { // deal with inf
- l = 1
- }
- m := gt / ft
- t := 2 - l
- s := math.Hypot(t, m)
- var r float64
- if l == 0 {
- r = math.Abs(m)
- } else {
- r = math.Hypot(l, m)
- }
- a := 0.5 * (s + r)
- ssmin = ha / a
- ssmax = fa * a
- if m == 0 {
- if l == 0 {
- t = math.Copysign(2, ft) * math.Copysign(1, gt)
- } else {
- t = gt/math.Copysign(d, ft) + m/t
- }
- } else {
- t = (m/(s+t) + m/(r+l)) * (1 + a)
- }
- l = math.Hypot(t, 2)
- crt = 2 / l
- srt = t / l
- clt = (crt + srt*m) / a
- slt = (ht / ft) * srt / a
- }
- }
- if swap {
- csl = srt
- snl = crt
- csr = slt
- snr = clt
- } else {
- csl = clt
- snl = slt
- csr = crt
- snr = srt
- }
- var tsign float64
- switch pmax {
- case 1:
- tsign = math.Copysign(1, csr) * math.Copysign(1, csl) * math.Copysign(1, f)
- case 2:
- tsign = math.Copysign(1, snr) * math.Copysign(1, csl) * math.Copysign(1, g)
- case 3:
- tsign = math.Copysign(1, snr) * math.Copysign(1, snl) * math.Copysign(1, h)
- }
- ssmax = math.Copysign(ssmax, tsign)
- ssmin = math.Copysign(ssmin, tsign*math.Copysign(1, f)*math.Copysign(1, h))
- return ssmin, ssmax, snr, csr, snl, csl
-}