diff --git a/linopy/expressions.py b/linopy/expressions.py index 2ab0b8d3..bf7c9dee 100644 --- a/linopy/expressions.py +++ b/linopy/expressions.py @@ -963,7 +963,8 @@ def _map_solution(self) -> DataArray: Replace variable labels by solution values. """ m = self.model - sol = pd.Series(m.matrices.sol, m.matrices.vlabels) + M = m.matrices + sol = pd.Series(M.sol, M.vlabels) sol[-1] = np.nan idx = np.ravel(self.vars) values = np.asarray(sol[idx]).reshape(self.vars.shape) diff --git a/linopy/matrices.py b/linopy/matrices.py index e694a720..21b50d2d 100644 --- a/linopy/matrices.py +++ b/linopy/matrices.py @@ -7,6 +7,7 @@ from __future__ import annotations +from functools import cached_property from typing import TYPE_CHECKING, cast import numpy as np @@ -96,7 +97,7 @@ def _build_cons(self) -> None: np.concatenate(sense_list) if sense_list else np.array([], dtype=object) ) - @property + @cached_property def c(self) -> ndarray: """Objective coefficients aligned with vlabels.""" m = self._parent @@ -121,7 +122,7 @@ def c(self) -> ndarray: np.add.at(result, label_to_pos[var_labels[mask]], coeffs[mask]) return result - @property + @cached_property def Q(self) -> scipy.sparse.csc_matrix | None: """Quadratic objective matrix, shape (n_active_vars, n_active_vars).""" m = self._parent @@ -130,7 +131,7 @@ def Q(self) -> scipy.sparse.csc_matrix | None: return None return expr.to_matrix()[self.vlabels][:, self.vlabels] - @property + @cached_property def sol(self) -> ndarray: """Solution values aligned with vlabels.""" if not self._parent.status == "ok": @@ -146,7 +147,7 @@ def sol(self) -> ndarray: result[positions] = var.solution.values.ravel()[mask] return result - @property + @cached_property def dual(self) -> ndarray: """Dual values aligned with clabels.""" if not self._parent.status == "ok":