mirror of
				https://github.com/gonum/gonum.git
				synced 2025-10-31 02:26:59 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			680 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			680 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright ©2020 The Gonum Authors. All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style
 | |
| // license that can be found in the LICENSE file.
 | |
| 
 | |
| package testlapack
 | |
| 
 | |
| import (
 | |
| 	"math"
 | |
| 
 | |
| 	"gonum.org/v1/gonum/blas"
 | |
| 	"gonum.org/v1/gonum/internal/asm/f64"
 | |
| 	"gonum.org/v1/gonum/lapack"
 | |
| )
 | |
| 
 | |
| // dlagtm is a local implementation of Dlagtm to keep code paths independent.
 | |
| func dlagtm(trans blas.Transpose, m, n int, alpha float64, dl, d, du []float64, b []float64, ldb int, beta float64, c []float64, ldc int) {
 | |
| 	if m == 0 || n == 0 {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	if beta != 1 {
 | |
| 		if beta == 0 {
 | |
| 			for i := 0; i < m; i++ {
 | |
| 				ci := c[i*ldc : i*ldc+n]
 | |
| 				for j := range ci {
 | |
| 					ci[j] = 0
 | |
| 				}
 | |
| 			}
 | |
| 		} else {
 | |
| 			for i := 0; i < m; i++ {
 | |
| 				ci := c[i*ldc : i*ldc+n]
 | |
| 				for j := range ci {
 | |
| 					ci[j] *= beta
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if alpha == 0 {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	if m == 1 {
 | |
| 		if alpha == 1 {
 | |
| 			for j := 0; j < n; j++ {
 | |
| 				c[j] += d[0] * b[j]
 | |
| 			}
 | |
| 		} else {
 | |
| 			for j := 0; j < n; j++ {
 | |
| 				c[j] += alpha * d[0] * b[j]
 | |
| 			}
 | |
| 		}
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	if trans != blas.NoTrans {
 | |
| 		dl, du = du, dl
 | |
| 	}
 | |
| 
 | |
| 	if alpha == 1 {
 | |
| 		for j := 0; j < n; j++ {
 | |
| 			c[j] += d[0]*b[j] + du[0]*b[ldb+j]
 | |
| 		}
 | |
| 		for i := 1; i < m-1; i++ {
 | |
| 			for j := 0; j < n; j++ {
 | |
| 				c[i*ldc+j] += dl[i-1]*b[(i-1)*ldb+j] + d[i]*b[i*ldb+j] + du[i]*b[(i+1)*ldb+j]
 | |
| 			}
 | |
| 		}
 | |
| 		for j := 0; j < n; j++ {
 | |
| 			c[(m-1)*ldc+j] += dl[m-2]*b[(m-2)*ldb+j] + d[m-1]*b[(m-1)*ldb+j]
 | |
| 		}
 | |
| 	} else {
 | |
| 		for j := 0; j < n; j++ {
 | |
| 			c[j] += alpha * (d[0]*b[j] + du[0]*b[ldb+j])
 | |
| 		}
 | |
| 		for i := 1; i < m-1; i++ {
 | |
| 			for j := 0; j < n; j++ {
 | |
| 				c[i*ldc+j] += alpha * (dl[i-1]*b[(i-1)*ldb+j] + d[i]*b[i*ldb+j] + du[i]*b[(i+1)*ldb+j])
 | |
| 			}
 | |
| 		}
 | |
| 		for j := 0; j < n; j++ {
 | |
| 			c[(m-1)*ldc+j] += alpha * (dl[m-2]*b[(m-2)*ldb+j] + d[m-1]*b[(m-1)*ldb+j])
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // dlangt is a local implementation of Dlangt to keep code paths independent.
 | |
| func dlangt(norm lapack.MatrixNorm, n int, dl, d, du []float64) float64 {
 | |
| 	if n == 0 {
 | |
| 		return 0
 | |
| 	}
 | |
| 
 | |
| 	dl = dl[:n-1]
 | |
| 	d = d[:n]
 | |
| 	du = du[:n-1]
 | |
| 
 | |
| 	var anorm float64
 | |
| 	switch norm {
 | |
| 	case lapack.MaxAbs:
 | |
| 		for _, diag := range [][]float64{dl, d, du} {
 | |
| 			for _, di := range diag {
 | |
| 				if math.IsNaN(di) {
 | |
| 					return di
 | |
| 				}
 | |
| 				di = math.Abs(di)
 | |
| 				if di > anorm {
 | |
| 					anorm = di
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	case lapack.MaxColumnSum:
 | |
| 		if n == 1 {
 | |
| 			return math.Abs(d[0])
 | |
| 		}
 | |
| 		anorm = math.Abs(d[0]) + math.Abs(dl[0])
 | |
| 		if math.IsNaN(anorm) {
 | |
| 			return anorm
 | |
| 		}
 | |
| 		tmp := math.Abs(du[n-2]) + math.Abs(d[n-1])
 | |
| 		if math.IsNaN(tmp) {
 | |
| 			return tmp
 | |
| 		}
 | |
| 		if tmp > anorm {
 | |
| 			anorm = tmp
 | |
| 		}
 | |
| 		for i := 1; i < n-1; i++ {
 | |
| 			tmp = math.Abs(du[i-1]) + math.Abs(d[i]) + math.Abs(dl[i])
 | |
| 			if math.IsNaN(tmp) {
 | |
| 				return tmp
 | |
| 			}
 | |
| 			if tmp > anorm {
 | |
| 				anorm = tmp
 | |
| 			}
 | |
| 		}
 | |
| 	case lapack.MaxRowSum:
 | |
| 		if n == 1 {
 | |
| 			return math.Abs(d[0])
 | |
| 		}
 | |
| 		anorm = math.Abs(d[0]) + math.Abs(du[0])
 | |
| 		if math.IsNaN(anorm) {
 | |
| 			return anorm
 | |
| 		}
 | |
| 		tmp := math.Abs(dl[n-2]) + math.Abs(d[n-1])
 | |
| 		if math.IsNaN(tmp) {
 | |
| 			return tmp
 | |
| 		}
 | |
| 		if tmp > anorm {
 | |
| 			anorm = tmp
 | |
| 		}
 | |
| 		for i := 1; i < n-1; i++ {
 | |
| 			tmp = math.Abs(dl[i-1]) + math.Abs(d[i]) + math.Abs(du[i])
 | |
| 			if math.IsNaN(tmp) {
 | |
| 				return tmp
 | |
| 			}
 | |
| 			if tmp > anorm {
 | |
| 				anorm = tmp
 | |
| 			}
 | |
| 		}
 | |
| 	case lapack.Frobenius:
 | |
| 		panic("not implemented")
 | |
| 	default:
 | |
| 		panic("invalid norm")
 | |
| 	}
 | |
| 	return anorm
 | |
| }
 | |
| 
 | |
| // dlansy is a local implementation of Dlansy to keep code paths independent.
 | |
| func dlansy(norm lapack.MatrixNorm, uplo blas.Uplo, n int, a []float64, lda int) float64 {
 | |
| 	if n == 0 {
 | |
| 		return 0
 | |
| 	}
 | |
| 	work := make([]float64, n)
 | |
| 	switch norm {
 | |
| 	case lapack.MaxAbs:
 | |
| 		if uplo == blas.Upper {
 | |
| 			var max float64
 | |
| 			for i := 0; i < n; i++ {
 | |
| 				for j := i; j < n; j++ {
 | |
| 					v := math.Abs(a[i*lda+j])
 | |
| 					if math.IsNaN(v) {
 | |
| 						return math.NaN()
 | |
| 					}
 | |
| 					if v > max {
 | |
| 						max = v
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			return max
 | |
| 		}
 | |
| 		var max float64
 | |
| 		for i := 0; i < n; i++ {
 | |
| 			for j := 0; j <= i; j++ {
 | |
| 				v := math.Abs(a[i*lda+j])
 | |
| 				if math.IsNaN(v) {
 | |
| 					return math.NaN()
 | |
| 				}
 | |
| 				if v > max {
 | |
| 					max = v
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		return max
 | |
| 	case lapack.MaxRowSum, lapack.MaxColumnSum:
 | |
| 		// A symmetric matrix has the same 1-norm and ∞-norm.
 | |
| 		for i := 0; i < n; i++ {
 | |
| 			work[i] = 0
 | |
| 		}
 | |
| 		if uplo == blas.Upper {
 | |
| 			for i := 0; i < n; i++ {
 | |
| 				work[i] += math.Abs(a[i*lda+i])
 | |
| 				for j := i + 1; j < n; j++ {
 | |
| 					v := math.Abs(a[i*lda+j])
 | |
| 					work[i] += v
 | |
| 					work[j] += v
 | |
| 				}
 | |
| 			}
 | |
| 		} else {
 | |
| 			for i := 0; i < n; i++ {
 | |
| 				for j := 0; j < i; j++ {
 | |
| 					v := math.Abs(a[i*lda+j])
 | |
| 					work[i] += v
 | |
| 					work[j] += v
 | |
| 				}
 | |
| 				work[i] += math.Abs(a[i*lda+i])
 | |
| 			}
 | |
| 		}
 | |
| 		var max float64
 | |
| 		for i := 0; i < n; i++ {
 | |
| 			v := work[i]
 | |
| 			if math.IsNaN(v) {
 | |
| 				return math.NaN()
 | |
| 			}
 | |
| 			if v > max {
 | |
| 				max = v
 | |
| 			}
 | |
| 		}
 | |
| 		return max
 | |
| 	case lapack.Frobenius:
 | |
| 		panic("not implemented")
 | |
| 	default:
 | |
| 		panic("invalid norm")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // dlange is a local implementation of Dlange to keep code paths independent.
 | |
| func dlange(norm lapack.MatrixNorm, m, n int, a []float64, lda int) float64 {
 | |
| 	if m == 0 || n == 0 {
 | |
| 		return 0
 | |
| 	}
 | |
| 	var value float64
 | |
| 	switch norm {
 | |
| 	case lapack.MaxAbs:
 | |
| 		for i := 0; i < m; i++ {
 | |
| 			for j := 0; j < n; j++ {
 | |
| 				value = math.Max(value, math.Abs(a[i*lda+j]))
 | |
| 			}
 | |
| 		}
 | |
| 	case lapack.MaxColumnSum:
 | |
| 		work := make([]float64, n)
 | |
| 		for i := 0; i < m; i++ {
 | |
| 			for j := 0; j < n; j++ {
 | |
| 				work[j] += math.Abs(a[i*lda+j])
 | |
| 			}
 | |
| 		}
 | |
| 		for i := 0; i < n; i++ {
 | |
| 			value = math.Max(value, work[i])
 | |
| 		}
 | |
| 	case lapack.MaxRowSum:
 | |
| 		for i := 0; i < m; i++ {
 | |
| 			var sum float64
 | |
| 			for j := 0; j < n; j++ {
 | |
| 				sum += math.Abs(a[i*lda+j])
 | |
| 			}
 | |
| 			value = math.Max(value, sum)
 | |
| 		}
 | |
| 	case lapack.Frobenius:
 | |
| 		for i := 0; i < m; i++ {
 | |
| 			row := f64.L2NormUnitary(a[i*lda : i*lda+n])
 | |
| 			value = math.Hypot(value, row)
 | |
| 		}
 | |
| 	default:
 | |
| 		panic("invalid norm")
 | |
| 	}
 | |
| 	return value
 | |
| }
 | |
| 
 | |
| // dlansb is a local implementation of Dlansb to keep code paths independent.
 | |
| func dlansb(norm lapack.MatrixNorm, uplo blas.Uplo, n, kd int, ab []float64, ldab int, work []float64) float64 {
 | |
| 	if n == 0 {
 | |
| 		return 0
 | |
| 	}
 | |
| 	var value float64
 | |
| 	switch norm {
 | |
| 	case lapack.MaxAbs:
 | |
| 		if uplo == blas.Upper {
 | |
| 			for i := 0; i < n; i++ {
 | |
| 				for j := 0; j < min(n-i, kd+1); j++ {
 | |
| 					aij := math.Abs(ab[i*ldab+j])
 | |
| 					if aij > value || math.IsNaN(aij) {
 | |
| 						value = aij
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		} else {
 | |
| 			for i := 0; i < n; i++ {
 | |
| 				for j := max(0, kd-i); j < kd+1; j++ {
 | |
| 					aij := math.Abs(ab[i*ldab+j])
 | |
| 					if aij > value || math.IsNaN(aij) {
 | |
| 						value = aij
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	case lapack.MaxColumnSum, lapack.MaxRowSum:
 | |
| 		work = work[:n]
 | |
| 		var sum float64
 | |
| 		if uplo == blas.Upper {
 | |
| 			for i := range work {
 | |
| 				work[i] = 0
 | |
| 			}
 | |
| 			for i := 0; i < n; i++ {
 | |
| 				sum := work[i] + math.Abs(ab[i*ldab])
 | |
| 				for j := i + 1; j < min(i+kd+1, n); j++ {
 | |
| 					aij := math.Abs(ab[i*ldab+j-i])
 | |
| 					sum += aij
 | |
| 					work[j] += aij
 | |
| 				}
 | |
| 				if sum > value || math.IsNaN(sum) {
 | |
| 					value = sum
 | |
| 				}
 | |
| 			}
 | |
| 		} else {
 | |
| 			for i := 0; i < n; i++ {
 | |
| 				sum = 0
 | |
| 				for j := max(0, i-kd); j < i; j++ {
 | |
| 					aij := math.Abs(ab[i*ldab+kd+j-i])
 | |
| 					sum += aij
 | |
| 					work[j] += aij
 | |
| 				}
 | |
| 				work[i] = sum + math.Abs(ab[i*ldab+kd])
 | |
| 			}
 | |
| 			for _, sum := range work {
 | |
| 				if sum > value || math.IsNaN(sum) {
 | |
| 					value = sum
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	case lapack.Frobenius:
 | |
| 		panic("not implemented")
 | |
| 	default:
 | |
| 		panic("invalid norm")
 | |
| 	}
 | |
| 	return value
 | |
| }
 | |
| 
 | |
| // dlantr is a local implementation of Dlantr to keep code paths independent.
 | |
| func dlantr(norm lapack.MatrixNorm, uplo blas.Uplo, diag blas.Diag, m, n int, a []float64, lda int, work []float64) float64 {
 | |
| 	// Quick return if possible.
 | |
| 	minmn := min(m, n)
 | |
| 	if minmn == 0 {
 | |
| 		return 0
 | |
| 	}
 | |
| 	switch norm {
 | |
| 	case lapack.MaxAbs:
 | |
| 		if diag == blas.Unit {
 | |
| 			value := 1.0
 | |
| 			if uplo == blas.Upper {
 | |
| 				for i := 0; i < m; i++ {
 | |
| 					for j := i + 1; j < n; j++ {
 | |
| 						tmp := math.Abs(a[i*lda+j])
 | |
| 						if math.IsNaN(tmp) {
 | |
| 							return tmp
 | |
| 						}
 | |
| 						if tmp > value {
 | |
| 							value = tmp
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 				return value
 | |
| 			}
 | |
| 			for i := 1; i < m; i++ {
 | |
| 				for j := 0; j < min(i, n); j++ {
 | |
| 					tmp := math.Abs(a[i*lda+j])
 | |
| 					if math.IsNaN(tmp) {
 | |
| 						return tmp
 | |
| 					}
 | |
| 					if tmp > value {
 | |
| 						value = tmp
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			return value
 | |
| 		}
 | |
| 		var value float64
 | |
| 		if uplo == blas.Upper {
 | |
| 			for i := 0; i < m; i++ {
 | |
| 				for j := i; j < n; j++ {
 | |
| 					tmp := math.Abs(a[i*lda+j])
 | |
| 					if math.IsNaN(tmp) {
 | |
| 						return tmp
 | |
| 					}
 | |
| 					if tmp > value {
 | |
| 						value = tmp
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 			return value
 | |
| 		}
 | |
| 		for i := 0; i < m; i++ {
 | |
| 			for j := 0; j <= min(i, n-1); j++ {
 | |
| 				tmp := math.Abs(a[i*lda+j])
 | |
| 				if math.IsNaN(tmp) {
 | |
| 					return tmp
 | |
| 				}
 | |
| 				if tmp > value {
 | |
| 					value = tmp
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		return value
 | |
| 	case lapack.MaxColumnSum:
 | |
| 		if diag == blas.Unit {
 | |
| 			for i := 0; i < minmn; i++ {
 | |
| 				work[i] = 1
 | |
| 			}
 | |
| 			for i := minmn; i < n; i++ {
 | |
| 				work[i] = 0
 | |
| 			}
 | |
| 			if uplo == blas.Upper {
 | |
| 				for i := 0; i < m; i++ {
 | |
| 					for j := i + 1; j < n; j++ {
 | |
| 						work[j] += math.Abs(a[i*lda+j])
 | |
| 					}
 | |
| 				}
 | |
| 			} else {
 | |
| 				for i := 1; i < m; i++ {
 | |
| 					for j := 0; j < min(i, n); j++ {
 | |
| 						work[j] += math.Abs(a[i*lda+j])
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		} else {
 | |
| 			for i := 0; i < n; i++ {
 | |
| 				work[i] = 0
 | |
| 			}
 | |
| 			if uplo == blas.Upper {
 | |
| 				for i := 0; i < m; i++ {
 | |
| 					for j := i; j < n; j++ {
 | |
| 						work[j] += math.Abs(a[i*lda+j])
 | |
| 					}
 | |
| 				}
 | |
| 			} else {
 | |
| 				for i := 0; i < m; i++ {
 | |
| 					for j := 0; j <= min(i, n-1); j++ {
 | |
| 						work[j] += math.Abs(a[i*lda+j])
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		var max float64
 | |
| 		for _, v := range work[:n] {
 | |
| 			if math.IsNaN(v) {
 | |
| 				return math.NaN()
 | |
| 			}
 | |
| 			if v > max {
 | |
| 				max = v
 | |
| 			}
 | |
| 		}
 | |
| 		return max
 | |
| 	case lapack.MaxRowSum:
 | |
| 		var maxsum float64
 | |
| 		if diag == blas.Unit {
 | |
| 			if uplo == blas.Upper {
 | |
| 				for i := 0; i < m; i++ {
 | |
| 					var sum float64
 | |
| 					if i < minmn {
 | |
| 						sum = 1
 | |
| 					}
 | |
| 					for j := i + 1; j < n; j++ {
 | |
| 						sum += math.Abs(a[i*lda+j])
 | |
| 					}
 | |
| 					if math.IsNaN(sum) {
 | |
| 						return math.NaN()
 | |
| 					}
 | |
| 					if sum > maxsum {
 | |
| 						maxsum = sum
 | |
| 					}
 | |
| 				}
 | |
| 				return maxsum
 | |
| 			} else {
 | |
| 				for i := 0; i < m; i++ {
 | |
| 					var sum float64
 | |
| 					if i < minmn {
 | |
| 						sum = 1
 | |
| 					}
 | |
| 					for j := 0; j < min(i, n); j++ {
 | |
| 						sum += math.Abs(a[i*lda+j])
 | |
| 					}
 | |
| 					if math.IsNaN(sum) {
 | |
| 						return math.NaN()
 | |
| 					}
 | |
| 					if sum > maxsum {
 | |
| 						maxsum = sum
 | |
| 					}
 | |
| 				}
 | |
| 				return maxsum
 | |
| 			}
 | |
| 		} else {
 | |
| 			if uplo == blas.Upper {
 | |
| 				for i := 0; i < m; i++ {
 | |
| 					var sum float64
 | |
| 					for j := i; j < n; j++ {
 | |
| 						sum += math.Abs(a[i*lda+j])
 | |
| 					}
 | |
| 					if math.IsNaN(sum) {
 | |
| 						return sum
 | |
| 					}
 | |
| 					if sum > maxsum {
 | |
| 						maxsum = sum
 | |
| 					}
 | |
| 				}
 | |
| 				return maxsum
 | |
| 			} else {
 | |
| 				for i := 0; i < m; i++ {
 | |
| 					var sum float64
 | |
| 					for j := 0; j <= min(i, n-1); j++ {
 | |
| 						sum += math.Abs(a[i*lda+j])
 | |
| 					}
 | |
| 					if math.IsNaN(sum) {
 | |
| 						return sum
 | |
| 					}
 | |
| 					if sum > maxsum {
 | |
| 						maxsum = sum
 | |
| 					}
 | |
| 				}
 | |
| 				return maxsum
 | |
| 			}
 | |
| 		}
 | |
| 	case lapack.Frobenius:
 | |
| 		panic("not implemented")
 | |
| 	default:
 | |
| 		panic("invalid norm")
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // dlantb is a local implementation of Dlantb to keep code paths independent.
 | |
| func dlantb(norm lapack.MatrixNorm, uplo blas.Uplo, diag blas.Diag, n, k int, a []float64, lda int, work []float64) float64 {
 | |
| 	if n == 0 {
 | |
| 		return 0
 | |
| 	}
 | |
| 	var value float64
 | |
| 	switch norm {
 | |
| 	case lapack.MaxAbs:
 | |
| 		if uplo == blas.Upper {
 | |
| 			var jfirst int
 | |
| 			if diag == blas.Unit {
 | |
| 				value = 1
 | |
| 				jfirst = 1
 | |
| 			}
 | |
| 			for i := 0; i < n; i++ {
 | |
| 				for _, aij := range a[i*lda+jfirst : i*lda+min(n-i, k+1)] {
 | |
| 					if math.IsNaN(aij) {
 | |
| 						return aij
 | |
| 					}
 | |
| 					aij = math.Abs(aij)
 | |
| 					if aij > value {
 | |
| 						value = aij
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		} else {
 | |
| 			jlast := k + 1
 | |
| 			if diag == blas.Unit {
 | |
| 				value = 1
 | |
| 				jlast = k
 | |
| 			}
 | |
| 			for i := 0; i < n; i++ {
 | |
| 				for _, aij := range a[i*lda+max(0, k-i) : i*lda+jlast] {
 | |
| 					if math.IsNaN(aij) {
 | |
| 						return math.NaN()
 | |
| 					}
 | |
| 					aij = math.Abs(aij)
 | |
| 					if aij > value {
 | |
| 						value = aij
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	case lapack.MaxRowSum:
 | |
| 		var sum float64
 | |
| 		if uplo == blas.Upper {
 | |
| 			var jfirst int
 | |
| 			if diag == blas.Unit {
 | |
| 				jfirst = 1
 | |
| 			}
 | |
| 			for i := 0; i < n; i++ {
 | |
| 				sum = 0
 | |
| 				if diag == blas.Unit {
 | |
| 					sum = 1
 | |
| 				}
 | |
| 				for _, aij := range a[i*lda+jfirst : i*lda+min(n-i, k+1)] {
 | |
| 					sum += math.Abs(aij)
 | |
| 				}
 | |
| 				if math.IsNaN(sum) {
 | |
| 					return math.NaN()
 | |
| 				}
 | |
| 				if sum > value {
 | |
| 					value = sum
 | |
| 				}
 | |
| 			}
 | |
| 		} else {
 | |
| 			jlast := k + 1
 | |
| 			if diag == blas.Unit {
 | |
| 				jlast = k
 | |
| 			}
 | |
| 			for i := 0; i < n; i++ {
 | |
| 				sum = 0
 | |
| 				if diag == blas.Unit {
 | |
| 					sum = 1
 | |
| 				}
 | |
| 				for _, aij := range a[i*lda+max(0, k-i) : i*lda+jlast] {
 | |
| 					sum += math.Abs(aij)
 | |
| 				}
 | |
| 				if math.IsNaN(sum) {
 | |
| 					return math.NaN()
 | |
| 				}
 | |
| 				if sum > value {
 | |
| 					value = sum
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	case lapack.MaxColumnSum:
 | |
| 		work = work[:n]
 | |
| 		if diag == blas.Unit {
 | |
| 			for i := range work {
 | |
| 				work[i] = 1
 | |
| 			}
 | |
| 		} else {
 | |
| 			for i := range work {
 | |
| 				work[i] = 0
 | |
| 			}
 | |
| 		}
 | |
| 		if uplo == blas.Upper {
 | |
| 			var jfirst int
 | |
| 			if diag == blas.Unit {
 | |
| 				jfirst = 1
 | |
| 			}
 | |
| 			for i := 0; i < n; i++ {
 | |
| 				for j, aij := range a[i*lda+jfirst : i*lda+min(n-i, k+1)] {
 | |
| 					work[i+jfirst+j] += math.Abs(aij)
 | |
| 				}
 | |
| 			}
 | |
| 		} else {
 | |
| 			jlast := k + 1
 | |
| 			if diag == blas.Unit {
 | |
| 				jlast = k
 | |
| 			}
 | |
| 			for i := 0; i < n; i++ {
 | |
| 				off := max(0, k-i)
 | |
| 				for j, aij := range a[i*lda+off : i*lda+jlast] {
 | |
| 					work[i+j+off-k] += math.Abs(aij)
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		for _, wi := range work {
 | |
| 			if math.IsNaN(wi) {
 | |
| 				return math.NaN()
 | |
| 			}
 | |
| 			if wi > value {
 | |
| 				value = wi
 | |
| 			}
 | |
| 		}
 | |
| 	case lapack.Frobenius:
 | |
| 		panic("not implemented")
 | |
| 	default:
 | |
| 		panic("invalid norm")
 | |
| 	}
 | |
| 	return value
 | |
| }
 | 
