gonum.org/v1/gonum@v0.14.0/lapack/gonum/dlange.go (about)

     1  // Copyright ©2015 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"
     9  
    10  	"gonum.org/v1/gonum/lapack"
    11  )
    12  
    13  // Dlange returns the value of the specified norm of a general m×n matrix A:
    14  //
    15  //	lapack.MaxAbs:       the maximum absolute value of any element.
    16  //	lapack.MaxColumnSum: the maximum column sum of the absolute values of the elements (1-norm).
    17  //	lapack.MaxRowSum:    the maximum row sum of the absolute values of the elements (infinity-norm).
    18  //	lapack.Frobenius:    the square root of the sum of the squares of the elements (Frobenius norm).
    19  //
    20  // If norm == lapack.MaxColumnSum, work must be of length n, and this function will
    21  // panic otherwise. There are no restrictions on work for the other matrix norms.
    22  func (impl Implementation) Dlange(norm lapack.MatrixNorm, m, n int, a []float64, lda int, work []float64) float64 {
    23  	// TODO(btracey): These should probably be refactored to use BLAS calls.
    24  	switch {
    25  	case norm != lapack.MaxRowSum && norm != lapack.MaxColumnSum && norm != lapack.Frobenius && norm != lapack.MaxAbs:
    26  		panic(badNorm)
    27  	case m < 0:
    28  		panic(mLT0)
    29  	case n < 0:
    30  		panic(nLT0)
    31  	case lda < max(1, n):
    32  		panic(badLdA)
    33  	}
    34  
    35  	// Quick return if possible.
    36  	if m == 0 || n == 0 {
    37  		return 0
    38  	}
    39  
    40  	switch {
    41  	case len(a) < (m-1)*lda+n:
    42  		panic(badLdA)
    43  	case norm == lapack.MaxColumnSum && len(work) < n:
    44  		panic(shortWork)
    45  	}
    46  
    47  	switch norm {
    48  	case lapack.MaxAbs:
    49  		var value float64
    50  		for i := 0; i < m; i++ {
    51  			for j := 0; j < n; j++ {
    52  				value = math.Max(value, math.Abs(a[i*lda+j]))
    53  			}
    54  		}
    55  		return value
    56  	case lapack.MaxColumnSum:
    57  		for i := 0; i < n; i++ {
    58  			work[i] = 0
    59  		}
    60  		for i := 0; i < m; i++ {
    61  			for j := 0; j < n; j++ {
    62  				work[j] += math.Abs(a[i*lda+j])
    63  			}
    64  		}
    65  		var value float64
    66  		for i := 0; i < n; i++ {
    67  			value = math.Max(value, work[i])
    68  		}
    69  		return value
    70  	case lapack.MaxRowSum:
    71  		var value float64
    72  		for i := 0; i < m; i++ {
    73  			var sum float64
    74  			for j := 0; j < n; j++ {
    75  				sum += math.Abs(a[i*lda+j])
    76  			}
    77  			value = math.Max(value, sum)
    78  		}
    79  		return value
    80  	default:
    81  		// lapack.Frobenius
    82  		scale := 0.0
    83  		sum := 1.0
    84  		for i := 0; i < m; i++ {
    85  			scale, sum = impl.Dlassq(n, a[i*lda:], 1, scale, sum)
    86  		}
    87  		return scale * math.Sqrt(sum)
    88  	}
    89  }