github.com/gopherd/gonum@v0.0.4/lapack/gonum/drscl.go (about)

     1  // Copyright ©2015 The Gonum Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package gonum
     6  
     7  import (
     8  	"math"
     9  
    10  	"github.com/gopherd/gonum/blas/blas64"
    11  )
    12  
    13  // Drscl multiplies the vector x by 1/a being careful to avoid overflow or
    14  // underflow where possible.
    15  //
    16  // Drscl is an internal routine. It is exported for testing purposes.
    17  func (impl Implementation) Drscl(n int, a float64, x []float64, incX int) {
    18  	switch {
    19  	case n < 0:
    20  		panic(nLT0)
    21  	case incX <= 0:
    22  		panic(badIncX)
    23  	}
    24  
    25  	// Quick return if possible.
    26  	if n == 0 {
    27  		return
    28  	}
    29  
    30  	if len(x) < 1+(n-1)*incX {
    31  		panic(shortX)
    32  	}
    33  
    34  	bi := blas64.Implementation()
    35  
    36  	cden := a
    37  	cnum := 1.0
    38  	smlnum := dlamchS
    39  	bignum := 1 / smlnum
    40  	for {
    41  		cden1 := cden * smlnum
    42  		cnum1 := cnum / bignum
    43  		var mul float64
    44  		var done bool
    45  		switch {
    46  		case cnum != 0 && math.Abs(cden1) > math.Abs(cnum):
    47  			mul = smlnum
    48  			done = false
    49  			cden = cden1
    50  		case math.Abs(cnum1) > math.Abs(cden):
    51  			mul = bignum
    52  			done = false
    53  			cnum = cnum1
    54  		default:
    55  			mul = cnum / cden
    56  			done = true
    57  		}
    58  		bi.Dscal(n, mul, x, incX)
    59  		if done {
    60  			break
    61  		}
    62  	}
    63  }