-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathtestpolymodule.jl
More file actions
145 lines (130 loc) · 4.7 KB
/
testpolymodule.jl
File metadata and controls
145 lines (130 loc) · 4.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
module TestPolyModule
using LinearAlgebra
using MathOptInterface
const MOI = MathOptInterface
using JuMP
using PolyJuMP
using MultivariatePolynomials
import MultivariateBases
const MB = MultivariateBases
using SemialgebraicSets
struct NonNeg{BT <: MB.AbstractPolynomialBasis,
DT <: SemialgebraicSets.AbstractSemialgebraicSet,
} <: MOI.AbstractVectorSet
basis::BT
domain::DT
kwargs
end
function Base.copy(set::NonNeg)
return NonNeg(set.basis, set.domain, set.kwargs)
end
struct TestNonNeg <: PolyJuMP.PolynomialSet end
JuMP.reshape_set(::NonNeg, ::PolyJuMP.PolynomialShape) = TestNonNeg()
function JuMP.moi_set(cone::TestNonNeg,
basis::MB.AbstractPolynomialBasis;
domain::AbstractSemialgebraicSet=FullSpace(),
kwargs...)
return NonNeg(basis, domain, kwargs)
end
function JuMP.build_constraint(_error::Function, p::AbstractPolynomialLike,
s::TestNonNeg; basis = MB.MonomialBasis, kwargs...)
coefs = PolyJuMP.non_constant_coefficients(p)
monos = MB.basis_covering_monomials(basis, monomials(p))
set = JuMP.moi_set(s, monos; kwargs...)
return JuMP.VectorConstraint(coefs, set, PolyJuMP.PolynomialShape(monos))
end
struct MatrixPolynomialShape{MT <: AbstractMonomial,
MVT <: AbstractVector{MT}} <: JuMP.AbstractShape
side_dimension::Int
monomials::Matrix{MVT}
end
function JuMP.reshape_vector(x::Vector,
shape::MatrixPolynomialShape{MT}) where {MT}
n = shape.side_dimension
p = Matrix{polynomialtype(MT, eltype(x))}(undef, n, n)
k = 0
for j in 1:n
for i in 1:n
m = length(shape.monomials[i, j])
p[i, j] = polynomial(x[k .+ (1:m)], shape.monomials[i, j])
k += m
end
end
@assert length(x) == k
return p
end
struct PosDefMatrix{BT <: MB.AbstractPolynomialBasis,
DT <: SemialgebraicSets.AbstractSemialgebraicSet,
MT <: MultivariatePolynomials.AbstractMonomial,
MVT <: AbstractVector{MT}} <: MOI.AbstractVectorSet
basis::Type{BT}
domain::DT
monomials::Matrix{MVT}
kwargs
end
struct TestPosDefMatrix <: PolyJuMP.PolynomialSet end
function JuMP.reshape_set(::PosDefMatrix, ::MatrixPolynomialShape)
return TestPosDefMatrix()
end
function JuMP.moi_set(::TestPosDefMatrix,
monos::Matrix{<:AbstractVector{<:AbstractMonomial}};
domain::AbstractSemialgebraicSet=FullSpace(),
basis=MB.MonomialBasis, kwargs...)
return PosDefMatrix(basis, domain, monos, kwargs)
end
function JuMP.build_constraint(_error::Function,
p::Matrix{<:AbstractPolynomialLike},
s::TestPosDefMatrix; kwargs...)
n = LinearAlgebra.checksquare(p)
# TODO we should use `non_constant_coefficients_type` once it exists
coefs = coefficienttype(p[1, 1])[]
for j in 1:n
for i in 1:n
append!(coefs, coefficients(p[i, j]))
end
end
monos = monomials.(p)
set = JuMP.moi_set(s, monos; kwargs...)
return JuMP.VectorConstraint(coefs, set, MatrixPolynomialShape(n, monos))
end
# TODO the function in JuMP should not require the eltype to be
# `AbstractJuMPScalar` so that we don't have to define this
# These methods are just copy-paste from JuMP/src/print.jl
function JuMP.function_string(::Type{REPLMode},
A::AbstractMatrix{<:AbstractPolynomialLike})
str = sprint(show, MIME"text/plain"(), A)
lines = split(str, '\n')
# We drop the first line with the signature "m×n Array{...}:"
lines = lines[2:end]
# We replace the first space by an opening `[`
lines[1] = '[' * lines[1][2:end]
for i in 1:length(lines)
lines[i] = lines[i] * (i == length(lines) ? ']' : ';')
end
return join(lines, '\n')
end
function JuMP.function_string(print_mode::Type{IJuliaMode},
A::AbstractMatrix{<:AbstractPolynomialLike})
str = sprint(show, MIME"text/plain"(), A)
str = "\\begin{bmatrix}\n"
for i in 1:size(A, 1)
line = ""
for j in 1:size(A, 2)
if j != 1
line *= " & "
end
if A isa Symmetric && i > j
line *= "\\cdot"
else
line *= JuMP.function_string(print_mode, A[i, j])
end
end
str *= line * "\\\\\n"
end
return str * "\\end{bmatrix}"
end
function setdefaults!(data::PolyJuMP.Data)
PolyJuMP.setdefault!(data, PolyJuMP.NonNegPoly, TestNonNeg)
PolyJuMP.setdefault!(data, PolyJuMP.PosDefPolyMatrix, TestPosDefMatrix)
end
end