jump-dev / ComplexOptInterface.jl
Showing 2 of 3 files from the diff.

@@ -14,17 +14,30 @@
Loading
14 14
similar_type(::Type{<:MOI.VectorAffineFunction}, T::Type) = MOI.VectorAffineFunction{T}
15 15
16 16
struct SplitZeroBridge{T, F<:MOI.Utilities.TypedLike{T}, G<:MOI.Utilities.TypedLike{Complex{T}}} <: MOI.Bridges.Constraint.AbstractBridge
17 -
    real::MOI.ConstraintIndex{F, MOI.Zeros}
18 -
    imag::MOI.ConstraintIndex{F, MOI.Zeros}
17 +
    dimension::Int
18 +
    constraint::MOI.ConstraintIndex{F, MOI.Zeros}
19 +
    real_indices::Vector{Int}
20 +
    imag_indices::Vector{Int}
21 +
end
22 +
function _nonzero_indices(func::MOI.AbstractVectorFunction)
23 +
    return [i for (i, scalar_func) in enumerate(MOIU.scalarize(func)) if !iszero(scalar_func)]
19 24
end
20 25
function MOI.Bridges.Constraint.bridge_constraint(
21 26
    ::Type{SplitZeroBridge{T, F, G}}, model::MOI.ModelLike,
22 27
    f::G,
23 28
    set::MOI.Zeros
24 29
) where {T, F, G}
25 -
    real_con = MOI.add_constraint(model, operate_coefficients(real, T, f), set)
26 -
    imag_con = MOI.add_constraint(model, operate_coefficients(imag, T, f), set)
27 -
    return SplitZeroBridge{T, F, G}(real_con, imag_con)
30 +
    real_part = operate_coefficients(real, T, f)
31 +
    imag_part = operate_coefficients(imag, T, f)
32 +
    real_indices = _nonzero_indices(real_part)
33 +
    imag_indices = _nonzero_indices(imag_part)
34 +
    func = MOIU.operate(
35 +
        vcat, T,
36 +
        MOIU.eachscalar(real_part)[real_indices],
37 +
        MOIU.eachscalar(imag_part)[imag_indices]
38 +
    )
39 +
    constraint = MOI.add_constraint(model, func, MOI.Zeros(length(real_indices) + length(imag_indices)))
40 +
    return SplitZeroBridge{T, F, G}(MOI.dimension(set), constraint, real_indices, imag_indices)
28 41
end
29 42
30 43
function MOI.supports_constraint(
@@ -45,17 +58,16 @@
Loading
45 58
# Attributes, Bridge acting as a model
46 59
function MOI.get(::SplitZeroBridge{T, F},
47 60
                 ::MOI.NumberOfConstraints{F, MOI.Zeros}) where {T, F}
48 -
    return 2
61 +
    return 1
49 62
end
50 63
function MOI.get(bridge::SplitZeroBridge{T, F},
51 64
                 ::MOI.ListOfConstraintIndices{F, MOI.Zeros}) where {T, F}
52 -
    return [bridge.real, bridge.imag]
65 +
    return [bridge.constraint]
53 66
end
54 67
55 68
# Indices
56 69
function MOI.delete(model::MOI.ModelLike, bridge::SplitZeroBridge)
57 -
    MOI.delete(model, bridge.imag)
58 -
    MOI.delete(model, bridge.real)
70 +
    MOI.delete(model, bridge.constraint)
59 71
end
60 72
61 73
# Attributes, Bridge acting as a constraint
@@ -68,10 +80,24 @@
Loading
68 80
end
69 81
function MOI.get(model::MOI.ModelLike, attr::Union{MOI.ConstraintPrimal, MOI.ConstraintPrimalStart, MOI.ConstraintDual, MOI.ConstraintDualStart},
70 82
                 bridge::SplitZeroBridge)
71 -
    return MOI.get(model, attr, bridge.real) + im * MOI.get(model, attr, bridge.imag)
83 +
    values = MOI.get(model, attr, bridge.constraint)
84 +
    output = zeros(Complex{eltype(values)}, bridge.dimension)
85 +
    for (i, idx) in enumerate(bridge.real_indices)
86 +
        output[idx] = values[i]
87 +
    end
88 +
    for (i, idx) in enumerate(bridge.imag_indices)
89 +
        output[idx] = values[length(bridge.real_indices) + i] * im
90 +
    end
91 +
    return output
72 92
end
73 93
function MOI.set(model::MOI.ModelLike, attr::Union{MOI.ConstraintPrimalStart, MOI.ConstraintDualStart},
74 -
                 bridge::SplitZeroBridge, value)
75 -
    MOI.set(model, attr, bridge.real, map(real, value))
76 -
    MOI.set(model, attr, bridge.imag, map(imag, value))
94 +
                 bridge::SplitZeroBridge{T}, value) where T
95 +
    input = Vector{T}(undef, length(bridge.real_indices) + length(bridge.imag_indices))
96 +
    for (i, idx) in enumerate(bridge.real_indices)
97 +
        input[i] = real(value[idx])
98 +
    end
99 +
    for (i, idx) in enumerate(bridge.imag_indices)
100 +
        input[length(bridge.real_indices) + i] = imag(value[idx])
101 +
    end
102 +
    MOI.set(model, attr, bridge.constraint, input)
77 103
end

@@ -56,28 +56,30 @@
Loading
56 56
    k22 = MOI.dimension(MOI.PositiveSemidefiniteConeTriangle(n))
57 57
    X11() = MOI.SingleVariable(variables[k11])
58 58
    X12() = MOI.SingleVariable(variables[k12])
59 -
    X21() = MOI.SingleVariable(variables[k21])
59 +
    function X21(i, j)
60 +
        I = j
61 +
        J = n + i
62 +
        k21 = MOI.dimension(MOI.PositiveSemidefiniteConeTriangle(J - 1)) + I
63 +
        return MOI.SingleVariable(variables[k21])
64 +
    end
60 65
    X22() = MOI.SingleVariable(variables[k22])
61 66
    con_11_22 = EQ{T}[]
62 67
    con12diag = EQ{T}[]
63 68
    con_12_21 = EQ{T}[]
64 69
    for j in 1:n
65 -
        k21 -= n + 1 - j
66 70
        k22 += n
67 71
        for i in 1:j
68 72
            k11 += 1
69 73
            k12 += 1
70 -
            k21 -= 1
71 74
            k22 += 1
72 75
            push!(con_11_22, MOI.add_constraint(model, MOI.Utilities.operate(-, T, X11(), X22()), MOI.EqualTo(zero(T))))
73 76
            if i == j
74 77
                push!(con12diag, MOI.add_constraint(model, convert(MOI.ScalarAffineFunction{T}, X12()), MOI.EqualTo(zero(T))))
75 78
            else
76 -
                push!(con_12_21, MOI.add_constraint(model, MOI.Utilities.operate(+, T, X21(), X12()), MOI.EqualTo(zero(T))))
79 +
                push!(con_12_21, MOI.add_constraint(model, MOI.Utilities.operate(+, T, X21(i, j), X12()), MOI.EqualTo(zero(T))))
77 80
            end
78 81
        end
79 82
        k12 += n
80 -
        k21 -= n - j
81 83
    end
82 84
83 85
    return HermitianToSymmetricPSDBridge(variables, psd_constraint, con_11_22, con12diag, con_12_21)
Files Coverage
src 74.84%
Project Totals (6 files) 74.84%
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading