Add complex EqualTo bridge
Fix format
Showing 1 of 3 files from the diff.
Newly tracked file
src/Bridges/Constraint/split_equalto.jl
created.
Other files ignored by Codecov
test/runtests.jl
has changed.
src/Bridges/Constraint/Constraint.jl
has changed.
@@ -0,0 +1,126 @@
Loading
1 | + | struct SplitEqualToBridge{ |
|
2 | + | T, |
|
3 | + | F<:MOI.Utilities.TypedScalarLike{T}, |
|
4 | + | G<:MOI.Utilities.TypedScalarLike{Complex{T}}, |
|
5 | + | } <: MOI.Bridges.Constraint.AbstractBridge |
|
6 | + | real_constraint::Union{Nothing,MOI.ConstraintIndex{F,MOI.EqualTo{T}}} |
|
7 | + | imag_constraint::Union{Nothing,MOI.ConstraintIndex{F,MOI.EqualTo{T}}} |
|
8 | + | end |
|
9 | + | function _add_constraint_if_nonzero(model, func, set) |
|
10 | + | if iszero(func) && iszero(MOI.constant(set)) |
|
11 | + | return nothing |
|
12 | + | else |
|
13 | + | return MOI.add_constraint(model, func, set) |
|
14 | + | end |
|
15 | + | end |
|
16 | + | function MOI.Bridges.Constraint.bridge_constraint( |
|
17 | + | ::Type{SplitEqualToBridge{T,F,G}}, |
|
18 | + | model::MOI.ModelLike, |
|
19 | + | func::G, |
|
20 | + | set::MOI.EqualTo, |
|
21 | + | ) where {T,F,G} |
|
22 | + | real_func = real(func) |
|
23 | + | imag_func = MOI.Utilities.operate(imag, T, func) |
|
24 | + | real_set = MOI.EqualTo(real(MOI.constant(set))) |
|
25 | + | imag_set = MOI.EqualTo(imag(MOI.constant(set))) |
|
26 | + | real_constraint = _add_constraint_if_nonzero(model, real_func, real_set) |
|
27 | + | imag_constraint = _add_constraint_if_nonzero(model, imag_func, imag_set) |
|
28 | + | return SplitEqualToBridge{T,F,G}(real_constraint, imag_constraint) |
|
29 | + | end |
|
30 | + | ||
31 | + | # We don't support `MOI.VariableIndex` as it would be a self-loop in the bridge graph |
|
32 | + | function MOI.supports_constraint( |
|
33 | + | ::Type{SplitEqualToBridge{T}}, |
|
34 | + | ::Type{<:MOI.Utilities.TypedLike{Complex{T}}}, |
|
35 | + | ::Type{<:MOI.EqualTo}, |
|
36 | + | ) where {T} |
|
37 | + | return true |
|
38 | + | end |
|
39 | + | MOIB.added_constrained_variable_types(::Type{<:SplitEqualToBridge}) = Tuple{DataType}[] |
|
40 | + | function MOIB.added_constraint_types(::Type{SplitEqualToBridge{T,F,G}}) where {T,F,G} |
|
41 | + | return Tuple{DataType,DataType}[(F, MOI.EqualTo{T})] |
|
42 | + | end |
|
43 | + | function MOI.Bridges.Constraint.concrete_bridge_type( |
|
44 | + | ::Type{<:SplitEqualToBridge{T}}, |
|
45 | + | G::Type{<:MOI.Utilities.TypedLike}, |
|
46 | + | ::Type{<:MOI.EqualTo}, |
|
47 | + | ) where {T} |
|
48 | + | F = MA.promote_operation(imag, G) |
|
49 | + | return SplitEqualToBridge{T,F,G} |
|
50 | + | end |
|
51 | + | ||
52 | + | # Attributes, Bridge acting as a model |
|
53 | + | function MOI.get( |
|
54 | + | bridge::SplitEqualToBridge{T,F}, |
|
55 | + | ::MOI.NumberOfConstraints{F,MOI.EqualTo{T}}, |
|
56 | + | ) where {T,F} |
|
57 | + | return !isnothing(bridge.real_constraint) + !isnothing(bridge.imag_constraint) |
|
58 | + | end |
|
59 | + | function MOI.get( |
|
60 | + | bridge::SplitEqualToBridge{T,F}, |
|
61 | + | ::MOI.ListOfConstraintIndices{F,MOI.EqualTo{T}}, |
|
62 | + | ) where {T,F} |
|
63 | + | list = MOI.ConstraintIndex{F,MOI.EqualTo{T}}[] |
|
64 | + | if !isnothing(bridge.real_constraint) |
|
65 | + | push!(list, bridge.real_constraint) |
|
66 | + | end |
|
67 | + | if !isnothing(bridge.imag_constraint) |
|
68 | + | push!(list, bridge.imag_constraint) |
|
69 | + | end |
|
70 | + | return list |
|
71 | + | end |
|
72 | + | ||
73 | + | # Indices |
|
74 | + | function MOI.delete(model::MOI.ModelLike, bridge::SplitEqualToBridge) |
|
75 | + | if !isnothing(bridge.real_constraint) |
|
76 | + | MOI.delete(model, bridge.real_constraint) |
|
77 | + | end |
|
78 | + | if !isnothing(bridge.imag_constraint) |
|
79 | + | MOI.delete(model, bridge.imag_constraint) |
|
80 | + | end |
|
81 | + | end |
|
82 | + | ||
83 | + | # Attributes, Bridge acting as a constraint |
|
84 | + | function MOI.supports( |
|
85 | + | ::MOI.ModelLike, |
|
86 | + | ::Union{MOI.ConstraintPrimalStart,MOI.ConstraintDualStart}, |
|
87 | + | ::Type{<:SplitEqualToBridge}, |
|
88 | + | ) |
|
89 | + | return true |
|
90 | + | end |
|
91 | + | function MOI.get( |
|
92 | + | model::MOI.ModelLike, |
|
93 | + | attr::Union{ |
|
94 | + | MOI.ConstraintPrimal, |
|
95 | + | MOI.ConstraintPrimalStart, |
|
96 | + | MOI.ConstraintDual, |
|
97 | + | MOI.ConstraintDualStart, |
|
98 | + | }, |
|
99 | + | bridge::SplitEqualToBridge{T}, |
|
100 | + | ) where {T} |
|
101 | + | if isnothing(bridge.real_constraint) |
|
102 | + | real_value = zero(T) |
|
103 | + | else |
|
104 | + | real_value = MOI.get(model, attr, bridge.real_constraint) |
|
105 | + | end |
|
106 | + | if isnothing(bridge.imag_constraint) |
|
107 | + | imag_value = zero(T) |
|
108 | + | else |
|
109 | + | imag_value = MOI.get(model, attr, bridge.imag_constraint) |
|
110 | + | end |
|
111 | + | return real_value + imag_value * im |
|
112 | + | end |
|
113 | + | function MOI.set( |
|
114 | + | model::MOI.ModelLike, |
|
115 | + | attr::Union{MOI.ConstraintPrimalStart,MOI.ConstraintDualStart}, |
|
116 | + | bridge::SplitEqualToBridge{T}, |
|
117 | + | value, |
|
118 | + | ) where {T} |
|
119 | + | if !isnothing(bridge.real_constraint) |
|
120 | + | MOI.set(model, attr, bridge.real_constraint, real(value)) |
|
121 | + | end |
|
122 | + | if !isnothing(bridge.imag_constraint) |
|
123 | + | MOI.set(model, attr, bridge.real_constraint, imag(value)) |
|
124 | + | end |
|
125 | + | return |
|
126 | + | end |
Files | Coverage |
---|---|
src | 73.39% |
Project Totals (4 files) | 73.39% |
1907635195
1907635195
1907635195
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.