|
| 1 | +# # Nearest correlation |
| 2 | + |
| 3 | +#md # [](@__REPO_ROOT_URL__/docs/src/examples/nearest_correlation.jl) |
| 4 | + |
| 5 | +# This example illustrates the sensitivity analysis of the nearest correlation problem studied in [H02]. |
| 6 | +# |
| 7 | +# Higham, Nicholas J. |
| 8 | +# *Computing the nearest correlation matrix—a problem from finance.* |
| 9 | +# IMA journal of Numerical Analysis 22.3 (2002): 329-343. |
| 10 | + |
| 11 | +using DiffOpt, JuMP, SCS, LinearAlgebra |
| 12 | +solver = SCS.Optimizer |
| 13 | + |
| 14 | +function proj(A, dH = Diagonal(ones(size(A, 1))), H = ones(size(A))) |
| 15 | + n = LinearAlgebra.checksquare(A) |
| 16 | + model = Model(() -> DiffOpt.diff_optimizer(solver)) |
| 17 | + @variable(model, X[1:n, 1:n] in PSDCone()) |
| 18 | + @constraint(model, [i in 1:n], X[i, i] == 1) |
| 19 | + @objective(model, Min, sum((H .* (X - A)) .^ 2)) |
| 20 | + MOI.set( |
| 21 | + model, |
| 22 | + DiffOpt.ForwardObjectiveFunction(), |
| 23 | + sum((dH .* (X - A)) .^ 2), |
| 24 | + ) |
| 25 | + optimize!(model) |
| 26 | + DiffOpt.forward_differentiate!(model) |
| 27 | + dX = MOI.get.(model, DiffOpt.ForwardVariablePrimal(), X) |
| 28 | + return value.(X), dX |
| 29 | +end |
| 30 | + |
| 31 | +# Example from [H02, p. 334-335]: |
| 32 | + |
| 33 | +A = LinearAlgebra.Tridiagonal(ones(2), ones(3), ones(2)) |
| 34 | + |
| 35 | +# The projection is computed as follows: |
| 36 | + |
| 37 | +X, dX = proj(A) |
| 38 | +nothing # hide |
| 39 | + |
| 40 | +# The projection of `A` is: |
| 41 | + |
| 42 | +X |
| 43 | + |
| 44 | +# The derivative of the projection with respect to increase uniformly the weights |
| 45 | +# of the diagonal entries is: |
| 46 | + |
| 47 | +dX |
| 48 | + |
| 49 | +# Example from [H02, Section 4, p. 340]: |
| 50 | + |
| 51 | +A = LinearAlgebra.Tridiagonal(-ones(3), 2ones(4), -ones(3)) |
| 52 | + |
| 53 | +# The projection is |
| 54 | + |
| 55 | +X, dX = proj(A) |
| 56 | +nothing # hide |
| 57 | + |
| 58 | +# The projection of `A` is: |
| 59 | + |
| 60 | +X |
| 61 | + |
| 62 | +# The derivative of the projection with respect to increase uniformly the weights |
| 63 | +# of the diagonal entries is: |
| 64 | + |
| 65 | +dX |
0 commit comments