@@ -43,9 +43,23 @@ function __init__()
43
43
end
44
44
end
45
45
46
- include (" ECOSSolverInterface.jl" ) # MathProgBase interface
47
46
include (" types.jl" ) # All the types and constants defined in ecos.h
48
47
48
+ # A julia container for matrices passed to ECOS.
49
+ # This makes it easy for the Julia GC to track these arrays.
50
+ # The format matches ECOS's spmat: 0-based compressed sparse column (CSC)
51
+ struct ECOSMatrix
52
+ pr:: Vector{Cdouble} # nzval
53
+ jc:: Vector{Clong} # colptr
54
+ ir:: Vector{Clong} # rowval
55
+ end
56
+
57
+ function ECOSMatrix (mat:: AbstractMatrix )
58
+ sparsemat = sparse (mat)
59
+ return ECOSMatrix (sparsemat. nzval, sparsemat. colptr .- 1 , sparsemat. rowval .- 1 )
60
+ end
61
+
62
+
49
63
# setup (direct interface)
50
64
# Provide ECOS with a problem in the form
51
65
# min c'x
@@ -66,35 +80,33 @@ include("types.jl") # All the types and constants defined in ecos.h
66
80
# e.g. cone 1 is indices 4:6, cone 2 is indices 7:10
67
81
# -> q = [3, 4]
68
82
# e Number of exponential cones present in problem
69
- # Gpr, Gjc, Gir
70
- # Non-zeros, column indices, and the row index arrays, respectively,
71
- # for the matrix G represented in column compressed storage (CCS) format
72
- # which is equivalent to Julia's SparseMatrixCSC
73
- # Apr, Ajc, Air
74
- # Equivalent to above for the matrix A.
83
+ # G The G matrix in ECOSMatrix format.
84
+ # A The A matrix in ECOSMatrix format.
75
85
# Can be all nothing if no equalities are present.
76
86
# c Objective coefficients, length(c) == n
77
87
# h RHS for inequality constraints, length(h) == m
78
88
# b RHS for equality constraints, length(b) == b (can be nothing)
79
89
# Returns a pointer to the ECOS pwork structure (Cpwork in ECOS.jl). See
80
90
# types.jl for more information.
91
+ # **NOTE**: ECOS retains references to the problem data passed in here.
92
+ # You *must* ensure that G, A, c, h, and b are not freed until after cleanup(), otherwise
93
+ # memory corruption will occur.
81
94
function setup (n:: Int , m:: Int , p:: Int , l:: Int , ncones:: Int , q:: Union{Vector{Int},Void} , e:: Int ,
82
- Gpr:: Vector{Float64} , Gjc:: Vector{Int} , Gir:: Vector{Int} ,
83
- Apr:: Union{Vector{Float64},Void} , Ajc:: Union{Vector{Int},Void} , Air:: Union{Vector{Int},Void} ,
84
- c:: Vector{Float64} , h:: Vector{Float64} , b:: Union{Vector{Float64},Void} ; kwargs... )
95
+ G:: ECOSMatrix , A:: Union{ECOSMatrix, Void} ,
96
+ c:: Vector{Float64} , h:: Vector{Float64} , b:: Union{Vector{Float64},Void} ; kwargs... )
85
97
# Convert to canonical forms
86
98
q = (q == nothing ) ? convert (Ptr{Clong}, C_NULL ) : convert (Vector{Clong},q)
87
- Apr = (Apr == nothing ) ? convert (Ptr{Cdouble}, C_NULL ) : Apr
88
- Ajc = (Ajc == nothing ) ? convert (Ptr{Cdouble}, C_NULL ) : convert (Vector{Clong},Ajc)
89
- Air = (Air == nothing ) ? convert (Ptr{Cdouble}, C_NULL ) : convert (Vector{Clong},Air)
99
+ Apr = (A == nothing ) ? convert (Ptr{Cdouble}, C_NULL ) : A . pr
100
+ Ajc = (A == nothing ) ? convert (Ptr{Cdouble}, C_NULL ) : A . jc
101
+ Air = (A == nothing ) ? convert (Ptr{Cdouble}, C_NULL ) : A . ir
90
102
b = (b == nothing ) ? convert (Ptr{Cdouble}, C_NULL ) : b
91
103
problem_ptr = ccall ((:ECOS_setup , ECOS. ecos), Ptr{Cpwork},
92
104
(Clong, Clong, Clong, Clong, Clong, Ptr{Clong}, Clong,
93
105
Ptr{Cdouble}, Ptr{Clong}, Ptr{Clong},
94
106
Ptr{Cdouble}, Ptr{Clong}, Ptr{Clong},
95
107
Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cdouble}),
96
108
n, m, p, l, ncones, q, e,
97
- Gpr, convert (Vector{Clong},Gjc), convert (Vector{Clong},Gir) ,
109
+ G . pr, G . jc, G . ir ,
98
110
Apr, Ajc, Air,
99
111
c, h, b)
100
112
@@ -122,47 +134,6 @@ function setup(n::Int, m::Int, p::Int, l::Int, ncones::Int, q::Union{Vector{Int}
122
134
problem_ptr
123
135
end
124
136
125
- # setup (more general interface)
126
- # A more tolerant version of the above method that doesn't require
127
- # user to fiddle with internals of the sparse matrix format
128
- # User can pass nothing as argument for A, b, and q
129
- function setup (n, m, p, l, ncones, q, e, G, A, c, h, b; options... )
130
- @assert m == l + sum (q) + 3 e
131
- @assert length (c) == n
132
- @assert ncones == length (q)
133
- if A == nothing
134
- if b != nothing
135
- @assert length (b) == 0
136
- b = nothing
137
- end
138
- @assert p == 0
139
- Apr = nothing
140
- Ajc = nothing
141
- Air = nothing
142
- else
143
- numrow, numcol = size (A)
144
- @assert numcol == n
145
- @assert numrow == length (b)
146
- @assert numrow == p
147
- sparseA = sparse (A)
148
- Apr = convert (Vector{Float64}, sparseA. nzval)
149
- Ajc = sparseA. colptr - 1 # C is 0-based
150
- Air = sparseA. rowval - 1
151
- end
152
-
153
- @assert size (G) == (m, n)
154
- @assert m == length (h)
155
- sparseG = sparse (G)
156
- Gpr = convert (Vector{Float64}, sparseG. nzval)
157
- Gjc = sparseG. colptr - 1 # C is 0-based
158
- Gir = sparseG. rowval - 1
159
-
160
- setup ( n, m, p, l, ncones, q, e,
161
- Gpr, Gjc, Gir,
162
- Apr, Ajc, Air,
163
- c, h, b; options... )
164
- end
165
-
166
137
# solve
167
138
# Solves the provided problem. Results are stored inside the structure,
168
139
# but currently there is no convenient interface-provided way to access
@@ -178,4 +149,6 @@ function cleanup(problem::Ptr{Cpwork}, keepvars::Int = 0)
178
149
ccall ((:ECOS_cleanup , ECOS. ecos), Void, (Ptr{Cpwork}, Clong), problem, keepvars)
179
150
end
180
151
152
+ include (" ECOSSolverInterface.jl" ) # MathProgBase interface
153
+
181
154
end # module
0 commit comments