From efbee9bf28481ae37d9f435d460144f50e29ac41 Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Sun, 16 May 2021 07:40:25 +0930 Subject: [PATCH] mat: rename pool helpers to be consistent with type names --- mat/band.go | 8 ++-- mat/cdense.go | 4 +- mat/cholesky.go | 28 +++++------ mat/dense.go | 8 ++-- mat/dense_arithmetic.go | 72 ++++++++++++++-------------- mat/eigen.go | 16 +++---- mat/hogsvd.go | 12 ++--- mat/lq.go | 24 +++++----- mat/lu.go | 20 ++++---- mat/pool.go | 102 ++++++++++++++++++++-------------------- mat/pool_test.go | 8 ++-- mat/product.go | 8 ++-- mat/qr.go | 24 +++++----- mat/solve.go | 12 ++--- mat/svd.go | 20 ++++---- mat/symband.go | 12 ++--- mat/symmetric.go | 12 ++--- mat/triangular.go | 12 ++--- mat/triband.go | 4 +- mat/tridiag.go | 4 +- mat/vector.go | 4 +- 21 files changed, 207 insertions(+), 207 deletions(-) diff --git a/mat/band.go b/mat/band.go index c1d7ec99..25aca349 100644 --- a/mat/band.go +++ b/mat/band.go @@ -347,15 +347,15 @@ func (b *BandDense) MulVecTo(dst *VecDense, trans bool, x Vector) { dst.checkOverlap(xVec.mat) blas64.Gbmv(t, 1, b.mat, xVec.mat, 0, dst.mat) } else { - xCopy := getWorkspaceVec(n, false) + xCopy := getVecDenseWorkspace(n, false) xCopy.CloneFromVec(xVec) blas64.Gbmv(t, 1, b.mat, xCopy.mat, 0, dst.mat) - putWorkspaceVec(xCopy) + putVecDenseWorkspace(xCopy) } } else { - xCopy := getWorkspaceVec(n, false) + xCopy := getVecDenseWorkspace(n, false) xCopy.CloneFromVec(x) blas64.Gbmv(t, 1, b.mat, xCopy.mat, 0, dst.mat) - putWorkspaceVec(xCopy) + putVecDenseWorkspace(xCopy) } } diff --git a/mat/cdense.go b/mat/cdense.go index 02c4109d..86f0423c 100644 --- a/mat/cdense.go +++ b/mat/cdense.go @@ -226,10 +226,10 @@ func (m *CDense) isolatedWorkspace(a CMatrix) (w *CDense, restore func()) { if r == 0 || c == 0 { panic(ErrZeroLength) } - w = getWorkspaceCmplx(r, c, false) + w = getCDenseWorkspace(r, c, false) return w, func() { m.Copy(w) - putWorkspaceCmplx(w) + putCDenseWorkspace(w) } } diff --git a/mat/cholesky.go b/mat/cholesky.go index a4834e34..0ef05ee5 100644 --- a/mat/cholesky.go +++ b/mat/cholesky.go @@ -55,8 +55,8 @@ type Cholesky struct { // the norm is estimated from the decomposition. func (c *Cholesky) updateCond(norm float64) { n := c.chol.mat.N - work := getFloats(3*n, false) - defer putFloats(work) + work := getFloat64s(3*n, false) + defer putFloat64s(work) if norm < 0 { // This is an approximation. By the definition of a norm, // |AB| <= |A| |B|. @@ -139,9 +139,9 @@ func (c *Cholesky) Factorize(a Symmetric) (ok bool) { copySymIntoTriangle(c.chol, a) sym := c.chol.asSymBlas() - work := getFloats(c.chol.mat.N, false) + work := getFloat64s(c.chol.mat.N, false) norm := lapack64.Lansy(CondNorm, sym, work) - putFloats(work) + putFloat64s(work) _, ok = lapack64.Potrf(sym) if ok { c.updateCond(norm) @@ -592,8 +592,8 @@ func (c *Cholesky) SymRankOne(orig *Cholesky, alpha float64, x Vector) (ok bool) // EPFL Technical Report 161468 (2004) // http://infoscience.epfl.ch/record/161468 - work := getFloats(n, false) - defer putFloats(work) + work := getFloat64s(n, false) + defer putFloat64s(work) var xmat blas64.Vector if rv, ok := x.(RawVectorer); ok { xmat = rv.RawVector() @@ -660,10 +660,10 @@ func (c *Cholesky) SymRankOne(orig *Cholesky, alpha float64, x Vector) (ok bool) return false } norm = math.Sqrt((1 + norm) * (1 - norm)) - cos := getFloats(n, false) - defer putFloats(cos) - sin := getFloats(n, false) - defer putFloats(sin) + cos := getFloat64s(n, false) + defer putFloat64s(cos) + sin := getFloat64s(n, false) + defer putFloat64s(sin) for i := n - 1; i >= 0; i-- { // Compute parameters of Givens matrices that zero elements of p // backwards. @@ -674,8 +674,8 @@ func (c *Cholesky) SymRankOne(orig *Cholesky, alpha float64, x Vector) (ok bool) sin[i] *= -1 } } - workMat := getWorkspaceTri(c.chol.mat.N, c.chol.triKind(), false) - defer putWorkspaceTri(workMat) + workMat := getTriDenseWorkspace(c.chol.mat.N, c.chol.triKind(), false) + defer putTriWorkspace(workMat) workMat.Copy(c.chol) umat := workMat.mat stride := workMat.mat.Stride @@ -752,12 +752,12 @@ func (ch *BandCholesky) Factorize(a SymBanded) (ok bool) { ch.Reset() return false } - work := getFloats(3*n, false) + work := getFloat64s(3*n, false) iwork := getInts(n, false) aNorm := lapack64.Lansb(CondNorm, cSym, work) ch.cond = 1 / lapack64.Pbcon(cSym, aNorm, work, iwork) putInts(iwork) - putFloats(work) + putFloat64s(work) return true } diff --git a/mat/dense.go b/mat/dense.go index 2c66b444..f2245c5b 100644 --- a/mat/dense.go +++ b/mat/dense.go @@ -166,10 +166,10 @@ func (m *Dense) isolatedWorkspace(a Matrix) (w *Dense, restore func()) { if r == 0 || c == 0 { panic(ErrZeroLength) } - w = getWorkspace(r, c, false) + w = getDenseWorkspace(r, c, false) return w, func() { m.Copy(w) - putWorkspace(w) + putDenseWorkspace(w) } } @@ -606,8 +606,8 @@ func (m *Dense) Norm(norm float64) float64 { } lnorm := normLapack(norm, false) if lnorm == lapack.MaxColumnSum { - work := getFloats(m.mat.Cols, false) - defer putFloats(work) + work := getFloat64s(m.mat.Cols, false) + defer putFloat64s(work) return lapack64.Lange(lnorm, m.mat, work) } return lapack64.Lange(lnorm, m.mat, nil) diff --git a/mat/dense_arithmetic.go b/mat/dense_arithmetic.go index 1488c743..d0c66509 100644 --- a/mat/dense_arithmetic.go +++ b/mat/dense_arithmetic.go @@ -226,10 +226,10 @@ func (m *Dense) Inverse(a Matrix) error { case *Dense: if m != aU || aTrans { if m == aU || m.checkOverlap(rm.mat) { - tmp := getWorkspace(r, c, false) + tmp := getDenseWorkspace(r, c, false) tmp.Copy(a) m.Copy(tmp) - putWorkspace(tmp) + putDenseWorkspace(tmp) break } m.Copy(a) @@ -238,7 +238,7 @@ func (m *Dense) Inverse(a Matrix) error { m.Copy(a) } // Compute the norm of A. - work := getFloats(4*r, false) // Length must be at least 4*r for Gecon. + work := getFloat64s(4*r, false) // Length must be at least 4*r for Gecon. norm := lapack64.Lange(CondNorm, m.mat, work) // Compute the LU factorization of A. ipiv := getInts(r, false) @@ -256,10 +256,10 @@ func (m *Dense) Inverse(a Matrix) error { lapack64.Getri(m.mat, ipiv, work, -1) if int(work[0]) > len(work) { l := int(work[0]) - putFloats(work) - work = getFloats(l, false) + putFloat64s(work) + work = getFloat64s(l, false) } - defer putFloats(work) + defer putFloat64s(work) ok = lapack64.Getri(m.mat, ipiv, work, len(work)) if !ok || rcond == 0 { // A is exactly singular. @@ -321,10 +321,10 @@ func (m *Dense) Mul(a, b Matrix) { case *SymDense: if aTrans { - c := getWorkspace(ac, ar, false) + c := getDenseWorkspace(ac, ar, false) blas64.Symm(blas.Left, 1, bU.mat, aU.mat, 0, c.mat) strictCopy(m, c.T()) - putWorkspace(c) + putDenseWorkspace(c) return } blas64.Symm(blas.Right, 1, bU.mat, aU.mat, 0, m.mat) @@ -333,7 +333,7 @@ func (m *Dense) Mul(a, b Matrix) { case *TriDense: // Trmm updates in place, so copy aU first. if aTrans { - c := getWorkspace(ac, ar, false) + c := getDenseWorkspace(ac, ar, false) var tmp Dense tmp.SetRawMatrix(aU.mat) c.Copy(&tmp) @@ -343,7 +343,7 @@ func (m *Dense) Mul(a, b Matrix) { } blas64.Trmm(blas.Left, bT, 1, bU.mat, c.mat) strictCopy(m, c.T()) - putWorkspace(c) + putDenseWorkspace(c) return } m.Copy(a) @@ -380,10 +380,10 @@ func (m *Dense) Mul(a, b Matrix) { switch aU := aU.(type) { case *SymDense: if bTrans { - c := getWorkspace(bc, br, false) + c := getDenseWorkspace(bc, br, false) blas64.Symm(blas.Right, 1, aU.mat, bU.mat, 0, c.mat) strictCopy(m, c.T()) - putWorkspace(c) + putDenseWorkspace(c) return } blas64.Symm(blas.Left, 1, aU.mat, bU.mat, 0, m.mat) @@ -392,7 +392,7 @@ func (m *Dense) Mul(a, b Matrix) { case *TriDense: // Trmm updates in place, so copy bU first. if bTrans { - c := getWorkspace(bc, br, false) + c := getDenseWorkspace(bc, br, false) var tmp Dense tmp.SetRawMatrix(bU.mat) c.Copy(&tmp) @@ -402,7 +402,7 @@ func (m *Dense) Mul(a, b Matrix) { } blas64.Trmm(blas.Right, aT, 1, aU.mat, c.mat) strictCopy(m, c.T()) - putWorkspace(c) + putDenseWorkspace(c) return } m.Copy(b) @@ -441,8 +441,8 @@ func (m *Dense) Mul(a, b Matrix) { m.checkOverlapMatrix(aU) m.checkOverlapMatrix(bU) - row := getFloats(ac, false) - defer putFloats(row) + row := getFloat64s(ac, false) + defer putFloat64s(row) for r := 0; r < ar; r++ { for i := range row { row[i] = a.At(r, i) @@ -504,19 +504,19 @@ func (m *Dense) Exp(a Matrix) { a1 := m a1.Copy(a) - v := getWorkspace(r, r, true) + v := getDenseWorkspace(r, r, true) vraw := v.RawMatrix() n := r * r vvec := blas64.Vector{N: n, Inc: 1, Data: vraw.Data} - defer putWorkspace(v) + defer putDenseWorkspace(v) - u := getWorkspace(r, r, true) + u := getDenseWorkspace(r, r, true) uraw := u.RawMatrix() uvec := blas64.Vector{N: n, Inc: 1, Data: uraw.Data} - defer putWorkspace(u) + defer putDenseWorkspace(u) - a2 := getWorkspace(r, r, false) - defer putWorkspace(a2) + a2 := getDenseWorkspace(r, r, false) + defer putDenseWorkspace(a2) n1 := Norm(a, 1) for i, t := range pade { @@ -526,10 +526,10 @@ func (m *Dense) Exp(a Matrix) { // This loop only executes once, so // this is not as horrible as it looks. - p := getWorkspace(r, r, true) + p := getDenseWorkspace(r, r, true) praw := p.RawMatrix() pvec := blas64.Vector{N: n, Inc: 1, Data: praw.Data} - defer putWorkspace(p) + defer putDenseWorkspace(p) for k := 0; k < r; k++ { p.set(k, k, 1) @@ -571,27 +571,27 @@ func (m *Dense) Exp(a Matrix) { } a2.Mul(a1, a1) - i := getWorkspace(r, r, true) + i := getDenseWorkspace(r, r, true) for j := 0; j < r; j++ { i.set(j, j, 1) } iraw := i.RawMatrix() ivec := blas64.Vector{N: n, Inc: 1, Data: iraw.Data} - defer putWorkspace(i) + defer putDenseWorkspace(i) a2raw := a2.RawMatrix() a2vec := blas64.Vector{N: n, Inc: 1, Data: a2raw.Data} - a4 := getWorkspace(r, r, false) + a4 := getDenseWorkspace(r, r, false) a4raw := a4.RawMatrix() a4vec := blas64.Vector{N: n, Inc: 1, Data: a4raw.Data} - defer putWorkspace(a4) + defer putDenseWorkspace(a4) a4.Mul(a2, a2) - a6 := getWorkspace(r, r, false) + a6 := getDenseWorkspace(r, r, false) a6raw := a6.RawMatrix() a6vec := blas64.Vector{N: n, Inc: 1, Data: a6raw.Data} - defer putWorkspace(a6) + defer putDenseWorkspace(a6) a6.Mul(a2, a4) // V = A_6(b_12*A_6 + b_10*A_4 + b_8*A_2) + b_6*A_6 + b_4*A_4 + b_2*A_2 +b_0*I @@ -659,11 +659,11 @@ func (m *Dense) Pow(a Matrix, n int) { } // Perform iterative exponentiation by squaring in work space. - w := getWorkspace(r, r, false) + w := getDenseWorkspace(r, r, false) w.Copy(a) - s := getWorkspace(r, r, false) + s := getDenseWorkspace(r, r, false) s.Copy(a) - x := getWorkspace(r, r, false) + x := getDenseWorkspace(r, r, false) for n--; n > 0; n >>= 1 { if n&1 != 0 { x.Mul(w, s) @@ -675,9 +675,9 @@ func (m *Dense) Pow(a Matrix, n int) { } } m.Copy(w) - putWorkspace(w) - putWorkspace(s) - putWorkspace(x) + putDenseWorkspace(w) + putDenseWorkspace(s) + putDenseWorkspace(x) } // Kronecker calculates the Kronecker product of a and b, placing the result in diff --git a/mat/eigen.go b/mat/eigen.go index 4bed4068..fc0085bd 100644 --- a/mat/eigen.go +++ b/mat/eigen.go @@ -50,9 +50,9 @@ func (e *EigenSym) Factorize(a Symmetric, vectors bool) (ok bool) { work := []float64{0} lapack64.Syev(jobz, sd.mat, w, work, -1) - work = getFloats(int(work[0]), false) + work = getFloat64s(int(work[0]), false) ok = lapack64.Syev(jobz, sd.mat, w, work, len(work)) - putFloats(work) + putFloat64s(work) if !ok { e.vectorsComputed = false e.values = nil @@ -195,16 +195,16 @@ func (e *Eigen) Factorize(a Matrix, kind EigenKind) (ok bool) { jobvr = lapack.RightEVCompute } - wr := getFloats(c, false) - defer putFloats(wr) - wi := getFloats(c, false) - defer putFloats(wi) + wr := getFloat64s(c, false) + defer putFloat64s(wr) + wi := getFloat64s(c, false) + defer putFloat64s(wi) work := []float64{0} lapack64.Geev(jobvl, jobvr, sd.mat, wr, wi, vl.mat, vr.mat, work, -1) - work = getFloats(int(work[0]), false) + work = getFloat64s(int(work[0]), false) first := lapack64.Geev(jobvl, jobvr, sd.mat, wr, wi, vl.mat, vr.mat, work, len(work)) - putFloats(work) + putFloat64s(work) if first != 0 { e.values = nil diff --git a/mat/hogsvd.go b/mat/hogsvd.go index d32780d3..ab53685d 100644 --- a/mat/hogsvd.go +++ b/mat/hogsvd.go @@ -79,10 +79,10 @@ func (gsvd *HOGSVD) Factorize(m ...Matrix) (ok bool) { } } - s := getWorkspace(c, c, true) - defer putWorkspace(s) - sij := getWorkspace(c, c, false) - defer putWorkspace(sij) + s := getDenseWorkspace(c, c, true) + defer putDenseWorkspace(s) + sij := getDenseWorkspace(c, c, false) + defer putDenseWorkspace(sij) for i, ai := range a { for _, aj := range a[i+1:] { gsvd.err = ai.SolveCholTo(sij, &aj) @@ -126,8 +126,8 @@ func (gsvd *HOGSVD) Factorize(m ...Matrix) (ok bool) { } b := make([]Dense, len(m)) - biT := getWorkspace(c, r, false) - defer putWorkspace(biT) + biT := getDenseWorkspace(c, r, false) + defer putDenseWorkspace(biT) for i, d := range m { // All calls to reset will leave an emptied // matrix with capacity to store the result diff --git a/mat/lq.go b/mat/lq.go index dfff65d0..18679da4 100644 --- a/mat/lq.go +++ b/mat/lq.go @@ -31,12 +31,12 @@ func (lq *LQ) updateCond(norm lapack.MatrixNorm) { // is not the case for CondNorm. Hopefully the error is negligible: κ // is only a qualitative measure anyway. m := lq.lq.mat.Rows - work := getFloats(3*m, false) + work := getFloat64s(3*m, false) iwork := getInts(m, false) l := lq.lq.asTriDense(m, blas.NonUnit, blas.Lower) v := lapack64.Trcon(norm, l.mat, work, iwork) lq.cond = 1 / v - putFloats(work) + putFloat64s(work) putInts(iwork) } @@ -63,9 +63,9 @@ func (lq *LQ) factorize(a Matrix, norm lapack.MatrixNorm) { work := []float64{0} lq.tau = make([]float64, k) lapack64.Gelqf(lq.lq.mat, lq.tau, work, -1) - work = getFloats(int(work[0]), false) + work = getFloat64s(int(work[0]), false) lapack64.Gelqf(lq.lq.mat, lq.tau, work, len(work)) - putFloats(work) + putFloat64s(work) lq.updateCond(norm) } @@ -159,9 +159,9 @@ func (lq *LQ) QTo(dst *Dense) { // Construct Q from the elementary reflectors. work := []float64{0} lapack64.Ormlq(blas.Left, blas.NoTrans, lq.lq.mat, lq.tau, q, work, -1) - work = getFloats(int(work[0]), false) + work = getFloat64s(int(work[0]), false) lapack64.Ormlq(blas.Left, blas.NoTrans, lq.lq.mat, lq.tau, q, work, len(work)) - putFloats(work) + putFloat64s(work) } // SolveTo finds a minimum-norm solution to a system of linear equations defined @@ -199,15 +199,15 @@ func (lq *LQ) SolveTo(dst *Dense, trans bool, b Matrix) error { } // Do not need to worry about overlap between x and b because w has its own // independent storage. - w := getWorkspace(max(r, c), bc, false) + w := getDenseWorkspace(max(r, c), bc, false) w.Copy(b) t := lq.lq.asTriDense(lq.lq.mat.Rows, blas.NonUnit, blas.Lower).mat if trans { work := []float64{0} lapack64.Ormlq(blas.Left, blas.NoTrans, lq.lq.mat, lq.tau, w.mat, work, -1) - work = getFloats(int(work[0]), false) + work = getFloat64s(int(work[0]), false) lapack64.Ormlq(blas.Left, blas.NoTrans, lq.lq.mat, lq.tau, w.mat, work, len(work)) - putFloats(work) + putFloat64s(work) ok := lapack64.Trtrs(blas.Trans, t, w.mat) if !ok { @@ -223,13 +223,13 @@ func (lq *LQ) SolveTo(dst *Dense, trans bool, b Matrix) error { } work := []float64{0} lapack64.Ormlq(blas.Left, blas.Trans, lq.lq.mat, lq.tau, w.mat, work, -1) - work = getFloats(int(work[0]), false) + work = getFloat64s(int(work[0]), false) lapack64.Ormlq(blas.Left, blas.Trans, lq.lq.mat, lq.tau, w.mat, work, len(work)) - putFloats(work) + putFloat64s(work) } // x was set above to be the correct size for the result. dst.Copy(w) - putWorkspace(w) + putDenseWorkspace(w) if lq.cond > ConditionTolerance { return Condition(lq.cond) } diff --git a/mat/lu.go b/mat/lu.go index 073a4523..a70b71a4 100644 --- a/mat/lu.go +++ b/mat/lu.go @@ -30,8 +30,8 @@ type LU struct { // norm of the original matrix. If anorm is negative it will be estimated. func (lu *LU) updateCond(anorm float64, norm lapack.MatrixNorm) { n := lu.lu.mat.Cols - work := getFloats(4*n, false) - defer putFloats(work) + work := getFloat64s(4*n, false) + defer putFloat64s(work) iwork := getInts(n, false) defer putInts(iwork) if anorm < 0 { @@ -79,9 +79,9 @@ func (lu *LU) factorize(a Matrix, norm lapack.MatrixNorm) { lu.pivot = make([]int, r) } lu.pivot = lu.pivot[:r] - work := getFloats(r, false) + work := getFloat64s(r, false) anorm := lapack64.Lange(norm, lu.lu.mat, work) - putFloats(work) + putFloat64s(work) lapack64.Getrf(lu.lu.mat, lu.pivot) lu.updateCond(anorm, norm) } @@ -131,8 +131,8 @@ func (lu *LU) LogDet() (det float64, sign float64) { } _, n := lu.lu.Dims() - logDiag := getFloats(n, false) - defer putFloats(logDiag) + logDiag := getFloat64s(n, false) + defer putFloat64s(logDiag) sign = 1.0 for i := 0; i < n; i++ { v := lu.lu.at(i, i) @@ -214,10 +214,10 @@ func (lu *LU) RankOne(orig *LU, alpha float64, x, y Vector) { lu.lu.Copy(orig.lu) } - xs := getFloats(n, false) - defer putFloats(xs) - ys := getFloats(n, false) - defer putFloats(ys) + xs := getFloat64s(n, false) + defer putFloat64s(xs) + ys := getFloat64s(n, false) + defer putFloat64s(ys) for i := 0; i < n; i++ { xs[i] = x.AtVec(i) ys[i] = y.AtVec(i) diff --git a/mat/pool.go b/mat/pool.go index 18cf9ecf..b9dce1c4 100644 --- a/mat/pool.go +++ b/mat/pool.go @@ -94,10 +94,10 @@ func init() { } } -// getWorkspace returns a *Dense of size r×c and a data slice +// getDenseWorkspace returns a *Dense of size r×c and a data slice // with a cap that is less than 2*r*c. If clear is true, the // data slice visible through the Matrix interface is zeroed. -func getWorkspace(r, c int, clear bool) *Dense { +func getDenseWorkspace(r, c int, clear bool) *Dense { l := uint(r * c) w := poolDense[poolFor(l)].Get().(*Dense) w.mat.Data = w.mat.Data[:l] @@ -112,17 +112,17 @@ func getWorkspace(r, c int, clear bool) *Dense { return w } -// putWorkspace replaces a used *Dense into the appropriate size -// workspace pool. putWorkspace must not be called with a matrix +// putDenseWorkspace replaces a used *Dense into the appropriate size +// workspace pool. putDenseWorkspace must not be called with a matrix // where references to the underlying data slice have been kept. -func putWorkspace(w *Dense) { +func putDenseWorkspace(w *Dense) { poolDense[poolFor(uint(cap(w.mat.Data)))].Put(w) } -// getWorkspaceSym returns a *SymDense of size n and a cap that +// getSymDenseWorkspace returns a *SymDense of size n and a cap that // is less than 2*n. If clear is true, the data slice visible // through the Matrix interface is zeroed. -func getWorkspaceSym(n int, clear bool) *SymDense { +func getSymDenseWorkspace(n int, clear bool) *SymDense { l := uint(n) l *= l s := poolSymDense[poolFor(l)].Get().(*SymDense) @@ -136,17 +136,17 @@ func getWorkspaceSym(n int, clear bool) *SymDense { return s } -// putWorkspaceSym replaces a used *SymDense into the appropriate size -// workspace pool. putWorkspaceSym must not be called with a matrix +// putSymDenseWorkspace replaces a used *SymDense into the appropriate size +// workspace pool. putSymDenseWorkspace must not be called with a matrix // where references to the underlying data slice have been kept. -func putWorkspaceSym(s *SymDense) { +func putSymDenseWorkspace(s *SymDense) { poolSymDense[poolFor(uint(cap(s.mat.Data)))].Put(s) } -// getWorkspaceTri returns a *TriDense of size n and a cap that +// getTriDenseWorkspace returns a *TriDense of size n and a cap that // is less than 2*n. If clear is true, the data slice visible // through the Matrix interface is zeroed. -func getWorkspaceTri(n int, kind TriKind, clear bool) *TriDense { +func getTriDenseWorkspace(n int, kind TriKind, clear bool) *TriDense { l := uint(n) l *= l t := poolTriDense[poolFor(l)].Get().(*TriDense) @@ -168,17 +168,17 @@ func getWorkspaceTri(n int, kind TriKind, clear bool) *TriDense { return t } -// putWorkspaceTri replaces a used *TriDense into the appropriate size -// workspace pool. putWorkspaceTri must not be called with a matrix +// putTriWorkspace replaces a used *TriDense into the appropriate size +// workspace pool. putTriWorkspace must not be called with a matrix // where references to the underlying data slice have been kept. -func putWorkspaceTri(t *TriDense) { +func putTriWorkspace(t *TriDense) { poolTriDense[poolFor(uint(cap(t.mat.Data)))].Put(t) } -// getWorkspaceVec returns a *VecDense of length n and a cap that +// getVecDenseWorkspace returns a *VecDense of length n and a cap that // is less than 2*n. If clear is true, the data slice visible // through the Matrix interface is zeroed. -func getWorkspaceVec(n int, clear bool) *VecDense { +func getVecDenseWorkspace(n int, clear bool) *VecDense { l := uint(n) v := poolVecDense[poolFor(l)].Get().(*VecDense) v.mat.Data = v.mat.Data[:l] @@ -189,16 +189,41 @@ func getWorkspaceVec(n int, clear bool) *VecDense { return v } -// putWorkspaceVec replaces a used *VecDense into the appropriate size -// workspace pool. putWorkspaceVec must not be called with a matrix +// putVecDenseWorkspace replaces a used *VecDense into the appropriate size +// workspace pool. putVecDenseWorkspace must not be called with a matrix // where references to the underlying data slice have been kept. -func putWorkspaceVec(v *VecDense) { +func putVecDenseWorkspace(v *VecDense) { poolVecDense[poolFor(uint(cap(v.mat.Data)))].Put(v) } -// getFloats returns a []float64 of length l and a cap that is +// getCDenseWorkspace returns a *CDense of size r×c and a data slice +// with a cap that is less than 2*r*c. If clear is true, the +// data slice visible through the CMatrix interface is zeroed. +func getCDenseWorkspace(r, c int, clear bool) *CDense { + l := uint(r * c) + w := poolCDense[poolFor(l)].Get().(*CDense) + w.mat.Data = w.mat.Data[:l] + if clear { + zeroC(w.mat.Data) + } + w.mat.Rows = r + w.mat.Cols = c + w.mat.Stride = c + w.capRows = r + w.capCols = c + return w +} + +// putCDenseWorkspace replaces a used *CDense into the appropriate size +// workspace pool. putWorkspace must not be called with a matrix +// where references to the underlying data slice have been kept. +func putCDenseWorkspace(w *CDense) { + poolCDense[poolFor(uint(cap(w.mat.Data)))].Put(w) +} + +// getFloat64s returns a []float64 of length l and a cap that is // less than 2*l. If clear is true, the slice visible is zeroed. -func getFloats(l int, clear bool) []float64 { +func getFloat64s(l int, clear bool) []float64 { w := *poolFloat64s[poolFor(uint(l))].Get().(*[]float64) w = w[:l] if clear { @@ -207,14 +232,14 @@ func getFloats(l int, clear bool) []float64 { return w } -// putFloats replaces a used []float64 into the appropriate size -// workspace pool. putFloats must not be called with a slice +// putFloat64s replaces a used []float64 into the appropriate size +// workspace pool. putFloat64s must not be called with a slice // where references to the underlying data have been kept. -func putFloats(w []float64) { +func putFloat64s(w []float64) { poolFloat64s[poolFor(uint(cap(w)))].Put(&w) } -// getInts returns a []ints of length l and a cap that is +// getInts returns a []int of length l and a cap that is // less than 2*l. If clear is true, the slice visible is zeroed. func getInts(l int, clear bool) []int { w := *poolInts[poolFor(uint(l))].Get().(*[]int) @@ -233,28 +258,3 @@ func getInts(l int, clear bool) []int { func putInts(w []int) { poolInts[poolFor(uint(cap(w)))].Put(&w) } - -// getWorkspaceCmplx returns a *CDense of size r×c and a data slice -// with a cap that is less than 2*r*c. If clear is true, the -// data slice visible through the CMatrix interface is zeroed. -func getWorkspaceCmplx(r, c int, clear bool) *CDense { - l := uint(r * c) - w := poolCDense[poolFor(l)].Get().(*CDense) - w.mat.Data = w.mat.Data[:l] - if clear { - zeroC(w.mat.Data) - } - w.mat.Rows = r - w.mat.Cols = c - w.mat.Stride = c - w.capRows = r - w.capCols = c - return w -} - -// putWorkspaceCmplx replaces a used *CDense into the appropriate size -// workspace pool. putWorkspace must not be called with a matrix -// where references to the underlying data slice have been kept. -func putWorkspaceCmplx(w *CDense) { - poolCDense[poolFor(uint(cap(w.mat.Data)))].Put(w) -} diff --git a/mat/pool_test.go b/mat/pool_test.go index 177cc1cc..25ea5084 100644 --- a/mat/pool_test.go +++ b/mat/pool_test.go @@ -20,7 +20,7 @@ func TestPool(t *testing.T) { for k := 0; k < 5; k++ { work := make([]*Dense, rand.Intn(10)+1) for l := range work { - w := getWorkspace(i, j, true) + w := getDenseWorkspace(i, j, true) if !reflect.DeepEqual(w.mat, m.mat) { t.Error("unexpected non-zeroed matrix returned by getWorkspace") } @@ -37,7 +37,7 @@ func TestPool(t *testing.T) { work[l] = w } for _, w := range work { - putWorkspace(w) + putDenseWorkspace(w) } } } @@ -48,8 +48,8 @@ var benchmat *Dense func poolBenchmark(n, r, c int, clear bool) { for i := 0; i < n; i++ { - benchmat = getWorkspace(r, c, clear) - putWorkspace(benchmat) + benchmat = getDenseWorkspace(r, c, clear) + putDenseWorkspace(benchmat) } } diff --git a/mat/product.go b/mat/product.go index d8e03027..43e46a2c 100644 --- a/mat/product.go +++ b/mat/product.go @@ -45,7 +45,7 @@ func (m *Dense) Product(factors ...Matrix) { result := p.multiply() m.reuseAsNonZeroed(result.Dims()) m.Copy(result) - putWorkspace(result) + putDenseWorkspace(result) } // debugProductWalk enables debugging output for Product. @@ -154,13 +154,13 @@ func (p *multiplier) multiplySubchain(i, j int) (m Matrix, intermediate bool) { i, ar, ac, result(aTmp), j, br, bc, result(bTmp)) } - r := getWorkspace(ar, bc, false) + r := getDenseWorkspace(ar, bc, false) r.Mul(a, b) if aTmp { - putWorkspace(a.(*Dense)) + putDenseWorkspace(a.(*Dense)) } if bTmp { - putWorkspace(b.(*Dense)) + putDenseWorkspace(b.(*Dense)) } return r, true } diff --git a/mat/qr.go b/mat/qr.go index 78e9f3e8..c7ea4c2e 100644 --- a/mat/qr.go +++ b/mat/qr.go @@ -31,11 +31,11 @@ func (qr *QR) updateCond(norm lapack.MatrixNorm) { // is not the case for CondNorm. Hopefully the error is negligible: κ // is only a qualitative measure anyway. n := qr.qr.mat.Cols - work := getFloats(3*n, false) + work := getFloat64s(3*n, false) iwork := getInts(n, false) r := qr.qr.asTriDense(n, blas.NonUnit, blas.Upper) v := lapack64.Trcon(norm, r.mat, work, iwork) - putFloats(work) + putFloat64s(work) putInts(iwork) qr.cond = 1 / v } @@ -63,9 +63,9 @@ func (qr *QR) factorize(a Matrix, norm lapack.MatrixNorm) { work := []float64{0} qr.tau = make([]float64, k) lapack64.Geqrf(qr.qr.mat, qr.tau, work, -1) - work = getFloats(int(work[0]), false) + work = getFloat64s(int(work[0]), false) lapack64.Geqrf(qr.qr.mat, qr.tau, work, len(work)) - putFloats(work) + putFloat64s(work) qr.updateCond(norm) } @@ -154,9 +154,9 @@ func (qr *QR) QTo(dst *Dense) { // Construct Q from the elementary reflectors. work := []float64{0} lapack64.Ormqr(blas.Left, blas.NoTrans, qr.qr.mat, qr.tau, dst.mat, work, -1) - work = getFloats(int(work[0]), false) + work = getFloat64s(int(work[0]), false) lapack64.Ormqr(blas.Left, blas.NoTrans, qr.qr.mat, qr.tau, dst.mat, work, len(work)) - putFloats(work) + putFloat64s(work) } // SolveTo finds a minimum-norm solution to a system of linear equations defined @@ -194,7 +194,7 @@ func (qr *QR) SolveTo(dst *Dense, trans bool, b Matrix) error { } // Do not need to worry about overlap between m and b because x has its own // independent storage. - w := getWorkspace(max(r, c), bc, false) + w := getDenseWorkspace(max(r, c), bc, false) w.Copy(b) t := qr.qr.asTriDense(qr.qr.mat.Cols, blas.NonUnit, blas.Upper).mat if trans { @@ -207,15 +207,15 @@ func (qr *QR) SolveTo(dst *Dense, trans bool, b Matrix) error { } work := []float64{0} lapack64.Ormqr(blas.Left, blas.NoTrans, qr.qr.mat, qr.tau, w.mat, work, -1) - work = getFloats(int(work[0]), false) + work = getFloat64s(int(work[0]), false) lapack64.Ormqr(blas.Left, blas.NoTrans, qr.qr.mat, qr.tau, w.mat, work, len(work)) - putFloats(work) + putFloat64s(work) } else { work := []float64{0} lapack64.Ormqr(blas.Left, blas.Trans, qr.qr.mat, qr.tau, w.mat, work, -1) - work = getFloats(int(work[0]), false) + work = getFloat64s(int(work[0]), false) lapack64.Ormqr(blas.Left, blas.Trans, qr.qr.mat, qr.tau, w.mat, work, len(work)) - putFloats(work) + putFloat64s(work) ok := lapack64.Trtrs(blas.NoTrans, t, w.mat) if !ok { @@ -224,7 +224,7 @@ func (qr *QR) SolveTo(dst *Dense, trans bool, b Matrix) error { } // X was set above to be the correct size for the result. dst.Copy(w) - putWorkspace(w) + putDenseWorkspace(w) if qr.cond > ConditionTolerance { return Condition(qr.cond) } diff --git a/mat/solve.go b/mat/solve.go index c01c2473..8ac380fe 100644 --- a/mat/solve.go +++ b/mat/solve.go @@ -52,10 +52,10 @@ func (m *Dense) Solve(a, b Matrix) error { case RawMatrixer: if m != bU || bTrans { if m == bU || m.checkOverlap(rm.RawMatrix()) { - tmp := getWorkspace(br, bc, false) + tmp := getDenseWorkspace(br, bc, false) tmp.Copy(b) m.Copy(tmp) - putWorkspace(tmp) + putDenseWorkspace(tmp) break } m.Copy(b) @@ -65,19 +65,19 @@ func (m *Dense) Solve(a, b Matrix) error { m.Copy(b) } else if bTrans { // m and b share data so Copy cannot be used directly. - tmp := getWorkspace(br, bc, false) + tmp := getDenseWorkspace(br, bc, false) tmp.Copy(b) m.Copy(tmp) - putWorkspace(tmp) + putDenseWorkspace(tmp) } } rm := rma.RawTriangular() blas64.Trsm(side, tA, 1, rm, m.mat) - work := getFloats(3*rm.N, false) + work := getFloat64s(3*rm.N, false) iwork := getInts(rm.N, false) cond := lapack64.Trcon(CondNorm, rm, work, iwork) - putFloats(work) + putFloat64s(work) putInts(iwork) if cond > ConditionTolerance { return Condition(cond) diff --git a/mat/svd.go b/mat/svd.go index 2b437b2f..648015dc 100644 --- a/mat/svd.go +++ b/mat/svd.go @@ -131,9 +131,9 @@ func (svd *SVD) Factorize(a Matrix, kind SVDKind) (ok bool) { work := []float64{0} lapack64.Gesvd(jobU, jobVT, aCopy.mat, svd.u, svd.vt, svd.s, work, -1) - work = getFloats(int(work[0]), false) + work = getFloat64s(int(work[0]), false) ok = lapack64.Gesvd(jobU, jobVT, aCopy.mat, svd.u, svd.vt, svd.s, work, len(work)) - putFloats(work) + putFloat64s(work) if !ok { svd.kind = 0 } @@ -318,12 +318,12 @@ func (svd *SVD) SolveTo(dst *Dense, b Matrix, rank int) []float64 { s := svd.s[:rank] _, bc := b.Dims() - c := getWorkspace(svd.u.Cols, bc, false) - defer putWorkspace(c) + c := getDenseWorkspace(svd.u.Cols, bc, false) + defer putDenseWorkspace(c) c.Mul(u.T(), b) - y := getWorkspace(rank, bc, false) - defer putWorkspace(y) + y := getDenseWorkspace(rank, bc, false) + defer putDenseWorkspace(y) y.DivElem(c.slice(0, rank, 0, bc), repVector{vec: s, cols: bc}) dst.Mul(vt.slice(0, rank, 0, svd.vt.Cols).T(), y) @@ -395,12 +395,12 @@ func (svd *SVD) SolveVecTo(dst *VecDense, b Vector, rank int) float64 { } s := svd.s[:rank] - c := getWorkspaceVec(svd.u.Cols, false) - defer putWorkspaceVec(c) + c := getVecDenseWorkspace(svd.u.Cols, false) + defer putVecDenseWorkspace(c) c.MulVec(u.T(), b) - y := getWorkspaceVec(rank, false) - defer putWorkspaceVec(y) + y := getVecDenseWorkspace(rank, false) + defer putVecDenseWorkspace(y) y.DivElemVec(c.sliceVec(0, rank), NewVecDense(rank, s)) dst.MulVec(vt.slice(0, rank, 0, svd.vt.Cols).T(), y) diff --git a/mat/symband.go b/mat/symband.go index ecc7df24..30dc1443 100644 --- a/mat/symband.go +++ b/mat/symband.go @@ -257,8 +257,8 @@ func (s *SymBandDense) Norm(norm float64) float64 { } lnorm := normLapack(norm, false) if lnorm == lapack.MaxColumnSum || lnorm == lapack.MaxRowSum { - work := getFloats(s.mat.N, false) - defer putFloats(work) + work := getFloat64s(s.mat.N, false) + defer putFloat64s(work) return lapack64.Lansb(lnorm, s.mat, work) } return lapack64.Lansb(lnorm, s.mat, nil) @@ -293,15 +293,15 @@ func (s *SymBandDense) MulVecTo(dst *VecDense, _ bool, x Vector) { dst.checkOverlap(xVec.mat) blas64.Sbmv(1, s.mat, xVec.mat, 0, dst.mat) } else { - xCopy := getWorkspaceVec(n, false) + xCopy := getVecDenseWorkspace(n, false) xCopy.CloneFromVec(xVec) blas64.Sbmv(1, s.mat, xCopy.mat, 0, dst.mat) - putWorkspaceVec(xCopy) + putVecDenseWorkspace(xCopy) } } else { - xCopy := getWorkspaceVec(n, false) + xCopy := getVecDenseWorkspace(n, false) xCopy.CloneFromVec(x) blas64.Sbmv(1, s.mat, xCopy.mat, 0, dst.mat) - putWorkspaceVec(xCopy) + putVecDenseWorkspace(xCopy) } } diff --git a/mat/symmetric.go b/mat/symmetric.go index d57763ec..dad6831b 100644 --- a/mat/symmetric.go +++ b/mat/symmetric.go @@ -238,10 +238,10 @@ func (s *SymDense) isolatedWorkspace(a Symmetric) (w *SymDense, restore func()) if n == 0 { panic(ErrZeroLength) } - w = getWorkspaceSym(n, false) + w = getSymDenseWorkspace(n, false) return w, func() { s.CopySym(w) - putWorkspaceSym(w) + putSymDenseWorkspace(w) } } @@ -405,10 +405,10 @@ func (s *SymDense) SymOuterK(alpha float64, x Matrix) { panic(badSymTriangle) case s.mat.N == n: if s == x { - w := getWorkspaceSym(n, true) + w := getSymDenseWorkspace(n, true) w.SymRankK(w, alpha, x) s.CopySym(w) - putWorkspaceSym(w) + putSymDenseWorkspace(w) } else { switch r := x.(type) { case RawMatrixer: @@ -592,8 +592,8 @@ func (s *SymDense) Norm(norm float64) float64 { } lnorm := normLapack(norm, false) if lnorm == lapack.MaxColumnSum || lnorm == lapack.MaxRowSum { - work := getFloats(s.mat.N, false) - defer putFloats(work) + work := getFloat64s(s.mat.N, false) + defer putFloat64s(work) return lapack64.Lansy(lnorm, s.mat, work) } return lapack64.Lansy(lnorm, s.mat, nil) diff --git a/mat/triangular.go b/mat/triangular.go index 63d7d9b1..39db932a 100644 --- a/mat/triangular.go +++ b/mat/triangular.go @@ -366,10 +366,10 @@ func (t *TriDense) isolatedWorkspace(a Triangular) (w *TriDense, restore func()) if n == 0 { panic(ErrZeroLength) } - w = getWorkspaceTri(n, kind, false) + w = getTriDenseWorkspace(n, kind, false) return w, func() { t.Copy(w) - putWorkspaceTri(w) + putTriWorkspace(w) } } @@ -459,10 +459,10 @@ func (t *TriDense) InverseTri(a Triangular) error { n, _ := a.Triangle() t.reuseAsNonZeroed(a.Triangle()) t.Copy(a) - work := getFloats(3*n, false) + work := getFloat64s(3*n, false) iwork := getInts(n, false) cond := lapack64.Trcon(CondNorm, t.mat, work, iwork) - putFloats(work) + putFloat64s(work) putInts(iwork) if math.IsInf(cond, 1) { return Condition(cond) @@ -634,8 +634,8 @@ func (t *TriDense) Norm(norm float64) float64 { } lnorm := normLapack(norm, false) if lnorm == lapack.MaxColumnSum { - work := getFloats(t.mat.N, false) - defer putFloats(work) + work := getFloat64s(t.mat.N, false) + defer putFloat64s(work) return lapack64.Lantr(lnorm, t.mat, work) } return lapack64.Lantr(lnorm, t.mat, nil) diff --git a/mat/triband.go b/mat/triband.go index eabd9cee..bbce37d6 100644 --- a/mat/triband.go +++ b/mat/triband.go @@ -461,8 +461,8 @@ func (t *TriBandDense) Norm(norm float64) float64 { } lnorm := normLapack(norm, false) if lnorm == lapack.MaxColumnSum { - work := getFloats(t.mat.N, false) - defer putFloats(work) + work := getFloat64s(t.mat.N, false) + defer putFloat64s(work) return lapack64.Lantb(lnorm, t.mat, work) } return lapack64.Lantb(lnorm, t.mat, nil) diff --git a/mat/tridiag.go b/mat/tridiag.go index 2b1be27e..4309e711 100644 --- a/mat/tridiag.go +++ b/mat/tridiag.go @@ -216,10 +216,10 @@ func (a *Tridiag) MulVecTo(dst *VecDense, trans bool, x Vector) { dst.checkOverlap(xVec.mat) lapack64.Lagtm(t, 1, a.mat, xVec.asGeneral(), 0, dst.asGeneral()) } else { - xCopy := getWorkspaceVec(n, false) + xCopy := getVecDenseWorkspace(n, false) xCopy.CloneFromVec(x) lapack64.Lagtm(t, 1, a.mat, xCopy.asGeneral(), 0, dst.asGeneral()) - putWorkspaceVec(xCopy) + putVecDenseWorkspace(xCopy) } } diff --git a/mat/vector.go b/mat/vector.go index b30ea92b..f7cbbc96 100644 --- a/mat/vector.go +++ b/mat/vector.go @@ -773,10 +773,10 @@ func (v *VecDense) isolatedWorkspace(a Vector) (n *VecDense, restore func()) { if l == 0 { panic(ErrZeroLength) } - n = getWorkspaceVec(l, false) + n = getVecDenseWorkspace(l, false) return n, func() { v.CopyVec(n) - putWorkspaceVec(n) + putVecDenseWorkspace(n) } }