Coverage for picos/solvers/solver_smcp.py: 65.85%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

41 statements  

1# ------------------------------------------------------------------------------ 

2# Copyright (C) 2017 Maximilian Stahlberg 

3# 

4# This file is part of PICOS. 

5# 

6# PICOS is free software: you can redistribute it and/or modify it under the 

7# terms of the GNU General Public License as published by the Free Software 

8# Foundation, either version 3 of the License, or (at your option) any later 

9# version. 

10# 

11# PICOS is distributed in the hope that it will be useful, but WITHOUT ANY 

12# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 

13# A PARTICULAR PURPOSE. See the GNU General Public License for more details. 

14# 

15# You should have received a copy of the GNU General Public License along with 

16# this program. If not, see <http://www.gnu.org/licenses/>. 

17# ------------------------------------------------------------------------------ 

18 

19"""Implementation of :class:`SMCPSolver`.""" 

20 

21# ------------------------------------------------------------------------------ 

22# This file is a skeleton implementation for the SMCP solver. 

23# Currently, the functional implementation is found in CVXOPTSolver. 

24# ------------------------------------------------------------------------------ 

25 

26from .. import settings 

27from ..apidoc import api_end, api_start 

28from ..constraints import AffineConstraint, DummyConstraint, LMIConstraint 

29from ..expressions import CONTINUOUS_VARTYPES, AffineExpression 

30from ..modeling.footprint import Specification 

31from .solver import Solver 

32from .solver_cvxopt import CVXOPTSolver 

33 

34_API_START = api_start(globals()) 

35# ------------------------------- 

36 

37 

38class SMCPSolver(CVXOPTSolver): 

39 """Interface to the SMCP solver. 

40 

41 Most of the logic is implemented in the 

42 :class:`CVXOPTSolver <picos.solvers.solver_cvxopt.CVXOPTSolver>` base class. 

43 """ 

44 

45 SUPPORTED = Specification( 

46 objectives=[ 

47 AffineExpression], 

48 variables=CONTINUOUS_VARTYPES, 

49 constraints=[ 

50 DummyConstraint, 

51 AffineConstraint, 

52 # TODO: See below. 

53 # SOCConstraint, 

54 # RSOCConstraint, 

55 LMIConstraint]) 

56 

57 @classmethod 

58 def supports(cls, footprint, explain=False): 

59 """Implement :meth:`~.solver.Solver.supports`.""" 

60 result = Solver.supports(footprint, explain) 

61 if not result or (explain and not result[0]): 

62 return result 

63 

64 # TODO: SMCP formally supports problems that are not SDPs, but it is 

65 # known to perform poorly for them, sometimes even returning 

66 # incorrect solutions. For now, only support SDPs. 

67 if not settings.UNRELIABLE_STRATEGIES \ 

68 and ("con", LMIConstraint) not in footprint: 

69 if explain: 

70 return False, "Problems other than SDPs (PICOS' choice)." 

71 else: 

72 return False 

73 

74 if footprint not in cls.SUPPORTED: 

75 if explain: 

76 return False, cls.SUPPORTED.mismatch_reason(footprint) 

77 else: 

78 return False 

79 

80 return (True, None) if explain else True 

81 

82 @classmethod 

83 def default_penalty(cls): 

84 """Implement :meth:`~.solver.Solver.default_penalty`.""" 

85 return 2.0 # Experimental free/open source solver. 

86 

87 @classmethod 

88 def test_availability(cls): 

89 """Implement :meth:`~.solver.Solver.test_availability`.""" 

90 cls.check_import("smcp") 

91 

92 @classmethod 

93 def names(cls): 

94 """Implement :meth:`~.solver.Solver.names`.""" 

95 return "smcp", "SMCP", "Sparse Matrix Cone Program Solver", None 

96 

97 @classmethod 

98 def is_free(cls): 

99 """Implement :meth:`~.solver.Solver.is_free`.""" 

100 return True 

101 

102 @property 

103 def is_smcp(self): 

104 """Whether to implement SMCP instead of CVXOPT.""" 

105 return True 

106 

107 

108# -------------------------------------- 

109__all__ = api_end(_API_START, globals())