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 }