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.
8 "gonum.org/v1/gonum/blas"
9 "gonum.org/v1/gonum/blas/blas64"
13 symBandDense *SymBandDense
14 _ Matrix = symBandDense
15 _ Symmetric = symBandDense
16 _ Banded = symBandDense
17 _ RawSymBander = symBandDense
18 _ MutableSymBanded = symBandDense
20 _ NonZeroDoer = symBandDense
21 _ RowNonZeroDoer = symBandDense
22 _ ColNonZeroDoer = symBandDense
25 // SymBandDense represents a symmetric band matrix in dense storage format.
26 type SymBandDense struct {
27 mat blas64.SymmetricBand
30 // MutableSymBanded is a symmetric band matrix interface type that allows elements
32 type MutableSymBanded interface {
34 Bandwidth() (kl, ku int)
35 SetSymBand(i, j int, v float64)
38 // A RawSymBander can return a blas64.SymmetricBand representation of the receiver.
39 // Changes to the blas64.SymmetricBand.Data slice will be reflected in the original
40 // matrix, changes to the N, K, Stride and Uplo fields will not.
41 type RawSymBander interface {
42 RawSymBand() blas64.SymmetricBand
45 // NewSymBandDense creates a new SymBand matrix with n rows and columns. If data == nil,
46 // a new slice is allocated for the backing slice. If len(data) == n*(k+1),
47 // data is used as the backing slice, and changes to the elements of the returned
48 // SymBandDense will be reflected in data. If neither of these is true, NewSymBandDense
49 // will panic. k must be at least zero and less than n, otherwise NewBandDense will panic.
51 // The data must be arranged in row-major order constructed by removing the zeros
52 // from the rows outside the band and aligning the diagonals. SymBandDense matrices
53 // are stored in the upper triangle. For example, the matrix
60 // becomes (* entries are never accessed)
67 // which is passed to NewBandDense as []float64{1, 2, 3, 4, ...} with k=2.
68 // Only the values in the band portion of the matrix are used.
69 func NewSymBandDense(n, k int, data []float64) *SymBandDense {
71 panic("mat: negative dimension")
74 panic("mat: band out of range")
77 if data != nil && len(data) != n*bc {
81 data = make([]float64, n*bc)
84 mat: blas64.SymmetricBand{
94 // NewDiagonal is a convenience function that returns a diagonal matrix represented by a
95 // SymBandDense. The length of data must be n or data must be nil, otherwise NewDiagonal
97 func NewDiagonal(n int, data []float64) *SymBandDense {
98 return NewSymBandDense(n, 0, data)
101 // Dims returns the number of rows and columns in the matrix.
102 func (s *SymBandDense) Dims() (r, c int) {
103 return s.mat.N, s.mat.N
106 // Symmetric returns the size of the receiver.
107 func (s *SymBandDense) Symmetric() int {
111 // Bandwidth returns the bandwidths of the matrix.
112 func (s *SymBandDense) Bandwidth() (kl, ku int) {
113 return s.mat.K, s.mat.K
116 // T implements the Matrix interface. Symmetric matrices, by definition, are
117 // equal to their transpose, and this is a no-op.
118 func (s *SymBandDense) T() Matrix {
122 // TBand implements the Banded interface.
123 func (s *SymBandDense) TBand() Banded {
127 // RawSymBand returns the underlying blas64.SymBand used by the receiver.
128 // Changes to elements in the receiver following the call will be reflected
129 // in returned blas64.SymBand.
130 func (s *SymBandDense) RawSymBand() blas64.SymmetricBand {
134 // DoNonZero calls the function fn for each of the non-zero elements of s. The function fn
135 // takes a row/column index and the element value of s at (i, j).
136 func (s *SymBandDense) DoNonZero(fn func(i, j int, v float64)) {
137 for i := 0; i < s.mat.N; i++ {
138 for j := max(0, i-s.mat.K); j < min(s.mat.N, i+s.mat.K+1); j++ {
147 // DoRowNonZero calls the function fn for each of the non-zero elements of row i of s. The function fn
148 // takes a row/column index and the element value of s at (i, j).
149 func (s *SymBandDense) DoRowNonZero(i int, fn func(i, j int, v float64)) {
150 if i < 0 || s.mat.N <= i {
153 for j := max(0, i-s.mat.K); j < min(s.mat.N, i+s.mat.K+1); j++ {
161 // DoColNonZero calls the function fn for each of the non-zero elements of column j of s. The function fn
162 // takes a row/column index and the element value of s at (i, j).
163 func (s *SymBandDense) DoColNonZero(j int, fn func(i, j int, v float64)) {
164 if j < 0 || s.mat.N <= j {
167 for i := 0; i < s.mat.N; i++ {
168 if i-s.mat.K <= j && j < i+s.mat.K+1 {