@@ -157,6 +157,17 @@ def _dual_cone(self, *args):
157157 args [2 ], self .alpha )
158158
159159
160+ class PowCone3DApprox (PowCone3D ):
161+ """PowCone3D with SOC-based rational approximation.
162+
163+ Identical semantics to PowCone3D, but the solving chain will
164+ convert this constraint to second-order cone (SOC) constraints
165+ via rational approximation of the exponent, following the same
166+ pattern as PowerApprox / PnormApprox for atoms.
167+ """
168+ pass
169+
170+
160171class PowConeND (Cone ):
161172 """
162173 Represents a collection of N-dimensional power cone constraints
@@ -237,7 +248,12 @@ def shape(self) -> Tuple[int, int]:
237248 # This constitutes the shape of the hypograph variable z
238249 # appended to W in the standard conic form.
239250 # TODO: support arbitrary z.dim
240- m , n = self .W .shape if self .axis == 0 else (self .W .shape [1 ], self .W .shape [0 ])
251+ if self .W .ndim == 1 :
252+ m , n = self .W .shape [0 ], 1
253+ elif self .axis == 0 :
254+ m , n = self .W .shape
255+ else :
256+ m , n = self .W .shape [1 ], self .W .shape [0 ]
241257 s = (m + 1 , n )
242258 return s
243259
@@ -285,13 +301,14 @@ def is_dqcp(self) -> bool:
285301 return self .is_dcp ()
286302
287303 def save_dual_value (self , value ) -> None :
288- dW = value [:, :- 1 ]
289- dz = value [:, - 1 ]
290- if self .axis == 0 :
304+ # Value has shape (n+1, k) from ConeMatrixStuffing (constraint.shape).
305+ # First n rows are W duals, last row is z duals.
306+ dW = value [:- 1 , :] # Shape (n, k)
307+ dz = value [- 1 , :] # Shape (k,)
308+ if self .axis == 1 :
291309 dW = dW .T
292- dz = dz .T
293- if dW .shape [1 ] == 1 :
294- #NOTE: Targetting problems where duals have the shape
310+ if dW .shape [- 1 ] == 1 :
311+ # NOTE: Targetting problems where duals have the shape
295312 # (n, 1) --- dropping the extra dimension is crucial for
296313 # the `_dual_cone` and `dual_residual` methods to work properly
297314 dW = np .squeeze (dW )
0 commit comments