From 3c713bab5046d212e6f6924e794effb15f35a1f3 Mon Sep 17 00:00:00 2001 From: Chenyang Yuan Date: Sat, 5 Oct 2024 18:41:19 -0400 Subject: [PATCH] Performance improvement in creating Basis objects --- .gitignore | 2 +- src/SumOfSquares/SoS.py | 2 +- src/SumOfSquares/basis.py | 18 ++++++++++++------ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index c48336c..fa5eb2c 100644 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,7 @@ __pycache__ *.out # Project specific -/Untitled.ipynb +/examples /.ipynb_checkpoints/ /build/ /dist/ diff --git a/src/SumOfSquares/SoS.py b/src/SumOfSquares/SoS.py index 7a53dcc..8e8d256 100644 --- a/src/SumOfSquares/SoS.py +++ b/src/SumOfSquares/SoS.py @@ -162,7 +162,7 @@ def poly_opt_prob(vars : List[sp.Symbol], deg : Optional[int] = None, sparse : bool = False) -> SOSProblem: '''Formulates and returns a degree DEG Sum-of-Squares relaxation of a polynomial - optimization problem in variables VARS that mininizes OBJ subject to + optimization problem in variables VARS that minimizes OBJ subject to equality constraints EQS (g(x) = 0) and inequality constraints INEQS (h(x) >= 0). INEQ_PRODS determines if products of inequalities are used. SPARSE uses Newton polytope reduction to do computations in a reduced-size diff --git a/src/SumOfSquares/basis.py b/src/SumOfSquares/basis.py index 9e2072b..322f044 100644 --- a/src/SumOfSquares/basis.py +++ b/src/SumOfSquares/basis.py @@ -3,6 +3,7 @@ import sympy as sp import numpy as np import math +from functools import lru_cache from collections import defaultdict from typing import Iterable, Tuple, List, Union @@ -39,12 +40,6 @@ def __init__(self, monoms: List[Tuple[int]]): self.nvars = len(monoms[0]) self.is_hom = sum(sum(m) != self.deg for m in self.monoms) == 0 - # A map from a monomial m (represented as tuple) to list of pairs (i, j) - # for all such pairs where m = basis[i]*basis[j]. - self.sos_sym_entries = defaultdict(list) - for i, bi in enumerate(self): - for j, bj in enumerate(self): - self.sos_sym_entries[sum_tuple(bi, bj)].append((i, j)) def __len__(self) -> int: return len(self.monoms) @@ -52,6 +47,17 @@ def __len__(self) -> int: def __iter__(self) -> Iterable[Tuple[int]]: return iter(self.monoms) + @property + @lru_cache() + def sos_sym_entries(self): + # A map from a monomial m (represented as tuple) to list of pairs (i, j) + # for all such pairs where m = basis[i]*basis[j]. + sos_sym_entries = defaultdict(list) + for i, bi in enumerate(self): + for j, bj in enumerate(self): + sos_sym_entries[sum_tuple(bi, bj)].append((i, j)) + return sos_sym_entries + def from_degree(nvars: int, deg: int, hom: bool=False) -> Basis: '''Constructs a basis by specifying the number of variables and degree''' return Basis(list((basis_hom if hom else basis_inhom)(nvars, deg)))