Constant LinearExpression * multi-term LinearExpression raises TypeError (mirrored product works)
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 68/100
Línea de trabajo
Empieza leyendo LinearExpression._multiply_by_linear_expression y __mul__, que el issue identifica como la causa; luego ejecuta las reproducciones con matrices densas y dispersas del issue. El trabajo está terminado cuando una LinearExpression constante multiplicada por una LinearExpression con varios términos devuelve el mismo resultado lineal escalado en ambos backends, y los casos reflejados existentes y los casos con un solo término siguen funcionando.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
[!NOTE]
The following content was generated by AI.
Version Checks
- I have confirmed this bug exists on the current
masterbranch of Linopy (95f6bfa4).
Issue Description
Multiplying a constant LinearExpression (no terms) by a multi-term LinearExpression raises TypeError on both the dense and sparse backends. The mirrored product (multi-term × constant) and constant × one-term expression both work and return the scaled linear expression.
Cause: LinearExpression._multiply_by_linear_expression checks other.nterm > 1 and raises before checking self.is_constant. __mul__ then turns that TypeError into NotImplemented, so the user only sees the generic unsupported operand type(s) message.
Found while building the dense/sparse conformance suite for #1019.
Reproducible Example
import warnings
from linopy import LinearExpression, Model
warnings.simplefilter("ignore") # PerformanceWarning on sparse
for sparse in (False, True):
m = Model(sparse=sparse)
x = m.add_variables(name="x")
y = m.add_variables(name="y")
c = LinearExpression(3, m)
print(f"sparse={sparse}")
for lab, f in {
"c * (2*x + 3*y)": lambda: c * (2 * x + 3 * y),
"(2*x + 3*y) * c": lambda: (2 * x + 3 * y) * c,
"c * (2*x)": lambda: c * (2 * x),
"3 * (2*x + 3*y)": lambda: 3 * (2 * x + 3 * y),
}.items():
try:
r = repr(f()).splitlines()[-1]
except Exception as e:
r = f"{type(e).__name__}: {e}"
print(f" {lab:18} -> {r}")
Output:
sparse=False
c * (2*x + 3*y) -> TypeError: unsupported operand type(s) for *: 'LinearExpression' and 'LinearExpression'
(2*x + 3*y) * c -> +6 x + 9 y
c * (2*x) -> +6 x
3 * (2*x + 3*y) -> +6 x + 9 y
sparse=True
c * (2*x + 3*y) -> TypeError: unsupported operand type(s) for *: 'LinearExpression' and 'LinearExpression'
(2*x + 3*y) * c -> +6 x + 9 y
c * (2*x) -> +6 x
3 * (2*x + 3*y) -> +6 x + 9 y
Traceback (without try/except)
Traceback (most recent call last):
File "repro.py", line 18, in <module>
c * (2 * x + 3 * y)
~~^~~~~~~~~~~~~~~~~
TypeError: unsupported operand type(s) for *: 'LinearExpression' and 'LinearExpression'
The same asymmetry applies to non-constant one-term factors, e.g. (x*0 + 3) * (2*x + 3*y) raises while (2*x + 3*y) * (x*0 + 3) returns a QuadraticExpression.
Expected Behavior
A constant expression acts like a scalar factor: c * (2*x + 3*y) returns the LinearExpression +6 x + 9 y, the same as (2*x + 3*y) * c and 3 * (2*x + 3*y).
- Lenguaje dominante
- Python
- Estrellas
- 262
- Forks
- 89
- Merge medio
- 2 d 4 h
- PR fusionados (30 d)
- 37
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de PyPSA/linopy
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día
-
bug solver interface
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
Los mantenedores suelen responder en 1 día
-
refactor sparse
Dificultad 4/5 3-5 días Aptitud para principiantes 48/100
PyPSA/linopy#1049 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
One netcdf layout for constraints and expressions written from the storePosiblemente ocupada @FabianHofmann la tomó hoy. Abiertorefactor sparse
Dificultad 4/5 3-5 días Aptitud para principiantes 48/100
Los mantenedores suelen responder en 1 día
-
One Constraint class: delete CSRConstraint, ConstraintBase and the freeze APIPosiblemente ocupada @FabianHofmann la tomó hoy. Abiertorefactor sparse
Dificultad 5/5 Más de una semana Aptitud para principiantes 38/100
PyPSA/linopy#1047 · 1 comentario ·
Los mantenedores suelen responder en 1 día
Todos los issues de PyPSA/linopy
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 77/100
AstrBotDevs/AstrBot#10720 ·
Los mantenedores suelen responder en 1 día
-
fix(xiaomi): curated picker list still offers six ids that return 400 (plan-limited vs retired)Abiertocause/upstream comp/cli P2 provider/other tool/file type/bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
NousResearch/hermes-agent#143900 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 1-3 horas Aptitud para principiantes 85/100
WLAN-Pi/wlanpi-profiler#341 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 77/100
Los mantenedores suelen responder en 1 día