-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathnearest_correlation_new.jl
More file actions
66 lines (46 loc) · 1.77 KB
/
Copy pathnearest_correlation_new.jl
File metadata and controls
66 lines (46 loc) · 1.77 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
# # Nearest correlation
#md # [](@__REPO_ROOT_URL__/docs/src/examples/nearest_correlation.jl)
# This example illustrates the sensitivity analysis of the nearest correlation problem studied in [H02].
#
# Higham, Nicholas J.
# *Computing the nearest correlation matrix—a problem from finance.*
# IMA journal of Numerical Analysis 22.3 (2002): 329-343.
using DiffOpt, JuMP, SCS, LinearAlgebra
solver = SCS.Optimizer
function proj(A, dH = Diagonal(ones(size(A, 1))), H_data = ones(size(A)))
n = LinearAlgebra.checksquare(A)
model = Model(() -> DiffOpt.diff_optimizer(solver))
@variable(model, X[1:n, 1:n] in PSDCone())
@variable(model, H[1:n, 1:n] in Parameter.(H_data))
@variable(model, E[1:n, 1:n])
@constraint(model, [i in 1:n], X[i, i] == 1)
@constraint(model, E .== (H .* (X .- A)))
@objective(model, Min, sum(E .^ 2))
for i in 1:n
set_attribute(H[i, i], DiffOpt.ForwardParameterValue(), dH[i, i])
end
optimize!(model)
DiffOpt.forward_differentiate!(model)
dX = get_attribute.(X, DiffOpt.ForwardVariablePrimal())
return value.(X), dX
end
# Example from [H02, p. 334-335]:
A = LinearAlgebra.Tridiagonal(ones(2), ones(3), ones(2))
# The projection is computed as follows:
X, dX = proj(A)
nothing # hide
# The projection of `A` is:
X
# The derivative of the projection with respect to a uniform increase of the weights
# of the diagonal entries is:
dX
# Example from [H02, Section 4, p. 340]:
A = LinearAlgebra.Tridiagonal(-ones(3), 2ones(4), -ones(3))
# The projection is computed as follows:
X, dX = proj(A)
nothing # hide
# The projection of `A` is:
X
# The derivative of the projection with respect to a uniform increase of the weights
# of the diagonal entries is:
dX