@@ -14,67 +14,6 @@ const conemap = Dict{Symbol, ProximableFunction}(
1414)
1515const 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
8019function 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
8524end
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
9727const 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 )
11148end
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
11956end
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+
12268function prox! (y:: AbstractArray , K:: DualConeProduct , x:: AbstractArray )
12369 m, n = K. m, K. n
12470 K1, K2 = K. K1, K. K2
0 commit comments