@@ -1564,3 +1564,318 @@ function setup_test(
1564
1564
)
1565
1565
return
1566
1566
end
1567
+
1568
+ function _test_matrix_norm_cone (
1569
+ model:: MOI.ModelLike ,
1570
+ config:: Config{T} ,
1571
+ set:: Union{MOI.NormSpectralCone,MOI.NormNuclearCone} ,
1572
+ b:: Union{Nothing,Vector{T}} ,
1573
+ ) where {T}
1574
+ @requires _supports (config, MOI. optimize!)
1575
+ F = b == nothing ? MOI. VectorOfVariables : MOI. VectorAffineFunction{T}
1576
+ @requires MOI. supports_constraint (model, F, typeof (set))
1577
+ t = MOI. add_variable (model)
1578
+ X = MOI. add_variables (model, 6 )
1579
+ f = if b === nothing
1580
+ MOI. VectorOfVariables ([t; X])
1581
+ else
1582
+ fx = MOI. Utilities. operate .(+ , T, X, b)
1583
+ MOI. Utilities. operate (vcat, T, t, fx... )
1584
+ end
1585
+ MOI. add_constraint (model, f, set)
1586
+ for i in 1 : 6
1587
+ MOI. add_constraint (model, X[i], MOI. EqualTo {T} (i))
1588
+ end
1589
+ MOI. set (model, MOI. ObjectiveSense (), MOI. MIN_SENSE)
1590
+ MOI. set (model, MOI. ObjectiveFunction {MOI.VariableIndex} (), t)
1591
+ MOI. optimize! (model)
1592
+ x_result = MOI. get (model, MOI. VariablePrimal (), X)
1593
+ @test ≈ (x_result, 1 : 6 , config)
1594
+ Y = reshape (x_result .+ something (b, T (0 )), set. row_dim, set. column_dim)
1595
+ # svdvals doesn't work for BigFloat etc. So don't use `T` as the element
1596
+ # type when computing the singular values.
1597
+ σ = LinearAlgebra. svdvals (convert (Matrix{Float64}, Y))
1598
+ result = set isa MOI. NormSpectralCone ? maximum (σ) : sum (σ)
1599
+ @test ≈ (MOI. get (model, MOI. VariablePrimal (), t), result, config)
1600
+ return
1601
+ end
1602
+
1603
+ function test_NormSpectralCone_VectorOfVariables_without_transform (
1604
+ model:: MOI.ModelLike ,
1605
+ config:: Config ,
1606
+ )
1607
+ _test_matrix_norm_cone (model, config, MOI. NormSpectralCone (3 , 2 ), nothing )
1608
+ return
1609
+ end
1610
+
1611
+ function setup_test (
1612
+ :: typeof (test_NormSpectralCone_VectorOfVariables_without_transform),
1613
+ model:: MOIU.MockOptimizer ,
1614
+ :: Config{T} ,
1615
+ ) where {T}
1616
+ # svdvals doesn't work for BigFloat etc. So don't use `T` as the element
1617
+ # type when computing the result.
1618
+ result = [1 , 2 , 3 , 4 , 5 , 6 ]
1619
+ t = LinearAlgebra. opnorm (reshape (result, 3 , 2 ))
1620
+ MOIU. set_mock_optimize! (
1621
+ model,
1622
+ (mock:: MOIU.MockOptimizer ) ->
1623
+ MOIU. mock_optimize! (mock, MOI. OPTIMAL, T[t; result]),
1624
+ )
1625
+ return
1626
+ end
1627
+
1628
+ function test_NormSpectralCone_VectorOfVariables_with_transform (
1629
+ model:: MOI.ModelLike ,
1630
+ config:: Config ,
1631
+ )
1632
+ _test_matrix_norm_cone (model, config, MOI. NormSpectralCone (2 , 3 ), nothing )
1633
+ return
1634
+ end
1635
+
1636
+ function setup_test (
1637
+ :: typeof (test_NormSpectralCone_VectorOfVariables_with_transform),
1638
+ model:: MOIU.MockOptimizer ,
1639
+ :: Config{T} ,
1640
+ ) where {T}
1641
+ # svdvals doesn't work for BigFloat etc. So don't use `T` as the element
1642
+ # type when computing the result.
1643
+ result = [1 , 2 , 3 , 4 , 5 , 6 ]
1644
+ t = LinearAlgebra. opnorm (reshape (result, 2 , 3 ))
1645
+ MOIU. set_mock_optimize! (
1646
+ model,
1647
+ (mock:: MOIU.MockOptimizer ) ->
1648
+ MOIU. mock_optimize! (mock, MOI. OPTIMAL, T[t; result]),
1649
+ )
1650
+ return
1651
+ end
1652
+
1653
+ function test_NormSpectralCone_VectorAffineFunction_without_transform (
1654
+ model:: MOI.ModelLike ,
1655
+ config:: Config{T} ,
1656
+ ) where {T}
1657
+ b = convert (Vector{T}, 7 : 12 )
1658
+ _test_matrix_norm_cone (model, config, MOI. NormSpectralCone (3 , 2 ), b)
1659
+ return
1660
+ end
1661
+
1662
+ function setup_test (
1663
+ :: typeof (test_NormSpectralCone_VectorAffineFunction_without_transform),
1664
+ model:: MOIU.MockOptimizer ,
1665
+ :: Config{T} ,
1666
+ ) where {T}
1667
+ # svdvals doesn't work for BigFloat etc. So don't use `T` as the element
1668
+ # type when computing the result.
1669
+ result = [1 , 2 , 3 , 4 , 5 , 6 ]
1670
+ t = LinearAlgebra. opnorm (reshape (result + collect (7 : 12 ), 3 , 2 ))
1671
+ MOIU. set_mock_optimize! (
1672
+ model,
1673
+ (mock:: MOIU.MockOptimizer ) ->
1674
+ MOIU. mock_optimize! (mock, MOI. OPTIMAL, T[t; result]),
1675
+ )
1676
+ return
1677
+ end
1678
+
1679
+ function test_NormSpectralCone_VectorAffineFunction_with_transform (
1680
+ model:: MOI.ModelLike ,
1681
+ config:: Config{T} ,
1682
+ ) where {T}
1683
+ b = convert (Vector{T}, 7 : 12 )
1684
+ _test_matrix_norm_cone (model, config, MOI. NormSpectralCone (2 , 3 ), b)
1685
+ return
1686
+ end
1687
+
1688
+ function setup_test (
1689
+ :: typeof (test_NormSpectralCone_VectorAffineFunction_with_transform),
1690
+ model:: MOIU.MockOptimizer ,
1691
+ :: Config{T} ,
1692
+ ) where {T}
1693
+ # svdvals doesn't work for BigFloat etc. So don't use `T` as the element
1694
+ # type when computing the result.
1695
+ result = [1 , 2 , 3 , 4 , 5 , 6 ]
1696
+ t = LinearAlgebra. opnorm (reshape (result + collect (7 : 12 ), 2 , 3 ))
1697
+ MOIU. set_mock_optimize! (
1698
+ model,
1699
+ (mock:: MOIU.MockOptimizer ) ->
1700
+ MOIU. mock_optimize! (mock, MOI. OPTIMAL, T[t; result]),
1701
+ )
1702
+ return
1703
+ end
1704
+
1705
+ function test_NormNuclearCone_VectorOfVariables_without_transform (
1706
+ model:: MOI.ModelLike ,
1707
+ config:: Config ,
1708
+ )
1709
+ _test_matrix_norm_cone (model, config, MOI. NormNuclearCone (3 , 2 ), nothing )
1710
+ return
1711
+ end
1712
+
1713
+ function setup_test (
1714
+ :: typeof (test_NormNuclearCone_VectorOfVariables_without_transform),
1715
+ model:: MOIU.MockOptimizer ,
1716
+ :: Config{T} ,
1717
+ ) where {T}
1718
+ # svdvals doesn't work for BigFloat etc. So don't use `T` as the element
1719
+ # type when computing the result.
1720
+ result = [1 , 2 , 3 , 4 , 5 , 6 ]
1721
+ t = sum (LinearAlgebra. svdvals (reshape (result, 3 , 2 )))
1722
+ MOIU. set_mock_optimize! (
1723
+ model,
1724
+ (mock:: MOIU.MockOptimizer ) ->
1725
+ MOIU. mock_optimize! (mock, MOI. OPTIMAL, T[t; result]),
1726
+ )
1727
+ return
1728
+ end
1729
+
1730
+ function test_NormNuclearCone_VectorOfVariables_with_transform (
1731
+ model:: MOI.ModelLike ,
1732
+ config:: Config ,
1733
+ )
1734
+ _test_matrix_norm_cone (model, config, MOI. NormNuclearCone (2 , 3 ), nothing )
1735
+ return
1736
+ end
1737
+
1738
+ function setup_test (
1739
+ :: typeof (test_NormNuclearCone_VectorOfVariables_with_transform),
1740
+ model:: MOIU.MockOptimizer ,
1741
+ :: Config{T} ,
1742
+ ) where {T}
1743
+ # svdvals doesn't work for BigFloat etc. So don't use `T` as the element
1744
+ # type when computing the result.
1745
+ result = [1 , 2 , 3 , 4 , 5 , 6 ]
1746
+ t = sum (LinearAlgebra. svdvals (reshape (result, 2 , 3 )))
1747
+ MOIU. set_mock_optimize! (
1748
+ model,
1749
+ (mock:: MOIU.MockOptimizer ) ->
1750
+ MOIU. mock_optimize! (mock, MOI. OPTIMAL, T[t; result]),
1751
+ )
1752
+ return
1753
+ end
1754
+
1755
+ function test_NormNuclearCone_VectorAffineFunction_without_transform (
1756
+ model:: MOI.ModelLike ,
1757
+ config:: Config{T} ,
1758
+ ) where {T}
1759
+ b = convert (Vector{T}, 7 : 12 )
1760
+ _test_matrix_norm_cone (model, config, MOI. NormNuclearCone (3 , 2 ), b)
1761
+ return
1762
+ end
1763
+
1764
+ function setup_test (
1765
+ :: typeof (test_NormNuclearCone_VectorAffineFunction_without_transform),
1766
+ model:: MOIU.MockOptimizer ,
1767
+ :: Config{T} ,
1768
+ ) where {T}
1769
+ # svdvals doesn't work for BigFloat etc. So don't use `T` as the element
1770
+ # type when computing the result.
1771
+ result = [1 , 2 , 3 , 4 , 5 , 6 ]
1772
+ t = sum (LinearAlgebra. svdvals (reshape (result + collect (7 : 12 ), 3 , 2 )))
1773
+ MOIU. set_mock_optimize! (
1774
+ model,
1775
+ (mock:: MOIU.MockOptimizer ) ->
1776
+ MOIU. mock_optimize! (mock, MOI. OPTIMAL, T[t; result]),
1777
+ )
1778
+ return
1779
+ end
1780
+
1781
+ function test_NormNuclearCone_VectorAffineFunction_with_transform (
1782
+ model:: MOI.ModelLike ,
1783
+ config:: Config{T} ,
1784
+ ) where {T}
1785
+ b = convert (Vector{T}, 7 : 12 )
1786
+ _test_matrix_norm_cone (model, config, MOI. NormNuclearCone (2 , 3 ), b)
1787
+ return
1788
+ end
1789
+
1790
+ function setup_test (
1791
+ :: typeof (test_NormNuclearCone_VectorAffineFunction_with_transform),
1792
+ model:: MOIU.MockOptimizer ,
1793
+ :: Config{T} ,
1794
+ ) where {T}
1795
+ # svdvals doesn't work for BigFloat etc. So don't use `T` as the element
1796
+ # type when computing the result.
1797
+ result = [1 , 2 , 3 , 4 , 5 , 6 ]
1798
+ t = sum (LinearAlgebra. svdvals (reshape (result + collect (7 : 12 ), 2 , 3 )))
1799
+ MOIU. set_mock_optimize! (
1800
+ model,
1801
+ (mock:: MOIU.MockOptimizer ) ->
1802
+ MOIU. mock_optimize! (mock, MOI. OPTIMAL, T[t; result]),
1803
+ )
1804
+ return
1805
+ end
1806
+
1807
+ function test_HermitianPSDCone_basic (
1808
+ model:: MOI.ModelLike ,
1809
+ config:: Config{T} ,
1810
+ ) where {T}
1811
+ @requires _supports (config, MOI. optimize!)
1812
+ S = MOI. HermitianPositiveSemidefiniteConeTriangle
1813
+ @requires MOI. supports_constraint (model, MOI. VectorAffineFunction{T}, S)
1814
+ x = MOI. add_variables (model, 9 )
1815
+ for i in eachindex (x)
1816
+ MOI. add_constraint (model, x[i], MOI. EqualTo {T} (i))
1817
+ end
1818
+ b = T[12 , 0 , 12 , 0 , 0 , 12 , 0 , 0 , 0 ]
1819
+ f = MOI. Utilities. operate (vcat, T, MOI. Utilities. operate .(+ , T, x, b)... )
1820
+ set = MOI. HermitianPositiveSemidefiniteConeTriangle (3 )
1821
+ MOI. add_constraint (model, f, set)
1822
+ MOI. optimize! (model)
1823
+ MOI. get (model, MOI. TerminationStatus ()) == config. optimal_status
1824
+ @test ≈ (MOI. get (model, MOI. VariablePrimal (), x), 1 : 9 , config)
1825
+ return
1826
+ end
1827
+
1828
+ function setup_test (
1829
+ :: typeof (test_HermitianPSDCone_basic),
1830
+ model:: MOIU.MockOptimizer ,
1831
+ :: Config{T} ,
1832
+ ) where {T}
1833
+ MOIU. set_mock_optimize! (
1834
+ model,
1835
+ (mock:: MOIU.MockOptimizer ) -> MOIU. mock_optimize! (
1836
+ mock,
1837
+ MOI. OPTIMAL,
1838
+ T[1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ],
1839
+ ),
1840
+ )
1841
+ return
1842
+ end
1843
+
1844
+ function test_HermitianPSDCone_min_t (
1845
+ model:: MOI.ModelLike ,
1846
+ config:: Config{T} ,
1847
+ ) where {T}
1848
+ @requires _supports (config, MOI. optimize!)
1849
+ S = MOI. HermitianPositiveSemidefiniteConeTriangle
1850
+ @requires MOI. supports_constraint (model, MOI. VectorAffineFunction{T}, S)
1851
+ t = MOI. add_variable (model)
1852
+ x = MOI. add_variables (model, 9 )
1853
+ for (i, xi) in enumerate (x)
1854
+ MOI. add_constraint (model, xi, MOI. EqualTo {T} (i))
1855
+ end
1856
+ bt = Union{MOI. VariableIndex,T}[t, T (0 ), t, T (0 ), T (0 ), t, T (0 ), T (0 ), T (0 )]
1857
+ f = MOI. Utilities. operate (vcat, T, MOI. Utilities. operate .(+ , T, x, bt)... )
1858
+ set = MOI. HermitianPositiveSemidefiniteConeTriangle (3 )
1859
+ MOI. add_constraint (model, f, set)
1860
+ MOI. set (model, MOI. ObjectiveSense (), MOI. MIN_SENSE)
1861
+ MOI. set (model, MOI. ObjectiveFunction {MOI.VariableIndex} (), t)
1862
+ MOI. optimize! (model)
1863
+ MOI. get (model, MOI. TerminationStatus ()) == config. optimal_status
1864
+ x_result = MOI. get (model, MOI. VariablePrimal (), x)
1865
+ @test ≈ (x_result, 1 : 9 , config)
1866
+ @test ≈ (MOI. get (model, MOI. VariablePrimal (), t), 11.034899152582094 , config)
1867
+ return
1868
+ end
1869
+
1870
+ function setup_test (
1871
+ :: typeof (test_HermitianPSDCone_min_t),
1872
+ model:: MOIU.MockOptimizer ,
1873
+ :: Config{T} ,
1874
+ ) where {T}
1875
+ x = T[11.034899152582094 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]
1876
+ MOIU. set_mock_optimize! (
1877
+ model,
1878
+ (mock:: MOIU.MockOptimizer ) -> MOIU. mock_optimize! (mock, MOI. OPTIMAL, x),
1879
+ )
1880
+ return
1881
+ end
0 commit comments