github.com/gopherd/gonum@v0.0.4/internal/asm/f64/ge_noasm.go (about)

     1  // Copyright ©2017 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  //go:build !amd64 || noasm || gccgo || safe
     6  // +build !amd64 noasm gccgo safe
     7  
     8  package f64
     9  
    10  // Ger performs the rank-one operation
    11  //  A += alpha * x * yᵀ
    12  // where A is an m×n dense matrix, x and y are vectors, and alpha is a scalar.
    13  func Ger(m, n uintptr, alpha float64, x []float64, incX uintptr, y []float64, incY uintptr, a []float64, lda uintptr) {
    14  	if incX == 1 && incY == 1 {
    15  		x = x[:m]
    16  		y = y[:n]
    17  		for i, xv := range x {
    18  			AxpyUnitary(alpha*xv, y, a[uintptr(i)*lda:uintptr(i)*lda+n])
    19  		}
    20  		return
    21  	}
    22  
    23  	var ky, kx uintptr
    24  	if int(incY) < 0 {
    25  		ky = uintptr(-int(n-1) * int(incY))
    26  	}
    27  	if int(incX) < 0 {
    28  		kx = uintptr(-int(m-1) * int(incX))
    29  	}
    30  
    31  	ix := kx
    32  	for i := 0; i < int(m); i++ {
    33  		AxpyInc(alpha*x[ix], y, a[uintptr(i)*lda:uintptr(i)*lda+n], n, incY, 1, ky, 0)
    34  		ix += incX
    35  	}
    36  }
    37  
    38  // GemvN computes
    39  //  y = alpha * A * x + beta * y
    40  // where A is an m×n dense matrix, x and y are vectors, and alpha and beta are scalars.
    41  func GemvN(m, n uintptr, alpha float64, a []float64, lda uintptr, x []float64, incX uintptr, beta float64, y []float64, incY uintptr) {
    42  	var kx, ky, i uintptr
    43  	if int(incX) < 0 {
    44  		kx = uintptr(-int(n-1) * int(incX))
    45  	}
    46  	if int(incY) < 0 {
    47  		ky = uintptr(-int(m-1) * int(incY))
    48  	}
    49  
    50  	if incX == 1 && incY == 1 {
    51  		if beta == 0 {
    52  			for i = 0; i < m; i++ {
    53  				y[i] = alpha * DotUnitary(a[lda*i:lda*i+n], x)
    54  			}
    55  			return
    56  		}
    57  		for i = 0; i < m; i++ {
    58  			y[i] = y[i]*beta + alpha*DotUnitary(a[lda*i:lda*i+n], x)
    59  		}
    60  		return
    61  	}
    62  	iy := ky
    63  	if beta == 0 {
    64  		for i = 0; i < m; i++ {
    65  			y[iy] = alpha * DotInc(x, a[lda*i:lda*i+n], n, incX, 1, kx, 0)
    66  			iy += incY
    67  		}
    68  		return
    69  	}
    70  	for i = 0; i < m; i++ {
    71  		y[iy] = y[iy]*beta + alpha*DotInc(x, a[lda*i:lda*i+n], n, incX, 1, kx, 0)
    72  		iy += incY
    73  	}
    74  }
    75  
    76  // GemvT computes
    77  //  y = alpha * Aᵀ * x + beta * y
    78  // where A is an m×n dense matrix, x and y are vectors, and alpha and beta are scalars.
    79  func GemvT(m, n uintptr, alpha float64, a []float64, lda uintptr, x []float64, incX uintptr, beta float64, y []float64, incY uintptr) {
    80  	var kx, ky, i uintptr
    81  	if int(incX) < 0 {
    82  		kx = uintptr(-int(m-1) * int(incX))
    83  	}
    84  	if int(incY) < 0 {
    85  		ky = uintptr(-int(n-1) * int(incY))
    86  	}
    87  	switch {
    88  	case beta == 0: // beta == 0 is special-cased to memclear
    89  		if incY == 1 {
    90  			for i := range y {
    91  				y[i] = 0
    92  			}
    93  		} else {
    94  			iy := ky
    95  			for i := 0; i < int(n); i++ {
    96  				y[iy] = 0
    97  				iy += incY
    98  			}
    99  		}
   100  	case int(incY) < 0:
   101  		ScalInc(beta, y, n, uintptr(int(-incY)))
   102  	case incY == 1:
   103  		ScalUnitary(beta, y[:n])
   104  	default:
   105  		ScalInc(beta, y, n, incY)
   106  	}
   107  
   108  	if incX == 1 && incY == 1 {
   109  		for i = 0; i < m; i++ {
   110  			AxpyUnitaryTo(y, alpha*x[i], a[lda*i:lda*i+n], y)
   111  		}
   112  		return
   113  	}
   114  	ix := kx
   115  	for i = 0; i < m; i++ {
   116  		AxpyInc(alpha*x[ix], a[lda*i:lda*i+n], y, n, 1, incY, 0, ky)
   117  		ix += incX
   118  	}
   119  }