mat: add band matrix types
MODIFY
mat/errors.go
mat/errors.go
@@ -129,6 +129,7 @@ var (
ErrPivot = Error{"matrix: malformed pivot list"}
ErrTriangle = Error{"matrix: triangular storage mismatch"}
ErrTriangleSet = Error{"matrix: triangular set out of bounds"}
+ ErrBandSet = Error{"matrix: band set out of bounds"}
ErrSliceLengthMismatch = Error{"matrix: input slice length mismatch"}
ErrNotPSD = Error{"matrix: input not positive symmetric definite"}
ErrFailedEigen = Error{"matrix: eigendecomposition not successful"}

MODIFY
mat/index_bound_checks.go
mat/index_bound_checks.go
@@ -141,3 +141,42 @@ func (t *TriDense) set(i, j int, v float64) {
}
t.mat.Data[i*t.mat.Stride+j] = v
}
+
+// At returns the element at row i, column j.
+func (b *BandDense) At(i, j int) float64 {
+ return b.at(i, j)
+}
+
+func (b *BandDense) at(i, j int) float64 {
+ if uint(i) >= uint(b.mat.Rows) {
+ panic(ErrRowAccess)
+ }
+ if uint(j) >= uint(b.mat.Cols) {
+ panic(ErrColAccess)
+ }
+ pj := j + b.mat.KL - i
+ if pj < 0 || b.mat.KL+b.mat.KU+1 <= pj {
+ return 0
+ }
+ return b.mat.Data[i*b.mat.Stride+pj]
+}
+
+// SetBand sets the element at row i, column j to the value v.
+// It panics if the location is outside the appropriate region of the matrix.
+func (b *BandDense) SetBand(i, j int, v float64) {
+ b.set(i, j, v)
+}
+
+func (b *BandDense) set(i, j int, v float64) {
+ if uint(i) >= uint(b.mat.Rows) {
+ panic(ErrRowAccess)
+ }
+ if uint(j) >= uint(b.mat.Cols) {
+ panic(ErrColAccess)
+ }
+ pj := j + b.mat.KL - i
+ if pj < 0 || b.mat.KL+b.mat.KU+1 <= pj {
+ panic(ErrBandSet)
+ }
+ b.mat.Data[i*b.mat.Stride+pj] = v
+}

MODIFY
mat/index_no_bound_checks.go
mat/index_no_bound_checks.go
@@ -141,3 +141,43 @@ func (t *TriDense) SetTri(i, j int, v float64) {
func (t *TriDense) set(i, j int, v float64) {
t.mat.Data[i*t.mat.Stride+j] = v
}
+
+// At returns the element at row i, column j.
+func (b *BandDense) At(i, j int) float64 {
+ if uint(i) >= uint(b.mat.Rows) {
+ panic(ErrRowAccess)
+ }
+ if uint(j) >= uint(b.mat.Cols) {
+ panic(ErrColAccess)
+ }
+ return b.at(i, j)
+}
+
+func (b *BandDense) at(i, j int) float64 {
+ pj := j + b.mat.KL - i
+ if pj < 0 || b.mat.KL+b.mat.KU+1 <= pj {
+ return 0
+ }
+ return b.mat.Data[i*b.mat.Stride+pj]
+}
+
+// SetBand sets the element at row i, column j to the value v.
+// It panics if the location is outside the appropriate region of the matrix.
+func (b *BandDense) SetBand(i, j int, v float64) {
+ if uint(i) >= uint(b.mat.Rows) {
+ panic(ErrRowAccess)
+ }
+ if uint(j) >= uint(b.mat.Cols) {
+ panic(ErrColAccess)
+ }
+ pj := j + b.mat.KL - i
+ if pj < 0 || b.mat.KL+b.mat.KU+1 <= pj {
+ panic(ErrBandSet)
+ }
+ b.set(i, j, v)
+}
+
+func (b *BandDense) set(i, j int, v float64) {
+ pj := j + b.mat.KL - i
+ b.mat.Data[i*b.mat.Stride+pj] = v
+}

MODIFY
mat/matrix.go
mat/matrix.go
@@ -77,6 +77,12 @@ type Untransposer interface {
Untranspose() Matrix
}
+// UntransposeBander is a type that can undo an implicit band transpose.
+type UntransposeBander interface {
+ // Untranspose returns the underlying Banded stored for the implicit transpose.
+ UntransposeBand() Banded
+}
+
// UntransposeTrier is a type that can undo an implicit triangular transpose.
type UntransposeTrier interface {
// Untranspose returns the underlying Triangular stored for the implicit transpose.

mat: add band matrix types