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