mirror of
https://github.com/gonum/gonum.git
synced 2025-10-06 15:47:01 +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
|
// 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
|
// 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.
|
// 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
|
// 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
|
// 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.
|
// 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.
|
// Only the values in the band portion of the matrix are used.
|
||||||
func NewBandDense(r, c, kl, ku int, data []float64) *BandDense {
|
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")
|
panic("mat: negative dimension")
|
||||||
}
|
}
|
||||||
if kl+1 > r || ku+1 > c {
|
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
|
// 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
|
// 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.
|
// 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
|
// 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.
|
// element in the data slice is the {i, j}-th element in the matrix.
|
||||||
func NewDense(r, c int, data []float64) *Dense {
|
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")
|
panic("mat: negative dimension")
|
||||||
}
|
}
|
||||||
if data != nil && r*c != len(data) {
|
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.
|
// 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
|
// 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 {
|
func NewDiagonal(n int, data []float64) *DiagDense {
|
||||||
if n < 0 {
|
if n <= 0 {
|
||||||
|
if n == 0 {
|
||||||
|
panic(ErrZeroLength)
|
||||||
|
}
|
||||||
panic("mat: negative dimension")
|
panic("mat: negative dimension")
|
||||||
}
|
}
|
||||||
if data == nil {
|
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"),
|
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,
|
err: ErrZeroLength,
|
||||||
eq: Equal,
|
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"),
|
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,
|
err: ErrZeroLength,
|
||||||
eq: Equal,
|
eq: Equal,
|
||||||
},
|
},
|
||||||
|
@@ -315,7 +315,10 @@ func makeRandOf(a Matrix, m, n int) Matrix {
|
|||||||
case Untransposer:
|
case Untransposer:
|
||||||
rMatrix = retranspose(a, makeRandOf(t.Untranspose(), n, m))
|
rMatrix = retranspose(a, makeRandOf(t.Untranspose(), n, m))
|
||||||
case *Dense, *basicMatrix:
|
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 i := 0; i < m; i++ {
|
||||||
for j := 0; j < n; j++ {
|
for j := 0; j < n; j++ {
|
||||||
mat.Set(i, j, rand.NormFloat64())
|
mat.Set(i, j, rand.NormFloat64())
|
||||||
@@ -363,7 +366,10 @@ func makeRandOf(a Matrix, m, n int) Matrix {
|
|||||||
if m != n {
|
if m != n {
|
||||||
panic("bad size")
|
panic("bad size")
|
||||||
}
|
}
|
||||||
mat := NewSymDense(n, nil)
|
mat := &SymDense{}
|
||||||
|
if n != 0 {
|
||||||
|
mat = NewSymDense(n, nil)
|
||||||
|
}
|
||||||
for i := 0; i < m; i++ {
|
for i := 0; i < m; i++ {
|
||||||
for j := i; j < n; j++ {
|
for j := i; j < n; j++ {
|
||||||
mat.SetSym(i, j, rand.NormFloat64())
|
mat.SetSym(i, j, rand.NormFloat64())
|
||||||
@@ -386,6 +392,14 @@ func makeRandOf(a Matrix, m, n int) Matrix {
|
|||||||
triKind = (*TriDense)(t).triKind()
|
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)
|
mat := NewTriDense(n, triKind, nil)
|
||||||
if triKind == Upper {
|
if triKind == Upper {
|
||||||
for i := 0; i < m; i++ {
|
for i := 0; i < m; i++ {
|
||||||
@@ -604,7 +618,7 @@ var testMatrices = []Matrix{
|
|||||||
&SymDense{},
|
&SymDense{},
|
||||||
NewTriDense(3, true, nil),
|
NewTriDense(3, true, nil),
|
||||||
NewTriDense(3, false, nil),
|
NewTriDense(3, false, nil),
|
||||||
NewVecDense(0, nil),
|
&VecDense{mat: blas64.Vector{Inc: 1}},
|
||||||
&DiagDense{},
|
&DiagDense{},
|
||||||
&basicVector{},
|
&basicVector{},
|
||||||
&VecDense{mat: blas64.Vector{Inc: 10}},
|
&VecDense{mat: blas64.Vector{Inc: 10}},
|
||||||
@@ -618,7 +632,7 @@ var testMatrices = []Matrix{
|
|||||||
TransposeTri{NewTriDense(3, true, nil)},
|
TransposeTri{NewTriDense(3, true, nil)},
|
||||||
Transpose{NewTriDense(3, false, nil)},
|
Transpose{NewTriDense(3, false, nil)},
|
||||||
TransposeTri{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{&VecDense{mat: blas64.Vector{Inc: 10}}},
|
||||||
Transpose{&DiagDense{}},
|
Transpose{&DiagDense{}},
|
||||||
TransposeTri{&DiagDense{}},
|
TransposeTri{&DiagDense{}},
|
||||||
|
@@ -97,7 +97,7 @@ func TestMulTypes(t *testing.T) {
|
|||||||
|
|
||||||
// Check that it panics if it is supposed to
|
// Check that it panics if it is supposed to
|
||||||
if test.Panics {
|
if test.Panics {
|
||||||
c := NewDense(0, 0, nil)
|
c := &Dense{}
|
||||||
fn := func() {
|
fn := func() {
|
||||||
c.Mul(a, b)
|
c.Mul(a, b)
|
||||||
}
|
}
|
||||||
@@ -125,7 +125,7 @@ func TestMulTypes(t *testing.T) {
|
|||||||
ccomp := matComp{r: ar, c: bc, data: cvecCopy}
|
ccomp := matComp{r: ar, c: bc, data: cvecCopy}
|
||||||
|
|
||||||
// Do normal multiply with empty dense
|
// Do normal multiply with empty dense
|
||||||
d := NewDense(0, 0, nil)
|
d := &Dense{}
|
||||||
|
|
||||||
testMul(t, a, b, d, acomp, bcomp, ccomp, false, "zero receiver")
|
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() {
|
panicked, message := panics(func() {
|
||||||
got.Product(factors...)
|
got.Product(factors...)
|
||||||
})
|
})
|
||||||
|
@@ -67,7 +67,10 @@ type RawSymBander interface {
|
|||||||
// which is passed to NewBandDense as []float64{1, 2, 3, 4, ...} with k=2.
|
// 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.
|
// Only the values in the band portion of the matrix are used.
|
||||||
func NewSymBandDense(n, k int, data []float64) *SymBandDense {
|
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")
|
panic("mat: negative dimension")
|
||||||
}
|
}
|
||||||
if k+1 > n {
|
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
|
// 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
|
// 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.
|
// 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
|
// 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.
|
// 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.
|
// Only the values in the upper triangular portion of the matrix are used.
|
||||||
func NewSymDense(n int, data []float64) *SymDense {
|
func NewSymDense(n int, data []float64) *SymDense {
|
||||||
if n < 0 {
|
if n <= 0 {
|
||||||
|
if n == 0 {
|
||||||
|
panic(ErrZeroLength)
|
||||||
|
}
|
||||||
panic("mat: negative dimension")
|
panic("mat: negative dimension")
|
||||||
}
|
}
|
||||||
if data != nil && n*n != len(data) {
|
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
|
// 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
|
// 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.
|
// 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
|
// 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.
|
// 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.
|
// Only the values in the triangular portion corresponding to kind are used.
|
||||||
func NewTriDense(n int, kind TriKind, data []float64) *TriDense {
|
func NewTriDense(n int, kind TriKind, data []float64) *TriDense {
|
||||||
if n < 0 {
|
if n <= 0 {
|
||||||
|
if n == 0 {
|
||||||
|
panic(ErrZeroLength)
|
||||||
|
}
|
||||||
panic("mat: negative dimension")
|
panic("mat: negative dimension")
|
||||||
}
|
}
|
||||||
if data != nil && len(data) != n*n {
|
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
|
// 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
|
// 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.
|
// 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 {
|
func NewVecDense(n int, data []float64) *VecDense {
|
||||||
if n < 0 {
|
if n <= 0 {
|
||||||
|
if n == 0 {
|
||||||
|
panic(ErrZeroLength)
|
||||||
|
}
|
||||||
panic("mat: negative dimension")
|
panic("mat: negative dimension")
|
||||||
}
|
}
|
||||||
if len(data) != n && data != nil {
|
if len(data) != n && data != nil {
|
||||||
|
Reference in New Issue
Block a user