1414limitations under the License.
1515"""
1616
17- import numpy as np
18-
19- from cvxpy .expressions .constants import Constant
2017from cvxpy .expressions .variable import Variable
2118from cvxpy .expressions .constants import Constant
2219import numpy as np
@@ -37,21 +34,6 @@ def collect_constant_and_variable(expr, constants, variable):
3734# Perhaps this should be a parameter exposed to the user?
3835LOWER_BOUND = 1e-5
3936
40- def collect_constant_and_variable (expr , constants , variable ):
41- if isinstance (expr , Constant ):
42- constants .append (expr )
43- elif isinstance (expr , Variable ):
44- variable .append (expr )
45- elif hasattr (expr , "args" ):
46- for subexpr in expr .args :
47- collect_constant_and_variable (subexpr , constants , variable )
48-
49- assert (len (variable ) <= 1 )
50-
51- # DCED: Without this lower bound the stress test for ML Gaussian non-zero mean fails.
52- # Perhaps this should be a parameter exposed to the user?
53- LOWER_BOUND = 1e-5
54-
5537def log_canon (expr , args ):
5638 t = Variable (args [0 ].size , bounds = [LOWER_BOUND , None ])
5739
@@ -83,10 +65,22 @@ def log_canon(expr, args):
8365 ubs = np .inf * np .ones (args [0 ].size )
8466 lbs [a > 0 ] = 0
8567 ubs [a < 0 ] = 0
86- variable [0 ].bounds = [lbs , ubs ]
68+
69+ if variable [0 ].bounds is not None :
70+ lbs = np .maximum (lbs , variable [0 ].bounds [0 ])
71+ ubs = np .minimum (ubs , variable [0 ].bounds [1 ])
72+
73+ variable [0 ].bounds = [lbs , ubs ]
8774 assert (args [0 ].value is not None and np .all (args [0 ].value > 0.0 ))
8875 t .value = args [0 ].value
8976
77+ # DCED: introducing an out variable for log works MUCH worse for the
78+ # Gaussian ML problem
79+ #v = Variable(args[0].size)
80+ #v.value = np.ones(expr.shape)
81+ #v.value = np.log(t.value)
82+ #return v, [v == expr.copy([t]), t == args[0]]
83+
9084 return expr .copy ([t ]), [t == args [0 ]]
9185
9286# TODO (DCED): On some problems this canonicalization seems to work better.
0 commit comments