mirror of
https://github.com/gonum/gonum.git
synced 2025-10-06 07:37:03 +08:00
mat: disallow New calls with zero length
This commit is contained in:

committed by
Dan Kortschak

parent
d41320af1e
commit
3b99883391
@@ -107,6 +107,7 @@ func (t TransposeBand) UntransposeBand() Banded {
|
||||
// BandDense will be reflected in data. If neither of these is true, NewBandDense
|
||||
// will panic. kl must be at least zero and less r, and ku must be at least zero and
|
||||
// less than c, otherwise NewBandDense will panic.
|
||||
// NewBandDense will panic if either r or c is zero.
|
||||
//
|
||||
// The data must be arranged in row-major order constructed by removing the zeros
|
||||
// from the rows outside the band and aligning the diagonals. For example, the matrix
|
||||
@@ -126,7 +127,10 @@ func (t TransposeBand) UntransposeBand() Banded {
|
||||
// which is passed to NewBandDense as []float64{*, 1, 2, 3, 4, ...} with kl=1 and ku=2.
|
||||
// Only the values in the band portion of the matrix are used.
|
||||
func NewBandDense(r, c, kl, ku int, data []float64) *BandDense {
|
||||
if r < 0 || c < 0 || kl < 0 || ku < 0 {
|
||||
if r <= 0 || c <= 0 || kl < 0 || ku < 0 {
|
||||
if r == 0 || c == 0 {
|
||||
panic(ErrZeroLength)
|
||||
}
|
||||
panic("mat: negative dimension")
|
||||
}
|
||||
if kl+1 > r || ku+1 > c {
|
||||
|
@@ -38,11 +38,15 @@ type Dense struct {
|
||||
// a new slice is allocated for the backing slice. If len(data) == r*c, data is
|
||||
// used as the backing slice, and changes to the elements of the returned Dense
|
||||
// will be reflected in data. If neither of these is true, NewDense will panic.
|
||||
// NewDense will panic if either r or c is zero.
|
||||
//
|
||||
// The data must be arranged in row-major order, i.e. the (i*c + j)-th
|
||||
// element in the data slice is the {i, j}-th element in the matrix.
|
||||
func NewDense(r, c int, data []float64) *Dense {
|
||||
if r < 0 || c < 0 {
|
||||
if r <= 0 || c <= 0 {
|
||||
if r == 0 || c == 0 {
|
||||
panic(ErrZeroLength)
|
||||
}
|
||||
panic("mat: negative dimension")
|
||||
}
|
||||
if data != nil && r*c != len(data) {
|
||||
|
@@ -42,9 +42,12 @@ type DiagDense struct {
|
||||
|
||||
// NewDiagonal creates a new Diagonal matrix with n rows and n columns.
|
||||
// The length of data must be n or data must be nil, otherwise NewDiagonal
|
||||
// will panic.
|
||||
// will panic. NewDiagonal will panic if n is zero.
|
||||
func NewDiagonal(n int, data []float64) *DiagDense {
|
||||
if n < 0 {
|
||||
if n <= 0 {
|
||||
if n == 0 {
|
||||
panic(ErrZeroLength)
|
||||
}
|
||||
panic("mat: negative dimension")
|
||||
}
|
||||
if data == nil {
|
||||
|
@@ -30,7 +30,7 @@ var denseData = []struct {
|
||||
}{
|
||||
{
|
||||
raw: []byte("\x01\x00\x00\x00GFA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"),
|
||||
want: NewDense(0, 0, []float64{}),
|
||||
want: &Dense{},
|
||||
err: ErrZeroLength,
|
||||
eq: Equal,
|
||||
},
|
||||
@@ -305,7 +305,7 @@ var vectorData = []struct {
|
||||
}{
|
||||
{
|
||||
raw: []byte("\x01\x00\x00\x00GFA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"),
|
||||
want: NewVecDense(0, []float64{}),
|
||||
want: &VecDense{},
|
||||
err: ErrZeroLength,
|
||||
eq: Equal,
|
||||
},
|
||||
|
@@ -315,7 +315,10 @@ func makeRandOf(a Matrix, m, n int) Matrix {
|
||||
case Untransposer:
|
||||
rMatrix = retranspose(a, makeRandOf(t.Untranspose(), n, m))
|
||||
case *Dense, *basicMatrix:
|
||||
mat := NewDense(m, n, nil)
|
||||
var mat = &Dense{}
|
||||
if m != 0 && n != 0 {
|
||||
mat = NewDense(m, n, nil)
|
||||
}
|
||||
for i := 0; i < m; i++ {
|
||||
for j := 0; j < n; j++ {
|
||||
mat.Set(i, j, rand.NormFloat64())
|
||||
@@ -363,7 +366,10 @@ func makeRandOf(a Matrix, m, n int) Matrix {
|
||||
if m != n {
|
||||
panic("bad size")
|
||||
}
|
||||
mat := NewSymDense(n, nil)
|
||||
mat := &SymDense{}
|
||||
if n != 0 {
|
||||
mat = NewSymDense(n, nil)
|
||||
}
|
||||
for i := 0; i < m; i++ {
|
||||
for j := i; j < n; j++ {
|
||||
mat.SetSym(i, j, rand.NormFloat64())
|
||||
@@ -386,6 +392,14 @@ func makeRandOf(a Matrix, m, n int) Matrix {
|
||||
triKind = (*TriDense)(t).triKind()
|
||||
}
|
||||
|
||||
if n == 0 {
|
||||
uplo := blas.Upper
|
||||
if triKind == Lower {
|
||||
uplo = blas.Lower
|
||||
}
|
||||
return returnAs(&TriDense{mat: blas64.Triangular{Uplo: uplo}}, t)
|
||||
}
|
||||
|
||||
mat := NewTriDense(n, triKind, nil)
|
||||
if triKind == Upper {
|
||||
for i := 0; i < m; i++ {
|
||||
@@ -604,7 +618,7 @@ var testMatrices = []Matrix{
|
||||
&SymDense{},
|
||||
NewTriDense(3, true, nil),
|
||||
NewTriDense(3, false, nil),
|
||||
NewVecDense(0, nil),
|
||||
&VecDense{mat: blas64.Vector{Inc: 1}},
|
||||
&DiagDense{},
|
||||
&basicVector{},
|
||||
&VecDense{mat: blas64.Vector{Inc: 10}},
|
||||
@@ -618,7 +632,7 @@ var testMatrices = []Matrix{
|
||||
TransposeTri{NewTriDense(3, true, nil)},
|
||||
Transpose{NewTriDense(3, false, nil)},
|
||||
TransposeTri{NewTriDense(3, false, nil)},
|
||||
Transpose{NewVecDense(0, nil)},
|
||||
Transpose{&VecDense{mat: blas64.Vector{Inc: 1}}},
|
||||
Transpose{&VecDense{mat: blas64.Vector{Inc: 10}}},
|
||||
Transpose{&DiagDense{}},
|
||||
TransposeTri{&DiagDense{}},
|
||||
|
@@ -97,7 +97,7 @@ func TestMulTypes(t *testing.T) {
|
||||
|
||||
// Check that it panics if it is supposed to
|
||||
if test.Panics {
|
||||
c := NewDense(0, 0, nil)
|
||||
c := &Dense{}
|
||||
fn := func() {
|
||||
c.Mul(a, b)
|
||||
}
|
||||
@@ -125,7 +125,7 @@ func TestMulTypes(t *testing.T) {
|
||||
ccomp := matComp{r: ar, c: bc, data: cvecCopy}
|
||||
|
||||
// Do normal multiply with empty dense
|
||||
d := NewDense(0, 0, nil)
|
||||
d := &Dense{}
|
||||
|
||||
testMul(t, a, b, d, acomp, bcomp, ccomp, false, "zero receiver")
|
||||
|
||||
|
@@ -126,7 +126,10 @@ func TestProduct(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
got := NewDense(test.product.r, test.product.c, nil)
|
||||
got := &Dense{}
|
||||
if test.product.r != 0 && test.product.c != 0 {
|
||||
got = NewDense(test.product.r, test.product.c, nil)
|
||||
}
|
||||
panicked, message := panics(func() {
|
||||
got.Product(factors...)
|
||||
})
|
||||
|
@@ -67,7 +67,10 @@ type RawSymBander interface {
|
||||
// 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 {
|
||||
if n <= 0 || k < 0 {
|
||||
if n == 0 {
|
||||
panic(ErrZeroLength)
|
||||
}
|
||||
panic("mat: negative dimension")
|
||||
}
|
||||
if k+1 > n {
|
||||
|
@@ -55,12 +55,16 @@ type MutableSymmetric interface {
|
||||
// a new slice is allocated for the backing slice. If len(data) == n*n, data is
|
||||
// used as the backing slice, and changes to the elements of the returned SymDense
|
||||
// will be reflected in data. If neither of these is true, NewSymDense will panic.
|
||||
// NewSymDense will panic if n is zero.
|
||||
//
|
||||
// The data must be arranged in row-major order, i.e. the (i*c + j)-th
|
||||
// element in the data slice is the {i, j}-th element in the matrix.
|
||||
// Only the values in the upper triangular portion of the matrix are used.
|
||||
func NewSymDense(n int, data []float64) *SymDense {
|
||||
if n < 0 {
|
||||
if n <= 0 {
|
||||
if n == 0 {
|
||||
panic(ErrZeroLength)
|
||||
}
|
||||
panic("mat: negative dimension")
|
||||
}
|
||||
if data != nil && n*n != len(data) {
|
||||
|
@@ -111,12 +111,16 @@ func (t TransposeTri) UntransposeTri() Triangular {
|
||||
// a new slice is allocated for the backing slice. If len(data) == n*n, data is
|
||||
// used as the backing slice, and changes to the elements of the returned TriDense
|
||||
// will be reflected in data. If neither of these is true, NewTriDense will panic.
|
||||
// NewTriDense will panic if n is zero.
|
||||
//
|
||||
// The data must be arranged in row-major order, i.e. the (i*c + j)-th
|
||||
// element in the data slice is the {i, j}-th element in the matrix.
|
||||
// Only the values in the triangular portion corresponding to kind are used.
|
||||
func NewTriDense(n int, kind TriKind, data []float64) *TriDense {
|
||||
if n < 0 {
|
||||
if n <= 0 {
|
||||
if n == 0 {
|
||||
panic(ErrZeroLength)
|
||||
}
|
||||
panic("mat: negative dimension")
|
||||
}
|
||||
if data != nil && len(data) != n*n {
|
||||
|
@@ -86,8 +86,12 @@ type VecDense struct {
|
||||
// a new slice is allocated for the backing slice. If len(data) == n, data is
|
||||
// used as the backing slice, and changes to the elements of the returned VecDense
|
||||
// will be reflected in data. If neither of these is true, NewVecDense will panic.
|
||||
// NewVecDense will panic if n is zero.
|
||||
func NewVecDense(n int, data []float64) *VecDense {
|
||||
if n < 0 {
|
||||
if n <= 0 {
|
||||
if n == 0 {
|
||||
panic(ErrZeroLength)
|
||||
}
|
||||
panic("mat: negative dimension")
|
||||
}
|
||||
if len(data) != n && data != nil {
|
||||
|
Reference in New Issue
Block a user