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.
10 "gonum.org/v1/gonum/blas"
11 "gonum.org/v1/gonum/internal/asm/c128"
14 // Zgemv performs one of the matrix-vector operations
15 // y = alpha * A * x + beta * y if trans = blas.NoTrans
16 // y = alpha * A^T * x + beta * y if trans = blas.Trans
17 // y = alpha * A^H * x + beta * y if trans = blas.ConjTrans
18 // where alpha and beta are scalars, x and y are vectors, and A is an m×n dense matrix.
19 func (Implementation) Zgemv(trans blas.Transpose, m, n int, alpha complex128, a []complex128, lda int, x []complex128, incX int, beta complex128, y []complex128, incY int) {
20 checkZMatrix('A', m, n, a, lda)
25 checkZVector('x', n, x, incX)
26 checkZVector('y', m, y, incY)
27 case blas.Trans, blas.ConjTrans:
28 checkZVector('x', m, x, incX)
29 checkZVector('y', n, y, incY)
32 if m == 0 || n == 0 || (alpha == 0 && beta == 1) {
37 if trans == blas.NoTrans {
46 kx = (1 - lenX) * incX
50 ky = (1 - lenY) * incY
57 for i := range y[:lenY] {
61 c128.ScalUnitary(beta, y[:lenY])
66 for i := 0; i < lenY; i++ {
72 c128.ScalInc(beta, y, uintptr(lenY), uintptr(incY))
74 c128.ScalInc(beta, y, uintptr(lenY), uintptr(-incY))
86 // Form y = alpha*A*x + y.
89 for i := 0; i < m; i++ {
90 y[iy] += alpha * c128.DotuUnitary(a[i*lda:i*lda+n], x[:n])
95 for i := 0; i < m; i++ {
96 y[iy] += alpha * c128.DotuInc(a[i*lda:i*lda+n], x, uintptr(n), 1, uintptr(incX), 0, uintptr(kx))
102 // Form y = alpha*A^T*x + y.
105 for i := 0; i < m; i++ {
106 c128.AxpyUnitary(alpha*x[ix], a[i*lda:i*lda+n], y[:n])
111 for i := 0; i < m; i++ {
112 c128.AxpyInc(alpha*x[ix], a[i*lda:i*lda+n], y, uintptr(n), 1, uintptr(incY), 0, uintptr(ky))
118 // Form y = alpha*A^H*x + y.
121 for i := 0; i < m; i++ {
123 for j := 0; j < n; j++ {
124 y[j] += tmp * cmplx.Conj(a[i*lda+j])
130 for i := 0; i < m; i++ {
133 for j := 0; j < n; j++ {
134 y[jy] += tmp * cmplx.Conj(a[i*lda+j])
143 // Zgerc performs the rank-one operation
144 // A += alpha * x * y^H
145 // where A is an m×n dense matrix, alpha is a scalar, x is an m element vector,
146 // and y is an n element vector.
147 func (Implementation) Zgerc(m, n int, alpha complex128, x []complex128, incX int, y []complex128, incY int, a []complex128, lda int) {
148 checkZMatrix('A', m, n, a, lda)
149 checkZVector('x', m, x, incX)
150 checkZVector('y', n, y, incY)
152 if m == 0 || n == 0 || alpha == 0 {
163 for j := 0; j < n; j++ {
165 tmp := alpha * cmplx.Conj(y[jy])
166 c128.AxpyInc(tmp, x, a[j:], uintptr(m), uintptr(incX), uintptr(lda), uintptr(kx), 0)
172 // Zgeru performs the rank-one operation
173 // A += alpha * x * y^T
174 // where A is an m×n dense matrix, alpha is a scalar, x is an m element vector,
175 // and y is an n element vector.
176 func (Implementation) Zgeru(m, n int, alpha complex128, x []complex128, incX int, y []complex128, incY int, a []complex128, lda int) {
177 checkZMatrix('A', m, n, a, lda)
178 checkZVector('x', m, x, incX)
179 checkZVector('y', n, y, incY)
181 if m == 0 || n == 0 || alpha == 0 {
190 for i := 0; i < m; i++ {
193 c128.AxpyUnitary(tmp, y[:n], a[i*lda:i*lda+n])
203 for i := 0; i < m; i++ {
206 c128.AxpyInc(tmp, y, a[i*lda:i*lda+n], uintptr(n), uintptr(incY), 1, uintptr(jy), 0)
212 // Zhemv performs the matrix-vector operation
213 // y = alpha * A * x + beta * y
214 // where alpha and beta are scalars, x and y are vectors, and A is an n×n
215 // Hermitian matrix. The imaginary parts of the diagonal elements of A are
216 // ignored and assumed to be zero.
217 func (Implementation) Zhemv(uplo blas.Uplo, n int, alpha complex128, a []complex128, lda int, x []complex128, incX int, beta complex128, y []complex128, incY int) {
218 if uplo != blas.Upper && uplo != blas.Lower {
221 checkZMatrix('A', n, n, a, lda)
222 checkZVector('x', n, x, incX)
223 checkZVector('y', n, y, incY)
225 if n == 0 || (alpha == 0 && beta == 1) {
229 // Set up the start indices in X and Y.
243 for i := range y[:n] {
247 for i, v := range y[:n] {
254 for i := 0; i < n; i++ {
259 for i := 0; i < n; i++ {
271 // The elements of A are accessed sequentially with one pass through
272 // the triangular part of A.
274 if uplo == blas.Upper {
275 // Form y when A is stored in upper triangle.
276 if incX == 1 && incY == 1 {
277 for i := 0; i < n; i++ {
280 for j := i + 1; j < n; j++ {
281 y[j] += tmp1 * cmplx.Conj(a[i*lda+j])
282 tmp2 += a[i*lda+j] * x[j]
284 aii := complex(real(a[i*lda+i]), 0)
285 y[i] += tmp1*aii + alpha*tmp2
290 for i := 0; i < n; i++ {
291 tmp1 := alpha * x[ix]
295 for j := i + 1; j < n; j++ {
298 y[jy] += tmp1 * cmplx.Conj(a[i*lda+j])
299 tmp2 += a[i*lda+j] * x[jx]
301 aii := complex(real(a[i*lda+i]), 0)
302 y[iy] += tmp1*aii + alpha*tmp2
310 // Form y when A is stored in lower triangle.
311 if incX == 1 && incY == 1 {
312 for i := 0; i < n; i++ {
315 for j := 0; j < i; j++ {
316 y[j] += tmp1 * cmplx.Conj(a[i*lda+j])
317 tmp2 += a[i*lda+j] * x[j]
319 aii := complex(real(a[i*lda+i]), 0)
320 y[i] += tmp1*aii + alpha*tmp2
325 for i := 0; i < n; i++ {
326 tmp1 := alpha * x[ix]
330 for j := 0; j < i; j++ {
331 y[jy] += tmp1 * cmplx.Conj(a[i*lda+j])
332 tmp2 += a[i*lda+j] * x[jx]
336 aii := complex(real(a[i*lda+i]), 0)
337 y[iy] += tmp1*aii + alpha*tmp2
344 // Zher performs the Hermitian rank-one operation
345 // A += alpha * x * x^H
346 // where A is an n×n Hermitian matrix, alpha is a real scalar, and x is an n
347 // element vector. On entry, the imaginary parts of the diagonal elements of A
348 // are ignored and assumed to be zero, on return they will be set to zero.
349 func (Implementation) Zher(uplo blas.Uplo, n int, alpha float64, x []complex128, incX int, a []complex128, lda int) {
350 if uplo != blas.Upper && uplo != blas.Lower {
353 checkZMatrix('A', n, n, a, lda)
354 checkZVector('x', n, x, incX)
356 if n == 0 || alpha == 0 {
364 if uplo == blas.Upper {
366 for i := 0; i < n; i++ {
368 tmp := complex(alpha*real(x[i]), alpha*imag(x[i]))
369 aii := real(a[i*lda+i])
370 xtmp := real(tmp * cmplx.Conj(x[i]))
371 a[i*lda+i] = complex(aii+xtmp, 0)
372 for j := i + 1; j < n; j++ {
373 a[i*lda+j] += tmp * cmplx.Conj(x[j])
376 aii := real(a[i*lda+i])
377 a[i*lda+i] = complex(aii, 0)
384 for i := 0; i < n; i++ {
386 tmp := complex(alpha*real(x[ix]), alpha*imag(x[ix]))
387 aii := real(a[i*lda+i])
388 xtmp := real(tmp * cmplx.Conj(x[ix]))
389 a[i*lda+i] = complex(aii+xtmp, 0)
391 for j := i + 1; j < n; j++ {
392 a[i*lda+j] += tmp * cmplx.Conj(x[jx])
396 aii := real(a[i*lda+i])
397 a[i*lda+i] = complex(aii, 0)
405 for i := 0; i < n; i++ {
407 tmp := complex(alpha*real(x[i]), alpha*imag(x[i]))
408 for j := 0; j < i; j++ {
409 a[i*lda+j] += tmp * cmplx.Conj(x[j])
411 aii := real(a[i*lda+i])
412 xtmp := real(tmp * cmplx.Conj(x[i]))
413 a[i*lda+i] = complex(aii+xtmp, 0)
415 aii := real(a[i*lda+i])
416 a[i*lda+i] = complex(aii, 0)
423 for i := 0; i < n; i++ {
425 tmp := complex(alpha*real(x[ix]), alpha*imag(x[ix]))
427 for j := 0; j < i; j++ {
428 a[i*lda+j] += tmp * cmplx.Conj(x[jx])
431 aii := real(a[i*lda+i])
432 xtmp := real(tmp * cmplx.Conj(x[ix]))
433 a[i*lda+i] = complex(aii+xtmp, 0)
436 aii := real(a[i*lda+i])
437 a[i*lda+i] = complex(aii, 0)
443 // Zher2 performs the Hermitian rank-two operation
444 // A += alpha*x*y^H + conj(alpha)*y*x^H
445 // where alpha is a scalar, x and y are n element vectors and A is an n×n
446 // Hermitian matrix. On entry, the imaginary parts of the diagonal elements are
447 // ignored and assumed to be zero. On return they will be set to zero.
448 func (Implementation) Zher2(uplo blas.Uplo, n int, alpha complex128, x []complex128, incX int, y []complex128, incY int, a []complex128, lda int) {
449 if uplo != blas.Upper && uplo != blas.Lower {
452 checkZMatrix('A', n, n, a, lda)
453 checkZVector('x', n, x, incX)
454 checkZVector('y', n, y, incY)
456 if n == 0 || alpha == 0 {
462 if incX != 1 || incY != 1 {
472 if uplo == blas.Upper {
473 if incX == 1 && incY == 1 {
474 for i := 0; i < n; i++ {
475 if x[i] != 0 || y[i] != 0 {
477 tmp2 := cmplx.Conj(alpha) * y[i]
478 aii := real(a[i*lda+i]) + real(tmp1*cmplx.Conj(y[i])) + real(tmp2*cmplx.Conj(x[i]))
479 a[i*lda+i] = complex(aii, 0)
480 for j := i + 1; j < n; j++ {
481 a[i*lda+j] += tmp1*cmplx.Conj(y[j]) + tmp2*cmplx.Conj(x[j])
484 aii := real(a[i*lda+i])
485 a[i*lda+i] = complex(aii, 0)
490 for i := 0; i < n; i++ {
491 if x[ix] != 0 || y[iy] != 0 {
492 tmp1 := alpha * x[ix]
493 tmp2 := cmplx.Conj(alpha) * y[iy]
494 aii := real(a[i*lda+i]) + real(tmp1*cmplx.Conj(y[iy])) + real(tmp2*cmplx.Conj(x[ix]))
495 a[i*lda+i] = complex(aii, 0)
498 for j := i + 1; j < n; j++ {
499 a[i*lda+j] += tmp1*cmplx.Conj(y[jy]) + tmp2*cmplx.Conj(x[jx])
504 aii := real(a[i*lda+i])
505 a[i*lda+i] = complex(aii, 0)
513 if incX == 1 && incY == 1 {
514 for i := 0; i < n; i++ {
515 if x[i] != 0 || y[i] != 0 {
517 tmp2 := cmplx.Conj(alpha) * y[i]
518 for j := 0; j < i; j++ {
519 a[i*lda+j] += tmp1*cmplx.Conj(y[j]) + tmp2*cmplx.Conj(x[j])
521 aii := real(a[i*lda+i]) + real(tmp1*cmplx.Conj(y[i])) + real(tmp2*cmplx.Conj(x[i]))
522 a[i*lda+i] = complex(aii, 0)
524 aii := real(a[i*lda+i])
525 a[i*lda+i] = complex(aii, 0)
530 for i := 0; i < n; i++ {
531 if x[ix] != 0 || y[iy] != 0 {
532 tmp1 := alpha * x[ix]
533 tmp2 := cmplx.Conj(alpha) * y[iy]
536 for j := 0; j < i; j++ {
537 a[i*lda+j] += tmp1*cmplx.Conj(y[jy]) + tmp2*cmplx.Conj(x[jx])
541 aii := real(a[i*lda+i]) + real(tmp1*cmplx.Conj(y[iy])) + real(tmp2*cmplx.Conj(x[ix]))
542 a[i*lda+i] = complex(aii, 0)
544 aii := real(a[i*lda+i])
545 a[i*lda+i] = complex(aii, 0)
552 // Zhpmv performs the matrix-vector operation
553 // y = alpha * A * x + beta * y
554 // where alpha and beta are scalars, x and y are vectors, and A is an n×n
555 // Hermitian matrix in packed form. The imaginary parts of the diagonal
556 // elements of A are ignored and assumed to be zero.
557 func (Implementation) Zhpmv(uplo blas.Uplo, n int, alpha complex128, ap []complex128, x []complex128, incX int, beta complex128, y []complex128, incY int) {
558 if uplo != blas.Upper && uplo != blas.Lower {
561 checkZVector('x', n, x, incX)
562 checkZVector('y', n, y, incY)
563 if len(ap) < n*(n+1)/2 {
564 panic("blas: insufficient A packed matrix slice length")
567 if n == 0 || (alpha == 0 && beta == 1) {
571 // Set up the start indices in X and Y.
585 for i := range y[:n] {
589 for i, v := range y[:n] {
596 for i := 0; i < n; i++ {
601 for i := 0; i < n; i++ {
613 // The elements of A are accessed sequentially with one pass through ap.
616 if uplo == blas.Upper {
617 // Form y when ap contains the upper triangle.
618 // Here, kk points to the current diagonal element in ap.
619 if incX == 1 && incY == 1 {
620 for i := 0; i < n; i++ {
622 y[i] += tmp1 * complex(real(ap[kk]), 0)
625 for j := i + 1; j < n; j++ {
626 y[j] += tmp1 * cmplx.Conj(ap[k])
636 for i := 0; i < n; i++ {
637 tmp1 := alpha * x[ix]
638 y[iy] += tmp1 * complex(real(ap[kk]), 0)
642 for k := kk + 1; k < kk+n-i; k++ {
645 y[jy] += tmp1 * cmplx.Conj(ap[k])
646 tmp2 += ap[k] * x[jx]
648 y[iy] += alpha * tmp2
657 // Form y when ap contains the lower triangle.
658 // Here, kk points to the beginning of current row in ap.
659 if incX == 1 && incY == 1 {
660 for i := 0; i < n; i++ {
664 for j := 0; j < i; j++ {
665 y[j] += tmp1 * cmplx.Conj(ap[k])
669 aii := complex(real(ap[kk+i]), 0)
670 y[i] += tmp1*aii + alpha*tmp2
676 for i := 0; i < n; i++ {
677 tmp1 := alpha * x[ix]
681 for k := kk; k < kk+i; k++ {
682 y[jy] += tmp1 * cmplx.Conj(ap[k])
683 tmp2 += ap[k] * x[jx]
687 aii := complex(real(ap[kk+i]), 0)
688 y[iy] += tmp1*aii + alpha*tmp2
696 // Zhpr performs the Hermitian rank-1 operation
697 // A += alpha * x * x^H,
698 // where alpha is a real scalar, x is a vector, and A is an n×n hermitian matrix
699 // in packed form. On entry, the imaginary parts of the diagonal elements are
700 // assumed to be zero, and on return they are set to zero.
701 func (Implementation) Zhpr(uplo blas.Uplo, n int, alpha float64, x []complex128, incX int, ap []complex128) {
702 if uplo != blas.Upper && uplo != blas.Lower {
708 checkZVector('x', n, x, incX)
709 if len(ap) < n*(n+1)/2 {
710 panic("blas: insufficient A packed matrix slice length")
713 if n == 0 || alpha == 0 {
717 // Set up start index in X.
723 // The elements of A are accessed sequentially with one pass through ap.
726 if uplo == blas.Upper {
727 // Form A when upper triangle is stored in AP.
728 // Here, kk points to the current diagonal element in ap.
730 for i := 0; i < n; i++ {
733 aii := real(ap[kk]) + alpha*real(cmplx.Conj(xi)*xi)
734 ap[kk] = complex(aii, 0)
736 tmp := complex(alpha, 0) * xi
737 a := ap[kk+1 : kk+n-i]
739 for j, v := range x {
740 a[j] += tmp * cmplx.Conj(v)
743 ap[kk] = complex(real(ap[kk]), 0)
749 for i := 0; i < n; i++ {
752 aii := real(ap[kk]) + alpha*real(cmplx.Conj(xi)*xi)
753 ap[kk] = complex(aii, 0)
755 tmp := complex(alpha, 0) * xi
757 a := ap[kk+1 : kk+n-i]
759 a[k] += tmp * cmplx.Conj(x[jx])
763 ap[kk] = complex(real(ap[kk]), 0)
772 // Form A when lower triangle is stored in AP.
773 // Here, kk points to the beginning of current row in ap.
775 for i := 0; i < n; i++ {
778 tmp := complex(alpha, 0) * xi
780 for j, v := range x[:i] {
781 a[j] += tmp * cmplx.Conj(v)
784 aii := real(ap[kk+i]) + alpha*real(cmplx.Conj(xi)*xi)
785 ap[kk+i] = complex(aii, 0)
787 ap[kk+i] = complex(real(ap[kk+i]), 0)
793 for i := 0; i < n; i++ {
796 tmp := complex(alpha, 0) * xi
800 a[k] += tmp * cmplx.Conj(x[jx])
804 aii := real(ap[kk+i]) + alpha*real(cmplx.Conj(xi)*xi)
805 ap[kk+i] = complex(aii, 0)
807 ap[kk+i] = complex(real(ap[kk+i]), 0)
815 // Zhpr2 performs the Hermitian rank-2 operation
816 // A += alpha*x*y^H + conj(alpha)*y*x^H,
817 // where alpha is a complex scalar, x and y are n element vectors, and A is an
818 // n×n Hermitian matrix, supplied in packed form. On entry, the imaginary parts
819 // of the diagonal elements are assumed to be zero, and on return they are set to zero.
820 func (Implementation) Zhpr2(uplo blas.Uplo, n int, alpha complex128, x []complex128, incX int, y []complex128, incY int, ap []complex128) {
821 if uplo != blas.Upper && uplo != blas.Lower {
827 checkZVector('x', n, x, incX)
828 checkZVector('y', n, y, incY)
829 if len(ap) < n*(n+1)/2 {
830 panic("blas: insufficient A packed matrix slice length")
833 if n == 0 || alpha == 0 {
837 // Set up start indices in X and Y.
847 // The elements of A are accessed sequentially with one pass through ap.
850 if uplo == blas.Upper {
851 // Form A when upper triangle is stored in AP.
852 // Here, kk points to the current diagonal element in ap.
853 if incX == 1 && incY == 1 {
854 for i := 0; i < n; i++ {
855 if x[i] != 0 || y[i] != 0 {
857 tmp2 := cmplx.Conj(alpha) * y[i]
858 aii := real(ap[kk]) + real(tmp1*cmplx.Conj(y[i])) + real(tmp2*cmplx.Conj(x[i]))
859 ap[kk] = complex(aii, 0)
861 for j := i + 1; j < n; j++ {
862 ap[k] += tmp1*cmplx.Conj(y[j]) + tmp2*cmplx.Conj(x[j])
866 ap[kk] = complex(real(ap[kk]), 0)
873 for i := 0; i < n; i++ {
874 if x[ix] != 0 || y[iy] != 0 {
875 tmp1 := alpha * x[ix]
876 tmp2 := cmplx.Conj(alpha) * y[iy]
877 aii := real(ap[kk]) + real(tmp1*cmplx.Conj(y[iy])) + real(tmp2*cmplx.Conj(x[ix]))
878 ap[kk] = complex(aii, 0)
881 for k := kk + 1; k < kk+n-i; k++ {
882 ap[k] += tmp1*cmplx.Conj(y[jy]) + tmp2*cmplx.Conj(x[jx])
887 ap[kk] = complex(real(ap[kk]), 0)
897 // Form A when lower triangle is stored in AP.
898 // Here, kk points to the beginning of current row in ap.
899 if incX == 1 && incY == 1 {
900 for i := 0; i < n; i++ {
901 if x[i] != 0 || y[i] != 0 {
903 tmp2 := cmplx.Conj(alpha) * y[i]
905 for j := 0; j < i; j++ {
906 ap[k] += tmp1*cmplx.Conj(y[j]) + tmp2*cmplx.Conj(x[j])
909 aii := real(ap[kk+i]) + real(tmp1*cmplx.Conj(y[i])) + real(tmp2*cmplx.Conj(x[i]))
910 ap[kk+i] = complex(aii, 0)
912 ap[kk+i] = complex(real(ap[kk+i]), 0)
919 for i := 0; i < n; i++ {
920 if x[ix] != 0 || y[iy] != 0 {
921 tmp1 := alpha * x[ix]
922 tmp2 := cmplx.Conj(alpha) * y[iy]
925 for k := kk; k < kk+i; k++ {
926 ap[k] += tmp1*cmplx.Conj(y[jy]) + tmp2*cmplx.Conj(x[jx])
930 aii := real(ap[kk+i]) + real(tmp1*cmplx.Conj(y[iy])) + real(tmp2*cmplx.Conj(x[ix]))
931 ap[kk+i] = complex(aii, 0)
933 ap[kk+i] = complex(real(ap[kk+i]), 0)
942 // Ztpmv performs one of the matrix-vector operations
943 // x = A * x if trans = blas.NoTrans
944 // x = A^T * x if trans = blas.Trans
945 // x = A^H * x if trans = blas.ConjTrans
946 // where x is an n element vector and A is an n×n triangular matrix, supplied in
948 func (Implementation) Ztpmv(uplo blas.Uplo, trans blas.Transpose, diag blas.Diag, n int, ap []complex128, x []complex128, incX int) {
949 if uplo != blas.Upper && uplo != blas.Lower {
952 if trans != blas.NoTrans && trans != blas.Trans && trans != blas.ConjTrans {
955 if diag != blas.Unit && diag != blas.NonUnit {
958 checkZVector('x', n, x, incX)
959 if len(ap) < n*(n+1)/2 {
960 panic("blas: insufficient A packed matrix slice length")
967 // Set up start index in X.
973 // The elements of A are accessed sequentially with one pass through A.
975 if trans == blas.NoTrans {
977 if uplo == blas.Upper {
978 // kk points to the current diagonal element in ap.
983 if diag == blas.NonUnit {
987 x[i] += c128.DotuUnitary(ap[kk+1:kk+n-i], x[i+1:])
993 for i := 0; i < n; i++ {
994 if diag == blas.NonUnit {
998 x[ix] += c128.DotuInc(ap[kk+1:kk+n-i], x, uintptr(n-i-1), 1, uintptr(incX), 0, uintptr(ix+incX))
1005 // kk points to the beginning of current row in ap.
1008 for i := n - 1; i >= 0; i-- {
1009 if diag == blas.NonUnit {
1013 x[i] += c128.DotuUnitary(ap[kk:kk+i], x[:i])
1018 ix := kx + (n-1)*incX
1019 for i := n - 1; i >= 0; i-- {
1020 if diag == blas.NonUnit {
1024 x[ix] += c128.DotuInc(ap[kk:kk+i], x, uintptr(i), 1, uintptr(incX), 0, uintptr(kx))
1034 if trans == blas.Trans {
1036 if uplo == blas.Upper {
1037 // kk points to the current diagonal element in ap.
1040 for i := n - 1; i >= 0; i-- {
1042 if diag == blas.NonUnit {
1046 c128.AxpyUnitary(xi, ap[kk+1:kk+n-i], x[i+1:n])
1051 ix := kx + (n-1)*incX
1052 for i := n - 1; i >= 0; i-- {
1054 if diag == blas.NonUnit {
1058 c128.AxpyInc(xi, ap[kk+1:kk+n-i], x, uintptr(n-i-1), 1, uintptr(incX), 0, uintptr(ix+incX))
1065 // kk points to the beginning of current row in ap.
1071 c128.AxpyUnitary(x[i], ap[kk:kk+i], x[:i])
1073 if diag == blas.NonUnit {
1080 for i := 0; i < n; i++ {
1082 c128.AxpyInc(x[ix], ap[kk:kk+i], x, uintptr(i), 1, uintptr(incX), 0, uintptr(kx))
1084 if diag == blas.NonUnit {
1096 if uplo == blas.Upper {
1097 // kk points to the current diagonal element in ap.
1100 for i := n - 1; i >= 0; i-- {
1102 if diag == blas.NonUnit {
1103 x[i] *= cmplx.Conj(ap[kk])
1106 for j := i + 1; j < n; j++ {
1107 x[j] += xi * cmplx.Conj(ap[k])
1113 ix := kx + (n-1)*incX
1114 for i := n - 1; i >= 0; i-- {
1116 if diag == blas.NonUnit {
1117 x[ix] *= cmplx.Conj(ap[kk])
1121 for j := i + 1; j < n; j++ {
1122 x[jx] += xi * cmplx.Conj(ap[k])
1131 // kk points to the beginning of current row in ap.
1135 for i, xi := range x {
1136 for j := 0; j < i; j++ {
1137 x[j] += xi * cmplx.Conj(ap[kk+j])
1139 if diag == blas.NonUnit {
1140 x[i] *= cmplx.Conj(ap[kk+i])
1146 for i := 0; i < n; i++ {
1149 for j := 0; j < i; j++ {
1150 x[jx] += xi * cmplx.Conj(ap[kk+j])
1153 if diag == blas.NonUnit {
1154 x[ix] *= cmplx.Conj(ap[kk+i])
1163 // Ztrmv performs one of the matrix-vector operations
1164 // x = A * x if trans = blas.NoTrans
1165 // x = A^T * x if trans = blas.Trans
1166 // x = A^H * x if trans = blas.ConjTrans
1167 // where x is a vector, and A is an n×n triangular matrix.
1168 func (Implementation) Ztrmv(uplo blas.Uplo, trans blas.Transpose, diag blas.Diag, n int, a []complex128, lda int, x []complex128, incX int) {
1169 if uplo != blas.Upper && uplo != blas.Lower {
1172 if trans != blas.NoTrans && trans != blas.Trans && trans != blas.ConjTrans {
1175 if diag != blas.Unit && diag != blas.NonUnit {
1178 checkZMatrix('A', n, n, a, lda)
1179 checkZVector('x', n, x, incX)
1185 // Set up start index in X.
1191 // The elements of A are accessed sequentially with one pass through A.
1193 if trans == blas.NoTrans {
1195 if uplo == blas.Upper {
1197 for i := 0; i < n; i++ {
1198 if diag == blas.NonUnit {
1202 x[i] += c128.DotuUnitary(a[i*lda+i+1:i*lda+n], x[i+1:n])
1207 for i := 0; i < n; i++ {
1208 if diag == blas.NonUnit {
1212 x[ix] += c128.DotuInc(a[i*lda+i+1:i*lda+n], x, uintptr(n-i-1), 1, uintptr(incX), 0, uintptr(ix+incX))
1219 for i := n - 1; i >= 0; i-- {
1220 if diag == blas.NonUnit {
1224 x[i] += c128.DotuUnitary(a[i*lda:i*lda+i], x[:i])
1228 ix := kx + (n-1)*incX
1229 for i := n - 1; i >= 0; i-- {
1230 if diag == blas.NonUnit {
1234 x[ix] += c128.DotuInc(a[i*lda:i*lda+i], x, uintptr(i), 1, uintptr(incX), 0, uintptr(kx))
1243 if trans == blas.Trans {
1245 if uplo == blas.Upper {
1247 for i := n - 1; i >= 0; i-- {
1249 if diag == blas.NonUnit {
1253 c128.AxpyUnitary(xi, a[i*lda+i+1:i*lda+n], x[i+1:n])
1257 ix := kx + (n-1)*incX
1258 for i := n - 1; i >= 0; i-- {
1260 if diag == blas.NonUnit {
1264 c128.AxpyInc(xi, a[i*lda+i+1:i*lda+n], x, uintptr(n-i-1), 1, uintptr(incX), 0, uintptr(ix+incX))
1271 for i := 0; i < n; i++ {
1273 c128.AxpyUnitary(x[i], a[i*lda:i*lda+i], x[:i])
1275 if diag == blas.NonUnit {
1281 for i := 0; i < n; i++ {
1283 c128.AxpyInc(x[ix], a[i*lda:i*lda+i], x, uintptr(i), 1, uintptr(incX), 0, uintptr(kx))
1285 if diag == blas.NonUnit {
1296 if uplo == blas.Upper {
1298 for i := n - 1; i >= 0; i-- {
1300 if diag == blas.NonUnit {
1301 x[i] *= cmplx.Conj(a[i*lda+i])
1303 for j := i + 1; j < n; j++ {
1304 x[j] += xi * cmplx.Conj(a[i*lda+j])
1308 ix := kx + (n-1)*incX
1309 for i := n - 1; i >= 0; i-- {
1311 if diag == blas.NonUnit {
1312 x[ix] *= cmplx.Conj(a[i*lda+i])
1315 for j := i + 1; j < n; j++ {
1316 x[jx] += xi * cmplx.Conj(a[i*lda+j])
1324 for i := 0; i < n; i++ {
1325 for j := 0; j < i; j++ {
1326 x[j] += x[i] * cmplx.Conj(a[i*lda+j])
1328 if diag == blas.NonUnit {
1329 x[i] *= cmplx.Conj(a[i*lda+i])
1334 for i := 0; i < n; i++ {
1336 for j := 0; j < i; j++ {
1337 x[jx] += x[ix] * cmplx.Conj(a[i*lda+j])
1340 if diag == blas.NonUnit {
1341 x[ix] *= cmplx.Conj(a[i*lda+i])
1349 // Ztrsv solves one of the systems of equations
1350 // A*x = b if trans == blas.NoTrans,
1351 // A^T*x = b, if trans == blas.Trans,
1352 // A^H*x = b, if trans == blas.ConjTrans,
1353 // where b and x are n element vectors and A is an n×n triangular matrix.
1355 // On entry, x contains the values of b, and the solution is
1356 // stored in-place into x.
1358 // No test for singularity or near-singularity is included in this
1359 // routine. Such tests must be performed before calling this routine.
1360 func (Implementation) Ztrsv(uplo blas.Uplo, trans blas.Transpose, diag blas.Diag, n int, a []complex128, lda int, x []complex128, incX int) {
1361 if uplo != blas.Upper && uplo != blas.Lower {
1364 if trans != blas.NoTrans && trans != blas.Trans && trans != blas.ConjTrans {
1367 if diag != blas.Unit && diag != blas.NonUnit {
1370 checkZMatrix('A', n, n, a, lda)
1371 checkZVector('x', n, x, incX)
1377 // Set up start index in X.
1383 // The elements of A are accessed sequentially with one pass through A.
1385 if trans == blas.NoTrans {
1386 // Form x = inv(A)*x.
1387 if uplo == blas.Upper {
1389 for i := n - 1; i >= 0; i-- {
1392 x[i] -= c128.DotuUnitary(x[i+1:n], a[i*lda+i+1:i*lda+n])
1394 if diag == blas.NonUnit {
1399 ix := kx + (n-1)*incX
1400 for i := n - 1; i >= 0; i-- {
1403 x[ix] -= c128.DotuInc(x, a[i*lda+i+1:i*lda+n], uintptr(n-i-1), uintptr(incX), 1, uintptr(ix+incX), 0)
1405 if diag == blas.NonUnit {
1413 for i := 0; i < n; i++ {
1415 x[i] -= c128.DotuUnitary(x[:i], a[i*lda:i*lda+i])
1417 if diag == blas.NonUnit {
1423 for i := 0; i < n; i++ {
1425 x[ix] -= c128.DotuInc(x, a[i*lda:i*lda+i], uintptr(i), uintptr(incX), 1, uintptr(kx), 0)
1427 if diag == blas.NonUnit {
1437 if trans == blas.Trans {
1438 // Form x = inv(A^T)*x.
1439 if uplo == blas.Upper {
1441 for j := 0; j < n; j++ {
1442 if diag == blas.NonUnit {
1446 c128.AxpyUnitary(-x[j], a[j*lda+j+1:j*lda+n], x[j+1:n])
1451 for j := 0; j < n; j++ {
1452 if diag == blas.NonUnit {
1456 c128.AxpyInc(-x[jx], a[j*lda+j+1:j*lda+n], x, uintptr(n-j-1), 1, uintptr(incX), 0, uintptr(jx+incX))
1463 for j := n - 1; j >= 0; j-- {
1464 if diag == blas.NonUnit {
1469 c128.AxpyUnitary(-xj, a[j*lda:j*lda+j], x[:j])
1473 jx := kx + (n-1)*incX
1474 for j := n - 1; j >= 0; j-- {
1475 if diag == blas.NonUnit {
1479 c128.AxpyInc(-x[jx], a[j*lda:j*lda+j], x, uintptr(j), 1, uintptr(incX), 0, uintptr(kx))
1488 // Form x = inv(A^H)*x.
1489 if uplo == blas.Upper {
1491 for j := 0; j < n; j++ {
1492 if diag == blas.NonUnit {
1493 x[j] /= cmplx.Conj(a[j*lda+j])
1496 for i := j + 1; i < n; i++ {
1497 x[i] -= xj * cmplx.Conj(a[j*lda+i])
1502 for j := 0; j < n; j++ {
1503 if diag == blas.NonUnit {
1504 x[jx] /= cmplx.Conj(a[j*lda+j])
1508 for i := j + 1; i < n; i++ {
1509 x[ix] -= xj * cmplx.Conj(a[j*lda+i])
1517 for j := n - 1; j >= 0; j-- {
1518 if diag == blas.NonUnit {
1519 x[j] /= cmplx.Conj(a[j*lda+j])
1522 for i := 0; i < j; i++ {
1523 x[i] -= xj * cmplx.Conj(a[j*lda+i])
1527 jx := kx + (n-1)*incX
1528 for j := n - 1; j >= 0; j-- {
1529 if diag == blas.NonUnit {
1530 x[jx] /= cmplx.Conj(a[j*lda+j])
1534 for i := 0; i < j; i++ {
1535 x[ix] -= xj * cmplx.Conj(a[j*lda+i])