Skip to content

Commit 2fc51a9

Browse files
committed
Using ProximalOperators.SlicedSeperableSum instead of ConeProduct
1 parent 6f18c58 commit 2fc51a9

File tree

3 files changed

+31
-85
lines changed

3 files changed

+31
-85
lines changed

src/FOSSolverInterface.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ function loadproblem!(model::FOSMathProgModel, c, A::SparseMatrixCSC, b, constr_
3939
cone_vars[1] in badcones && error("Cone type $(cone_vars[1]) not supported")
4040
end
4141

42-
conesK1 = tuple([conemap[t[1]] for t in constr_cones]...)
43-
indexK1 = tuple([t[2] for t in constr_cones]...)
44-
model.K1 = ConeProduct(indexK1, conesK1)
42+
conesK1 = [conemap[t[1]] for t in constr_cones]
43+
indexK1 = [(t[2],) for t in constr_cones]
44+
model.K1 = SlicedSeparableSum(conesK1, indexK1)
4545

46-
conesK2 = tuple([conemap[t[1]] for t in var_cones]...)
47-
indexK2 = tuple([t[2] for t in var_cones]...)
48-
model.K2 = ConeProduct(indexK2, conesK2)
46+
conesK2 = [conemap[t[1]] for t in var_cones]
47+
indexK2 = [(t[2],) for t in var_cones]
48+
model.K2 = SlicedSeparableSum(conesK2, indexK2)
4949

5050
model.A = A
5151
# TODO figure out :Min/:Max

src/cones.jl

Lines changed: 22 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -14,67 +14,6 @@ const conemap = Dict{Symbol, ProximableFunction}(
1414
)
1515
const badcones = ProximableFunction[]
1616

17-
# type DualCone{T<:ProximableFunction} <: ProximableFunction
18-
# C::T
19-
# end
20-
21-
# dual{T<:ProximableFunction}(C::T) = DualCone{T}(C)
22-
# dual(C::DualCone) = C.C
23-
24-
# function prox!(cone::DualCone, x, y)
25-
# prox!(cone.C, -x, y)
26-
# for i = 1:length(x)
27-
# y[i] = x[i] + y[i]
28-
# end
29-
# end
30-
31-
type ConeProduct{N,T} <: ProximableFunction
32-
ranges::NTuple{N, UnitRange{Int64}}
33-
cones::T
34-
end
35-
#
36-
ConeProduct() = ConeProduct{0,Any}((),())
37-
38-
# function ConeProduct(ranges::NTuple{N, UnitRange{Int64}}, cones::T) where {N,T}
39-
# return ConeProduct{N,T}(ranges, cones)
40-
# end
41-
42-
toRanges{N}(rangesIn::NTuple{N, UnitRange{Int64}}) = rangesIn
43-
44-
function toRanges{N, T<:Integer}(rangesIn::NTuple{N,Array{T,1}})
45-
ranges = Array{UnitRange{Int64},1}(N)
46-
for j in 1:N
47-
range = rangesIn[j]
48-
for (i,el) in enumerate(range[1]:range[end])
49-
if el != range[i]
50-
error("Invalid range in input")
51-
end
52-
end
53-
ranges[j] = range[1]:range[end]
54-
end
55-
return tuple(ranges...)
56-
end
57-
58-
#Should accept tro tuples with UnitRange{Int64} and ProximableFunction
59-
#Cant enforce types or ambigous with default constructor?
60-
function ConeProduct(rangesIn, cones)
61-
ranges = toRanges(rangesIn)
62-
N = length(cones)
63-
@assert typeof(ranges) == NTuple{N, UnitRange{Int64}}
64-
@assert length(ranges) == N
65-
@assert typeof(cones) <: Tuple
66-
#Verify that ranges covers the whole range
67-
prevRangeEnd = 0
68-
for i = 1:N
69-
@assert ranges[i][1] == prevRangeEnd + 1
70-
prevRangeEnd = ranges[i][end]
71-
@assert typeof(cones[i]) <: ProximableFunction
72-
end
73-
T = typeof(cones)
74-
#println("Dumping cones input")
75-
#dump(cones)
76-
ConeProduct(ranges, cones)
77-
end
7817

7918
#Wrapper for dual prox to avoid double duals
8019
function proxDual!(y::AbstractArray, C::ProximableFunction, x::AbstractArray)
@@ -83,15 +22,6 @@ function proxDual!(y::AbstractArray, C::ProximableFunction, x::AbstractArray)
8322
y[i] = x[i] + y[i]
8423
end
8524
end
86-
# proxDual!(y, C::DualCone, x) = prox!(y, C.C, x)
87-
88-
89-
function prox!{N,T}(y::AbstractArray, C::ConeProduct{N,T}, x::AbstractArray)
90-
#TODO Paralell implementation
91-
for i = 1:N
92-
prox!(view(y, C.ranges[i]), C.cones[i], view(x, C.ranges[i]))
93-
end
94-
end
9525

9626
## Some better dual projections
9727
const myIndFree = IndFree()
@@ -103,22 +33,38 @@ proxDual!(y::AbstractArray, C::IndNonpositive, x::AbstractArray) = prox!(y, C,
10333
# TODO figure out if self dual PSD
10434
#proxDual!(y::AbstractArray, C::IndPSD, x::AbstractArray) = prox!(y, C, x)
10535

106-
function proxDual!{N,T}(y::AbstractArray, C::ConeProduct{N,T}, x::AbstractArray)
107-
#TODO Paralell implementation
108-
for i = 1:N
109-
proxDual!(view(y, C.ranges[i]), C.cones[i], view(x, C.ranges[i]))
36+
# Unroll the loop over the different types of functions to prox on, same as for prox! in ProximalOperators
37+
# Ignores function value
38+
@generated function proxDual!{T, A, B, N}(y::AbstractArray{T}, f::SlicedSeparableSum{A, B, N}, x::AbstractArray{T})
39+
ex = :()
40+
for i = 1:N # For each function type
41+
ex = quote $ex;
42+
for k in eachindex(f.fs[$i]) # For each function of that type
43+
proxDual!(view(y, f.idxs[$i][k]...), f.fs[$i][k], view(x,f.idxs[$i][k]...))
44+
end
11045
end
46+
end
47+
ex = :($ex; return)
11148
end
11249

11350
""" Indicator of K2×K1*×R+ × K2*×K1×R+ ∈ (R^n,R^m,R)^2"""
114-
type DualConeProduct{T1<:ConeProduct,T2<:ConeProduct} <: ProximableFunction
51+
type DualConeProduct{T1<:SlicedSeparableSum,T2<:SlicedSeparableSum} <: ProximableFunction
11552
K1::T1
11653
K2::T2
11754
m::Int64
11855
n::Int64
11956
end
12057

121-
DualConeProduct{T1,T2}(K1::T1,K2::T2) = DualConeProduct{T1,T2}(K1, K2, K1.ranges[end][end], K2.ranges[end][end])
58+
"""
59+
Finds the largest index in a SlicedSeparableSum
60+
"""
61+
largestindex(e) = error("Something unexpected happend with the product cones with index of type $(typeof(e))")
62+
largestindex(K::SlicedSeparableSum) = largestindex(K.idxs) # Recursive call on indices
63+
largestindex(l::Union{Tuple, AbstractArray}) = maximum(largestindex.(l)) # Recursive call, apply on each element
64+
largestindex(l::Union{AbstractUnitRange,Number}) = maximum(l) # Possible elements
65+
66+
DualConeProduct{T1,T2}(K1::T1,K2::T2) = DualConeProduct{T1,T2}(K1, K2, largestindex(K1), largestindex(K2))
67+
12268
function prox!(y::AbstractArray, K::DualConeProduct, x::AbstractArray)
12369
m, n = K.m, K.n
12470
K1, K2 = K.K1, K.K2

src/types.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ end
2626
type FOSMathProgModel <: AbstractConicModel
2727
input_numconstr::Int64 # Only needed for interface?
2828
input_numvar::Int64 # Only needed for interface?
29-
K1::ConeProduct
30-
K2::ConeProduct
29+
K1::SlicedSeparableSum
30+
K2::SlicedSeparableSum
3131
A::SparseMatrixCSC{Float64,Int} # The A matrix (equalities)
3232
b::Vector{Float64} # RHS
3333
c::Vector{Float64} # The objective coeffs (always min)
@@ -48,7 +48,7 @@ type FOSMathProgModel <: AbstractConicModel
4848
end
4949

5050
function FOSMathProgModel(s::FOSAlgorithm; kwargs...)
51-
FOSMathProgModel(0, 0, ConeProduct(), ConeProduct(), spzeros(0, 0),
51+
FOSMathProgModel(0, 0, SlicedSeparableSum([],[]), SlicedSeparableSum([],[]), spzeros(0, 0),
5252
Float64[], Float64[], s, FOSSolverDataPlaceholder(), :NotSolved,
5353
0.0, Float64[], Float64[], Float64[], Dict{Symbol,Any}(kwargs), -1,
5454
x -> error("No status generator defined"), UInt64(1), ValueHistories.MVHistory())

0 commit comments

Comments
 (0)