// 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" // Dlartg generates a plane rotation so that // [ cs sn] * [f] = [r] // [-sn cs] [g] = [0] // This is a more accurate version of BLAS drotg, with the other differences that // if g = 0, then cs = 1 and sn = 0, and if f = 0 and g != 0, then cs = 0 and sn = 1. // If abs(f) > abs(g), cs will be positive. // // Dlartg is an internal routine. It is exported for testing purposes. func (impl Implementation) Dlartg(f, g float64) (cs, sn, r float64) { safmn2 := math.Pow(dlamchB, math.Trunc(math.Log(dlamchS/dlamchE)/math.Log(dlamchB)/2)) safmx2 := 1 / safmn2 if g == 0 { cs = 1 sn = 0 r = f return cs, sn, r } if f == 0 { cs = 0 sn = 1 r = g return cs, sn, r } f1 := f g1 := g scale := math.Max(math.Abs(f1), math.Abs(g1)) if scale >= safmx2 { var count int for { count++ f1 *= safmn2 g1 *= safmn2 scale = math.Max(math.Abs(f1), math.Abs(g1)) if scale < safmx2 { break } } r = math.Sqrt(f1*f1 + g1*g1) cs = f1 / r sn = g1 / r for i := 0; i < count; i++ { r *= safmx2 } } else if scale <= safmn2 { var count int for { count++ f1 *= safmx2 g1 *= safmx2 scale = math.Max(math.Abs(f1), math.Abs(g1)) if scale >= safmn2 { break } } r = math.Sqrt(f1*f1 + g1*g1) cs = f1 / r sn = g1 / r for i := 0; i < count; i++ { r *= safmn2 } } else { r = math.Sqrt(f1*f1 + g1*g1) cs = f1 / r sn = g1 / r } if math.Abs(f) > math.Abs(g) && cs < 0 { cs *= -1 sn *= -1 r *= -1 } return cs, sn, r }