github.com/gonum/lapack@v0.0.0-20181123203213-e4cdc5a0bff9/native/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 native
     6  
     7  import (
     8  	"math"
     9  
    10  	"github.com/gonum/lapack"
    11  )
    12  
    13  // Dlange computes the matrix norm of the general m×n matrix a. The input norm
    14  // specifies the norm computed.
    15  //  lapack.MaxAbs: the maximum absolute value of an element.
    16  //  lapack.MaxColumnSum: the maximum column sum of the absolute values of the entries.
    17  //  lapack.MaxRowSum: the maximum row sum of the absolute values of the entries.
    18  //  lapack.NormFrob: the square root of the sum of the squares of the entries.
    19  // If norm == lapack.MaxColumnSum, work must be of length n, and this function will panic otherwise.
    20  // There are no restrictions on work for the other matrix norms.
    21  func (impl Implementation) Dlange(norm lapack.MatrixNorm, m, n int, a []float64, lda int, work []float64) float64 {
    22  	// TODO(btracey): These should probably be refactored to use BLAS calls.
    23  	checkMatrix(m, n, a, lda)
    24  	switch norm {
    25  	case lapack.MaxRowSum, lapack.MaxColumnSum, lapack.NormFrob, lapack.MaxAbs:
    26  	default:
    27  		panic(badNorm)
    28  	}
    29  	if norm == lapack.MaxColumnSum && len(work) < n {
    30  		panic(badWork)
    31  	}
    32  	if m == 0 && n == 0 {
    33  		return 0
    34  	}
    35  	if norm == lapack.MaxAbs {
    36  		var value float64
    37  		for i := 0; i < m; i++ {
    38  			for j := 0; j < n; j++ {
    39  				value = math.Max(value, math.Abs(a[i*lda+j]))
    40  			}
    41  		}
    42  		return value
    43  	}
    44  	if norm == lapack.MaxColumnSum {
    45  		if len(work) < n {
    46  			panic(badWork)
    47  		}
    48  		for i := 0; i < n; i++ {
    49  			work[i] = 0
    50  		}
    51  		for i := 0; i < m; i++ {
    52  			for j := 0; j < n; j++ {
    53  				work[j] += math.Abs(a[i*lda+j])
    54  			}
    55  		}
    56  		var value float64
    57  		for i := 0; i < n; i++ {
    58  			value = math.Max(value, work[i])
    59  		}
    60  		return value
    61  	}
    62  	if norm == lapack.MaxRowSum {
    63  		var value float64
    64  		for i := 0; i < m; i++ {
    65  			var sum float64
    66  			for j := 0; j < n; j++ {
    67  				sum += math.Abs(a[i*lda+j])
    68  			}
    69  			value = math.Max(value, sum)
    70  		}
    71  		return value
    72  	}
    73  	if norm == lapack.NormFrob {
    74  		var value float64
    75  		scale := 0.0
    76  		sum := 1.0
    77  		for i := 0; i < m; i++ {
    78  			scale, sum = impl.Dlassq(n, a[i*lda:], 1, scale, sum)
    79  		}
    80  		value = scale * math.Sqrt(sum)
    81  		return value
    82  	}
    83  	panic("lapack: bad matrix norm")
    84  }