mat: add NonZeroDoer interfaces and implementations

Also clean up some documentation and missing type checks related to
tests for NonZeroDoers.
This commit is contained in:
kortschak
2017-07-08 13:39:59 +09:30
committed by Dan Kortschak
parent 5b2cbc7a56
commit ffd939f8ca
6 changed files with 297 additions and 4 deletions

View File

@@ -14,9 +14,14 @@ import (
var (
triDense *TriDense
_ Matrix = triDense
_ Triangular = triDense
_ RawTriangular = triDense
_ Matrix = triDense
_ Triangular = triDense
_ RawTriangular = triDense
_ MutableTriangular = triDense
_ NonZeroDoer = triDense
_ RowNonZeroDoer = triDense
_ ColNonZeroDoer = triDense
)
const badTriCap = "mat: bad capacity for TriDense"
@@ -28,6 +33,7 @@ type TriDense struct {
cap int
}
// Triangular represents a triangular matrix. Triangular matrices are always square.
type Triangular interface {
Matrix
// Triangular returns the number of rows/columns in the matrix and its
@@ -39,10 +45,17 @@ type Triangular interface {
TTri() Triangular
}
// A RawTriangular can return a view of itself as a BLAS Triangular matrix.
type RawTriangular interface {
RawTriangular() blas64.Triangular
}
// A MutableTriangular can set elements of a triangular matrix.
type MutableTriangular interface {
Triangular
SetTri(i, j int, v float64)
}
var (
_ Matrix = TransposeTri{}
_ Triangular = TransposeTri{}
@@ -455,3 +468,73 @@ func copySymIntoTriangle(t *TriDense, s Symmetric) {
}
}
}
// DoNonZero calls the function fn for each of the non-zero elements of t. The function fn
// takes a row/column index and the element value of t at (i, j).
func (t *TriDense) DoNonZero(fn func(i, j int, v float64)) {
if t.isUpper() {
for i := 0; i < t.mat.N; i++ {
for j := i; j < t.mat.N; j++ {
v := t.at(i, j)
if v != 0 {
fn(i, j, v)
}
}
}
return
}
for i := 0; i < t.mat.N; i++ {
for j := 0; j <= i; j++ {
v := t.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 t. The function fn
// takes a row/column index and the element value of t at (i, j).
func (t *TriDense) DoRowNonZero(i int, fn func(i, j int, v float64)) {
if i < 0 || t.mat.N <= i {
panic(ErrRowAccess)
}
if t.isUpper() {
for j := i; j < t.mat.N; j++ {
v := t.at(i, j)
if v != 0 {
fn(i, j, v)
}
}
return
}
for j := 0; j <= i; j++ {
v := t.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 t. The function fn
// takes a row/column index and the element value of t at (i, j).
func (t *TriDense) DoColNonZero(j int, fn func(i, j int, v float64)) {
if j < 0 || t.mat.N <= j {
panic(ErrColAccess)
}
if t.isUpper() {
for i := 0; i <= j; i++ {
v := t.at(i, j)
if v != 0 {
fn(i, j, v)
}
}
return
}
for i := j; i < t.mat.N; i++ {
v := t.at(i, j)
if v != 0 {
fn(i, j, v)
}
}
}