gonum.org/v1/gonum@v0.14.0/blas/gonum/level2cmplx128.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  package gonum
     6  
     7  import (
     8  	"math/cmplx"
     9  
    10  	"gonum.org/v1/gonum/blas"
    11  	"gonum.org/v1/gonum/internal/asm/c128"
    12  )
    13  
    14  var _ blas.Complex128Level2 = Implementation{}
    15  
    16  // Zgbmv performs one of the matrix-vector operations
    17  //
    18  //	y = alpha * A * x + beta * y   if trans = blas.NoTrans
    19  //	y = alpha * Aᵀ * x + beta * y  if trans = blas.Trans
    20  //	y = alpha * Aᴴ * x + beta * y  if trans = blas.ConjTrans
    21  //
    22  // where alpha and beta are scalars, x and y are vectors, and A is an m×n band matrix
    23  // with kL sub-diagonals and kU super-diagonals.
    24  func (Implementation) Zgbmv(trans blas.Transpose, m, n, kL, kU int, alpha complex128, a []complex128, lda int, x []complex128, incX int, beta complex128, y []complex128, incY int) {
    25  	switch trans {
    26  	default:
    27  		panic(badTranspose)
    28  	case blas.NoTrans, blas.Trans, blas.ConjTrans:
    29  	}
    30  	if m < 0 {
    31  		panic(mLT0)
    32  	}
    33  	if n < 0 {
    34  		panic(nLT0)
    35  	}
    36  	if kL < 0 {
    37  		panic(kLLT0)
    38  	}
    39  	if kU < 0 {
    40  		panic(kULT0)
    41  	}
    42  	if lda < kL+kU+1 {
    43  		panic(badLdA)
    44  	}
    45  	if incX == 0 {
    46  		panic(zeroIncX)
    47  	}
    48  	if incY == 0 {
    49  		panic(zeroIncY)
    50  	}
    51  
    52  	// Quick return if possible.
    53  	if m == 0 || n == 0 {
    54  		return
    55  	}
    56  
    57  	// For zero matrix size the following slice length checks are trivially satisfied.
    58  	if len(a) < lda*(min(m, n+kL)-1)+kL+kU+1 {
    59  		panic(shortA)
    60  	}
    61  	var lenX, lenY int
    62  	if trans == blas.NoTrans {
    63  		lenX, lenY = n, m
    64  	} else {
    65  		lenX, lenY = m, n
    66  	}
    67  	if (incX > 0 && len(x) <= (lenX-1)*incX) || (incX < 0 && len(x) <= (1-lenX)*incX) {
    68  		panic(shortX)
    69  	}
    70  	if (incY > 0 && len(y) <= (lenY-1)*incY) || (incY < 0 && len(y) <= (1-lenY)*incY) {
    71  		panic(shortY)
    72  	}
    73  
    74  	// Quick return if possible.
    75  	if alpha == 0 && beta == 1 {
    76  		return
    77  	}
    78  
    79  	var kx int
    80  	if incX < 0 {
    81  		kx = (1 - lenX) * incX
    82  	}
    83  	var ky int
    84  	if incY < 0 {
    85  		ky = (1 - lenY) * incY
    86  	}
    87  
    88  	// Form y = beta*y.
    89  	if beta != 1 {
    90  		if incY == 1 {
    91  			if beta == 0 {
    92  				for i := range y[:lenY] {
    93  					y[i] = 0
    94  				}
    95  			} else {
    96  				c128.ScalUnitary(beta, y[:lenY])
    97  			}
    98  		} else {
    99  			iy := ky
   100  			if beta == 0 {
   101  				for i := 0; i < lenY; i++ {
   102  					y[iy] = 0
   103  					iy += incY
   104  				}
   105  			} else {
   106  				if incY > 0 {
   107  					c128.ScalInc(beta, y, uintptr(lenY), uintptr(incY))
   108  				} else {
   109  					c128.ScalInc(beta, y, uintptr(lenY), uintptr(-incY))
   110  				}
   111  			}
   112  		}
   113  	}
   114  
   115  	nRow := min(m, n+kL)
   116  	nCol := kL + 1 + kU
   117  	switch trans {
   118  	case blas.NoTrans:
   119  		iy := ky
   120  		if incX == 1 {
   121  			for i := 0; i < nRow; i++ {
   122  				l := max(0, kL-i)
   123  				u := min(nCol, n+kL-i)
   124  				aRow := a[i*lda+l : i*lda+u]
   125  				off := max(0, i-kL)
   126  				xtmp := x[off : off+u-l]
   127  				var sum complex128
   128  				for j, v := range aRow {
   129  					sum += xtmp[j] * v
   130  				}
   131  				y[iy] += alpha * sum
   132  				iy += incY
   133  			}
   134  		} else {
   135  			for i := 0; i < nRow; i++ {
   136  				l := max(0, kL-i)
   137  				u := min(nCol, n+kL-i)
   138  				aRow := a[i*lda+l : i*lda+u]
   139  				off := max(0, i-kL) * incX
   140  				jx := kx
   141  				var sum complex128
   142  				for _, v := range aRow {
   143  					sum += x[off+jx] * v
   144  					jx += incX
   145  				}
   146  				y[iy] += alpha * sum
   147  				iy += incY
   148  			}
   149  		}
   150  	case blas.Trans:
   151  		if incX == 1 {
   152  			for i := 0; i < nRow; i++ {
   153  				l := max(0, kL-i)
   154  				u := min(nCol, n+kL-i)
   155  				aRow := a[i*lda+l : i*lda+u]
   156  				off := max(0, i-kL) * incY
   157  				alphaxi := alpha * x[i]
   158  				jy := ky
   159  				for _, v := range aRow {
   160  					y[off+jy] += alphaxi * v
   161  					jy += incY
   162  				}
   163  			}
   164  		} else {
   165  			ix := kx
   166  			for i := 0; i < nRow; i++ {
   167  				l := max(0, kL-i)
   168  				u := min(nCol, n+kL-i)
   169  				aRow := a[i*lda+l : i*lda+u]
   170  				off := max(0, i-kL) * incY
   171  				alphaxi := alpha * x[ix]
   172  				jy := ky
   173  				for _, v := range aRow {
   174  					y[off+jy] += alphaxi * v
   175  					jy += incY
   176  				}
   177  				ix += incX
   178  			}
   179  		}
   180  	case blas.ConjTrans:
   181  		if incX == 1 {
   182  			for i := 0; i < nRow; i++ {
   183  				l := max(0, kL-i)
   184  				u := min(nCol, n+kL-i)
   185  				aRow := a[i*lda+l : i*lda+u]
   186  				off := max(0, i-kL) * incY
   187  				alphaxi := alpha * x[i]
   188  				jy := ky
   189  				for _, v := range aRow {
   190  					y[off+jy] += alphaxi * cmplx.Conj(v)
   191  					jy += incY
   192  				}
   193  			}
   194  		} else {
   195  			ix := kx
   196  			for i := 0; i < nRow; i++ {
   197  				l := max(0, kL-i)
   198  				u := min(nCol, n+kL-i)
   199  				aRow := a[i*lda+l : i*lda+u]
   200  				off := max(0, i-kL) * incY
   201  				alphaxi := alpha * x[ix]
   202  				jy := ky
   203  				for _, v := range aRow {
   204  					y[off+jy] += alphaxi * cmplx.Conj(v)
   205  					jy += incY
   206  				}
   207  				ix += incX
   208  			}
   209  		}
   210  	}
   211  }
   212  
   213  // Zgemv performs one of the matrix-vector operations
   214  //
   215  //	y = alpha * A * x + beta * y   if trans = blas.NoTrans
   216  //	y = alpha * Aᵀ * x + beta * y  if trans = blas.Trans
   217  //	y = alpha * Aᴴ * x + beta * y  if trans = blas.ConjTrans
   218  //
   219  // where alpha and beta are scalars, x and y are vectors, and A is an m×n dense matrix.
   220  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) {
   221  	switch trans {
   222  	default:
   223  		panic(badTranspose)
   224  	case blas.NoTrans, blas.Trans, blas.ConjTrans:
   225  	}
   226  	if m < 0 {
   227  		panic(mLT0)
   228  	}
   229  	if n < 0 {
   230  		panic(nLT0)
   231  	}
   232  	if lda < max(1, n) {
   233  		panic(badLdA)
   234  	}
   235  	if incX == 0 {
   236  		panic(zeroIncX)
   237  	}
   238  	if incY == 0 {
   239  		panic(zeroIncY)
   240  	}
   241  
   242  	// Quick return if possible.
   243  	if m == 0 || n == 0 {
   244  		return
   245  	}
   246  
   247  	// For zero matrix size the following slice length checks are trivially satisfied.
   248  	var lenX, lenY int
   249  	if trans == blas.NoTrans {
   250  		lenX = n
   251  		lenY = m
   252  	} else {
   253  		lenX = m
   254  		lenY = n
   255  	}
   256  	if len(a) < lda*(m-1)+n {
   257  		panic(shortA)
   258  	}
   259  	if (incX > 0 && len(x) <= (lenX-1)*incX) || (incX < 0 && len(x) <= (1-lenX)*incX) {
   260  		panic(shortX)
   261  	}
   262  	if (incY > 0 && len(y) <= (lenY-1)*incY) || (incY < 0 && len(y) <= (1-lenY)*incY) {
   263  		panic(shortY)
   264  	}
   265  
   266  	// Quick return if possible.
   267  	if alpha == 0 && beta == 1 {
   268  		return
   269  	}
   270  
   271  	var kx int
   272  	if incX < 0 {
   273  		kx = (1 - lenX) * incX
   274  	}
   275  	var ky int
   276  	if incY < 0 {
   277  		ky = (1 - lenY) * incY
   278  	}
   279  
   280  	// Form y = beta*y.
   281  	if beta != 1 {
   282  		if incY == 1 {
   283  			if beta == 0 {
   284  				for i := range y[:lenY] {
   285  					y[i] = 0
   286  				}
   287  			} else {
   288  				c128.ScalUnitary(beta, y[:lenY])
   289  			}
   290  		} else {
   291  			iy := ky
   292  			if beta == 0 {
   293  				for i := 0; i < lenY; i++ {
   294  					y[iy] = 0
   295  					iy += incY
   296  				}
   297  			} else {
   298  				if incY > 0 {
   299  					c128.ScalInc(beta, y, uintptr(lenY), uintptr(incY))
   300  				} else {
   301  					c128.ScalInc(beta, y, uintptr(lenY), uintptr(-incY))
   302  				}
   303  			}
   304  		}
   305  	}
   306  
   307  	if alpha == 0 {
   308  		return
   309  	}
   310  
   311  	switch trans {
   312  	default:
   313  		// Form y = alpha*A*x + y.
   314  		iy := ky
   315  		if incX == 1 {
   316  			for i := 0; i < m; i++ {
   317  				y[iy] += alpha * c128.DotuUnitary(a[i*lda:i*lda+n], x[:n])
   318  				iy += incY
   319  			}
   320  			return
   321  		}
   322  		for i := 0; i < m; i++ {
   323  			y[iy] += alpha * c128.DotuInc(a[i*lda:i*lda+n], x, uintptr(n), 1, uintptr(incX), 0, uintptr(kx))
   324  			iy += incY
   325  		}
   326  		return
   327  
   328  	case blas.Trans:
   329  		// Form y = alpha*Aᵀ*x + y.
   330  		ix := kx
   331  		if incY == 1 {
   332  			for i := 0; i < m; i++ {
   333  				c128.AxpyUnitary(alpha*x[ix], a[i*lda:i*lda+n], y[:n])
   334  				ix += incX
   335  			}
   336  			return
   337  		}
   338  		for i := 0; i < m; i++ {
   339  			c128.AxpyInc(alpha*x[ix], a[i*lda:i*lda+n], y, uintptr(n), 1, uintptr(incY), 0, uintptr(ky))
   340  			ix += incX
   341  		}
   342  		return
   343  
   344  	case blas.ConjTrans:
   345  		// Form y = alpha*Aᴴ*x + y.
   346  		ix := kx
   347  		if incY == 1 {
   348  			for i := 0; i < m; i++ {
   349  				tmp := alpha * x[ix]
   350  				for j := 0; j < n; j++ {
   351  					y[j] += tmp * cmplx.Conj(a[i*lda+j])
   352  				}
   353  				ix += incX
   354  			}
   355  			return
   356  		}
   357  		for i := 0; i < m; i++ {
   358  			tmp := alpha * x[ix]
   359  			jy := ky
   360  			for j := 0; j < n; j++ {
   361  				y[jy] += tmp * cmplx.Conj(a[i*lda+j])
   362  				jy += incY
   363  			}
   364  			ix += incX
   365  		}
   366  		return
   367  	}
   368  }
   369  
   370  // Zgerc performs the rank-one operation
   371  //
   372  //	A += alpha * x * yᴴ
   373  //
   374  // where A is an m×n dense matrix, alpha is a scalar, x is an m element vector,
   375  // and y is an n element vector.
   376  func (Implementation) Zgerc(m, n int, alpha complex128, x []complex128, incX int, y []complex128, incY int, a []complex128, lda int) {
   377  	if m < 0 {
   378  		panic(mLT0)
   379  	}
   380  	if n < 0 {
   381  		panic(nLT0)
   382  	}
   383  	if lda < max(1, n) {
   384  		panic(badLdA)
   385  	}
   386  	if incX == 0 {
   387  		panic(zeroIncX)
   388  	}
   389  	if incY == 0 {
   390  		panic(zeroIncY)
   391  	}
   392  
   393  	// Quick return if possible.
   394  	if m == 0 || n == 0 {
   395  		return
   396  	}
   397  
   398  	// For zero matrix size the following slice length checks are trivially satisfied.
   399  	if (incX > 0 && len(x) <= (m-1)*incX) || (incX < 0 && len(x) <= (1-m)*incX) {
   400  		panic(shortX)
   401  	}
   402  	if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
   403  		panic(shortY)
   404  	}
   405  	if len(a) < lda*(m-1)+n {
   406  		panic(shortA)
   407  	}
   408  
   409  	// Quick return if possible.
   410  	if alpha == 0 {
   411  		return
   412  	}
   413  
   414  	var kx, jy int
   415  	if incX < 0 {
   416  		kx = (1 - m) * incX
   417  	}
   418  	if incY < 0 {
   419  		jy = (1 - n) * incY
   420  	}
   421  	for j := 0; j < n; j++ {
   422  		if y[jy] != 0 {
   423  			tmp := alpha * cmplx.Conj(y[jy])
   424  			c128.AxpyInc(tmp, x, a[j:], uintptr(m), uintptr(incX), uintptr(lda), uintptr(kx), 0)
   425  		}
   426  		jy += incY
   427  	}
   428  }
   429  
   430  // Zgeru performs the rank-one operation
   431  //
   432  //	A += alpha * x * yᵀ
   433  //
   434  // where A is an m×n dense matrix, alpha is a scalar, x is an m element vector,
   435  // and y is an n element vector.
   436  func (Implementation) Zgeru(m, n int, alpha complex128, x []complex128, incX int, y []complex128, incY int, a []complex128, lda int) {
   437  	if m < 0 {
   438  		panic(mLT0)
   439  	}
   440  	if n < 0 {
   441  		panic(nLT0)
   442  	}
   443  	if lda < max(1, n) {
   444  		panic(badLdA)
   445  	}
   446  	if incX == 0 {
   447  		panic(zeroIncX)
   448  	}
   449  	if incY == 0 {
   450  		panic(zeroIncY)
   451  	}
   452  
   453  	// Quick return if possible.
   454  	if m == 0 || n == 0 {
   455  		return
   456  	}
   457  
   458  	// For zero matrix size the following slice length checks are trivially satisfied.
   459  	if (incX > 0 && len(x) <= (m-1)*incX) || (incX < 0 && len(x) <= (1-m)*incX) {
   460  		panic(shortX)
   461  	}
   462  	if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
   463  		panic(shortY)
   464  	}
   465  	if len(a) < lda*(m-1)+n {
   466  		panic(shortA)
   467  	}
   468  
   469  	// Quick return if possible.
   470  	if alpha == 0 {
   471  		return
   472  	}
   473  
   474  	var kx int
   475  	if incX < 0 {
   476  		kx = (1 - m) * incX
   477  	}
   478  	if incY == 1 {
   479  		for i := 0; i < m; i++ {
   480  			if x[kx] != 0 {
   481  				tmp := alpha * x[kx]
   482  				c128.AxpyUnitary(tmp, y[:n], a[i*lda:i*lda+n])
   483  			}
   484  			kx += incX
   485  		}
   486  		return
   487  	}
   488  	var jy int
   489  	if incY < 0 {
   490  		jy = (1 - n) * incY
   491  	}
   492  	for i := 0; i < m; i++ {
   493  		if x[kx] != 0 {
   494  			tmp := alpha * x[kx]
   495  			c128.AxpyInc(tmp, y, a[i*lda:i*lda+n], uintptr(n), uintptr(incY), 1, uintptr(jy), 0)
   496  		}
   497  		kx += incX
   498  	}
   499  }
   500  
   501  // Zhbmv performs the matrix-vector operation
   502  //
   503  //	y = alpha * A * x + beta * y
   504  //
   505  // where alpha and beta are scalars, x and y are vectors, and A is an n×n
   506  // Hermitian band matrix with k super-diagonals. The imaginary parts of
   507  // the diagonal elements of A are ignored and assumed to be zero.
   508  func (Implementation) Zhbmv(uplo blas.Uplo, n, k int, alpha complex128, a []complex128, lda int, x []complex128, incX int, beta complex128, y []complex128, incY int) {
   509  	switch uplo {
   510  	default:
   511  		panic(badUplo)
   512  	case blas.Upper, blas.Lower:
   513  	}
   514  	if n < 0 {
   515  		panic(nLT0)
   516  	}
   517  	if k < 0 {
   518  		panic(kLT0)
   519  	}
   520  	if lda < k+1 {
   521  		panic(badLdA)
   522  	}
   523  	if incX == 0 {
   524  		panic(zeroIncX)
   525  	}
   526  	if incY == 0 {
   527  		panic(zeroIncY)
   528  	}
   529  
   530  	// Quick return if possible.
   531  	if n == 0 {
   532  		return
   533  	}
   534  
   535  	// For zero matrix size the following slice length checks are trivially satisfied.
   536  	if len(a) < lda*(n-1)+k+1 {
   537  		panic(shortA)
   538  	}
   539  	if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
   540  		panic(shortX)
   541  	}
   542  	if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
   543  		panic(shortY)
   544  	}
   545  
   546  	// Quick return if possible.
   547  	if alpha == 0 && beta == 1 {
   548  		return
   549  	}
   550  
   551  	// Set up the start indices in X and Y.
   552  	var kx int
   553  	if incX < 0 {
   554  		kx = (1 - n) * incX
   555  	}
   556  	var ky int
   557  	if incY < 0 {
   558  		ky = (1 - n) * incY
   559  	}
   560  
   561  	// Form y = beta*y.
   562  	if beta != 1 {
   563  		if incY == 1 {
   564  			if beta == 0 {
   565  				for i := range y[:n] {
   566  					y[i] = 0
   567  				}
   568  			} else {
   569  				for i, v := range y[:n] {
   570  					y[i] = beta * v
   571  				}
   572  			}
   573  		} else {
   574  			iy := ky
   575  			if beta == 0 {
   576  				for i := 0; i < n; i++ {
   577  					y[iy] = 0
   578  					iy += incY
   579  				}
   580  			} else {
   581  				for i := 0; i < n; i++ {
   582  					y[iy] = beta * y[iy]
   583  					iy += incY
   584  				}
   585  			}
   586  		}
   587  	}
   588  
   589  	if alpha == 0 {
   590  		return
   591  	}
   592  
   593  	// The elements of A are accessed sequentially with one pass through a.
   594  	switch uplo {
   595  	case blas.Upper:
   596  		iy := ky
   597  		if incX == 1 {
   598  			for i := 0; i < n; i++ {
   599  				aRow := a[i*lda:]
   600  				alphaxi := alpha * x[i]
   601  				sum := alphaxi * complex(real(aRow[0]), 0)
   602  				u := min(k+1, n-i)
   603  				jy := incY
   604  				for j := 1; j < u; j++ {
   605  					v := aRow[j]
   606  					sum += alpha * x[i+j] * v
   607  					y[iy+jy] += alphaxi * cmplx.Conj(v)
   608  					jy += incY
   609  				}
   610  				y[iy] += sum
   611  				iy += incY
   612  			}
   613  		} else {
   614  			ix := kx
   615  			for i := 0; i < n; i++ {
   616  				aRow := a[i*lda:]
   617  				alphaxi := alpha * x[ix]
   618  				sum := alphaxi * complex(real(aRow[0]), 0)
   619  				u := min(k+1, n-i)
   620  				jx := incX
   621  				jy := incY
   622  				for j := 1; j < u; j++ {
   623  					v := aRow[j]
   624  					sum += alpha * x[ix+jx] * v
   625  					y[iy+jy] += alphaxi * cmplx.Conj(v)
   626  					jx += incX
   627  					jy += incY
   628  				}
   629  				y[iy] += sum
   630  				ix += incX
   631  				iy += incY
   632  			}
   633  		}
   634  	case blas.Lower:
   635  		iy := ky
   636  		if incX == 1 {
   637  			for i := 0; i < n; i++ {
   638  				l := max(0, k-i)
   639  				alphaxi := alpha * x[i]
   640  				jy := l * incY
   641  				aRow := a[i*lda:]
   642  				for j := l; j < k; j++ {
   643  					v := aRow[j]
   644  					y[iy] += alpha * v * x[i-k+j]
   645  					y[iy-k*incY+jy] += alphaxi * cmplx.Conj(v)
   646  					jy += incY
   647  				}
   648  				y[iy] += alphaxi * complex(real(aRow[k]), 0)
   649  				iy += incY
   650  			}
   651  		} else {
   652  			ix := kx
   653  			for i := 0; i < n; i++ {
   654  				l := max(0, k-i)
   655  				alphaxi := alpha * x[ix]
   656  				jx := l * incX
   657  				jy := l * incY
   658  				aRow := a[i*lda:]
   659  				for j := l; j < k; j++ {
   660  					v := aRow[j]
   661  					y[iy] += alpha * v * x[ix-k*incX+jx]
   662  					y[iy-k*incY+jy] += alphaxi * cmplx.Conj(v)
   663  					jx += incX
   664  					jy += incY
   665  				}
   666  				y[iy] += alphaxi * complex(real(aRow[k]), 0)
   667  				ix += incX
   668  				iy += incY
   669  			}
   670  		}
   671  	}
   672  }
   673  
   674  // Zhemv performs the matrix-vector operation
   675  //
   676  //	y = alpha * A * x + beta * y
   677  //
   678  // where alpha and beta are scalars, x and y are vectors, and A is an n×n
   679  // Hermitian matrix. The imaginary parts of the diagonal elements of A are
   680  // ignored and assumed to be zero.
   681  func (Implementation) Zhemv(uplo blas.Uplo, n int, alpha complex128, a []complex128, lda int, x []complex128, incX int, beta complex128, y []complex128, incY int) {
   682  	switch uplo {
   683  	default:
   684  		panic(badUplo)
   685  	case blas.Upper, blas.Lower:
   686  	}
   687  	if n < 0 {
   688  		panic(nLT0)
   689  	}
   690  	if lda < max(1, n) {
   691  		panic(badLdA)
   692  	}
   693  	if incX == 0 {
   694  		panic(zeroIncX)
   695  	}
   696  	if incY == 0 {
   697  		panic(zeroIncY)
   698  	}
   699  
   700  	// Quick return if possible.
   701  	if n == 0 {
   702  		return
   703  	}
   704  
   705  	// For zero matrix size the following slice length checks are trivially satisfied.
   706  	if len(a) < lda*(n-1)+n {
   707  		panic(shortA)
   708  	}
   709  	if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
   710  		panic(shortX)
   711  	}
   712  	if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
   713  		panic(shortY)
   714  	}
   715  
   716  	// Quick return if possible.
   717  	if alpha == 0 && beta == 1 {
   718  		return
   719  	}
   720  
   721  	// Set up the start indices in X and Y.
   722  	var kx int
   723  	if incX < 0 {
   724  		kx = (1 - n) * incX
   725  	}
   726  	var ky int
   727  	if incY < 0 {
   728  		ky = (1 - n) * incY
   729  	}
   730  
   731  	// Form y = beta*y.
   732  	if beta != 1 {
   733  		if incY == 1 {
   734  			if beta == 0 {
   735  				for i := range y[:n] {
   736  					y[i] = 0
   737  				}
   738  			} else {
   739  				for i, v := range y[:n] {
   740  					y[i] = beta * v
   741  				}
   742  			}
   743  		} else {
   744  			iy := ky
   745  			if beta == 0 {
   746  				for i := 0; i < n; i++ {
   747  					y[iy] = 0
   748  					iy += incY
   749  				}
   750  			} else {
   751  				for i := 0; i < n; i++ {
   752  					y[iy] = beta * y[iy]
   753  					iy += incY
   754  				}
   755  			}
   756  		}
   757  	}
   758  
   759  	if alpha == 0 {
   760  		return
   761  	}
   762  
   763  	// The elements of A are accessed sequentially with one pass through
   764  	// the triangular part of A.
   765  
   766  	if uplo == blas.Upper {
   767  		// Form y when A is stored in upper triangle.
   768  		if incX == 1 && incY == 1 {
   769  			for i := 0; i < n; i++ {
   770  				tmp1 := alpha * x[i]
   771  				var tmp2 complex128
   772  				for j := i + 1; j < n; j++ {
   773  					y[j] += tmp1 * cmplx.Conj(a[i*lda+j])
   774  					tmp2 += a[i*lda+j] * x[j]
   775  				}
   776  				aii := complex(real(a[i*lda+i]), 0)
   777  				y[i] += tmp1*aii + alpha*tmp2
   778  			}
   779  		} else {
   780  			ix := kx
   781  			iy := ky
   782  			for i := 0; i < n; i++ {
   783  				tmp1 := alpha * x[ix]
   784  				var tmp2 complex128
   785  				jx := ix
   786  				jy := iy
   787  				for j := i + 1; j < n; j++ {
   788  					jx += incX
   789  					jy += incY
   790  					y[jy] += tmp1 * cmplx.Conj(a[i*lda+j])
   791  					tmp2 += a[i*lda+j] * x[jx]
   792  				}
   793  				aii := complex(real(a[i*lda+i]), 0)
   794  				y[iy] += tmp1*aii + alpha*tmp2
   795  				ix += incX
   796  				iy += incY
   797  			}
   798  		}
   799  		return
   800  	}
   801  
   802  	// Form y when A is stored in lower triangle.
   803  	if incX == 1 && incY == 1 {
   804  		for i := 0; i < n; i++ {
   805  			tmp1 := alpha * x[i]
   806  			var tmp2 complex128
   807  			for j := 0; j < i; j++ {
   808  				y[j] += tmp1 * cmplx.Conj(a[i*lda+j])
   809  				tmp2 += a[i*lda+j] * x[j]
   810  			}
   811  			aii := complex(real(a[i*lda+i]), 0)
   812  			y[i] += tmp1*aii + alpha*tmp2
   813  		}
   814  	} else {
   815  		ix := kx
   816  		iy := ky
   817  		for i := 0; i < n; i++ {
   818  			tmp1 := alpha * x[ix]
   819  			var tmp2 complex128
   820  			jx := kx
   821  			jy := ky
   822  			for j := 0; j < i; j++ {
   823  				y[jy] += tmp1 * cmplx.Conj(a[i*lda+j])
   824  				tmp2 += a[i*lda+j] * x[jx]
   825  				jx += incX
   826  				jy += incY
   827  			}
   828  			aii := complex(real(a[i*lda+i]), 0)
   829  			y[iy] += tmp1*aii + alpha*tmp2
   830  			ix += incX
   831  			iy += incY
   832  		}
   833  	}
   834  }
   835  
   836  // Zher performs the Hermitian rank-one operation
   837  //
   838  //	A += alpha * x * xᴴ
   839  //
   840  // where A is an n×n Hermitian matrix, alpha is a real scalar, and x is an n
   841  // element vector. On entry, the imaginary parts of the diagonal elements of A
   842  // are ignored and assumed to be zero, on return they will be set to zero.
   843  func (Implementation) Zher(uplo blas.Uplo, n int, alpha float64, x []complex128, incX int, a []complex128, lda int) {
   844  	switch uplo {
   845  	default:
   846  		panic(badUplo)
   847  	case blas.Upper, blas.Lower:
   848  	}
   849  	if n < 0 {
   850  		panic(nLT0)
   851  	}
   852  	if lda < max(1, n) {
   853  		panic(badLdA)
   854  	}
   855  	if incX == 0 {
   856  		panic(zeroIncX)
   857  	}
   858  
   859  	// Quick return if possible.
   860  	if n == 0 {
   861  		return
   862  	}
   863  
   864  	// For zero matrix size the following slice length checks are trivially satisfied.
   865  	if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
   866  		panic(shortX)
   867  	}
   868  	if len(a) < lda*(n-1)+n {
   869  		panic(shortA)
   870  	}
   871  
   872  	// Quick return if possible.
   873  	if alpha == 0 {
   874  		return
   875  	}
   876  
   877  	var kx int
   878  	if incX < 0 {
   879  		kx = (1 - n) * incX
   880  	}
   881  	if uplo == blas.Upper {
   882  		if incX == 1 {
   883  			for i := 0; i < n; i++ {
   884  				if x[i] != 0 {
   885  					tmp := complex(alpha*real(x[i]), alpha*imag(x[i]))
   886  					aii := real(a[i*lda+i])
   887  					xtmp := real(tmp * cmplx.Conj(x[i]))
   888  					a[i*lda+i] = complex(aii+xtmp, 0)
   889  					for j := i + 1; j < n; j++ {
   890  						a[i*lda+j] += tmp * cmplx.Conj(x[j])
   891  					}
   892  				} else {
   893  					aii := real(a[i*lda+i])
   894  					a[i*lda+i] = complex(aii, 0)
   895  				}
   896  			}
   897  			return
   898  		}
   899  
   900  		ix := kx
   901  		for i := 0; i < n; i++ {
   902  			if x[ix] != 0 {
   903  				tmp := complex(alpha*real(x[ix]), alpha*imag(x[ix]))
   904  				aii := real(a[i*lda+i])
   905  				xtmp := real(tmp * cmplx.Conj(x[ix]))
   906  				a[i*lda+i] = complex(aii+xtmp, 0)
   907  				jx := ix + incX
   908  				for j := i + 1; j < n; j++ {
   909  					a[i*lda+j] += tmp * cmplx.Conj(x[jx])
   910  					jx += incX
   911  				}
   912  			} else {
   913  				aii := real(a[i*lda+i])
   914  				a[i*lda+i] = complex(aii, 0)
   915  			}
   916  			ix += incX
   917  		}
   918  		return
   919  	}
   920  
   921  	if incX == 1 {
   922  		for i := 0; i < n; i++ {
   923  			if x[i] != 0 {
   924  				tmp := complex(alpha*real(x[i]), alpha*imag(x[i]))
   925  				for j := 0; j < i; j++ {
   926  					a[i*lda+j] += tmp * cmplx.Conj(x[j])
   927  				}
   928  				aii := real(a[i*lda+i])
   929  				xtmp := real(tmp * cmplx.Conj(x[i]))
   930  				a[i*lda+i] = complex(aii+xtmp, 0)
   931  			} else {
   932  				aii := real(a[i*lda+i])
   933  				a[i*lda+i] = complex(aii, 0)
   934  			}
   935  		}
   936  		return
   937  	}
   938  
   939  	ix := kx
   940  	for i := 0; i < n; i++ {
   941  		if x[ix] != 0 {
   942  			tmp := complex(alpha*real(x[ix]), alpha*imag(x[ix]))
   943  			jx := kx
   944  			for j := 0; j < i; j++ {
   945  				a[i*lda+j] += tmp * cmplx.Conj(x[jx])
   946  				jx += incX
   947  			}
   948  			aii := real(a[i*lda+i])
   949  			xtmp := real(tmp * cmplx.Conj(x[ix]))
   950  			a[i*lda+i] = complex(aii+xtmp, 0)
   951  
   952  		} else {
   953  			aii := real(a[i*lda+i])
   954  			a[i*lda+i] = complex(aii, 0)
   955  		}
   956  		ix += incX
   957  	}
   958  }
   959  
   960  // Zher2 performs the Hermitian rank-two operation
   961  //
   962  //	A += alpha * x * yᴴ + conj(alpha) * y * xᴴ
   963  //
   964  // where alpha is a scalar, x and y are n element vectors and A is an n×n
   965  // Hermitian matrix. On entry, the imaginary parts of the diagonal elements are
   966  // ignored and assumed to be zero. On return they will be set to zero.
   967  func (Implementation) Zher2(uplo blas.Uplo, n int, alpha complex128, x []complex128, incX int, y []complex128, incY int, a []complex128, lda int) {
   968  	switch uplo {
   969  	default:
   970  		panic(badUplo)
   971  	case blas.Upper, blas.Lower:
   972  	}
   973  	if n < 0 {
   974  		panic(nLT0)
   975  	}
   976  	if lda < max(1, n) {
   977  		panic(badLdA)
   978  	}
   979  	if incX == 0 {
   980  		panic(zeroIncX)
   981  	}
   982  	if incY == 0 {
   983  		panic(zeroIncY)
   984  	}
   985  
   986  	// Quick return if possible.
   987  	if n == 0 {
   988  		return
   989  	}
   990  
   991  	// For zero matrix size the following slice length checks are trivially satisfied.
   992  	if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
   993  		panic(shortX)
   994  	}
   995  	if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
   996  		panic(shortY)
   997  	}
   998  	if len(a) < lda*(n-1)+n {
   999  		panic(shortA)
  1000  	}
  1001  
  1002  	// Quick return if possible.
  1003  	if alpha == 0 {
  1004  		return
  1005  	}
  1006  
  1007  	var kx, ky int
  1008  	var ix, iy int
  1009  	if incX != 1 || incY != 1 {
  1010  		if incX < 0 {
  1011  			kx = (1 - n) * incX
  1012  		}
  1013  		if incY < 0 {
  1014  			ky = (1 - n) * incY
  1015  		}
  1016  		ix = kx
  1017  		iy = ky
  1018  	}
  1019  	if uplo == blas.Upper {
  1020  		if incX == 1 && incY == 1 {
  1021  			for i := 0; i < n; i++ {
  1022  				if x[i] != 0 || y[i] != 0 {
  1023  					tmp1 := alpha * x[i]
  1024  					tmp2 := cmplx.Conj(alpha) * y[i]
  1025  					aii := real(a[i*lda+i]) + real(tmp1*cmplx.Conj(y[i])) + real(tmp2*cmplx.Conj(x[i]))
  1026  					a[i*lda+i] = complex(aii, 0)
  1027  					for j := i + 1; j < n; j++ {
  1028  						a[i*lda+j] += tmp1*cmplx.Conj(y[j]) + tmp2*cmplx.Conj(x[j])
  1029  					}
  1030  				} else {
  1031  					aii := real(a[i*lda+i])
  1032  					a[i*lda+i] = complex(aii, 0)
  1033  				}
  1034  			}
  1035  			return
  1036  		}
  1037  		for i := 0; i < n; i++ {
  1038  			if x[ix] != 0 || y[iy] != 0 {
  1039  				tmp1 := alpha * x[ix]
  1040  				tmp2 := cmplx.Conj(alpha) * y[iy]
  1041  				aii := real(a[i*lda+i]) + real(tmp1*cmplx.Conj(y[iy])) + real(tmp2*cmplx.Conj(x[ix]))
  1042  				a[i*lda+i] = complex(aii, 0)
  1043  				jx := ix + incX
  1044  				jy := iy + incY
  1045  				for j := i + 1; j < n; j++ {
  1046  					a[i*lda+j] += tmp1*cmplx.Conj(y[jy]) + tmp2*cmplx.Conj(x[jx])
  1047  					jx += incX
  1048  					jy += incY
  1049  				}
  1050  			} else {
  1051  				aii := real(a[i*lda+i])
  1052  				a[i*lda+i] = complex(aii, 0)
  1053  			}
  1054  			ix += incX
  1055  			iy += incY
  1056  		}
  1057  		return
  1058  	}
  1059  
  1060  	if incX == 1 && incY == 1 {
  1061  		for i := 0; i < n; i++ {
  1062  			if x[i] != 0 || y[i] != 0 {
  1063  				tmp1 := alpha * x[i]
  1064  				tmp2 := cmplx.Conj(alpha) * y[i]
  1065  				for j := 0; j < i; j++ {
  1066  					a[i*lda+j] += tmp1*cmplx.Conj(y[j]) + tmp2*cmplx.Conj(x[j])
  1067  				}
  1068  				aii := real(a[i*lda+i]) + real(tmp1*cmplx.Conj(y[i])) + real(tmp2*cmplx.Conj(x[i]))
  1069  				a[i*lda+i] = complex(aii, 0)
  1070  			} else {
  1071  				aii := real(a[i*lda+i])
  1072  				a[i*lda+i] = complex(aii, 0)
  1073  			}
  1074  		}
  1075  		return
  1076  	}
  1077  	for i := 0; i < n; i++ {
  1078  		if x[ix] != 0 || y[iy] != 0 {
  1079  			tmp1 := alpha * x[ix]
  1080  			tmp2 := cmplx.Conj(alpha) * y[iy]
  1081  			jx := kx
  1082  			jy := ky
  1083  			for j := 0; j < i; j++ {
  1084  				a[i*lda+j] += tmp1*cmplx.Conj(y[jy]) + tmp2*cmplx.Conj(x[jx])
  1085  				jx += incX
  1086  				jy += incY
  1087  			}
  1088  			aii := real(a[i*lda+i]) + real(tmp1*cmplx.Conj(y[iy])) + real(tmp2*cmplx.Conj(x[ix]))
  1089  			a[i*lda+i] = complex(aii, 0)
  1090  		} else {
  1091  			aii := real(a[i*lda+i])
  1092  			a[i*lda+i] = complex(aii, 0)
  1093  		}
  1094  		ix += incX
  1095  		iy += incY
  1096  	}
  1097  }
  1098  
  1099  // Zhpmv performs the matrix-vector operation
  1100  //
  1101  //	y = alpha * A * x + beta * y
  1102  //
  1103  // where alpha and beta are scalars, x and y are vectors, and A is an n×n
  1104  // Hermitian matrix in packed form. The imaginary parts of the diagonal
  1105  // elements of A are ignored and assumed to be zero.
  1106  func (Implementation) Zhpmv(uplo blas.Uplo, n int, alpha complex128, ap []complex128, x []complex128, incX int, beta complex128, y []complex128, incY int) {
  1107  	switch uplo {
  1108  	default:
  1109  		panic(badUplo)
  1110  	case blas.Upper, blas.Lower:
  1111  	}
  1112  	if n < 0 {
  1113  		panic(nLT0)
  1114  	}
  1115  	if incX == 0 {
  1116  		panic(zeroIncX)
  1117  	}
  1118  	if incY == 0 {
  1119  		panic(zeroIncY)
  1120  	}
  1121  
  1122  	// Quick return if possible.
  1123  	if n == 0 {
  1124  		return
  1125  	}
  1126  
  1127  	// For zero matrix size the following slice length checks are trivially satisfied.
  1128  	if len(ap) < n*(n+1)/2 {
  1129  		panic(shortAP)
  1130  	}
  1131  	if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
  1132  		panic(shortX)
  1133  	}
  1134  	if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
  1135  		panic(shortY)
  1136  	}
  1137  
  1138  	// Quick return if possible.
  1139  	if alpha == 0 && beta == 1 {
  1140  		return
  1141  	}
  1142  
  1143  	// Set up the start indices in X and Y.
  1144  	var kx int
  1145  	if incX < 0 {
  1146  		kx = (1 - n) * incX
  1147  	}
  1148  	var ky int
  1149  	if incY < 0 {
  1150  		ky = (1 - n) * incY
  1151  	}
  1152  
  1153  	// Form y = beta*y.
  1154  	if beta != 1 {
  1155  		if incY == 1 {
  1156  			if beta == 0 {
  1157  				for i := range y[:n] {
  1158  					y[i] = 0
  1159  				}
  1160  			} else {
  1161  				for i, v := range y[:n] {
  1162  					y[i] = beta * v
  1163  				}
  1164  			}
  1165  		} else {
  1166  			iy := ky
  1167  			if beta == 0 {
  1168  				for i := 0; i < n; i++ {
  1169  					y[iy] = 0
  1170  					iy += incY
  1171  				}
  1172  			} else {
  1173  				for i := 0; i < n; i++ {
  1174  					y[iy] *= beta
  1175  					iy += incY
  1176  				}
  1177  			}
  1178  		}
  1179  	}
  1180  
  1181  	if alpha == 0 {
  1182  		return
  1183  	}
  1184  
  1185  	// The elements of A are accessed sequentially with one pass through ap.
  1186  
  1187  	var kk int
  1188  	if uplo == blas.Upper {
  1189  		// Form y when ap contains the upper triangle.
  1190  		// Here, kk points to the current diagonal element in ap.
  1191  		if incX == 1 && incY == 1 {
  1192  			for i := 0; i < n; i++ {
  1193  				tmp1 := alpha * x[i]
  1194  				y[i] += tmp1 * complex(real(ap[kk]), 0)
  1195  				var tmp2 complex128
  1196  				k := kk + 1
  1197  				for j := i + 1; j < n; j++ {
  1198  					y[j] += tmp1 * cmplx.Conj(ap[k])
  1199  					tmp2 += ap[k] * x[j]
  1200  					k++
  1201  				}
  1202  				y[i] += alpha * tmp2
  1203  				kk += n - i
  1204  			}
  1205  		} else {
  1206  			ix := kx
  1207  			iy := ky
  1208  			for i := 0; i < n; i++ {
  1209  				tmp1 := alpha * x[ix]
  1210  				y[iy] += tmp1 * complex(real(ap[kk]), 0)
  1211  				var tmp2 complex128
  1212  				jx := ix
  1213  				jy := iy
  1214  				for k := kk + 1; k < kk+n-i; k++ {
  1215  					jx += incX
  1216  					jy += incY
  1217  					y[jy] += tmp1 * cmplx.Conj(ap[k])
  1218  					tmp2 += ap[k] * x[jx]
  1219  				}
  1220  				y[iy] += alpha * tmp2
  1221  				ix += incX
  1222  				iy += incY
  1223  				kk += n - i
  1224  			}
  1225  		}
  1226  		return
  1227  	}
  1228  
  1229  	// Form y when ap contains the lower triangle.
  1230  	// Here, kk points to the beginning of current row in ap.
  1231  	if incX == 1 && incY == 1 {
  1232  		for i := 0; i < n; i++ {
  1233  			tmp1 := alpha * x[i]
  1234  			var tmp2 complex128
  1235  			k := kk
  1236  			for j := 0; j < i; j++ {
  1237  				y[j] += tmp1 * cmplx.Conj(ap[k])
  1238  				tmp2 += ap[k] * x[j]
  1239  				k++
  1240  			}
  1241  			aii := complex(real(ap[kk+i]), 0)
  1242  			y[i] += tmp1*aii + alpha*tmp2
  1243  			kk += i + 1
  1244  		}
  1245  	} else {
  1246  		ix := kx
  1247  		iy := ky
  1248  		for i := 0; i < n; i++ {
  1249  			tmp1 := alpha * x[ix]
  1250  			var tmp2 complex128
  1251  			jx := kx
  1252  			jy := ky
  1253  			for k := kk; k < kk+i; k++ {
  1254  				y[jy] += tmp1 * cmplx.Conj(ap[k])
  1255  				tmp2 += ap[k] * x[jx]
  1256  				jx += incX
  1257  				jy += incY
  1258  			}
  1259  			aii := complex(real(ap[kk+i]), 0)
  1260  			y[iy] += tmp1*aii + alpha*tmp2
  1261  			ix += incX
  1262  			iy += incY
  1263  			kk += i + 1
  1264  		}
  1265  	}
  1266  }
  1267  
  1268  // Zhpr performs the Hermitian rank-1 operation
  1269  //
  1270  //	A += alpha * x * xᴴ
  1271  //
  1272  // where alpha is a real scalar, x is a vector, and A is an n×n hermitian matrix
  1273  // in packed form. On entry, the imaginary parts of the diagonal elements are
  1274  // assumed to be zero, and on return they are set to zero.
  1275  func (Implementation) Zhpr(uplo blas.Uplo, n int, alpha float64, x []complex128, incX int, ap []complex128) {
  1276  	switch uplo {
  1277  	default:
  1278  		panic(badUplo)
  1279  	case blas.Upper, blas.Lower:
  1280  	}
  1281  	if n < 0 {
  1282  		panic(nLT0)
  1283  	}
  1284  	if incX == 0 {
  1285  		panic(zeroIncX)
  1286  	}
  1287  
  1288  	// Quick return if possible.
  1289  	if n == 0 {
  1290  		return
  1291  	}
  1292  
  1293  	// For zero matrix size the following slice length checks are trivially satisfied.
  1294  	if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
  1295  		panic(shortX)
  1296  	}
  1297  	if len(ap) < n*(n+1)/2 {
  1298  		panic(shortAP)
  1299  	}
  1300  
  1301  	// Quick return if possible.
  1302  	if alpha == 0 {
  1303  		return
  1304  	}
  1305  
  1306  	// Set up start index in X.
  1307  	var kx int
  1308  	if incX < 0 {
  1309  		kx = (1 - n) * incX
  1310  	}
  1311  
  1312  	// The elements of A are accessed sequentially with one pass through ap.
  1313  
  1314  	var kk int
  1315  	if uplo == blas.Upper {
  1316  		// Form A when upper triangle is stored in AP.
  1317  		// Here, kk points to the current diagonal element in ap.
  1318  		if incX == 1 {
  1319  			for i := 0; i < n; i++ {
  1320  				xi := x[i]
  1321  				if xi != 0 {
  1322  					aii := real(ap[kk]) + alpha*real(cmplx.Conj(xi)*xi)
  1323  					ap[kk] = complex(aii, 0)
  1324  
  1325  					tmp := complex(alpha, 0) * xi
  1326  					a := ap[kk+1 : kk+n-i]
  1327  					x := x[i+1 : n]
  1328  					for j, v := range x {
  1329  						a[j] += tmp * cmplx.Conj(v)
  1330  					}
  1331  				} else {
  1332  					ap[kk] = complex(real(ap[kk]), 0)
  1333  				}
  1334  				kk += n - i
  1335  			}
  1336  		} else {
  1337  			ix := kx
  1338  			for i := 0; i < n; i++ {
  1339  				xi := x[ix]
  1340  				if xi != 0 {
  1341  					aii := real(ap[kk]) + alpha*real(cmplx.Conj(xi)*xi)
  1342  					ap[kk] = complex(aii, 0)
  1343  
  1344  					tmp := complex(alpha, 0) * xi
  1345  					jx := ix + incX
  1346  					a := ap[kk+1 : kk+n-i]
  1347  					for k := range a {
  1348  						a[k] += tmp * cmplx.Conj(x[jx])
  1349  						jx += incX
  1350  					}
  1351  				} else {
  1352  					ap[kk] = complex(real(ap[kk]), 0)
  1353  				}
  1354  				ix += incX
  1355  				kk += n - i
  1356  			}
  1357  		}
  1358  		return
  1359  	}
  1360  
  1361  	// Form A when lower triangle is stored in AP.
  1362  	// Here, kk points to the beginning of current row in ap.
  1363  	if incX == 1 {
  1364  		for i := 0; i < n; i++ {
  1365  			xi := x[i]
  1366  			if xi != 0 {
  1367  				tmp := complex(alpha, 0) * xi
  1368  				a := ap[kk : kk+i]
  1369  				for j, v := range x[:i] {
  1370  					a[j] += tmp * cmplx.Conj(v)
  1371  				}
  1372  
  1373  				aii := real(ap[kk+i]) + alpha*real(cmplx.Conj(xi)*xi)
  1374  				ap[kk+i] = complex(aii, 0)
  1375  			} else {
  1376  				ap[kk+i] = complex(real(ap[kk+i]), 0)
  1377  			}
  1378  			kk += i + 1
  1379  		}
  1380  	} else {
  1381  		ix := kx
  1382  		for i := 0; i < n; i++ {
  1383  			xi := x[ix]
  1384  			if xi != 0 {
  1385  				tmp := complex(alpha, 0) * xi
  1386  				a := ap[kk : kk+i]
  1387  				jx := kx
  1388  				for k := range a {
  1389  					a[k] += tmp * cmplx.Conj(x[jx])
  1390  					jx += incX
  1391  				}
  1392  
  1393  				aii := real(ap[kk+i]) + alpha*real(cmplx.Conj(xi)*xi)
  1394  				ap[kk+i] = complex(aii, 0)
  1395  			} else {
  1396  				ap[kk+i] = complex(real(ap[kk+i]), 0)
  1397  			}
  1398  			ix += incX
  1399  			kk += i + 1
  1400  		}
  1401  	}
  1402  }
  1403  
  1404  // Zhpr2 performs the Hermitian rank-2 operation
  1405  //
  1406  //	A += alpha * x * yᴴ + conj(alpha) * y * xᴴ
  1407  //
  1408  // where alpha is a complex scalar, x and y are n element vectors, and A is an
  1409  // n×n Hermitian matrix, supplied in packed form. On entry, the imaginary parts
  1410  // of the diagonal elements are assumed to be zero, and on return they are set to zero.
  1411  func (Implementation) Zhpr2(uplo blas.Uplo, n int, alpha complex128, x []complex128, incX int, y []complex128, incY int, ap []complex128) {
  1412  	switch uplo {
  1413  	default:
  1414  		panic(badUplo)
  1415  	case blas.Upper, blas.Lower:
  1416  	}
  1417  	if n < 0 {
  1418  		panic(nLT0)
  1419  	}
  1420  	if incX == 0 {
  1421  		panic(zeroIncX)
  1422  	}
  1423  	if incY == 0 {
  1424  		panic(zeroIncY)
  1425  	}
  1426  
  1427  	// Quick return if possible.
  1428  	if n == 0 {
  1429  		return
  1430  	}
  1431  
  1432  	// For zero matrix size the following slice length checks are trivially satisfied.
  1433  	if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
  1434  		panic(shortX)
  1435  	}
  1436  	if (incY > 0 && len(y) <= (n-1)*incY) || (incY < 0 && len(y) <= (1-n)*incY) {
  1437  		panic(shortY)
  1438  	}
  1439  	if len(ap) < n*(n+1)/2 {
  1440  		panic(shortAP)
  1441  	}
  1442  
  1443  	// Quick return if possible.
  1444  	if alpha == 0 {
  1445  		return
  1446  	}
  1447  
  1448  	// Set up start indices in X and Y.
  1449  	var kx int
  1450  	if incX < 0 {
  1451  		kx = (1 - n) * incX
  1452  	}
  1453  	var ky int
  1454  	if incY < 0 {
  1455  		ky = (1 - n) * incY
  1456  	}
  1457  
  1458  	// The elements of A are accessed sequentially with one pass through ap.
  1459  
  1460  	var kk int
  1461  	if uplo == blas.Upper {
  1462  		// Form A when upper triangle is stored in AP.
  1463  		// Here, kk points to the current diagonal element in ap.
  1464  		if incX == 1 && incY == 1 {
  1465  			for i := 0; i < n; i++ {
  1466  				if x[i] != 0 || y[i] != 0 {
  1467  					tmp1 := alpha * x[i]
  1468  					tmp2 := cmplx.Conj(alpha) * y[i]
  1469  					aii := real(ap[kk]) + real(tmp1*cmplx.Conj(y[i])) + real(tmp2*cmplx.Conj(x[i]))
  1470  					ap[kk] = complex(aii, 0)
  1471  					k := kk + 1
  1472  					for j := i + 1; j < n; j++ {
  1473  						ap[k] += tmp1*cmplx.Conj(y[j]) + tmp2*cmplx.Conj(x[j])
  1474  						k++
  1475  					}
  1476  				} else {
  1477  					ap[kk] = complex(real(ap[kk]), 0)
  1478  				}
  1479  				kk += n - i
  1480  			}
  1481  		} else {
  1482  			ix := kx
  1483  			iy := ky
  1484  			for i := 0; i < n; i++ {
  1485  				if x[ix] != 0 || y[iy] != 0 {
  1486  					tmp1 := alpha * x[ix]
  1487  					tmp2 := cmplx.Conj(alpha) * y[iy]
  1488  					aii := real(ap[kk]) + real(tmp1*cmplx.Conj(y[iy])) + real(tmp2*cmplx.Conj(x[ix]))
  1489  					ap[kk] = complex(aii, 0)
  1490  					jx := ix + incX
  1491  					jy := iy + incY
  1492  					for k := kk + 1; k < kk+n-i; k++ {
  1493  						ap[k] += tmp1*cmplx.Conj(y[jy]) + tmp2*cmplx.Conj(x[jx])
  1494  						jx += incX
  1495  						jy += incY
  1496  					}
  1497  				} else {
  1498  					ap[kk] = complex(real(ap[kk]), 0)
  1499  				}
  1500  				ix += incX
  1501  				iy += incY
  1502  				kk += n - i
  1503  			}
  1504  		}
  1505  		return
  1506  	}
  1507  
  1508  	// Form A when lower triangle is stored in AP.
  1509  	// Here, kk points to the beginning of current row in ap.
  1510  	if incX == 1 && incY == 1 {
  1511  		for i := 0; i < n; i++ {
  1512  			if x[i] != 0 || y[i] != 0 {
  1513  				tmp1 := alpha * x[i]
  1514  				tmp2 := cmplx.Conj(alpha) * y[i]
  1515  				k := kk
  1516  				for j := 0; j < i; j++ {
  1517  					ap[k] += tmp1*cmplx.Conj(y[j]) + tmp2*cmplx.Conj(x[j])
  1518  					k++
  1519  				}
  1520  				aii := real(ap[kk+i]) + real(tmp1*cmplx.Conj(y[i])) + real(tmp2*cmplx.Conj(x[i]))
  1521  				ap[kk+i] = complex(aii, 0)
  1522  			} else {
  1523  				ap[kk+i] = complex(real(ap[kk+i]), 0)
  1524  			}
  1525  			kk += i + 1
  1526  		}
  1527  	} else {
  1528  		ix := kx
  1529  		iy := ky
  1530  		for i := 0; i < n; i++ {
  1531  			if x[ix] != 0 || y[iy] != 0 {
  1532  				tmp1 := alpha * x[ix]
  1533  				tmp2 := cmplx.Conj(alpha) * y[iy]
  1534  				jx := kx
  1535  				jy := ky
  1536  				for k := kk; k < kk+i; k++ {
  1537  					ap[k] += tmp1*cmplx.Conj(y[jy]) + tmp2*cmplx.Conj(x[jx])
  1538  					jx += incX
  1539  					jy += incY
  1540  				}
  1541  				aii := real(ap[kk+i]) + real(tmp1*cmplx.Conj(y[iy])) + real(tmp2*cmplx.Conj(x[ix]))
  1542  				ap[kk+i] = complex(aii, 0)
  1543  			} else {
  1544  				ap[kk+i] = complex(real(ap[kk+i]), 0)
  1545  			}
  1546  			ix += incX
  1547  			iy += incY
  1548  			kk += i + 1
  1549  		}
  1550  	}
  1551  }
  1552  
  1553  // Ztbmv performs one of the matrix-vector operations
  1554  //
  1555  //	x = A * x   if trans = blas.NoTrans
  1556  //	x = Aᵀ * x  if trans = blas.Trans
  1557  //	x = Aᴴ * x  if trans = blas.ConjTrans
  1558  //
  1559  // where x is an n element vector and A is an n×n triangular band matrix, with
  1560  // (k+1) diagonals.
  1561  func (Implementation) Ztbmv(uplo blas.Uplo, trans blas.Transpose, diag blas.Diag, n, k int, a []complex128, lda int, x []complex128, incX int) {
  1562  	switch trans {
  1563  	default:
  1564  		panic(badTranspose)
  1565  	case blas.NoTrans, blas.Trans, blas.ConjTrans:
  1566  	}
  1567  	switch uplo {
  1568  	default:
  1569  		panic(badUplo)
  1570  	case blas.Upper, blas.Lower:
  1571  	}
  1572  	switch diag {
  1573  	default:
  1574  		panic(badDiag)
  1575  	case blas.NonUnit, blas.Unit:
  1576  	}
  1577  	if n < 0 {
  1578  		panic(nLT0)
  1579  	}
  1580  	if k < 0 {
  1581  		panic(kLT0)
  1582  	}
  1583  	if lda < k+1 {
  1584  		panic(badLdA)
  1585  	}
  1586  	if incX == 0 {
  1587  		panic(zeroIncX)
  1588  	}
  1589  
  1590  	// Quick return if possible.
  1591  	if n == 0 {
  1592  		return
  1593  	}
  1594  
  1595  	// For zero matrix size the following slice length checks are trivially satisfied.
  1596  	if len(a) < lda*(n-1)+k+1 {
  1597  		panic(shortA)
  1598  	}
  1599  	if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
  1600  		panic(shortX)
  1601  	}
  1602  
  1603  	// Set up start index in X.
  1604  	var kx int
  1605  	if incX < 0 {
  1606  		kx = (1 - n) * incX
  1607  	}
  1608  
  1609  	switch trans {
  1610  	case blas.NoTrans:
  1611  		if uplo == blas.Upper {
  1612  			if incX == 1 {
  1613  				for i := 0; i < n; i++ {
  1614  					xi := x[i]
  1615  					if diag == blas.NonUnit {
  1616  						xi *= a[i*lda]
  1617  					}
  1618  					kk := min(k, n-i-1)
  1619  					for j, aij := range a[i*lda+1 : i*lda+kk+1] {
  1620  						xi += x[i+j+1] * aij
  1621  					}
  1622  					x[i] = xi
  1623  				}
  1624  			} else {
  1625  				ix := kx
  1626  				for i := 0; i < n; i++ {
  1627  					xi := x[ix]
  1628  					if diag == blas.NonUnit {
  1629  						xi *= a[i*lda]
  1630  					}
  1631  					kk := min(k, n-i-1)
  1632  					jx := ix + incX
  1633  					for _, aij := range a[i*lda+1 : i*lda+kk+1] {
  1634  						xi += x[jx] * aij
  1635  						jx += incX
  1636  					}
  1637  					x[ix] = xi
  1638  					ix += incX
  1639  				}
  1640  			}
  1641  		} else {
  1642  			if incX == 1 {
  1643  				for i := n - 1; i >= 0; i-- {
  1644  					xi := x[i]
  1645  					if diag == blas.NonUnit {
  1646  						xi *= a[i*lda+k]
  1647  					}
  1648  					kk := min(k, i)
  1649  					for j, aij := range a[i*lda+k-kk : i*lda+k] {
  1650  						xi += x[i-kk+j] * aij
  1651  					}
  1652  					x[i] = xi
  1653  				}
  1654  			} else {
  1655  				ix := kx + (n-1)*incX
  1656  				for i := n - 1; i >= 0; i-- {
  1657  					xi := x[ix]
  1658  					if diag == blas.NonUnit {
  1659  						xi *= a[i*lda+k]
  1660  					}
  1661  					kk := min(k, i)
  1662  					jx := ix - kk*incX
  1663  					for _, aij := range a[i*lda+k-kk : i*lda+k] {
  1664  						xi += x[jx] * aij
  1665  						jx += incX
  1666  					}
  1667  					x[ix] = xi
  1668  					ix -= incX
  1669  				}
  1670  			}
  1671  		}
  1672  	case blas.Trans:
  1673  		if uplo == blas.Upper {
  1674  			if incX == 1 {
  1675  				for i := n - 1; i >= 0; i-- {
  1676  					kk := min(k, n-i-1)
  1677  					xi := x[i]
  1678  					for j, aij := range a[i*lda+1 : i*lda+kk+1] {
  1679  						x[i+j+1] += xi * aij
  1680  					}
  1681  					if diag == blas.NonUnit {
  1682  						x[i] *= a[i*lda]
  1683  					}
  1684  				}
  1685  			} else {
  1686  				ix := kx + (n-1)*incX
  1687  				for i := n - 1; i >= 0; i-- {
  1688  					kk := min(k, n-i-1)
  1689  					jx := ix + incX
  1690  					xi := x[ix]
  1691  					for _, aij := range a[i*lda+1 : i*lda+kk+1] {
  1692  						x[jx] += xi * aij
  1693  						jx += incX
  1694  					}
  1695  					if diag == blas.NonUnit {
  1696  						x[ix] *= a[i*lda]
  1697  					}
  1698  					ix -= incX
  1699  				}
  1700  			}
  1701  		} else {
  1702  			if incX == 1 {
  1703  				for i := 0; i < n; i++ {
  1704  					kk := min(k, i)
  1705  					xi := x[i]
  1706  					for j, aij := range a[i*lda+k-kk : i*lda+k] {
  1707  						x[i-kk+j] += xi * aij
  1708  					}
  1709  					if diag == blas.NonUnit {
  1710  						x[i] *= a[i*lda+k]
  1711  					}
  1712  				}
  1713  			} else {
  1714  				ix := kx
  1715  				for i := 0; i < n; i++ {
  1716  					kk := min(k, i)
  1717  					jx := ix - kk*incX
  1718  					xi := x[ix]
  1719  					for _, aij := range a[i*lda+k-kk : i*lda+k] {
  1720  						x[jx] += xi * aij
  1721  						jx += incX
  1722  					}
  1723  					if diag == blas.NonUnit {
  1724  						x[ix] *= a[i*lda+k]
  1725  					}
  1726  					ix += incX
  1727  				}
  1728  			}
  1729  		}
  1730  	case blas.ConjTrans:
  1731  		if uplo == blas.Upper {
  1732  			if incX == 1 {
  1733  				for i := n - 1; i >= 0; i-- {
  1734  					kk := min(k, n-i-1)
  1735  					xi := x[i]
  1736  					for j, aij := range a[i*lda+1 : i*lda+kk+1] {
  1737  						x[i+j+1] += xi * cmplx.Conj(aij)
  1738  					}
  1739  					if diag == blas.NonUnit {
  1740  						x[i] *= cmplx.Conj(a[i*lda])
  1741  					}
  1742  				}
  1743  			} else {
  1744  				ix := kx + (n-1)*incX
  1745  				for i := n - 1; i >= 0; i-- {
  1746  					kk := min(k, n-i-1)
  1747  					jx := ix + incX
  1748  					xi := x[ix]
  1749  					for _, aij := range a[i*lda+1 : i*lda+kk+1] {
  1750  						x[jx] += xi * cmplx.Conj(aij)
  1751  						jx += incX
  1752  					}
  1753  					if diag == blas.NonUnit {
  1754  						x[ix] *= cmplx.Conj(a[i*lda])
  1755  					}
  1756  					ix -= incX
  1757  				}
  1758  			}
  1759  		} else {
  1760  			if incX == 1 {
  1761  				for i := 0; i < n; i++ {
  1762  					kk := min(k, i)
  1763  					xi := x[i]
  1764  					for j, aij := range a[i*lda+k-kk : i*lda+k] {
  1765  						x[i-kk+j] += xi * cmplx.Conj(aij)
  1766  					}
  1767  					if diag == blas.NonUnit {
  1768  						x[i] *= cmplx.Conj(a[i*lda+k])
  1769  					}
  1770  				}
  1771  			} else {
  1772  				ix := kx
  1773  				for i := 0; i < n; i++ {
  1774  					kk := min(k, i)
  1775  					jx := ix - kk*incX
  1776  					xi := x[ix]
  1777  					for _, aij := range a[i*lda+k-kk : i*lda+k] {
  1778  						x[jx] += xi * cmplx.Conj(aij)
  1779  						jx += incX
  1780  					}
  1781  					if diag == blas.NonUnit {
  1782  						x[ix] *= cmplx.Conj(a[i*lda+k])
  1783  					}
  1784  					ix += incX
  1785  				}
  1786  			}
  1787  		}
  1788  	}
  1789  }
  1790  
  1791  // Ztbsv solves one of the systems of equations
  1792  //
  1793  //	A * x = b   if trans == blas.NoTrans
  1794  //	Aᵀ * x = b  if trans == blas.Trans
  1795  //	Aᴴ * x = b  if trans == blas.ConjTrans
  1796  //
  1797  // where b and x are n element vectors and A is an n×n triangular band matrix
  1798  // with (k+1) diagonals.
  1799  //
  1800  // On entry, x contains the values of b, and the solution is
  1801  // stored in-place into x.
  1802  //
  1803  // No test for singularity or near-singularity is included in this
  1804  // routine. Such tests must be performed before calling this routine.
  1805  func (Implementation) Ztbsv(uplo blas.Uplo, trans blas.Transpose, diag blas.Diag, n, k int, a []complex128, lda int, x []complex128, incX int) {
  1806  	switch trans {
  1807  	default:
  1808  		panic(badTranspose)
  1809  	case blas.NoTrans, blas.Trans, blas.ConjTrans:
  1810  	}
  1811  	switch uplo {
  1812  	default:
  1813  		panic(badUplo)
  1814  	case blas.Upper, blas.Lower:
  1815  	}
  1816  	switch diag {
  1817  	default:
  1818  		panic(badDiag)
  1819  	case blas.NonUnit, blas.Unit:
  1820  	}
  1821  	if n < 0 {
  1822  		panic(nLT0)
  1823  	}
  1824  	if k < 0 {
  1825  		panic(kLT0)
  1826  	}
  1827  	if lda < k+1 {
  1828  		panic(badLdA)
  1829  	}
  1830  	if incX == 0 {
  1831  		panic(zeroIncX)
  1832  	}
  1833  
  1834  	// Quick return if possible.
  1835  	if n == 0 {
  1836  		return
  1837  	}
  1838  
  1839  	// For zero matrix size the following slice length checks are trivially satisfied.
  1840  	if len(a) < lda*(n-1)+k+1 {
  1841  		panic(shortA)
  1842  	}
  1843  	if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
  1844  		panic(shortX)
  1845  	}
  1846  
  1847  	// Set up start index in X.
  1848  	var kx int
  1849  	if incX < 0 {
  1850  		kx = (1 - n) * incX
  1851  	}
  1852  
  1853  	switch trans {
  1854  	case blas.NoTrans:
  1855  		if uplo == blas.Upper {
  1856  			if incX == 1 {
  1857  				for i := n - 1; i >= 0; i-- {
  1858  					kk := min(k, n-i-1)
  1859  					var sum complex128
  1860  					for j, aij := range a[i*lda+1 : i*lda+kk+1] {
  1861  						sum += x[i+1+j] * aij
  1862  					}
  1863  					x[i] -= sum
  1864  					if diag == blas.NonUnit {
  1865  						x[i] /= a[i*lda]
  1866  					}
  1867  				}
  1868  			} else {
  1869  				ix := kx + (n-1)*incX
  1870  				for i := n - 1; i >= 0; i-- {
  1871  					kk := min(k, n-i-1)
  1872  					var sum complex128
  1873  					jx := ix + incX
  1874  					for _, aij := range a[i*lda+1 : i*lda+kk+1] {
  1875  						sum += x[jx] * aij
  1876  						jx += incX
  1877  					}
  1878  					x[ix] -= sum
  1879  					if diag == blas.NonUnit {
  1880  						x[ix] /= a[i*lda]
  1881  					}
  1882  					ix -= incX
  1883  				}
  1884  			}
  1885  		} else {
  1886  			if incX == 1 {
  1887  				for i := 0; i < n; i++ {
  1888  					kk := min(k, i)
  1889  					var sum complex128
  1890  					for j, aij := range a[i*lda+k-kk : i*lda+k] {
  1891  						sum += x[i-kk+j] * aij
  1892  					}
  1893  					x[i] -= sum
  1894  					if diag == blas.NonUnit {
  1895  						x[i] /= a[i*lda+k]
  1896  					}
  1897  				}
  1898  			} else {
  1899  				ix := kx
  1900  				for i := 0; i < n; i++ {
  1901  					kk := min(k, i)
  1902  					var sum complex128
  1903  					jx := ix - kk*incX
  1904  					for _, aij := range a[i*lda+k-kk : i*lda+k] {
  1905  						sum += x[jx] * aij
  1906  						jx += incX
  1907  					}
  1908  					x[ix] -= sum
  1909  					if diag == blas.NonUnit {
  1910  						x[ix] /= a[i*lda+k]
  1911  					}
  1912  					ix += incX
  1913  				}
  1914  			}
  1915  		}
  1916  	case blas.Trans:
  1917  		if uplo == blas.Upper {
  1918  			if incX == 1 {
  1919  				for i := 0; i < n; i++ {
  1920  					if diag == blas.NonUnit {
  1921  						x[i] /= a[i*lda]
  1922  					}
  1923  					kk := min(k, n-i-1)
  1924  					xi := x[i]
  1925  					for j, aij := range a[i*lda+1 : i*lda+kk+1] {
  1926  						x[i+1+j] -= xi * aij
  1927  					}
  1928  				}
  1929  			} else {
  1930  				ix := kx
  1931  				for i := 0; i < n; i++ {
  1932  					if diag == blas.NonUnit {
  1933  						x[ix] /= a[i*lda]
  1934  					}
  1935  					kk := min(k, n-i-1)
  1936  					xi := x[ix]
  1937  					jx := ix + incX
  1938  					for _, aij := range a[i*lda+1 : i*lda+kk+1] {
  1939  						x[jx] -= xi * aij
  1940  						jx += incX
  1941  					}
  1942  					ix += incX
  1943  				}
  1944  			}
  1945  		} else {
  1946  			if incX == 1 {
  1947  				for i := n - 1; i >= 0; i-- {
  1948  					if diag == blas.NonUnit {
  1949  						x[i] /= a[i*lda+k]
  1950  					}
  1951  					kk := min(k, i)
  1952  					xi := x[i]
  1953  					for j, aij := range a[i*lda+k-kk : i*lda+k] {
  1954  						x[i-kk+j] -= xi * aij
  1955  					}
  1956  				}
  1957  			} else {
  1958  				ix := kx + (n-1)*incX
  1959  				for i := n - 1; i >= 0; i-- {
  1960  					if diag == blas.NonUnit {
  1961  						x[ix] /= a[i*lda+k]
  1962  					}
  1963  					kk := min(k, i)
  1964  					xi := x[ix]
  1965  					jx := ix - kk*incX
  1966  					for _, aij := range a[i*lda+k-kk : i*lda+k] {
  1967  						x[jx] -= xi * aij
  1968  						jx += incX
  1969  					}
  1970  					ix -= incX
  1971  				}
  1972  			}
  1973  		}
  1974  	case blas.ConjTrans:
  1975  		if uplo == blas.Upper {
  1976  			if incX == 1 {
  1977  				for i := 0; i < n; i++ {
  1978  					if diag == blas.NonUnit {
  1979  						x[i] /= cmplx.Conj(a[i*lda])
  1980  					}
  1981  					kk := min(k, n-i-1)
  1982  					xi := x[i]
  1983  					for j, aij := range a[i*lda+1 : i*lda+kk+1] {
  1984  						x[i+1+j] -= xi * cmplx.Conj(aij)
  1985  					}
  1986  				}
  1987  			} else {
  1988  				ix := kx
  1989  				for i := 0; i < n; i++ {
  1990  					if diag == blas.NonUnit {
  1991  						x[ix] /= cmplx.Conj(a[i*lda])
  1992  					}
  1993  					kk := min(k, n-i-1)
  1994  					xi := x[ix]
  1995  					jx := ix + incX
  1996  					for _, aij := range a[i*lda+1 : i*lda+kk+1] {
  1997  						x[jx] -= xi * cmplx.Conj(aij)
  1998  						jx += incX
  1999  					}
  2000  					ix += incX
  2001  				}
  2002  			}
  2003  		} else {
  2004  			if incX == 1 {
  2005  				for i := n - 1; i >= 0; i-- {
  2006  					if diag == blas.NonUnit {
  2007  						x[i] /= cmplx.Conj(a[i*lda+k])
  2008  					}
  2009  					kk := min(k, i)
  2010  					xi := x[i]
  2011  					for j, aij := range a[i*lda+k-kk : i*lda+k] {
  2012  						x[i-kk+j] -= xi * cmplx.Conj(aij)
  2013  					}
  2014  				}
  2015  			} else {
  2016  				ix := kx + (n-1)*incX
  2017  				for i := n - 1; i >= 0; i-- {
  2018  					if diag == blas.NonUnit {
  2019  						x[ix] /= cmplx.Conj(a[i*lda+k])
  2020  					}
  2021  					kk := min(k, i)
  2022  					xi := x[ix]
  2023  					jx := ix - kk*incX
  2024  					for _, aij := range a[i*lda+k-kk : i*lda+k] {
  2025  						x[jx] -= xi * cmplx.Conj(aij)
  2026  						jx += incX
  2027  					}
  2028  					ix -= incX
  2029  				}
  2030  			}
  2031  		}
  2032  	}
  2033  }
  2034  
  2035  // Ztpmv performs one of the matrix-vector operations
  2036  //
  2037  //	x = A * x   if trans = blas.NoTrans
  2038  //	x = Aᵀ * x  if trans = blas.Trans
  2039  //	x = Aᴴ * x  if trans = blas.ConjTrans
  2040  //
  2041  // where x is an n element vector and A is an n×n triangular matrix, supplied in
  2042  // packed form.
  2043  func (Implementation) Ztpmv(uplo blas.Uplo, trans blas.Transpose, diag blas.Diag, n int, ap []complex128, x []complex128, incX int) {
  2044  	switch uplo {
  2045  	default:
  2046  		panic(badUplo)
  2047  	case blas.Upper, blas.Lower:
  2048  	}
  2049  	switch trans {
  2050  	default:
  2051  		panic(badTranspose)
  2052  	case blas.NoTrans, blas.Trans, blas.ConjTrans:
  2053  	}
  2054  	switch diag {
  2055  	default:
  2056  		panic(badDiag)
  2057  	case blas.NonUnit, blas.Unit:
  2058  	}
  2059  	if n < 0 {
  2060  		panic(nLT0)
  2061  	}
  2062  	if incX == 0 {
  2063  		panic(zeroIncX)
  2064  	}
  2065  
  2066  	// Quick return if possible.
  2067  	if n == 0 {
  2068  		return
  2069  	}
  2070  
  2071  	// For zero matrix size the following slice length checks are trivially satisfied.
  2072  	if len(ap) < n*(n+1)/2 {
  2073  		panic(shortAP)
  2074  	}
  2075  	if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
  2076  		panic(shortX)
  2077  	}
  2078  
  2079  	// Set up start index in X.
  2080  	var kx int
  2081  	if incX < 0 {
  2082  		kx = (1 - n) * incX
  2083  	}
  2084  
  2085  	// The elements of A are accessed sequentially with one pass through A.
  2086  
  2087  	if trans == blas.NoTrans {
  2088  		// Form x = A*x.
  2089  		if uplo == blas.Upper {
  2090  			// kk points to the current diagonal element in ap.
  2091  			kk := 0
  2092  			if incX == 1 {
  2093  				x = x[:n]
  2094  				for i := range x {
  2095  					if diag == blas.NonUnit {
  2096  						x[i] *= ap[kk]
  2097  					}
  2098  					if n-i-1 > 0 {
  2099  						x[i] += c128.DotuUnitary(ap[kk+1:kk+n-i], x[i+1:])
  2100  					}
  2101  					kk += n - i
  2102  				}
  2103  			} else {
  2104  				ix := kx
  2105  				for i := 0; i < n; i++ {
  2106  					if diag == blas.NonUnit {
  2107  						x[ix] *= ap[kk]
  2108  					}
  2109  					if n-i-1 > 0 {
  2110  						x[ix] += c128.DotuInc(ap[kk+1:kk+n-i], x, uintptr(n-i-1), 1, uintptr(incX), 0, uintptr(ix+incX))
  2111  					}
  2112  					ix += incX
  2113  					kk += n - i
  2114  				}
  2115  			}
  2116  		} else {
  2117  			// kk points to the beginning of current row in ap.
  2118  			kk := n*(n+1)/2 - n
  2119  			if incX == 1 {
  2120  				for i := n - 1; i >= 0; i-- {
  2121  					if diag == blas.NonUnit {
  2122  						x[i] *= ap[kk+i]
  2123  					}
  2124  					if i > 0 {
  2125  						x[i] += c128.DotuUnitary(ap[kk:kk+i], x[:i])
  2126  					}
  2127  					kk -= i
  2128  				}
  2129  			} else {
  2130  				ix := kx + (n-1)*incX
  2131  				for i := n - 1; i >= 0; i-- {
  2132  					if diag == blas.NonUnit {
  2133  						x[ix] *= ap[kk+i]
  2134  					}
  2135  					if i > 0 {
  2136  						x[ix] += c128.DotuInc(ap[kk:kk+i], x, uintptr(i), 1, uintptr(incX), 0, uintptr(kx))
  2137  					}
  2138  					ix -= incX
  2139  					kk -= i
  2140  				}
  2141  			}
  2142  		}
  2143  		return
  2144  	}
  2145  
  2146  	if trans == blas.Trans {
  2147  		// Form x = Aᵀ*x.
  2148  		if uplo == blas.Upper {
  2149  			// kk points to the current diagonal element in ap.
  2150  			kk := n*(n+1)/2 - 1
  2151  			if incX == 1 {
  2152  				for i := n - 1; i >= 0; i-- {
  2153  					xi := x[i]
  2154  					if diag == blas.NonUnit {
  2155  						x[i] *= ap[kk]
  2156  					}
  2157  					if n-i-1 > 0 {
  2158  						c128.AxpyUnitary(xi, ap[kk+1:kk+n-i], x[i+1:n])
  2159  					}
  2160  					kk -= n - i + 1
  2161  				}
  2162  			} else {
  2163  				ix := kx + (n-1)*incX
  2164  				for i := n - 1; i >= 0; i-- {
  2165  					xi := x[ix]
  2166  					if diag == blas.NonUnit {
  2167  						x[ix] *= ap[kk]
  2168  					}
  2169  					if n-i-1 > 0 {
  2170  						c128.AxpyInc(xi, ap[kk+1:kk+n-i], x, uintptr(n-i-1), 1, uintptr(incX), 0, uintptr(ix+incX))
  2171  					}
  2172  					ix -= incX
  2173  					kk -= n - i + 1
  2174  				}
  2175  			}
  2176  		} else {
  2177  			// kk points to the beginning of current row in ap.
  2178  			kk := 0
  2179  			if incX == 1 {
  2180  				x = x[:n]
  2181  				for i := range x {
  2182  					if i > 0 {
  2183  						c128.AxpyUnitary(x[i], ap[kk:kk+i], x[:i])
  2184  					}
  2185  					if diag == blas.NonUnit {
  2186  						x[i] *= ap[kk+i]
  2187  					}
  2188  					kk += i + 1
  2189  				}
  2190  			} else {
  2191  				ix := kx
  2192  				for i := 0; i < n; i++ {
  2193  					if i > 0 {
  2194  						c128.AxpyInc(x[ix], ap[kk:kk+i], x, uintptr(i), 1, uintptr(incX), 0, uintptr(kx))
  2195  					}
  2196  					if diag == blas.NonUnit {
  2197  						x[ix] *= ap[kk+i]
  2198  					}
  2199  					ix += incX
  2200  					kk += i + 1
  2201  				}
  2202  			}
  2203  		}
  2204  		return
  2205  	}
  2206  
  2207  	// Form x = Aᴴ*x.
  2208  	if uplo == blas.Upper {
  2209  		// kk points to the current diagonal element in ap.
  2210  		kk := n*(n+1)/2 - 1
  2211  		if incX == 1 {
  2212  			for i := n - 1; i >= 0; i-- {
  2213  				xi := x[i]
  2214  				if diag == blas.NonUnit {
  2215  					x[i] *= cmplx.Conj(ap[kk])
  2216  				}
  2217  				k := kk + 1
  2218  				for j := i + 1; j < n; j++ {
  2219  					x[j] += xi * cmplx.Conj(ap[k])
  2220  					k++
  2221  				}
  2222  				kk -= n - i + 1
  2223  			}
  2224  		} else {
  2225  			ix := kx + (n-1)*incX
  2226  			for i := n - 1; i >= 0; i-- {
  2227  				xi := x[ix]
  2228  				if diag == blas.NonUnit {
  2229  					x[ix] *= cmplx.Conj(ap[kk])
  2230  				}
  2231  				jx := ix + incX
  2232  				k := kk + 1
  2233  				for j := i + 1; j < n; j++ {
  2234  					x[jx] += xi * cmplx.Conj(ap[k])
  2235  					jx += incX
  2236  					k++
  2237  				}
  2238  				ix -= incX
  2239  				kk -= n - i + 1
  2240  			}
  2241  		}
  2242  	} else {
  2243  		// kk points to the beginning of current row in ap.
  2244  		kk := 0
  2245  		if incX == 1 {
  2246  			x = x[:n]
  2247  			for i, xi := range x {
  2248  				for j := 0; j < i; j++ {
  2249  					x[j] += xi * cmplx.Conj(ap[kk+j])
  2250  				}
  2251  				if diag == blas.NonUnit {
  2252  					x[i] *= cmplx.Conj(ap[kk+i])
  2253  				}
  2254  				kk += i + 1
  2255  			}
  2256  		} else {
  2257  			ix := kx
  2258  			for i := 0; i < n; i++ {
  2259  				xi := x[ix]
  2260  				jx := kx
  2261  				for j := 0; j < i; j++ {
  2262  					x[jx] += xi * cmplx.Conj(ap[kk+j])
  2263  					jx += incX
  2264  				}
  2265  				if diag == blas.NonUnit {
  2266  					x[ix] *= cmplx.Conj(ap[kk+i])
  2267  				}
  2268  				ix += incX
  2269  				kk += i + 1
  2270  			}
  2271  		}
  2272  	}
  2273  }
  2274  
  2275  // Ztpsv solves one of the systems of equations
  2276  //
  2277  //	A * x = b   if trans == blas.NoTrans
  2278  //	Aᵀ * x = b  if trans == blas.Trans
  2279  //	Aᴴ * x = b  if trans == blas.ConjTrans
  2280  //
  2281  // where b and x are n element vectors and A is an n×n triangular matrix in
  2282  // packed form.
  2283  //
  2284  // On entry, x contains the values of b, and the solution is
  2285  // stored in-place into x.
  2286  //
  2287  // No test for singularity or near-singularity is included in this
  2288  // routine. Such tests must be performed before calling this routine.
  2289  func (Implementation) Ztpsv(uplo blas.Uplo, trans blas.Transpose, diag blas.Diag, n int, ap []complex128, x []complex128, incX int) {
  2290  	switch uplo {
  2291  	default:
  2292  		panic(badUplo)
  2293  	case blas.Upper, blas.Lower:
  2294  	}
  2295  	switch trans {
  2296  	default:
  2297  		panic(badTranspose)
  2298  	case blas.NoTrans, blas.Trans, blas.ConjTrans:
  2299  	}
  2300  	switch diag {
  2301  	default:
  2302  		panic(badDiag)
  2303  	case blas.NonUnit, blas.Unit:
  2304  	}
  2305  	if n < 0 {
  2306  		panic(nLT0)
  2307  	}
  2308  	if incX == 0 {
  2309  		panic(zeroIncX)
  2310  	}
  2311  
  2312  	// Quick return if possible.
  2313  	if n == 0 {
  2314  		return
  2315  	}
  2316  
  2317  	// For zero matrix size the following slice length checks are trivially satisfied.
  2318  	if len(ap) < n*(n+1)/2 {
  2319  		panic(shortAP)
  2320  	}
  2321  	if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
  2322  		panic(shortX)
  2323  	}
  2324  
  2325  	// Set up start index in X.
  2326  	var kx int
  2327  	if incX < 0 {
  2328  		kx = (1 - n) * incX
  2329  	}
  2330  
  2331  	// The elements of A are accessed sequentially with one pass through ap.
  2332  
  2333  	if trans == blas.NoTrans {
  2334  		// Form x = inv(A)*x.
  2335  		if uplo == blas.Upper {
  2336  			kk := n*(n+1)/2 - 1
  2337  			if incX == 1 {
  2338  				for i := n - 1; i >= 0; i-- {
  2339  					aii := ap[kk]
  2340  					if n-i-1 > 0 {
  2341  						x[i] -= c128.DotuUnitary(x[i+1:n], ap[kk+1:kk+n-i])
  2342  					}
  2343  					if diag == blas.NonUnit {
  2344  						x[i] /= aii
  2345  					}
  2346  					kk -= n - i + 1
  2347  				}
  2348  			} else {
  2349  				ix := kx + (n-1)*incX
  2350  				for i := n - 1; i >= 0; i-- {
  2351  					aii := ap[kk]
  2352  					if n-i-1 > 0 {
  2353  						x[ix] -= c128.DotuInc(x, ap[kk+1:kk+n-i], uintptr(n-i-1), uintptr(incX), 1, uintptr(ix+incX), 0)
  2354  					}
  2355  					if diag == blas.NonUnit {
  2356  						x[ix] /= aii
  2357  					}
  2358  					ix -= incX
  2359  					kk -= n - i + 1
  2360  				}
  2361  			}
  2362  		} else {
  2363  			kk := 0
  2364  			if incX == 1 {
  2365  				for i := 0; i < n; i++ {
  2366  					if i > 0 {
  2367  						x[i] -= c128.DotuUnitary(x[:i], ap[kk:kk+i])
  2368  					}
  2369  					if diag == blas.NonUnit {
  2370  						x[i] /= ap[kk+i]
  2371  					}
  2372  					kk += i + 1
  2373  				}
  2374  			} else {
  2375  				ix := kx
  2376  				for i := 0; i < n; i++ {
  2377  					if i > 0 {
  2378  						x[ix] -= c128.DotuInc(x, ap[kk:kk+i], uintptr(i), uintptr(incX), 1, uintptr(kx), 0)
  2379  					}
  2380  					if diag == blas.NonUnit {
  2381  						x[ix] /= ap[kk+i]
  2382  					}
  2383  					ix += incX
  2384  					kk += i + 1
  2385  				}
  2386  			}
  2387  		}
  2388  		return
  2389  	}
  2390  
  2391  	if trans == blas.Trans {
  2392  		// Form x = inv(Aᵀ)*x.
  2393  		if uplo == blas.Upper {
  2394  			kk := 0
  2395  			if incX == 1 {
  2396  				for j := 0; j < n; j++ {
  2397  					if diag == blas.NonUnit {
  2398  						x[j] /= ap[kk]
  2399  					}
  2400  					if n-j-1 > 0 {
  2401  						c128.AxpyUnitary(-x[j], ap[kk+1:kk+n-j], x[j+1:n])
  2402  					}
  2403  					kk += n - j
  2404  				}
  2405  			} else {
  2406  				jx := kx
  2407  				for j := 0; j < n; j++ {
  2408  					if diag == blas.NonUnit {
  2409  						x[jx] /= ap[kk]
  2410  					}
  2411  					if n-j-1 > 0 {
  2412  						c128.AxpyInc(-x[jx], ap[kk+1:kk+n-j], x, uintptr(n-j-1), 1, uintptr(incX), 0, uintptr(jx+incX))
  2413  					}
  2414  					jx += incX
  2415  					kk += n - j
  2416  				}
  2417  			}
  2418  		} else {
  2419  			kk := n*(n+1)/2 - n
  2420  			if incX == 1 {
  2421  				for j := n - 1; j >= 0; j-- {
  2422  					if diag == blas.NonUnit {
  2423  						x[j] /= ap[kk+j]
  2424  					}
  2425  					if j > 0 {
  2426  						c128.AxpyUnitary(-x[j], ap[kk:kk+j], x[:j])
  2427  					}
  2428  					kk -= j
  2429  				}
  2430  			} else {
  2431  				jx := kx + (n-1)*incX
  2432  				for j := n - 1; j >= 0; j-- {
  2433  					if diag == blas.NonUnit {
  2434  						x[jx] /= ap[kk+j]
  2435  					}
  2436  					if j > 0 {
  2437  						c128.AxpyInc(-x[jx], ap[kk:kk+j], x, uintptr(j), 1, uintptr(incX), 0, uintptr(kx))
  2438  					}
  2439  					jx -= incX
  2440  					kk -= j
  2441  				}
  2442  			}
  2443  		}
  2444  		return
  2445  	}
  2446  
  2447  	// Form x = inv(Aᴴ)*x.
  2448  	if uplo == blas.Upper {
  2449  		kk := 0
  2450  		if incX == 1 {
  2451  			for j := 0; j < n; j++ {
  2452  				if diag == blas.NonUnit {
  2453  					x[j] /= cmplx.Conj(ap[kk])
  2454  				}
  2455  				xj := x[j]
  2456  				k := kk + 1
  2457  				for i := j + 1; i < n; i++ {
  2458  					x[i] -= xj * cmplx.Conj(ap[k])
  2459  					k++
  2460  				}
  2461  				kk += n - j
  2462  			}
  2463  		} else {
  2464  			jx := kx
  2465  			for j := 0; j < n; j++ {
  2466  				if diag == blas.NonUnit {
  2467  					x[jx] /= cmplx.Conj(ap[kk])
  2468  				}
  2469  				xj := x[jx]
  2470  				ix := jx + incX
  2471  				k := kk + 1
  2472  				for i := j + 1; i < n; i++ {
  2473  					x[ix] -= xj * cmplx.Conj(ap[k])
  2474  					ix += incX
  2475  					k++
  2476  				}
  2477  				jx += incX
  2478  				kk += n - j
  2479  			}
  2480  		}
  2481  	} else {
  2482  		kk := n*(n+1)/2 - n
  2483  		if incX == 1 {
  2484  			for j := n - 1; j >= 0; j-- {
  2485  				if diag == blas.NonUnit {
  2486  					x[j] /= cmplx.Conj(ap[kk+j])
  2487  				}
  2488  				xj := x[j]
  2489  				for i := 0; i < j; i++ {
  2490  					x[i] -= xj * cmplx.Conj(ap[kk+i])
  2491  				}
  2492  				kk -= j
  2493  			}
  2494  		} else {
  2495  			jx := kx + (n-1)*incX
  2496  			for j := n - 1; j >= 0; j-- {
  2497  				if diag == blas.NonUnit {
  2498  					x[jx] /= cmplx.Conj(ap[kk+j])
  2499  				}
  2500  				xj := x[jx]
  2501  				ix := kx
  2502  				for i := 0; i < j; i++ {
  2503  					x[ix] -= xj * cmplx.Conj(ap[kk+i])
  2504  					ix += incX
  2505  				}
  2506  				jx -= incX
  2507  				kk -= j
  2508  			}
  2509  		}
  2510  	}
  2511  }
  2512  
  2513  // Ztrmv performs one of the matrix-vector operations
  2514  //
  2515  //	x = A * x   if trans = blas.NoTrans
  2516  //	x = Aᵀ * x  if trans = blas.Trans
  2517  //	x = Aᴴ * x  if trans = blas.ConjTrans
  2518  //
  2519  // where x is a vector, and A is an n×n triangular matrix.
  2520  func (Implementation) Ztrmv(uplo blas.Uplo, trans blas.Transpose, diag blas.Diag, n int, a []complex128, lda int, x []complex128, incX int) {
  2521  	switch trans {
  2522  	default:
  2523  		panic(badTranspose)
  2524  	case blas.NoTrans, blas.Trans, blas.ConjTrans:
  2525  	}
  2526  	switch uplo {
  2527  	default:
  2528  		panic(badUplo)
  2529  	case blas.Upper, blas.Lower:
  2530  	}
  2531  	switch diag {
  2532  	default:
  2533  		panic(badDiag)
  2534  	case blas.NonUnit, blas.Unit:
  2535  	}
  2536  	if n < 0 {
  2537  		panic(nLT0)
  2538  	}
  2539  	if lda < max(1, n) {
  2540  		panic(badLdA)
  2541  	}
  2542  	if incX == 0 {
  2543  		panic(zeroIncX)
  2544  	}
  2545  
  2546  	// Quick return if possible.
  2547  	if n == 0 {
  2548  		return
  2549  	}
  2550  
  2551  	// For zero matrix size the following slice length checks are trivially satisfied.
  2552  	if len(a) < lda*(n-1)+n {
  2553  		panic(shortA)
  2554  	}
  2555  	if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
  2556  		panic(shortX)
  2557  	}
  2558  
  2559  	// Set up start index in X.
  2560  	var kx int
  2561  	if incX < 0 {
  2562  		kx = (1 - n) * incX
  2563  	}
  2564  
  2565  	// The elements of A are accessed sequentially with one pass through A.
  2566  
  2567  	if trans == blas.NoTrans {
  2568  		// Form x = A*x.
  2569  		if uplo == blas.Upper {
  2570  			if incX == 1 {
  2571  				for i := 0; i < n; i++ {
  2572  					if diag == blas.NonUnit {
  2573  						x[i] *= a[i*lda+i]
  2574  					}
  2575  					if n-i-1 > 0 {
  2576  						x[i] += c128.DotuUnitary(a[i*lda+i+1:i*lda+n], x[i+1:n])
  2577  					}
  2578  				}
  2579  			} else {
  2580  				ix := kx
  2581  				for i := 0; i < n; i++ {
  2582  					if diag == blas.NonUnit {
  2583  						x[ix] *= a[i*lda+i]
  2584  					}
  2585  					if n-i-1 > 0 {
  2586  						x[ix] += c128.DotuInc(a[i*lda+i+1:i*lda+n], x, uintptr(n-i-1), 1, uintptr(incX), 0, uintptr(ix+incX))
  2587  					}
  2588  					ix += incX
  2589  				}
  2590  			}
  2591  		} else {
  2592  			if incX == 1 {
  2593  				for i := n - 1; i >= 0; i-- {
  2594  					if diag == blas.NonUnit {
  2595  						x[i] *= a[i*lda+i]
  2596  					}
  2597  					if i > 0 {
  2598  						x[i] += c128.DotuUnitary(a[i*lda:i*lda+i], x[:i])
  2599  					}
  2600  				}
  2601  			} else {
  2602  				ix := kx + (n-1)*incX
  2603  				for i := n - 1; i >= 0; i-- {
  2604  					if diag == blas.NonUnit {
  2605  						x[ix] *= a[i*lda+i]
  2606  					}
  2607  					if i > 0 {
  2608  						x[ix] += c128.DotuInc(a[i*lda:i*lda+i], x, uintptr(i), 1, uintptr(incX), 0, uintptr(kx))
  2609  					}
  2610  					ix -= incX
  2611  				}
  2612  			}
  2613  		}
  2614  		return
  2615  	}
  2616  
  2617  	if trans == blas.Trans {
  2618  		// Form x = Aᵀ*x.
  2619  		if uplo == blas.Upper {
  2620  			if incX == 1 {
  2621  				for i := n - 1; i >= 0; i-- {
  2622  					xi := x[i]
  2623  					if diag == blas.NonUnit {
  2624  						x[i] *= a[i*lda+i]
  2625  					}
  2626  					if n-i-1 > 0 {
  2627  						c128.AxpyUnitary(xi, a[i*lda+i+1:i*lda+n], x[i+1:n])
  2628  					}
  2629  				}
  2630  			} else {
  2631  				ix := kx + (n-1)*incX
  2632  				for i := n - 1; i >= 0; i-- {
  2633  					xi := x[ix]
  2634  					if diag == blas.NonUnit {
  2635  						x[ix] *= a[i*lda+i]
  2636  					}
  2637  					if n-i-1 > 0 {
  2638  						c128.AxpyInc(xi, a[i*lda+i+1:i*lda+n], x, uintptr(n-i-1), 1, uintptr(incX), 0, uintptr(ix+incX))
  2639  					}
  2640  					ix -= incX
  2641  				}
  2642  			}
  2643  		} else {
  2644  			if incX == 1 {
  2645  				for i := 0; i < n; i++ {
  2646  					if i > 0 {
  2647  						c128.AxpyUnitary(x[i], a[i*lda:i*lda+i], x[:i])
  2648  					}
  2649  					if diag == blas.NonUnit {
  2650  						x[i] *= a[i*lda+i]
  2651  					}
  2652  				}
  2653  			} else {
  2654  				ix := kx
  2655  				for i := 0; i < n; i++ {
  2656  					if i > 0 {
  2657  						c128.AxpyInc(x[ix], a[i*lda:i*lda+i], x, uintptr(i), 1, uintptr(incX), 0, uintptr(kx))
  2658  					}
  2659  					if diag == blas.NonUnit {
  2660  						x[ix] *= a[i*lda+i]
  2661  					}
  2662  					ix += incX
  2663  				}
  2664  			}
  2665  		}
  2666  		return
  2667  	}
  2668  
  2669  	// Form x = Aᴴ*x.
  2670  	if uplo == blas.Upper {
  2671  		if incX == 1 {
  2672  			for i := n - 1; i >= 0; i-- {
  2673  				xi := x[i]
  2674  				if diag == blas.NonUnit {
  2675  					x[i] *= cmplx.Conj(a[i*lda+i])
  2676  				}
  2677  				for j := i + 1; j < n; j++ {
  2678  					x[j] += xi * cmplx.Conj(a[i*lda+j])
  2679  				}
  2680  			}
  2681  		} else {
  2682  			ix := kx + (n-1)*incX
  2683  			for i := n - 1; i >= 0; i-- {
  2684  				xi := x[ix]
  2685  				if diag == blas.NonUnit {
  2686  					x[ix] *= cmplx.Conj(a[i*lda+i])
  2687  				}
  2688  				jx := ix + incX
  2689  				for j := i + 1; j < n; j++ {
  2690  					x[jx] += xi * cmplx.Conj(a[i*lda+j])
  2691  					jx += incX
  2692  				}
  2693  				ix -= incX
  2694  			}
  2695  		}
  2696  	} else {
  2697  		if incX == 1 {
  2698  			for i := 0; i < n; i++ {
  2699  				for j := 0; j < i; j++ {
  2700  					x[j] += x[i] * cmplx.Conj(a[i*lda+j])
  2701  				}
  2702  				if diag == blas.NonUnit {
  2703  					x[i] *= cmplx.Conj(a[i*lda+i])
  2704  				}
  2705  			}
  2706  		} else {
  2707  			ix := kx
  2708  			for i := 0; i < n; i++ {
  2709  				jx := kx
  2710  				for j := 0; j < i; j++ {
  2711  					x[jx] += x[ix] * cmplx.Conj(a[i*lda+j])
  2712  					jx += incX
  2713  				}
  2714  				if diag == blas.NonUnit {
  2715  					x[ix] *= cmplx.Conj(a[i*lda+i])
  2716  				}
  2717  				ix += incX
  2718  			}
  2719  		}
  2720  	}
  2721  }
  2722  
  2723  // Ztrsv solves one of the systems of equations
  2724  //
  2725  //	A * x = b   if trans == blas.NoTrans
  2726  //	Aᵀ * x = b  if trans == blas.Trans
  2727  //	Aᴴ * x = b  if trans == blas.ConjTrans
  2728  //
  2729  // where b and x are n element vectors and A is an n×n triangular matrix.
  2730  //
  2731  // On entry, x contains the values of b, and the solution is
  2732  // stored in-place into x.
  2733  //
  2734  // No test for singularity or near-singularity is included in this
  2735  // routine. Such tests must be performed before calling this routine.
  2736  func (Implementation) Ztrsv(uplo blas.Uplo, trans blas.Transpose, diag blas.Diag, n int, a []complex128, lda int, x []complex128, incX int) {
  2737  	switch trans {
  2738  	default:
  2739  		panic(badTranspose)
  2740  	case blas.NoTrans, blas.Trans, blas.ConjTrans:
  2741  	}
  2742  	switch uplo {
  2743  	default:
  2744  		panic(badUplo)
  2745  	case blas.Upper, blas.Lower:
  2746  	}
  2747  	switch diag {
  2748  	default:
  2749  		panic(badDiag)
  2750  	case blas.NonUnit, blas.Unit:
  2751  	}
  2752  	if n < 0 {
  2753  		panic(nLT0)
  2754  	}
  2755  	if lda < max(1, n) {
  2756  		panic(badLdA)
  2757  	}
  2758  	if incX == 0 {
  2759  		panic(zeroIncX)
  2760  	}
  2761  
  2762  	// Quick return if possible.
  2763  	if n == 0 {
  2764  		return
  2765  	}
  2766  
  2767  	// For zero matrix size the following slice length checks are trivially satisfied.
  2768  	if len(a) < lda*(n-1)+n {
  2769  		panic(shortA)
  2770  	}
  2771  	if (incX > 0 && len(x) <= (n-1)*incX) || (incX < 0 && len(x) <= (1-n)*incX) {
  2772  		panic(shortX)
  2773  	}
  2774  
  2775  	// Set up start index in X.
  2776  	var kx int
  2777  	if incX < 0 {
  2778  		kx = (1 - n) * incX
  2779  	}
  2780  
  2781  	// The elements of A are accessed sequentially with one pass through A.
  2782  
  2783  	if trans == blas.NoTrans {
  2784  		// Form x = inv(A)*x.
  2785  		if uplo == blas.Upper {
  2786  			if incX == 1 {
  2787  				for i := n - 1; i >= 0; i-- {
  2788  					aii := a[i*lda+i]
  2789  					if n-i-1 > 0 {
  2790  						x[i] -= c128.DotuUnitary(x[i+1:n], a[i*lda+i+1:i*lda+n])
  2791  					}
  2792  					if diag == blas.NonUnit {
  2793  						x[i] /= aii
  2794  					}
  2795  				}
  2796  			} else {
  2797  				ix := kx + (n-1)*incX
  2798  				for i := n - 1; i >= 0; i-- {
  2799  					aii := a[i*lda+i]
  2800  					if n-i-1 > 0 {
  2801  						x[ix] -= c128.DotuInc(x, a[i*lda+i+1:i*lda+n], uintptr(n-i-1), uintptr(incX), 1, uintptr(ix+incX), 0)
  2802  					}
  2803  					if diag == blas.NonUnit {
  2804  						x[ix] /= aii
  2805  					}
  2806  					ix -= incX
  2807  				}
  2808  			}
  2809  		} else {
  2810  			if incX == 1 {
  2811  				for i := 0; i < n; i++ {
  2812  					if i > 0 {
  2813  						x[i] -= c128.DotuUnitary(x[:i], a[i*lda:i*lda+i])
  2814  					}
  2815  					if diag == blas.NonUnit {
  2816  						x[i] /= a[i*lda+i]
  2817  					}
  2818  				}
  2819  			} else {
  2820  				ix := kx
  2821  				for i := 0; i < n; i++ {
  2822  					if i > 0 {
  2823  						x[ix] -= c128.DotuInc(x, a[i*lda:i*lda+i], uintptr(i), uintptr(incX), 1, uintptr(kx), 0)
  2824  					}
  2825  					if diag == blas.NonUnit {
  2826  						x[ix] /= a[i*lda+i]
  2827  					}
  2828  					ix += incX
  2829  				}
  2830  			}
  2831  		}
  2832  		return
  2833  	}
  2834  
  2835  	if trans == blas.Trans {
  2836  		// Form x = inv(Aᵀ)*x.
  2837  		if uplo == blas.Upper {
  2838  			if incX == 1 {
  2839  				for j := 0; j < n; j++ {
  2840  					if diag == blas.NonUnit {
  2841  						x[j] /= a[j*lda+j]
  2842  					}
  2843  					if n-j-1 > 0 {
  2844  						c128.AxpyUnitary(-x[j], a[j*lda+j+1:j*lda+n], x[j+1:n])
  2845  					}
  2846  				}
  2847  			} else {
  2848  				jx := kx
  2849  				for j := 0; j < n; j++ {
  2850  					if diag == blas.NonUnit {
  2851  						x[jx] /= a[j*lda+j]
  2852  					}
  2853  					if n-j-1 > 0 {
  2854  						c128.AxpyInc(-x[jx], a[j*lda+j+1:j*lda+n], x, uintptr(n-j-1), 1, uintptr(incX), 0, uintptr(jx+incX))
  2855  					}
  2856  					jx += incX
  2857  				}
  2858  			}
  2859  		} else {
  2860  			if incX == 1 {
  2861  				for j := n - 1; j >= 0; j-- {
  2862  					if diag == blas.NonUnit {
  2863  						x[j] /= a[j*lda+j]
  2864  					}
  2865  					xj := x[j]
  2866  					if j > 0 {
  2867  						c128.AxpyUnitary(-xj, a[j*lda:j*lda+j], x[:j])
  2868  					}
  2869  				}
  2870  			} else {
  2871  				jx := kx + (n-1)*incX
  2872  				for j := n - 1; j >= 0; j-- {
  2873  					if diag == blas.NonUnit {
  2874  						x[jx] /= a[j*lda+j]
  2875  					}
  2876  					if j > 0 {
  2877  						c128.AxpyInc(-x[jx], a[j*lda:j*lda+j], x, uintptr(j), 1, uintptr(incX), 0, uintptr(kx))
  2878  					}
  2879  					jx -= incX
  2880  				}
  2881  			}
  2882  		}
  2883  		return
  2884  	}
  2885  
  2886  	// Form x = inv(Aᴴ)*x.
  2887  	if uplo == blas.Upper {
  2888  		if incX == 1 {
  2889  			for j := 0; j < n; j++ {
  2890  				if diag == blas.NonUnit {
  2891  					x[j] /= cmplx.Conj(a[j*lda+j])
  2892  				}
  2893  				xj := x[j]
  2894  				for i := j + 1; i < n; i++ {
  2895  					x[i] -= xj * cmplx.Conj(a[j*lda+i])
  2896  				}
  2897  			}
  2898  		} else {
  2899  			jx := kx
  2900  			for j := 0; j < n; j++ {
  2901  				if diag == blas.NonUnit {
  2902  					x[jx] /= cmplx.Conj(a[j*lda+j])
  2903  				}
  2904  				xj := x[jx]
  2905  				ix := jx + incX
  2906  				for i := j + 1; i < n; i++ {
  2907  					x[ix] -= xj * cmplx.Conj(a[j*lda+i])
  2908  					ix += incX
  2909  				}
  2910  				jx += incX
  2911  			}
  2912  		}
  2913  	} else {
  2914  		if incX == 1 {
  2915  			for j := n - 1; j >= 0; j-- {
  2916  				if diag == blas.NonUnit {
  2917  					x[j] /= cmplx.Conj(a[j*lda+j])
  2918  				}
  2919  				xj := x[j]
  2920  				for i := 0; i < j; i++ {
  2921  					x[i] -= xj * cmplx.Conj(a[j*lda+i])
  2922  				}
  2923  			}
  2924  		} else {
  2925  			jx := kx + (n-1)*incX
  2926  			for j := n - 1; j >= 0; j-- {
  2927  				if diag == blas.NonUnit {
  2928  					x[jx] /= cmplx.Conj(a[j*lda+j])
  2929  				}
  2930  				xj := x[jx]
  2931  				ix := kx
  2932  				for i := 0; i < j; i++ {
  2933  					x[ix] -= xj * cmplx.Conj(a[j*lda+i])
  2934  					ix += incX
  2935  				}
  2936  				jx -= incX
  2937  			}
  2938  		}
  2939  	}
  2940  }