mat: tracer for banded types
MODIFY
mat/band.go
mat/band.go
@@ -261,3 +261,17 @@ func (b *BandDense) Zero() {
zero(b.mat.Data[i*b.mat.Stride+l : i*b.mat.Stride+u])
}
}
+
+// Trace computes the trace of the matrix.
+func (b *BandDense) Trace() float64 {
+ r, c := b.Dims()
+ if r != c {
+ panic(ErrShape)
+ }
+ rb := b.RawBand()
+ var tr float64
+ for i := 0; i < r; i++ {
+ tr += rb.Data[rb.KL+i*rb.Stride]
+ }
+ return tr
+}

MODIFY
mat/diagonal.go
mat/diagonal.go
@@ -309,3 +309,14 @@ func (d *DiagDense) IsZero() bool {
// zeros in this case. See comment in Reset().
return d.mat.Inc == 0
}
+
+// Trace returns the trace.
+func (d *DiagDense) Trace() float64 {
+ rb := d.RawBand()
+ var tr float64
+ for i := 0; i < rb.Rows; i++ {
+ tr += rb.Data[rb.KL+i*rb.Stride]
+ }
+ return tr
+
+}

MODIFY
mat/matrix_test.go
mat/matrix_test.go
@@ -562,6 +562,47 @@ func TestTrace(t *testing.T) {
testOneInputFunc(t, "Trace", f, denseComparison, sameAnswerFloat, isAnyType, isSquare)
}
+func TestTracer(t *testing.T) {
+ for _, test := range []struct {
+ a Tracer
+ want float64
+ }{
+ {
+ a: NewDense(3, 3, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9}),
+ want: 15,
+ },
+ {
+ a: NewSymDense(4, []float64{1, 2, 3, 4, 0, 5, 6, 7, 0, 0, 8, 9, 0, 0, 0, 10}),
+ want: 24,
+ },
+ {
+ a: NewBandDense(6, 6, 1, 2, []float64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 0, 19, 20, 0, 0}),
+ want: 65,
+ },
+ {
+ a: NewDiagDense(6, []float64{1, 2, 3, 4, 5, 6}),
+ want: 21,
+ },
+ {
+ a: NewSymBandDense(6, 2, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 15, 0, 0}),
+ want: 50,
+ },
+ {
+ a: NewTriBandDense(6, 2, Upper, []float64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 15, 0, 0}),
+ want: 50,
+ },
+ {
+ a: NewTriBandDense(6, 2, Lower, []float64{0, 0, 1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}),
+ want: 46,
+ },
+ } {
+ got := test.a.Trace()
+ if got != test.want {
+ t.Errorf("Trace mismatch. Want %v, got %v", test.want, got)
+ }
+ }
+}
+
func TestDoer(t *testing.T) {
type MatrixDoer interface {
Matrix

MODIFY
mat/symband.go
mat/symband.go
@@ -219,3 +219,13 @@ func (s *SymBandDense) DoColNonZero(j int, fn func(i, j int, v float64)) {
}
}
}
+
+// Trace returns the trace.
+func (s *SymBandDense) Trace() float64 {
+ rb := s.RawSymBand()
+ var tr float64
+ for i := 0; i < rb.N; i++ {
+ tr += rb.Data[i*rb.Stride]
+ }
+ return tr
+}

MODIFY
mat/triband.go
mat/triband.go
@@ -351,3 +351,17 @@ func (t *TriBandDense) DiagView() Diagonal {
},
}
}
+
+// Trace returns the trace.
+func (t *TriBandDense) Trace() float64 {
+ rb := t.RawTriBand()
+ var tr float64
+ var offsetIndex int
+ if rb.Uplo == blas.Lower {
+ offsetIndex = rb.K
+ }
+ for i := 0; i < rb.N; i++ {
+ tr += rb.Data[offsetIndex+i*rb.Stride]
+ }
+ return tr
+}

mat: tracer for banded types