pepflow 0.1.0__py3-none-any.whl → 0.1.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pepflow/point_test.py CHANGED
@@ -1,3 +1,22 @@
1
+ # Copyright: 2025 The PEPFlow Developers
2
+ #
3
+ # Licensed to the Apache Software Foundation (ASF) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The ASF licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+
1
20
  import time
2
21
 
3
22
  import numpy as np
@@ -30,6 +49,16 @@ def test_point_tag():
30
49
  p1 = point.Point(is_basis=True, eval_expression=None)
31
50
  p1.add_tag(tag="my_tag")
32
51
  assert p1.tags == ["my_tag"]
52
+ assert p1.tag == "my_tag"
53
+
54
+
55
+ def test_point_repr():
56
+ pep_builder = pep.PEPBuilder()
57
+ with pep_builder.make_context("test"):
58
+ p1 = point.Point(is_basis=True)
59
+ print(p1) # it should be fine without tag
60
+ p1.add_tag("my_tag")
61
+ assert str(p1) == "my_tag"
33
62
 
34
63
 
35
64
  def test_scalar_tag():
@@ -38,6 +67,16 @@ def test_scalar_tag():
38
67
  s1 = scalar.Scalar(is_basis=True, eval_expression=None)
39
68
  s1.add_tag(tag="my_tag")
40
69
  assert s1.tags == ["my_tag"]
70
+ assert s1.tag == "my_tag"
71
+
72
+
73
+ def test_scalar_repr():
74
+ pep_builder = pep.PEPBuilder()
75
+ with pep_builder.make_context("test"):
76
+ s1 = scalar.Scalar(is_basis=True)
77
+ print(s1) # it should be fine without tag
78
+ s1.add_tag("my_tag")
79
+ assert str(s1) == "my_tag"
41
80
 
42
81
 
43
82
  def test_point_in_a_list():
@@ -224,26 +263,33 @@ def test_expression_manager_eval_point_large_scale():
224
263
  for pp in ctx.points:
225
264
  pm.eval_point(pp)
226
265
 
227
- assert (time.time() - t) < 0.1
266
+ assert (time.time() - t) < 0.5
228
267
 
229
268
 
230
269
  def test_function_generate_triplet():
231
270
  pep_builder = pep.PEPBuilder()
232
271
  with pep_builder.make_context("test") as ctx:
233
272
  f = fc.Function(is_basis=True, reuse_gradient=True)
273
+ f.add_tag("f")
234
274
  g = fc.Function(is_basis=True, reuse_gradient=True)
275
+ g.add_tag("g")
235
276
  h = 5 * f + 5 * g
277
+ h.add_tag("h")
236
278
 
237
279
  f1 = fc.Function(is_basis=True, reuse_gradient=False)
280
+ f1.add_tag("f1")
238
281
  g1 = fc.Function(is_basis=True, reuse_gradient=False)
282
+ g1.add_tag("g1")
239
283
  h1 = 5 * f1 + 5 * g1
284
+ h1.add_tag("h1")
240
285
 
241
286
  p1 = point.Point(is_basis=True)
242
- _, func_value, grad = h.generate_triplet(p1)
243
- _, func_value_1, grad_1 = h.generate_triplet(p1)
287
+ p1.add_tag("p1")
288
+ p1_triplet = h.generate_triplet(p1)
289
+ p1_triplet_1 = h.generate_triplet(p1)
244
290
 
245
- _, func_value_2, grad_2 = h1.generate_triplet(p1)
246
- _, func_value_3, grad_3 = h1.generate_triplet(p1)
291
+ p1_triplet_2 = h1.generate_triplet(p1)
292
+ p1_triplet_3 = h1.generate_triplet(p1)
247
293
 
248
294
  pm = exm.ExpressionManager(ctx)
249
295
 
@@ -252,31 +298,31 @@ def test_function_generate_triplet():
252
298
  )
253
299
 
254
300
  np.testing.assert_allclose(
255
- pm.eval_point(grad).vector, np.array([0, 5, 5, 0, 0, 0, 0])
301
+ pm.eval_point(p1_triplet.gradient).vector, np.array([0, 5, 5, 0, 0, 0, 0])
256
302
  )
257
303
  np.testing.assert_allclose(
258
- pm.eval_scalar(func_value).vector, np.array([5, 5, 0, 0])
304
+ pm.eval_scalar(p1_triplet.function_value).vector, np.array([5, 5, 0, 0])
259
305
  )
260
306
 
261
307
  np.testing.assert_allclose(
262
- pm.eval_point(grad_1).vector, np.array([0, 5, 5, 0, 0, 0, 0])
308
+ pm.eval_point(p1_triplet_1.gradient).vector, np.array([0, 5, 5, 0, 0, 0, 0])
263
309
  )
264
310
  np.testing.assert_allclose(
265
- pm.eval_scalar(func_value_1).vector, np.array([5, 5, 0, 0])
311
+ pm.eval_scalar(p1_triplet_1.function_value).vector, np.array([5, 5, 0, 0])
266
312
  )
267
313
 
268
314
  np.testing.assert_allclose(
269
- pm.eval_point(grad_2).vector, np.array([0, 0, 0, 5, 5, 0, 0])
315
+ pm.eval_point(p1_triplet_2.gradient).vector, np.array([0, 0, 0, 5, 5, 0, 0])
270
316
  )
271
317
  np.testing.assert_allclose(
272
- pm.eval_scalar(func_value_2).vector, np.array([0, 0, 5, 5])
318
+ pm.eval_scalar(p1_triplet_2.function_value).vector, np.array([0, 0, 5, 5])
273
319
  )
274
320
 
275
321
  np.testing.assert_allclose(
276
- pm.eval_point(grad_3).vector, np.array([0, 0, 0, 0, 0, 5, 5])
322
+ pm.eval_point(p1_triplet_3.gradient).vector, np.array([0, 0, 0, 0, 0, 5, 5])
277
323
  )
278
324
  np.testing.assert_allclose(
279
- pm.eval_scalar(func_value_3).vector, np.array([0, 0, 5, 5])
325
+ pm.eval_scalar(p1_triplet_3.function_value).vector, np.array([0, 0, 5, 5])
280
326
  )
281
327
 
282
328
 
@@ -284,28 +330,24 @@ def test_function_add_stationary_point():
284
330
  pep_builder = pep.PEPBuilder()
285
331
  with pep_builder.make_context("test") as ctx:
286
332
  f = fc.Function(is_basis=True, reuse_gradient=True)
287
- x_opt = f.add_stationary_point()
333
+ f.add_tag("f")
334
+ x_opt = f.add_stationary_point("x_opt")
288
335
 
289
336
  pm = exm.ExpressionManager(ctx)
290
337
 
291
- np.testing.assert_allclose(pm.eval_point(x_opt).vector, np.array([1, 0]))
292
-
293
- np.testing.assert_allclose(
294
- pm.eval_scalar(f.constraints[0].scalar).matrix, [[0, 0], [0, 1]]
295
- )
296
- np.testing.assert_allclose(pm.eval_scalar(f.constraints[0].scalar).vector, [0])
297
- np.testing.assert_allclose(pm.eval_scalar(f.constraints[0].scalar).constant, 0)
298
- assert f.constraints[0].comparator == utils.Comparator.EQ
338
+ np.testing.assert_allclose(pm.eval_point(x_opt).vector, np.array([1]))
299
339
 
300
340
 
301
341
  def test_smooth_interpolability_constraints():
302
342
  pep_builder = pep.PEPBuilder()
303
343
  with pep_builder.make_context("test") as ctx:
304
344
  f = fc.SmoothConvexFunction(L=1)
305
- _ = f.add_stationary_point()
345
+ f.add_tag("f")
346
+ _ = f.add_stationary_point("x_opt")
306
347
 
307
348
  x_0 = point.Point(is_basis=True)
308
- _, _, _ = f.generate_triplet(x_0)
349
+ x_0.add_tag("x_0")
350
+ _ = f.generate_triplet(x_0)
309
351
 
310
352
  all_interpolation_constraints = f.get_interpolation_constraints()
311
353
 
@@ -316,12 +358,7 @@ def test_smooth_interpolability_constraints():
316
358
  )
317
359
  np.testing.assert_allclose(
318
360
  pm.eval_scalar(all_interpolation_constraints[1].scalar).matrix,
319
- [
320
- [0.0, -0.5, 0.0, 0.0],
321
- [-0.5, 0.5, 0.5, -0.5],
322
- [0.0, 0.5, 0.0, 0.0],
323
- [0.0, -0.5, 0.0, 0.5],
324
- ],
361
+ [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.5]],
325
362
  )
326
363
 
327
364
  np.testing.assert_allclose(
pepflow/scalar.py CHANGED
@@ -1,3 +1,22 @@
1
+ # Copyright: 2025 The PEPFlow Developers
2
+ #
3
+ # Licensed to the Apache Software Foundation (ASF) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The ASF licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+
1
20
  from __future__ import annotations
2
21
 
3
22
  import uuid
@@ -31,8 +50,8 @@ class EvalExpressionScalar:
31
50
 
32
51
  @attrs.frozen
33
52
  class EvaluatedScalar:
34
- vector: np.array
35
- matrix: np.array
53
+ vector: np.ndarray
54
+ matrix: np.ndarray
36
55
  constant: float
37
56
 
38
57
  def __add__(self, other):
@@ -140,9 +159,20 @@ class Scalar:
140
159
  raise RuntimeError("Did you forget to create a context?")
141
160
  pep_context.add_scalar(self)
142
161
 
162
+ @property
163
+ def tag(self):
164
+ if len(self.tags) == 0:
165
+ raise ValueError("Scalar should have a name.")
166
+ return self.tags[-1]
167
+
143
168
  def add_tag(self, tag: str):
144
169
  self.tags.append(tag)
145
170
 
171
+ def __repr__(self):
172
+ if self.tags:
173
+ return self.tag
174
+ return super().__repr__()
175
+
146
176
  def __add__(self, other):
147
177
  assert is_numerical_or_scalar(other)
148
178
  return Scalar(
pepflow/solver.py CHANGED
@@ -1,13 +1,39 @@
1
+ # Copyright: 2025 The PEPFlow Developers
2
+ #
3
+ # Licensed to the Apache Software Foundation (ASF) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The ASF licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+
1
20
  import warnings
2
21
 
3
22
  import cvxpy
4
23
 
24
+ from pepflow import constants
5
25
  from pepflow import constraint as ctr
6
26
  from pepflow import expression_manager as exm
7
27
  from pepflow import pep_context as pc
8
28
  from pepflow import scalar as sc
9
29
  from pepflow import utils
10
30
 
31
+ warnings.filterwarnings(
32
+ "ignore",
33
+ message=".*compressed sparse column.*",
34
+ category=UserWarning,
35
+ )
36
+
11
37
 
12
38
  def evaled_scalar_to_cvx_express(
13
39
  eval_scalar: sc.EvaluatedScalar, vec_var: cvxpy.Variable, matrix_var: cvxpy.Variable
@@ -38,10 +64,9 @@ class DualVariableManager:
38
64
 
39
65
  def dual_value(self, name: str) -> float | None:
40
66
  if name not in self.named_constraints:
41
- raise KeyError(f"Cannot find the constraint named {name}")
67
+ return None # Is this good choice?
42
68
  dual_value = self.named_constraints[name].dual_value
43
69
  if dual_value is None:
44
- warnings.warn("Did you forget to solve the problem first?")
45
70
  return None
46
71
  return dual_value
47
72
 
@@ -72,7 +97,7 @@ class CVXSolver:
72
97
  em.eval_scalar(scalar)
73
98
 
74
99
  self.dual_var_manager.clear()
75
- self.dual_var_manager.add_constraint("PSD of Grammian Matrix", g_var >> 0)
100
+ self.dual_var_manager.add_constraint(constants.PSD_CONSTRAINT, g_var >> 0)
76
101
  for c in self.constraints:
77
102
  exp = evaled_scalar_to_cvx_express(em.eval_scalar(c.scalar), f_var, g_var)
78
103
  if c.comparator == utils.Comparator.GT:
pepflow/solver_test.py CHANGED
@@ -1,3 +1,22 @@
1
+ # Copyright: 2025 The PEPFlow Developers
2
+ #
3
+ # Licensed to the Apache Software Foundation (ASF) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The ASF licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+
1
20
  import numpy as np
2
21
 
3
22
  from pepflow import pep as pep
pepflow/utils.py CHANGED
@@ -1,3 +1,22 @@
1
+ # Copyright: 2025 The PEPFlow Developers
2
+ #
3
+ # Licensed to the Apache Software Foundation (ASF) under one
4
+ # or more contributor license agreements. See the NOTICE file
5
+ # distributed with this work for additional information
6
+ # regarding copyright ownership. The ASF licenses this file
7
+ # to you under the Apache License, Version 2.0 (the
8
+ # "License"); you may not use this file except in compliance
9
+ # with the License. You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing,
14
+ # software distributed under the License is distributed on an
15
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ # KIND, either express or implied. See the License for the
17
+ # specific language governing permissions and limitations
18
+ # under the License.
19
+
1
20
  from __future__ import annotations
2
21
 
3
22
  import enum
@@ -16,24 +35,6 @@ def SOP_self(v):
16
35
  return SOP(v, v)
17
36
 
18
37
 
19
- def merge_dict(dict1, dict2):
20
- merged_dict = dict1.copy()
21
- for key in dict2.keys():
22
- if key in dict1.keys():
23
- merged_dict[key] += dict2[key]
24
- else:
25
- merged_dict[key] = dict2[key]
26
- return merged_dict
27
-
28
-
29
- def prune_dict(my_dict):
30
- pruned_dict = dict()
31
- for key in my_dict.keys():
32
- if my_dict[key] != 0:
33
- pruned_dict[key] = my_dict[key]
34
- return pruned_dict
35
-
36
-
37
38
  class Op(enum.Enum):
38
39
  ADD = "add"
39
40
  SUB = "sub"
@@ -1,15 +1,20 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pepflow
3
- Version: 0.1.0
4
- Summary: Add your description here
3
+ Version: 0.1.2
4
+ Summary: PEPFlow: A framework for Performance Estimation Problem (PEP) Workflow
5
5
  Requires-Python: >=3.9
6
6
  Description-Content-Type: text/markdown
7
7
  License-File: LICENSE
8
8
  Requires-Dist: attrs>=25.3.0
9
9
  Requires-Dist: cvxpy>=1.7.1
10
+ Requires-Dist: dash>=3.2.0
11
+ Requires-Dist: dash-bootstrap-components>=2.0.3
10
12
  Requires-Dist: isort>=6.0.1
11
13
  Requires-Dist: matplotlib>=3.9.4
14
+ Requires-Dist: natsort>=8.4.0
12
15
  Requires-Dist: numpy>=2.0.2
16
+ Requires-Dist: pandas>=2.3.1
17
+ Requires-Dist: plotly>=6.3.0
13
18
  Requires-Dist: pytest>=8.4.1
14
19
  Requires-Dist: ruff>=0.12.4
15
20
  Requires-Dist: sympy>=1.14.0
@@ -0,0 +1,22 @@
1
+ pepflow/__init__.py,sha256=tLnOlZ1y_mIodRl5Fr5HMLPP5M7h_ad76s4in5OgiHE,1930
2
+ pepflow/constants.py,sha256=t29CDRE8kw773zgKS0ZZCYGegwagaDDdLfpSaeDpK14,871
3
+ pepflow/constraint.py,sha256=n-01dcQplvsXB7V4fceJBImbwSr-Wa9k9tE7ZcVmi3o,1153
4
+ pepflow/expression_manager.py,sha256=64FbdMjcUrIqtbFZyJoxoDZ42j1bl1CeGxhJnKcGTD8,5222
5
+ pepflow/function.py,sha256=yQcx78Ml6O34pVTcqYXxmO75l7IGdVvfwaY01lwsOHc,12566
6
+ pepflow/function_test.py,sha256=947Jv0i7HtQ-LOi9-Hd7YsIGbX6BjnHsW3N4Q9HZE-A,4833
7
+ pepflow/interactive_constraint.py,sha256=HMwAo80tJyCKwWKryxNGk1LAh-qlnQk5OeULLwKZUOQ,9826
8
+ pepflow/pep.py,sha256=IKrYW6DBIekKOjGfL7rc6t1xU06VJEyL_gxj1sH_m_Q,5824
9
+ pepflow/pep_context.py,sha256=IgrikL5Eqi0RfrFaVKn9lsodqtjj9A_RWFb82Qk-SYQ,4443
10
+ pepflow/pep_context_test.py,sha256=1kFkmG56JVkmjaT9ic9byV-F9WOs9ZNQz5P1P5v5lLw,3092
11
+ pepflow/pep_test.py,sha256=aWwP3CqXNJzQUhJqC5sNcsM83i_asJaZewpGNqC1G7M,2504
12
+ pepflow/point.py,sha256=2iKmU6K_e3DmskCW9faQBxTaqPm3MUQPHTZvKVh3_yM,6711
13
+ pepflow/point_test.py,sha256=jwbvjfwHP_9oY7KLp4UE_uSEbAVlDTXAQjr8d0z-eME,12602
14
+ pepflow/scalar.py,sha256=vVA9qZjKIvM6RlZ4wN5MEFyG9eTFx7ItQaXtPY7ws7c,7846
15
+ pepflow/solver.py,sha256=WzeN_IWNBs9IpE212jenhYMWFuuwH890h0vaFmJRM6I,4312
16
+ pepflow/solver_test.py,sha256=BC37ggL_S8NDtnq8nPwRR2xItMCYMLs-n931u7f34YE,2414
17
+ pepflow/utils.py,sha256=tYcpOOWAieNay5Ly7v7dRll69RPYCUGMEuW-Bwp2z68,1321
18
+ pepflow-0.1.2.dist-info/licenses/LICENSE,sha256=na5oVXAps-5f1hLGG4SYnwFdavQeXgYUeN-E3MxOA_s,11361
19
+ pepflow-0.1.2.dist-info/METADATA,sha256=tZyuaGvCHycaEKDj2RUQhhAguXM1F9JQYMpWbA-jRSc,1434
20
+ pepflow-0.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
21
+ pepflow-0.1.2.dist-info/top_level.txt,sha256=0YEPCZQQa6yIAIwMumzDg4pj7AME8aXu2sXkuq8xM6M,8
22
+ pepflow-0.1.2.dist-info/RECORD,,
@@ -1,18 +0,0 @@
1
- pepflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- pepflow/constraint.py,sha256=-WSSpnzpso-Co4Fd-7B53mbTCB8pmgpPHgy3chZP0ws,324
3
- pepflow/expression_manager.py,sha256=xPo6i4tz_7e9c_2-iRen2i1-2JxLfR1b5HDqmaOtJ90,4393
4
- pepflow/function.py,sha256=hxbrvxUhBMRM8MdiNF9sP6oGaf-0swkuDW_Vp3Ogr90,6165
5
- pepflow/pep.py,sha256=I9MFXjtZnUBmnsqnixosZuV9_KHUthctXjxkCNuExcw,3688
6
- pepflow/pep_context.py,sha256=kh7iOAFWS-FMq_wiON1feQsbZLTPB4zARhe4mGR60Dk,707
7
- pepflow/pep_test.py,sha256=6gUhH8Gb2JOspoVwCFkf9NcoDRKwgs1BBFC367eL2hQ,1675
8
- pepflow/point.py,sha256=zKcWdNa24W__dTuappVWh134k12SuQF58XjDc8eZVBQ,5618
9
- pepflow/point_test.py,sha256=pxmxbCEmoF76RlrwQMl74Er6TdLt7_Fak4Wr2ymQn8o,11307
10
- pepflow/scalar.py,sha256=pSRvHztVKoIqUnVpIiwtcx3aP1wckFIzZTL5I3ZxXKg,6750
11
- pepflow/solver.py,sha256=v4eazPCsi8HhrHjTJ0Pf5OO4ABY3_Sns65UDyNZjOIc,3436
12
- pepflow/solver_test.py,sha256=dXdfCh91qp9itdcL3PfIAWuBxc7HdHo8XH3c9r5kWPk,1585
13
- pepflow/utils.py,sha256=v1LZbQXzwub55W05ou1LTiTI2MACTFw0FJt4K9lmFwU,918
14
- pepflow-0.1.0.dist-info/licenses/LICENSE,sha256=na5oVXAps-5f1hLGG4SYnwFdavQeXgYUeN-E3MxOA_s,11361
15
- pepflow-0.1.0.dist-info/METADATA,sha256=SEg5zgEa0fWxrQRA3E0uffnB_pxLmBJmemMSTNjlsnc,1226
16
- pepflow-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
17
- pepflow-0.1.0.dist-info/top_level.txt,sha256=0YEPCZQQa6yIAIwMumzDg4pj7AME8aXu2sXkuq8xM6M,8
18
- pepflow-0.1.0.dist-info/RECORD,,