Files
tensor/optim/rowblocks_pin_test.go
T
petrbalvin af4ee19703
Release / gates (push) Successful in 4m38s
Test / test (push) Successful in 5m16s
Release / release (push) Successful in 35s
feat: initial release
Assisted-by: GLM 5.3 Flash
2026-09-03 10:00:00 +02:00

49 lines
1.4 KiB
Go

// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
// SPDX-License-Identifier: MIT
package optim
import (
"math"
"testing"
"sourcedock.dev/petrbalvin/tensor/internal/core"
)
// MinimiseLinearRows hands both standard rows of a two-sided constraint
// slots in the one backing block, taken in build order. A fixture with
// a two-sided row and a one-sided row pins the hand-computed optimum,
// which a row that aliased its neighbour could not reach.
func TestMinimiseLinearRowsTwoSidedConstraint(t *testing.T) {
// minimise x1 - 2*x2 over 2 ≤ x1 + x2 ≤ 3 and 0 ≤ x1 ≤ 1: the
// objective pushes x2 up and x1 down, so x1 = 0, x2 = 3 and the
// optimum is -6.
cost, err := core.FromFloats([]float64{1, -2}, 2)
if err != nil {
t.Fatalf("FromFloats: %v", err)
}
a, err := core.FromFloats([]float64{1, 1, 1, 0}, 2, 2)
if err != nil {
t.Fatalf("FromFloats: %v", err)
}
cons := LinearConstraints{
A: a,
Lower: []float64{2, 0},
Upper: []float64{3, 1},
}
x, value, merr := MinimiseLinearRows(cost, cons, LinearProgramOptions{})
if merr != nil {
t.Fatalf("MinimiseLinearRows: %v", merr)
}
if math.Abs(value+6) > 1e-9 {
t.Fatalf("optimum = %v, want -6", value)
}
if v := x.FloatAt(0); math.Abs(v) > 1e-9 {
t.Fatalf("x1 = %v, want 0", v)
}
if v := x.FloatAt(1); math.Abs(v-3) > 1e-9 {
t.Fatalf("x2 = %v, want 3", v)
}
}