gonum.org/v1/gonum@v0.14.0/blas/gonum/level1float32.go (about)

     1  // Code generated by "go generate gonum.org/v1/gonum/blas/gonum”; DO NOT EDIT.
     2  
     3  // Copyright ©2015 The Gonum Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  package gonum
     8  
     9  import (
    10  	math "gonum.org/v1/gonum/internal/math32"
    11  
    12  	"gonum.org/v1/gonum/blas"
    13  	"gonum.org/v1/gonum/internal/asm/f32"
    14  )
    15  
    16  var _ blas.Float32Level1 = Implementation{}
    17  
    18  // Snrm2 computes the Euclidean norm of a vector,
    19  //
    20  //	sqrt(\sum_i x[i] * x[i]).
    21  //
    22  // This function returns 0 if incX is negative.
    23  //
    24  // Float32 implementations are autogenerated and not directly tested.
    25  func (Implementation) Snrm2(n int, x []float32, incX int) float32 {
    26  	if incX < 1 {
    27  		if incX == 0 {
    28  			panic(zeroIncX)
    29  		}
    30  		return 0
    31  	}
    32  	if len(x) <= (n-1)*incX {
    33  		panic(shortX)
    34  	}
    35  	if n < 2 {
    36  		if n == 1 {
    37  			return math.Abs(x[0])
    38  		}
    39  		if n == 0 {
    40  			return 0
    41  		}
    42  		panic(nLT0)
    43  	}
    44  	if incX == 1 {
    45  		return f32.L2NormUnitary(x[:n])
    46  	}
    47  	return f32.L2NormInc(x, uintptr(n), uintptr(incX))
    48  }
    49  
    50  // Sasum computes the sum of the absolute values of the elements of x.
    51  //
    52  //	\sum_i |x[i]|
    53  //
    54  // Sasum returns 0 if incX is negative.
    55  //
    56  // Float32 implementations are autogenerated and not directly tested.
    57  func (Implementation) Sasum(n int, x []float32, incX int) float32 {
    58  	var sum float32
    59  	if n < 0 {
    60  		panic(nLT0)
    61  	}
    62  	if incX < 1 {
    63  		if incX == 0 {
    64  			panic(zeroIncX)
    65  		}
    66  		return 0
    67  	}
    68  	if len(x) <= (n-1)*incX {
    69  		panic(shortX)
    70  	}
    71  	if incX == 1 {
    72  		x = x[:n]
    73  		for _, v := range x {
    74  			sum += math.Abs(v)
    75  		}
    76  		return sum
    77  	}
    78  	for i := 0; i < n; i++ {
    79  		sum += math.Abs(x[i*incX])
    80  	}
    81  	return sum
    82  }
    83  
    84  // Isamax returns the index of an element of x with the largest absolute value.
    85  // If there are multiple such indices the earliest is returned.
    86  // Isamax returns -1 if n == 0.
    87  //
    88  // Float32 implementations are autogenerated and not directly tested.
    89  func (Implementation) Isamax(n int, x []float32, incX int) int {
    90  	if incX < 1 {
    91  		if incX == 0 {
    92  			panic(zeroIncX)
    93  		}
    94  		return -1
    95  	}
    96  	if len(x) <= (n-1)*incX {
    97  		panic(shortX)
    98  	}
    99  	if n < 2 {
   100  		if n == 1 {
   101  			return 0
   102  		}
   103  		if n == 0 {
   104  			return -1 // Netlib returns invalid index when n == 0.
   105  		}
   106  		panic(nLT0)
   107  	}
   108  	idx := 0
   109  	max := math.Abs(x[0])
   110  	if incX == 1 {
   111  		for i, v := range x[:n] {
   112  			absV := math.Abs(v)
   113  			if absV > max {
   114  				max = absV
   115  				idx = i
   116  			}
   117  		}
   118  		return idx
   119  	}
   120  	ix := incX
   121  	for i := 1; i < n; i++ {
   122  		v := x[ix]
   123  		absV := math.Abs(v)
   124  		if absV > max {
   125  			max = absV
   126  			idx = i
   127  		}
   128  		ix += incX
   129  	}
   130  	return idx
   131  }
   132  
   133  // Sswap exchanges the elements of two vectors.
   134  //
   135  //	x[i], y[i] = y[i], x[i] for all i
   136  //
   137  // Float32 implementations are autogenerated and not directly tested.
   138  func (Implementation) Sswap(n int, x []float32, incX int, y []float32, incY int) {
   139  	if incX == 0 {
   140  		panic(zeroIncX)
   141  	}
   142  	if incY == 0 {
   143  		panic(zeroIncY)
   144  	}
   145  	if n < 1 {
   146  		if n == 0 {
   147  			return
   148  		}
   149  		panic(nLT0)
   150  	}
   151  	if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
   152  		panic(shortX)
   153  	}
   154  	if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
   155  		panic(shortY)
   156  	}
   157  	if incX == 1 && incY == 1 {
   158  		x = x[:n]
   159  		for i, v := range x {
   160  			x[i], y[i] = y[i], v
   161  		}
   162  		return
   163  	}
   164  	var ix, iy int
   165  	if incX < 0 {
   166  		ix = (-n + 1) * incX
   167  	}
   168  	if incY < 0 {
   169  		iy = (-n + 1) * incY
   170  	}
   171  	for i := 0; i < n; i++ {
   172  		x[ix], y[iy] = y[iy], x[ix]
   173  		ix += incX
   174  		iy += incY
   175  	}
   176  }
   177  
   178  // Scopy copies the elements of x into the elements of y.
   179  //
   180  //	y[i] = x[i] for all i
   181  //
   182  // Float32 implementations are autogenerated and not directly tested.
   183  func (Implementation) Scopy(n int, x []float32, incX int, y []float32, incY int) {
   184  	if incX == 0 {
   185  		panic(zeroIncX)
   186  	}
   187  	if incY == 0 {
   188  		panic(zeroIncY)
   189  	}
   190  	if n < 1 {
   191  		if n == 0 {
   192  			return
   193  		}
   194  		panic(nLT0)
   195  	}
   196  	if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
   197  		panic(shortX)
   198  	}
   199  	if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
   200  		panic(shortY)
   201  	}
   202  	if incX == 1 && incY == 1 {
   203  		copy(y[:n], x[:n])
   204  		return
   205  	}
   206  	var ix, iy int
   207  	if incX < 0 {
   208  		ix = (-n + 1) * incX
   209  	}
   210  	if incY < 0 {
   211  		iy = (-n + 1) * incY
   212  	}
   213  	for i := 0; i < n; i++ {
   214  		y[iy] = x[ix]
   215  		ix += incX
   216  		iy += incY
   217  	}
   218  }
   219  
   220  // Saxpy adds alpha times x to y
   221  //
   222  //	y[i] += alpha * x[i] for all i
   223  //
   224  // Float32 implementations are autogenerated and not directly tested.
   225  func (Implementation) Saxpy(n int, alpha float32, x []float32, incX int, y []float32, incY int) {
   226  	if incX == 0 {
   227  		panic(zeroIncX)
   228  	}
   229  	if incY == 0 {
   230  		panic(zeroIncY)
   231  	}
   232  	if n < 1 {
   233  		if n == 0 {
   234  			return
   235  		}
   236  		panic(nLT0)
   237  	}
   238  	if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
   239  		panic(shortX)
   240  	}
   241  	if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
   242  		panic(shortY)
   243  	}
   244  	if alpha == 0 {
   245  		return
   246  	}
   247  	if incX == 1 && incY == 1 {
   248  		f32.AxpyUnitary(alpha, x[:n], y[:n])
   249  		return
   250  	}
   251  	var ix, iy int
   252  	if incX < 0 {
   253  		ix = (-n + 1) * incX
   254  	}
   255  	if incY < 0 {
   256  		iy = (-n + 1) * incY
   257  	}
   258  	f32.AxpyInc(alpha, x, y, uintptr(n), uintptr(incX), uintptr(incY), uintptr(ix), uintptr(iy))
   259  }
   260  
   261  // Srotg computes a plane rotation
   262  //
   263  //	⎡  c s ⎤ ⎡ a ⎤ = ⎡ r ⎤
   264  //	⎣ -s c ⎦ ⎣ b ⎦   ⎣ 0 ⎦
   265  //
   266  // satisfying c^2 + s^2 = 1.
   267  //
   268  // The computation uses the formulas
   269  //
   270  //	sigma = sgn(a)    if |a| >  |b|
   271  //	      = sgn(b)    if |b| >= |a|
   272  //	r = sigma*sqrt(a^2 + b^2)
   273  //	c = 1; s = 0      if r = 0
   274  //	c = a/r; s = b/r  if r != 0
   275  //	c >= 0            if |a| > |b|
   276  //
   277  // The subroutine also computes
   278  //
   279  //	z = s    if |a| > |b|,
   280  //	  = 1/c  if |b| >= |a| and c != 0
   281  //	  = 1    if c = 0
   282  //
   283  // This allows c and s to be reconstructed from z as follows:
   284  //
   285  //	If z = 1, set c = 0, s = 1.
   286  //	If |z| < 1, set c = sqrt(1 - z^2) and s = z.
   287  //	If |z| > 1, set c = 1/z and s = sqrt(1 - c^2).
   288  //
   289  // NOTE: There is a discrepancy between the reference implementation and the
   290  // BLAS technical manual regarding the sign for r when a or b are zero. Drotg
   291  // agrees with the definition in the manual and other common BLAS
   292  // implementations.
   293  //
   294  // Float32 implementations are autogenerated and not directly tested.
   295  func (Implementation) Srotg(a, b float32) (c, s, r, z float32) {
   296  	// Implementation based on Supplemental Material to:
   297  	// Edward Anderson. 2017. Algorithm 978: Safe Scaling in the Level 1 BLAS.
   298  	// ACM Trans. Math. Softw. 44, 1, Article 12 (July 2017), 28 pages.
   299  	// DOI: https://doi.org/10.1145/3061665
   300  	const (
   301  		safmin = 0x1p-126
   302  		safmax = 1 / safmin
   303  	)
   304  	anorm := math.Abs(a)
   305  	bnorm := math.Abs(b)
   306  	switch {
   307  	case bnorm == 0:
   308  		c = 1
   309  		s = 0
   310  		r = a
   311  		z = 0
   312  	case anorm == 0:
   313  		c = 0
   314  		s = 1
   315  		r = b
   316  		z = 1
   317  	default:
   318  		maxab := math.Max(anorm, bnorm)
   319  		scl := math.Min(math.Max(safmin, maxab), safmax)
   320  		var sigma float32
   321  		if anorm > bnorm {
   322  			sigma = math.Copysign(1, a)
   323  		} else {
   324  			sigma = math.Copysign(1, b)
   325  		}
   326  		ascl := a / scl
   327  		bscl := b / scl
   328  		r = sigma * (scl * math.Sqrt(ascl*ascl+bscl*bscl))
   329  		c = a / r
   330  		s = b / r
   331  		switch {
   332  		case anorm > bnorm:
   333  			z = s
   334  		case c != 0:
   335  			z = 1 / c
   336  		default:
   337  			z = 1
   338  		}
   339  	}
   340  	return c, s, r, z
   341  }
   342  
   343  // Srotmg computes the modified Givens rotation. See
   344  // http://www.netlib.org/lapack/explore-html/df/deb/drotmg_8f.html
   345  // for more details.
   346  //
   347  // Float32 implementations are autogenerated and not directly tested.
   348  func (Implementation) Srotmg(d1, d2, x1, y1 float32) (p blas.SrotmParams, rd1, rd2, rx1 float32) {
   349  	// The implementation of Drotmg used here is taken from Hopkins 1997
   350  	// Appendix A: https://doi.org/10.1145/289251.289253
   351  	// with the exception of the gam constants below.
   352  
   353  	const (
   354  		gam    = 4096.0
   355  		gamsq  = gam * gam
   356  		rgamsq = 1.0 / gamsq
   357  	)
   358  
   359  	if d1 < 0 {
   360  		p.Flag = blas.Rescaling // Error state.
   361  		return p, 0, 0, 0
   362  	}
   363  
   364  	if d2 == 0 || y1 == 0 {
   365  		p.Flag = blas.Identity
   366  		return p, d1, d2, x1
   367  	}
   368  
   369  	var h11, h12, h21, h22 float32
   370  	if (d1 == 0 || x1 == 0) && d2 > 0 {
   371  		p.Flag = blas.Diagonal
   372  		h12 = 1
   373  		h21 = -1
   374  		x1 = y1
   375  		d1, d2 = d2, d1
   376  	} else {
   377  		p2 := d2 * y1
   378  		p1 := d1 * x1
   379  		q2 := p2 * y1
   380  		q1 := p1 * x1
   381  		if math.Abs(q1) > math.Abs(q2) {
   382  			p.Flag = blas.OffDiagonal
   383  			h11 = 1
   384  			h22 = 1
   385  			h21 = -y1 / x1
   386  			h12 = p2 / p1
   387  			u := 1 - float32(h12*h21)
   388  			if u <= 0 {
   389  				p.Flag = blas.Rescaling // Error state.
   390  				return p, 0, 0, 0
   391  			}
   392  
   393  			d1 /= u
   394  			d2 /= u
   395  			x1 *= u
   396  		} else {
   397  			if q2 < 0 {
   398  				p.Flag = blas.Rescaling // Error state.
   399  				return p, 0, 0, 0
   400  			}
   401  
   402  			p.Flag = blas.Diagonal
   403  			h21 = -1
   404  			h12 = 1
   405  			h11 = p1 / p2
   406  			h22 = x1 / y1
   407  			u := 1 + float32(h11*h22)
   408  			d1, d2 = d2/u, d1/u
   409  			x1 = y1 * u
   410  		}
   411  	}
   412  
   413  	for d1 <= rgamsq && d1 != 0 {
   414  		p.Flag = blas.Rescaling
   415  		d1 = (d1 * gam) * gam
   416  		x1 /= gam
   417  		h11 /= gam
   418  		h12 /= gam
   419  	}
   420  	for d1 > gamsq {
   421  		p.Flag = blas.Rescaling
   422  		d1 = (d1 / gam) / gam
   423  		x1 *= gam
   424  		h11 *= gam
   425  		h12 *= gam
   426  	}
   427  
   428  	for math.Abs(d2) <= rgamsq && d2 != 0 {
   429  		p.Flag = blas.Rescaling
   430  		d2 = (d2 * gam) * gam
   431  		h21 /= gam
   432  		h22 /= gam
   433  	}
   434  	for math.Abs(d2) > gamsq {
   435  		p.Flag = blas.Rescaling
   436  		d2 = (d2 / gam) / gam
   437  		h21 *= gam
   438  		h22 *= gam
   439  	}
   440  
   441  	switch p.Flag {
   442  	case blas.Diagonal:
   443  		p.H = [4]float32{0: h11, 3: h22}
   444  	case blas.OffDiagonal:
   445  		p.H = [4]float32{1: h21, 2: h12}
   446  	case blas.Rescaling:
   447  		p.H = [4]float32{h11, h21, h12, h22}
   448  	default:
   449  		panic(badFlag)
   450  	}
   451  
   452  	return p, d1, d2, x1
   453  }
   454  
   455  // Srot applies a plane transformation.
   456  //
   457  //	x[i] = c * x[i] + s * y[i]
   458  //	y[i] = c * y[i] - s * x[i]
   459  //
   460  // Float32 implementations are autogenerated and not directly tested.
   461  func (Implementation) Srot(n int, x []float32, incX int, y []float32, incY int, c float32, s float32) {
   462  	if incX == 0 {
   463  		panic(zeroIncX)
   464  	}
   465  	if incY == 0 {
   466  		panic(zeroIncY)
   467  	}
   468  	if n < 1 {
   469  		if n == 0 {
   470  			return
   471  		}
   472  		panic(nLT0)
   473  	}
   474  	if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
   475  		panic(shortX)
   476  	}
   477  	if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
   478  		panic(shortY)
   479  	}
   480  	if incX == 1 && incY == 1 {
   481  		x = x[:n]
   482  		for i, vx := range x {
   483  			vy := y[i]
   484  			x[i], y[i] = c*vx+s*vy, c*vy-s*vx
   485  		}
   486  		return
   487  	}
   488  	var ix, iy int
   489  	if incX < 0 {
   490  		ix = (-n + 1) * incX
   491  	}
   492  	if incY < 0 {
   493  		iy = (-n + 1) * incY
   494  	}
   495  	for i := 0; i < n; i++ {
   496  		vx := x[ix]
   497  		vy := y[iy]
   498  		x[ix], y[iy] = c*vx+s*vy, c*vy-s*vx
   499  		ix += incX
   500  		iy += incY
   501  	}
   502  }
   503  
   504  // Srotm applies the modified Givens rotation to the 2×n matrix.
   505  //
   506  // Float32 implementations are autogenerated and not directly tested.
   507  func (Implementation) Srotm(n int, x []float32, incX int, y []float32, incY int, p blas.SrotmParams) {
   508  	if incX == 0 {
   509  		panic(zeroIncX)
   510  	}
   511  	if incY == 0 {
   512  		panic(zeroIncY)
   513  	}
   514  	if n <= 0 {
   515  		if n == 0 {
   516  			return
   517  		}
   518  		panic(nLT0)
   519  	}
   520  	if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
   521  		panic(shortX)
   522  	}
   523  	if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
   524  		panic(shortY)
   525  	}
   526  
   527  	if p.Flag == blas.Identity {
   528  		return
   529  	}
   530  
   531  	switch p.Flag {
   532  	case blas.Rescaling:
   533  		h11 := p.H[0]
   534  		h12 := p.H[2]
   535  		h21 := p.H[1]
   536  		h22 := p.H[3]
   537  		if incX == 1 && incY == 1 {
   538  			x = x[:n]
   539  			for i, vx := range x {
   540  				vy := y[i]
   541  				x[i], y[i] = float32(vx*h11)+float32(vy*h12), float32(vx*h21)+float32(vy*h22)
   542  			}
   543  			return
   544  		}
   545  		var ix, iy int
   546  		if incX < 0 {
   547  			ix = (-n + 1) * incX
   548  		}
   549  		if incY < 0 {
   550  			iy = (-n + 1) * incY
   551  		}
   552  		for i := 0; i < n; i++ {
   553  			vx := x[ix]
   554  			vy := y[iy]
   555  			x[ix], y[iy] = float32(vx*h11)+float32(vy*h12), float32(vx*h21)+float32(vy*h22)
   556  			ix += incX
   557  			iy += incY
   558  		}
   559  	case blas.OffDiagonal:
   560  		h12 := p.H[2]
   561  		h21 := p.H[1]
   562  		if incX == 1 && incY == 1 {
   563  			x = x[:n]
   564  			for i, vx := range x {
   565  				vy := y[i]
   566  				x[i], y[i] = vx+float32(vy*h12), float32(vx*h21)+vy
   567  			}
   568  			return
   569  		}
   570  		var ix, iy int
   571  		if incX < 0 {
   572  			ix = (-n + 1) * incX
   573  		}
   574  		if incY < 0 {
   575  			iy = (-n + 1) * incY
   576  		}
   577  		for i := 0; i < n; i++ {
   578  			vx := x[ix]
   579  			vy := y[iy]
   580  			x[ix], y[iy] = vx+float32(vy*h12), float32(vx*h21)+vy
   581  			ix += incX
   582  			iy += incY
   583  		}
   584  	case blas.Diagonal:
   585  		h11 := p.H[0]
   586  		h22 := p.H[3]
   587  		if incX == 1 && incY == 1 {
   588  			x = x[:n]
   589  			for i, vx := range x {
   590  				vy := y[i]
   591  				x[i], y[i] = float32(vx*h11)+vy, -vx+float32(vy*h22)
   592  			}
   593  			return
   594  		}
   595  		var ix, iy int
   596  		if incX < 0 {
   597  			ix = (-n + 1) * incX
   598  		}
   599  		if incY < 0 {
   600  			iy = (-n + 1) * incY
   601  		}
   602  		for i := 0; i < n; i++ {
   603  			vx := x[ix]
   604  			vy := y[iy]
   605  			x[ix], y[iy] = float32(vx*h11)+vy, -vx+float32(vy*h22)
   606  			ix += incX
   607  			iy += incY
   608  		}
   609  	}
   610  }
   611  
   612  // Sscal scales x by alpha.
   613  //
   614  //	x[i] *= alpha
   615  //
   616  // Sscal has no effect if incX < 0.
   617  //
   618  // Float32 implementations are autogenerated and not directly tested.
   619  func (Implementation) Sscal(n int, alpha float32, x []float32, incX int) {
   620  	if incX < 1 {
   621  		if incX == 0 {
   622  			panic(zeroIncX)
   623  		}
   624  		return
   625  	}
   626  	if n < 1 {
   627  		if n == 0 {
   628  			return
   629  		}
   630  		panic(nLT0)
   631  	}
   632  	if (n-1)*incX >= len(x) {
   633  		panic(shortX)
   634  	}
   635  	if alpha == 0 {
   636  		if incX == 1 {
   637  			x = x[:n]
   638  			for i := range x {
   639  				x[i] = 0
   640  			}
   641  			return
   642  		}
   643  		for ix := 0; ix < n*incX; ix += incX {
   644  			x[ix] = 0
   645  		}
   646  		return
   647  	}
   648  	if incX == 1 {
   649  		f32.ScalUnitary(alpha, x[:n])
   650  		return
   651  	}
   652  	f32.ScalInc(alpha, x, uintptr(n), uintptr(incX))
   653  }