Skip to content

Commit 29cdc00

Browse files
Adding Advanced Support for Linear Program Analysis (#9)
* Introducing conversion methods from the Simplex repo * Upgrading SymbolicMath.go dependency * Upgrading the version of Go used in the testing workflow * Adding support for new gonum mat * tidying * Adding new errors and example * Migrated to helper utilities from simplex to MPI: Transforming optimization problems to have all positive variables and transforming an arbitrary LP into the standard (equality) form * Changed function signature for getting linear equality and inequality matrices * renamed some parts of workflow * Attempting to use newer version of action with specific file name input * Attempting to improve when the workflow is triggered * hail mary; does coverage2 contain useful info for upload? * Added tests for calling the LinearInequalityConstraintMatrices and LinearEqualityConstraintMatrices functions when there are none of the corresponding problems in the problem * Introduced tests to cover more of the cases in ToLPStandardForm1 * Small formatting of ToLPStandardForm1 * Added a new error for when an optimization problem is not linear * Fixed typo in one of the for loops * Added tests for a few more corner cases of LPStandardForm1 inputs * Did some test renaming * Added test for the not well defined possibility of CheckIfLinear
1 parent 0214315 commit 29cdc00

File tree

10 files changed

+1139
-54
lines changed

10 files changed

+1139
-54
lines changed

.github/workflows/coverage1.yaml

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
1-
name: Go # The name of the workflow that will appear on Github
1+
name: Testing # The name of the workflow that will appear on Github
22

33
on:
4-
push:
5-
branches: [ main , kr-feature-problem1 ]
64
pull_request:
7-
branches: [ main ]
85
# Allows you to run this workflow manually from the Actions tab
96
workflow_dispatch:
107

118
jobs:
12-
build:
9+
compute-coverage:
1310
runs-on: ${{ matrix.os }}
1411
strategy:
1512
matrix:
1613
os: [ubuntu-latest, macos-latest, windows-latest]
17-
go: [1.19]
14+
go: [1.23]
1815
permissions:
1916
# Give the default GITHUB_TOKEN write permission to commit and push the
2017
# added or changed files to the repository.
@@ -40,7 +37,8 @@ jobs:
4037
go tool cover -func coverage.out -o coverage2.out
4138
4239
- name: Upload coverage reports to Codecov
43-
uses: codecov/codecov-action@v3
40+
uses: codecov/codecov-action@v5
41+
with:
42+
files: ./coverage2.out
4443
env:
4544
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
46-
files: ./coverage.out

causeOfProblemNonlinearity/causes.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package causeOfProblemNonlinearity
2+
3+
type Cause string
4+
5+
const (
6+
Objective Cause = "Objective"
7+
Constraint = "Constraint"
8+
NotWellDefined = "NotWellDefined"
9+
)

go.mod

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
module github.com/MatProGo-dev/MatProInterface.go
22

3-
go 1.21
3+
go 1.23.0
44

5-
require gonum.org/v1/gonum v0.14.0
5+
toolchain go1.23.9
66

7-
require github.com/MatProGo-dev/SymbolicMath.go v0.2.1
7+
require gonum.org/v1/gonum v0.16.0
8+
9+
require github.com/MatProGo-dev/SymbolicMath.go v0.2.2

go.sum

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
1-
github.com/MatProGo-dev/SymbolicMath.go v0.1.8 h1:lpe+6cK/2fg29WwxOykm4hKvfJeqvFUBGturC9qh5ug=
2-
github.com/MatProGo-dev/SymbolicMath.go v0.1.8/go.mod h1:gKbGR/6sYWi2koMUEDIPWBPi6jQPELKle0ijIM+eaHU=
3-
github.com/MatProGo-dev/SymbolicMath.go v0.1.9 h1:NMqvS9Bt2DWWLGxd+j3Qta4Ckq/x74gpMM7bt32om5g=
4-
github.com/MatProGo-dev/SymbolicMath.go v0.1.9/go.mod h1:gKbGR/6sYWi2koMUEDIPWBPi6jQPELKle0ijIM+eaHU=
5-
github.com/MatProGo-dev/SymbolicMath.go v0.2.0 h1:W8IREsZGeIuPAKHgJDyeCr3vLJjMr6H/O9RNFAjOVp8=
6-
github.com/MatProGo-dev/SymbolicMath.go v0.2.0/go.mod h1:gKbGR/6sYWi2koMUEDIPWBPi6jQPELKle0ijIM+eaHU=
7-
github.com/MatProGo-dev/SymbolicMath.go v0.2.1 h1:3qcLYNx3+9Ud/saS4QWxJzmDUbVvYZIWt9aX2bQ9iOk=
8-
github.com/MatProGo-dev/SymbolicMath.go v0.2.1/go.mod h1:gKbGR/6sYWi2koMUEDIPWBPi6jQPELKle0ijIM+eaHU=
9-
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
10-
golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
11-
gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0=
12-
gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU=
1+
github.com/MatProGo-dev/SymbolicMath.go v0.2.2 h1:U9nLLgtslRXbweCsgW9uSw8AvoGMgjq2luQtXIuN3eA=
2+
github.com/MatProGo-dev/SymbolicMath.go v0.2.2/go.mod h1:tW8thj4pkaTV9lFNU3OCKmwQ3mZ2Eim6S4JpHRDfRvU=
3+
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
4+
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package mpiErrors
2+
3+
type NoEqualityConstraintsFoundError struct{}
4+
5+
func (e NoEqualityConstraintsFoundError) Error() string {
6+
return "No equality constraints found in the optimization problem; please define some by adding them with \"testProblem1.Constraints = append(testProblem1.Constraints, newConstraint)\""
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package mpiErrors
2+
3+
type NoInequalityConstraintsFoundError struct{}
4+
5+
func (e NoInequalityConstraintsFoundError) Error() string {
6+
return "No inequality constraints found in the optimization problem; please define some by adding them with \"testProblem1.Constraints = append(testProblem1.Constraints, newConstraint)\""
7+
}

mpiErrors/not_linear.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package mpiErrors
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/MatProGo-dev/MatProInterface.go/causeOfProblemNonlinearity"
7+
)
8+
9+
type ProblemNotLinearError struct {
10+
ProblemName string
11+
Cause causeOfProblemNonlinearity.Cause
12+
ConstraintIndex int // Index of the constraint that is not linear, if applicable
13+
}
14+
15+
func (e ProblemNotLinearError) Error() string {
16+
preamble := "The problem " + e.ProblemName + " is not linear"
17+
switch e.Cause {
18+
case causeOfProblemNonlinearity.Objective:
19+
preamble += "; the objective is not linear"
20+
case causeOfProblemNonlinearity.Constraint:
21+
preamble += fmt.Sprintf("; constraint #%v is not linear", e.ConstraintIndex)
22+
case causeOfProblemNonlinearity.NotWellDefined:
23+
preamble += "; the problem is not well defined"
24+
default:
25+
preamble += "; the cause of the problem is not recognized (create an issue on GitHub if you think this is a bug!)"
26+
}
27+
// Return the error message
28+
return preamble
29+
}

problem/examples.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package problem
2+
3+
import (
4+
getKMatrix "github.com/MatProGo-dev/SymbolicMath.go/get/KMatrix"
5+
getKVector "github.com/MatProGo-dev/SymbolicMath.go/get/KVector"
6+
"github.com/MatProGo-dev/SymbolicMath.go/symbolic"
7+
)
8+
9+
/*
10+
GetExampleProblem3
11+
Description:
12+
13+
Returns the LP from this youtube video:
14+
https://www.youtube.com/watch?v=QAR8zthQypc&t=483s
15+
It should look like this:
16+
Maximize 4 x1 + 3 x2 + 5 x3
17+
Subject to
18+
x1 + 2 x2 + 2 x3 <= 4
19+
3 x1 + 4 x3 <= 6
20+
2 x1 + x2 + 4 x3 <= 8
21+
x1 >= 0
22+
x2 >= 0
23+
x3 >= 0
24+
*/
25+
func GetExampleProblem3() *OptimizationProblem {
26+
// Setup
27+
out := NewProblem("TestProblem3")
28+
29+
// Create variables
30+
x := out.AddVariableVectorClassic(
31+
3,
32+
0.0,
33+
symbolic.Infinity.Constant(),
34+
symbolic.Continuous,
35+
)
36+
37+
// Create Basic Objective
38+
c := getKVector.From([]float64{4.0, 3.0, 5.0})
39+
out.SetObjective(
40+
c.Transpose().Multiply(x),
41+
SenseMaximize,
42+
)
43+
44+
// Create Constraints (using one big matrix)
45+
A := getKMatrix.From([][]float64{
46+
{1.0, 2.0, 2.0},
47+
{3.0, 0.0, 4.0},
48+
{2.0, 1.0, 4.0},
49+
})
50+
b := getKVector.From([]float64{4.0, 6.0, 8.0})
51+
out.Constraints = append(out.Constraints, A.Multiply(x).LessEq(b))
52+
53+
// TODO(kwesi): Figure out how to add non-negativity constraints
54+
// // Add non-negativity constraints
55+
// for _, varII := range x {
56+
// out.Constraints = append(
57+
// out.Constraints,
58+
// varII.GreaterEq(0.0),
59+
// )
60+
// }
61+
return out
62+
}

0 commit comments

Comments
 (0)