-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwrappers.go
96 lines (82 loc) · 2.87 KB
/
wrappers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Package clpwrapper contains simple wrappers to help with lanl/clp
// once go has an approximately-standard sparse matrix
// package this code can go into the clp itself
package clpwrapper
import (
"github.com/james-bowman/sparse"
"github.com/lanl/clp"
"gonum.org/v1/gonum/floats/scalar"
"gonum.org/v1/gonum/mat"
)
// GoNumMatrixToCLPPackedMatrix converts a likely-sparse mat.Matrix into a CoinPackedMatrix
func GoNumMatrixToCLPPackedMatrix(matrix mat.Matrix) *clp.PackedMatrix {
return GoNumMatrixToCLPPackedMatrixAtTolerance(matrix, 0.0)
}
// GoNumMatrixToCLPPackedMatrixAtTolerance converts a likely-sparse mat.Matrix into a CoinPackedMatrix
// entries with absolute value less than tolerance are dropped
func GoNumMatrixToCLPPackedMatrixAtTolerance(matrix mat.Matrix, tolerance float64) *clp.PackedMatrix {
nRows, nCols := matrix.Dims()
packedMat := clp.NewPackedMatrix()
packedMat.Reserve(nCols, nRows*nCols, false)
for c := 0; c < nCols; c++ {
col := make([]clp.Nonzero, 0)
for r := 0; r < nRows; r++ {
thisVal := matrix.At(r, c)
if !scalar.EqualWithinAbs(thisVal, 0.0, tolerance) {
col = append(col, clp.Nonzero{Index: r, Value: thisVal})
}
}
packedMat.AppendColumn(col)
}
packedMat.SetDimensions(nRows, nCols)
return packedMat
}
// CSCToCLPPackedMatrix converts a sparse.CSC into a CoinPackedMatrix
func CSCToCLPPackedMatrix(matrix *sparse.CSC) *clp.PackedMatrix {
nRows, nCols := matrix.Dims()
totalNNZ := matrix.NNZ()
packedMat := clp.NewPackedMatrix()
packedMat.Reserve(nCols, totalNNZ, false)
for c := 0; c < nCols; c++ {
col := make([]clp.Nonzero, 0)
matrix.DoColNonZero(c, func(i, j int, v float64) {
ele := clp.Nonzero{Index: i, Value: v}
col = append(col, ele)
})
packedMat.AppendColumn(col)
}
packedMat.SetDimensions(nRows, nCols)
return packedMat
}
// COOToCLPPackedMatrix converts a sparse.COO into a CoinPackedMatrix
func COOToCLPPackedMatrix(matrix *sparse.COO) *clp.PackedMatrix {
csc := matrix.ToCSC()
return CSCToCLPPackedMatrix(csc)
}
// LoadSparseProblem loads from sparse constraint matrices
func LoadSparseProblem(simp *clp.Simplex, C []float64,
varBounds, ubBounds []clp.Bounds, eqBoundsVec []float64,
AEQ, AUB *sparse.COO) {
nRowsEQ, nColsEQ := AEQ.Dims()
nRowsUB, _ := AUB.Dims()
AEQcsc := AEQ.ToCSC()
AUBcsc := AUB.ToCSC()
// merge together the A_eq and A_ub matrices
mergedCOO := sparse.NewCOO(nRowsEQ+nRowsUB, nColsEQ, nil, nil, nil)
for c := 0; c < len(C); c++ {
AEQcsc.DoColNonZero(c, func(i, j int, v float64) {
mergedCOO.Set(i, j, v)
})
AUBcsc.DoColNonZero(c, func(i, j int, v float64) {
mergedCOO.Set(i+nRowsEQ, j, v)
})
}
mergedCSC := mergedCOO.ToCSC()
// merge the bounds
eqBounds := BuildEqualityBounds(eqBoundsVec)
fullBounds := append(eqBounds, ubBounds...)
// Load the problem into the model.
cpm := CSCToCLPPackedMatrix(mergedCSC)
simp.LoadProblem(cpm, varBounds, C, fullBounds, nil)
}
// eof