diff --git a/go.mod b/go.mod index 05c45d5c116..c146372113d 100644 --- a/go.mod +++ b/go.mod @@ -84,7 +84,6 @@ require ( github.com/segmentio/fasthash v1.0.3 github.com/xitongsys/parquet-go v1.6.2 golang.org/x/time v0.5.0 - gonum.org/v1/gonum v0.14.0 google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f gopkg.in/inf.v0 v0.9.1 ) diff --git a/go.sum b/go.sum index 8aa19f8845b..88c3d7a4b89 100644 --- a/go.sum +++ b/go.sum @@ -735,8 +735,6 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= -gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= diff --git a/internal/common/linalg/linalg.go b/internal/common/linalg/linalg.go deleted file mode 100644 index c807ca651d0..00000000000 --- a/internal/common/linalg/linalg.go +++ /dev/null @@ -1,19 +0,0 @@ -package linalg - -import "gonum.org/v1/gonum/mat" - -// ExtendVecDense extends the length of vec in-place to be at least n. -func ExtendVecDense(vec *mat.VecDense, n int) *mat.VecDense { - if vec == nil { - return mat.NewVecDense(n, make([]float64, n)) - } - rawVec := vec.RawVector() - d := n - rawVec.N - if d <= 0 { - return vec - } - rawVec.Data = append(rawVec.Data, make([]float64, d)...) - rawVec.N = n - vec.SetRawVector(rawVec) - return vec -} diff --git a/internal/common/linalg/lingalg_test.go b/internal/common/linalg/lingalg_test.go deleted file mode 100644 index 200d9c0aacf..00000000000 --- a/internal/common/linalg/lingalg_test.go +++ /dev/null @@ -1,45 +0,0 @@ -package linalg - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "gonum.org/v1/gonum/mat" - - armadaslices "github.com/armadaproject/armada/internal/common/slices" -) - -func TestExtendVecDense(t *testing.T) { - tests := map[string]struct { - vec *mat.VecDense - n int - expected *mat.VecDense - }{ - "nil vec": { - vec: nil, - n: 3, - expected: mat.NewVecDense(3, armadaslices.Zeros[float64](3)), - }, - "extend": { - vec: mat.NewVecDense(1, armadaslices.Zeros[float64](1)), - n: 3, - expected: mat.NewVecDense(3, armadaslices.Zeros[float64](3)), - }, - "extend unnecessary due to greater length": { - vec: mat.NewVecDense(3, armadaslices.Zeros[float64](3)), - n: 1, - expected: mat.NewVecDense(3, armadaslices.Zeros[float64](3)), - }, - "extend unnecessary due to equal length": { - vec: mat.NewVecDense(3, armadaslices.Zeros[float64](3)), - n: 3, - expected: mat.NewVecDense(3, armadaslices.Zeros[float64](3)), - }, - } - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - actual := ExtendVecDense(tc.vec, tc.n) - assert.Equal(t, tc.expected, actual) - }) - } -} diff --git a/internal/common/optimisation/descent/descent.go b/internal/common/optimisation/descent/descent.go deleted file mode 100644 index c57051084ac..00000000000 --- a/internal/common/optimisation/descent/descent.go +++ /dev/null @@ -1,44 +0,0 @@ -package descent - -import ( - "fmt" - - "github.com/pkg/errors" - "gonum.org/v1/gonum/mat" - - "github.com/armadaproject/armada/internal/common/armadaerrors" -) - -// Gradient descent optimiser; see the following link for details: -// https://fluxml.ai/Flux.jl/stable/training/optimisers/ -type Descent struct { - eta float64 -} - -func New(eta float64) (*Descent, error) { - if eta < 0 { - return nil, errors.WithStack(&armadaerrors.ErrInvalidArgument{ - Name: "eta", - Value: eta, - Message: fmt.Sprintf("outside allowed range [0, Inf)"), - }) - } - return &Descent{eta: eta}, nil -} - -func MustNew(eta float64) *Descent { - opt, err := New(eta) - if err != nil { - panic(err) - } - return opt -} - -func (o *Descent) Update(out, p *mat.VecDense, g mat.Vector) *mat.VecDense { - out.AddScaledVec(p, -o.eta, g) - return p -} - -func (o *Descent) Extend(_ int) { - return -} diff --git a/internal/common/optimisation/descent/descent_test.go b/internal/common/optimisation/descent/descent_test.go deleted file mode 100644 index 83571b7ea46..00000000000 --- a/internal/common/optimisation/descent/descent_test.go +++ /dev/null @@ -1,44 +0,0 @@ -package descent - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "gonum.org/v1/gonum/mat" - - armadaslices "github.com/armadaproject/armada/internal/common/slices" -) - -func TestDescent(t *testing.T) { - tests := map[string]struct { - eta float64 - p *mat.VecDense - g *mat.VecDense - expected *mat.VecDense - }{ - "eta is zero": { - eta: 0.0, - p: mat.NewVecDense(2, armadaslices.Ones[float64](2)), - g: mat.NewVecDense(2, armadaslices.Ones[float64](2)), - expected: mat.NewVecDense(2, armadaslices.Ones[float64](2)), - }, - "eta is non-zero": { - eta: 2.0, - p: mat.NewVecDense(2, armadaslices.Zeros[float64](2)), - g: mat.NewVecDense(2, armadaslices.Ones[float64](2)), - expected: func() *mat.VecDense { - rv := mat.NewVecDense(2, armadaslices.Ones[float64](2)) - rv.ScaleVec(-2, rv) - return rv - }(), - }, - } - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - opt := MustNew(tc.eta) - rv := opt.Update(tc.p, tc.p, tc.g) - assert.Equal(t, tc.p, rv) - assert.Equal(t, tc.expected, tc.p) - }) - } -} diff --git a/internal/common/optimisation/nesterov/nesterov.go b/internal/common/optimisation/nesterov/nesterov.go deleted file mode 100644 index 050f91f5e7f..00000000000 --- a/internal/common/optimisation/nesterov/nesterov.go +++ /dev/null @@ -1,60 +0,0 @@ -package nesterov - -import ( - "fmt" - "math" - - "github.com/pkg/errors" - "gonum.org/v1/gonum/mat" - - "github.com/armadaproject/armada/internal/common/armadaerrors" - "github.com/armadaproject/armada/internal/common/linalg" -) - -// Nesterov accelerated gradient descent optimiser; see the following link for details: -// https://fluxml.ai/Flux.jl/stable/training/optimisers/ -type Nesterov struct { - eta float64 - rho float64 - vel *mat.VecDense -} - -func New(eta, rho float64) (*Nesterov, error) { - if eta < 0 { - return nil, errors.WithStack(&armadaerrors.ErrInvalidArgument{ - Name: "eta", - Value: eta, - Message: fmt.Sprintf("outside allowed range [0, Inf)"), - }) - } - if rho < 0 || rho >= 1 { - return nil, errors.WithStack(&armadaerrors.ErrInvalidArgument{ - Name: "rho", - Value: rho, - Message: fmt.Sprintf("outside allowed range [0, 1)"), - }) - } - return &Nesterov{eta: eta, rho: rho}, nil -} - -func MustNew(eta, rho float64) *Nesterov { - opt, err := New(eta, rho) - if err != nil { - panic(err) - } - return opt -} - -func (o *Nesterov) Update(out, p *mat.VecDense, g mat.Vector) *mat.VecDense { - out.CopyVec(p) - out.AddScaledVec(out, math.Pow(o.rho, 2), o.vel) - out.AddScaledVec(out, -(1+o.rho)*o.eta, g) - - o.vel.ScaleVec(o.rho, o.vel) - o.vel.AddScaledVec(o.vel, -o.eta, g) - return p -} - -func (o *Nesterov) Extend(n int) { - o.vel = linalg.ExtendVecDense(o.vel, n) -} diff --git a/internal/common/optimisation/nesterov/nesterov_test.go b/internal/common/optimisation/nesterov/nesterov_test.go deleted file mode 100644 index 24df99f2120..00000000000 --- a/internal/common/optimisation/nesterov/nesterov_test.go +++ /dev/null @@ -1,83 +0,0 @@ -package nesterov - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "gonum.org/v1/gonum/mat" - - armadaslices "github.com/armadaproject/armada/internal/common/slices" -) - -func TestNesterov(t *testing.T) { - tests := map[string]struct { - eta float64 - rho float64 - p0 *mat.VecDense - gs []*mat.VecDense - expecteds []*mat.VecDense - }{ - "eta is zero": { - eta: 0.0, - rho: 0.9, - p0: mat.NewVecDense(2, armadaslices.Ones[float64](2)), - gs: []*mat.VecDense{ - mat.NewVecDense(2, armadaslices.Ones[float64](2)), - mat.NewVecDense(2, armadaslices.Ones[float64](2)), - }, - expecteds: []*mat.VecDense{ - mat.NewVecDense(2, armadaslices.Ones[float64](2)), - mat.NewVecDense(2, armadaslices.Ones[float64](2)), - }, - }, - "rho is zero": { - eta: 2.0, - rho: 0.0, - p0: mat.NewVecDense(2, armadaslices.Zeros[float64](2)), - gs: []*mat.VecDense{ - mat.NewVecDense(2, armadaslices.Ones[float64](2)), - mat.NewVecDense(2, armadaslices.Ones[float64](2)), - }, - expecteds: func() []*mat.VecDense { - rv := make([]*mat.VecDense, 2) - rv[0] = mat.NewVecDense(2, armadaslices.Ones[float64](2)) - rv[0].ScaleVec(-2, rv[0]) - rv[1] = mat.NewVecDense(2, armadaslices.Ones[float64](2)) - rv[1].ScaleVec(-4, rv[1]) - return rv - }(), - }, - "eta and rho non-zero": { - eta: 2.0, - rho: 0.5, - p0: mat.NewVecDense(2, armadaslices.Zeros[float64](2)), - gs: []*mat.VecDense{ - mat.NewVecDense(2, armadaslices.Ones[float64](2)), - mat.NewVecDense(2, armadaslices.Ones[float64](2)), - mat.NewVecDense(2, armadaslices.Ones[float64](2)), - }, - expecteds: func() []*mat.VecDense { - rv := make([]*mat.VecDense, 3) - rv[0] = mat.NewVecDense(2, armadaslices.Ones[float64](2)) - rv[0].ScaleVec(-3, rv[0]) - rv[1] = mat.NewVecDense(2, armadaslices.Ones[float64](2)) - rv[1].ScaleVec(-6.5, rv[1]) - rv[2] = mat.NewVecDense(2, armadaslices.Ones[float64](2)) - rv[2].ScaleVec(-10.25, rv[2]) - return rv - }(), - }, - } - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - opt := MustNew(tc.eta, tc.rho) - p := tc.p0 - for i, g := range tc.gs { - opt.Extend(g.Len()) - rv := opt.Update(p, p, g) - assert.Equal(t, p, rv) - assert.Equal(t, tc.expecteds[i], p) - } - }) - } -} diff --git a/internal/common/optimisation/optimisation.go b/internal/common/optimisation/optimisation.go deleted file mode 100644 index 4bad4826f72..00000000000 --- a/internal/common/optimisation/optimisation.go +++ /dev/null @@ -1,11 +0,0 @@ -package optimisation - -import "gonum.org/v1/gonum/mat" - -// Optimiser represents a first-order optimisation algorithm. -type Optimiser interface { - // Update the parameters using gradient and store the result in out. - Update(out, parameters *mat.VecDense, gradient mat.Vector) *mat.VecDense - // Extend the internal state of the optimiser to accommodate at least n parameters. - Extend(n int) -} diff --git a/internal/common/slices/slices.go b/internal/common/slices/slices.go index b974b18dd17..0eb84145472 100644 --- a/internal/common/slices/slices.go +++ b/internal/common/slices/slices.go @@ -6,8 +6,6 @@ import ( "math/rand" goslices "golang.org/x/exp/slices" - - "github.com/armadaproject/armada/internal/common/interfaces" ) // PartitionToMaxLen partitions the elements of s into non-overlapping slices, @@ -205,31 +203,10 @@ func AnyFunc[S ~[]T, T any](s S, predicate func(val T) bool) bool { // AllFunc returns true if predicate(v) returns true for all values v in s. func AllFunc[S ~[]T, T any](s S, predicate func(val T) bool) bool { - result := true for _, v := range s { - result = predicate(v) && result - if !result { - return result + if !predicate(v) { + return false } } - return result -} - -// Zeros returns a slice T[] of length n with all elements equal to zero. -func Zeros[T any](n int) []T { - return make([]T, n) -} - -// Fill returns a slice T[] of length n with all elements equal to v. -func Fill[T any](v T, n int) []T { - rv := make([]T, n) - for i := range rv { - rv[i] = v - } - return rv -} - -// Ones returns a slice T[] of length n with all elements equal to 1. -func Ones[T interfaces.Number](n int) []T { - return Fill[T](1, n) + return true } diff --git a/internal/common/slices/slices_test.go b/internal/common/slices/slices_test.go index 3d787392ad4..dd733ad98bf 100644 --- a/internal/common/slices/slices_test.go +++ b/internal/common/slices/slices_test.go @@ -450,18 +450,3 @@ func TestAny(t *testing.T) { AnyFunc([]int{1, 2, 3}, func(v int) bool { return v > 3 }), ) } - -func TestZeros(t *testing.T) { - assert.Equal(t, make([]int, 3), Zeros[int](3)) - assert.Equal(t, make([]string, 3), Zeros[string](3)) -} - -func TestOnes(t *testing.T) { - assert.Equal(t, []int{1, 1, 1}, Ones[int](3)) - assert.Equal(t, []float64{1, 1, 1}, Ones[float64](3)) -} - -func TestFill(t *testing.T) { - assert.Equal(t, []int{2, 2, 2}, Fill[int](2, 3)) - assert.Equal(t, []float64{0.5, 0.5, 0.5}, Fill[float64](0.5, 3)) -}