+++ /dev/null
-// Copyright ©2017 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 mat
-
-import (
- "gonum.org/v1/gonum/blas"
- "gonum.org/v1/gonum/blas/blas64"
-)
-
-var (
- symBandDense *SymBandDense
- _ Matrix = symBandDense
- _ Symmetric = symBandDense
- _ Banded = symBandDense
- _ RawSymBander = symBandDense
- _ MutableSymBanded = symBandDense
-
- _ NonZeroDoer = symBandDense
- _ RowNonZeroDoer = symBandDense
- _ ColNonZeroDoer = symBandDense
-)
-
-// SymBandDense represents a symmetric band matrix in dense storage format.
-type SymBandDense struct {
- mat blas64.SymmetricBand
-}
-
-// MutableSymBanded is a symmetric band matrix interface type that allows elements
-// to be altered.
-type MutableSymBanded interface {
- Symmetric
- Bandwidth() (kl, ku int)
- SetSymBand(i, j int, v float64)
-}
-
-// A RawSymBander can return a blas64.SymmetricBand representation of the receiver.
-// Changes to the blas64.SymmetricBand.Data slice will be reflected in the original
-// matrix, changes to the N, K, Stride and Uplo fields will not.
-type RawSymBander interface {
- RawSymBand() blas64.SymmetricBand
-}
-
-// NewSymBandDense creates a new SymBand matrix with n rows and columns. If data == nil,
-// a new slice is allocated for the backing slice. If len(data) == n*(k+1),
-// data is used as the backing slice, and changes to the elements of the returned
-// SymBandDense will be reflected in data. If neither of these is true, NewSymBandDense
-// will panic. k must be at least zero and less than n, otherwise NewBandDense will panic.
-//
-// The data must be arranged in row-major order constructed by removing the zeros
-// from the rows outside the band and aligning the diagonals. SymBandDense matrices
-// are stored in the upper triangle. For example, the matrix
-// 1 2 3 0 0 0
-// 2 4 5 6 0 0
-// 3 5 7 8 9 0
-// 0 6 8 10 11 12
-// 0 0 9 11 13 14
-// 0 0 0 12 14 15
-// becomes (* entries are never accessed)
-// 1 2 3
-// 4 5 6
-// 7 8 9
-// 10 11 12
-// 13 14 *
-// 15 * *
-// which is passed to NewBandDense as []float64{1, 2, 3, 4, ...} with k=2.
-// Only the values in the band portion of the matrix are used.
-func NewSymBandDense(n, k int, data []float64) *SymBandDense {
- if n < 0 || k < 0 {
- panic("mat: negative dimension")
- }
- if k+1 > n {
- panic("mat: band out of range")
- }
- bc := k + 1
- if data != nil && len(data) != n*bc {
- panic(ErrShape)
- }
- if data == nil {
- data = make([]float64, n*bc)
- }
- return &SymBandDense{
- mat: blas64.SymmetricBand{
- N: n,
- K: k,
- Stride: bc,
- Uplo: blas.Upper,
- Data: data,
- },
- }
-}
-
-// NewDiagonal is a convenience function that returns a diagonal matrix represented by a
-// SymBandDense. The length of data must be n or data must be nil, otherwise NewDiagonal
-// will panic.
-func NewDiagonal(n int, data []float64) *SymBandDense {
- return NewSymBandDense(n, 0, data)
-}
-
-// Dims returns the number of rows and columns in the matrix.
-func (s *SymBandDense) Dims() (r, c int) {
- return s.mat.N, s.mat.N
-}
-
-// Symmetric returns the size of the receiver.
-func (s *SymBandDense) Symmetric() int {
- return s.mat.N
-}
-
-// Bandwidth returns the bandwidths of the matrix.
-func (s *SymBandDense) Bandwidth() (kl, ku int) {
- return s.mat.K, s.mat.K
-}
-
-// T implements the Matrix interface. Symmetric matrices, by definition, are
-// equal to their transpose, and this is a no-op.
-func (s *SymBandDense) T() Matrix {
- return s
-}
-
-// TBand implements the Banded interface.
-func (s *SymBandDense) TBand() Banded {
- return s
-}
-
-// RawSymBand returns the underlying blas64.SymBand used by the receiver.
-// Changes to elements in the receiver following the call will be reflected
-// in returned blas64.SymBand.
-func (s *SymBandDense) RawSymBand() blas64.SymmetricBand {
- return s.mat
-}
-
-// DoNonZero calls the function fn for each of the non-zero elements of s. The function fn
-// takes a row/column index and the element value of s at (i, j).
-func (s *SymBandDense) DoNonZero(fn func(i, j int, v float64)) {
- for i := 0; i < s.mat.N; i++ {
- for j := max(0, i-s.mat.K); j < min(s.mat.N, i+s.mat.K+1); j++ {
- v := s.at(i, j)
- if v != 0 {
- fn(i, j, v)
- }
- }
- }
-}
-
-// DoRowNonZero calls the function fn for each of the non-zero elements of row i of s. The function fn
-// takes a row/column index and the element value of s at (i, j).
-func (s *SymBandDense) DoRowNonZero(i int, fn func(i, j int, v float64)) {
- if i < 0 || s.mat.N <= i {
- panic(ErrRowAccess)
- }
- for j := max(0, i-s.mat.K); j < min(s.mat.N, i+s.mat.K+1); j++ {
- v := s.at(i, j)
- if v != 0 {
- fn(i, j, v)
- }
- }
-}
-
-// DoColNonZero calls the function fn for each of the non-zero elements of column j of s. The function fn
-// takes a row/column index and the element value of s at (i, j).
-func (s *SymBandDense) DoColNonZero(j int, fn func(i, j int, v float64)) {
- if j < 0 || s.mat.N <= j {
- panic(ErrColAccess)
- }
- for i := 0; i < s.mat.N; i++ {
- if i-s.mat.K <= j && j < i+s.mat.K+1 {
- v := s.at(i, j)
- if v != 0 {
- fn(i, j, v)
- }
- }
- }
-}