Skip to content

Commit ee4d329

Browse files
Transurgeonclaude
andcommitted
Fix PowerApprox support after upstream Power/PowerApprox split
The upstream CVXPY split Power into exact (Power) and approximate (PowerApprox) subclasses. This broke NLP solving because: 1. dnlp2smooth used `power` (function) as dict key but lookup uses `type(expr)` which returns the class (Power or PowerApprox) 2. power_canon.py used `p_rational` which doesn't exist on PowerApprox 3. diff_engine converters used "power" (lowercase) but class name is "Power" Fixes: - dnlp2smooth/__init__.py: Import Power and PowerApprox classes, register both with power_canon - power_canon.py: Use `p_used` instead of `p_rational` - converters.py: Use "Power" and "PowerApprox" as keys Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent eb26d21 commit ee4d329

3 files changed

Lines changed: 6 additions & 4 deletions

File tree

cvxpy/reductions/dnlp2smooth/canonicalizers/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from cvxpy.atoms.elementwise.kl_div import kl_div
2525
from cvxpy.atoms.elementwise.minimum import minimum
2626
from cvxpy.atoms.elementwise.maximum import maximum
27-
from cvxpy.atoms.elementwise.power import power
27+
from cvxpy.atoms.elementwise.power import Power, PowerApprox
2828
from cvxpy.atoms.elementwise.trig import cos, sin, tan
2929
from cvxpy.atoms.elementwise.hyperbolic import sinh, asinh, tanh, atanh
3030
from cvxpy.atoms.elementwise.huber import huber
@@ -77,7 +77,8 @@
7777
tanh: tanh_canon,
7878
atanh: atanh_canon,
7979
quad_over_lin: quad_over_lin_canon,
80-
power: power_canon,
80+
Power: power_canon,
81+
PowerApprox: power_canon,
8182
Pnorm : pnorm_canon,
8283
DivExpression: div_canon,
8384
entr: entr_canon,

cvxpy/reductions/dnlp2smooth/canonicalizers/power_canon.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
def power_canon(expr, args):
2626
x = args[0]
27-
p = expr.p_rational
27+
p = expr.p_used
2828
shape = expr.shape
2929
ones = Constant(np.ones(shape))
3030
if p == 0:

cvxpy/reductions/solvers/nlp_solvers/diff_engine/converters.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,8 @@ def _convert_diag_vec(expr, children):
304304
# Matrix multiplication
305305
"MulExpression": _convert_matmul,
306306
# Elementwise univariate with parameter
307-
"power": lambda expr, children: _diffengine.make_power(children[0], float(expr.p.value)),
307+
"Power": lambda expr, children: _diffengine.make_power(children[0], float(expr.p.value)),
308+
"PowerApprox": lambda expr, children: _diffengine.make_power(children[0], float(expr.p.value)),
308309
# Trigonometric
309310
"sin": lambda _expr, children: _diffengine.make_sin(children[0]),
310311
"cos": lambda _expr, children: _diffengine.make_cos(children[0]),

0 commit comments

Comments
 (0)