pepflow 0.1.3a1__py3-none-any.whl → 0.1.4a1__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/__init__.py +1 -0
- pepflow/constraint_test.py +71 -0
- pepflow/e2e_test.py +69 -0
- pepflow/expression_manager.py +72 -2
- pepflow/expression_manager_test.py +116 -0
- pepflow/function.py +142 -48
- pepflow/function_test.py +249 -108
- pepflow/interactive_constraint.py +165 -75
- pepflow/pep.py +18 -3
- pepflow/pep_context.py +12 -7
- pepflow/pep_context_test.py +23 -21
- pepflow/pep_test.py +8 -0
- pepflow/point.py +43 -8
- pepflow/point_test.py +106 -308
- pepflow/scalar.py +39 -1
- pepflow/scalar_test.py +207 -0
- pepflow/solver_test.py +7 -7
- pepflow/utils.py +14 -1
- {pepflow-0.1.3a1.dist-info → pepflow-0.1.4a1.dist-info}/METADATA +19 -1
- pepflow-0.1.4a1.dist-info/RECORD +26 -0
- pepflow-0.1.3a1.dist-info/RECORD +0 -22
- {pepflow-0.1.3a1.dist-info → pepflow-0.1.4a1.dist-info}/WHEEL +0 -0
- {pepflow-0.1.3a1.dist-info → pepflow-0.1.4a1.dist-info}/licenses/LICENSE +0 -0
- {pepflow-0.1.3a1.dist-info → pepflow-0.1.4a1.dist-info}/top_level.txt +0 -0
pepflow/function_test.py
CHANGED
@@ -17,118 +17,259 @@
|
|
17
17
|
# specific language governing permissions and limitations
|
18
18
|
# under the License.
|
19
19
|
|
20
|
+
from typing import Iterator
|
21
|
+
|
20
22
|
import numpy as np
|
23
|
+
import pytest
|
21
24
|
|
22
25
|
from pepflow import expression_manager as exm
|
23
26
|
from pepflow import function as fc
|
24
27
|
from pepflow import pep as pep
|
28
|
+
from pepflow import pep_context as pc
|
29
|
+
from pepflow import point
|
30
|
+
|
31
|
+
|
32
|
+
@pytest.fixture
|
33
|
+
def pep_context() -> Iterator[pc.PEPContext]:
|
34
|
+
"""Prepare the pep context and reset the context to None at the end."""
|
35
|
+
ctx = pc.PEPContext("test").set_as_current()
|
36
|
+
yield ctx
|
37
|
+
pc.set_current_context(None)
|
38
|
+
|
39
|
+
|
40
|
+
def test_function_add_tag(pep_context: pc.PEPContext) -> None:
|
41
|
+
f1 = fc.Function(is_basis=True, tags=["f1"])
|
42
|
+
f2 = fc.Function(is_basis=True, tags=["f2"])
|
43
|
+
|
44
|
+
f_add = f1 + f2
|
45
|
+
assert f_add.tag == "f1+f2"
|
46
|
+
|
47
|
+
f_sub = f1 - f2
|
48
|
+
assert f_sub.tag == "f1-f2"
|
49
|
+
|
50
|
+
f_sub = f1 - (f2 + f1)
|
51
|
+
assert f_sub.tag == "f1-(f2+f1)"
|
52
|
+
|
53
|
+
f_sub = f1 - (f2 - f1)
|
54
|
+
assert f_sub.tag == "f1-(f2-f1)"
|
55
|
+
|
56
|
+
|
57
|
+
def test_function_mul_tag(pep_context: pc.PEPContext) -> None:
|
58
|
+
f = fc.Function(is_basis=True, tags=["f"])
|
59
|
+
|
60
|
+
f_mul = f * 0.1
|
61
|
+
assert f_mul.tag == "0.1*f"
|
62
|
+
|
63
|
+
f_rmul = 0.1 * f
|
64
|
+
assert f_rmul.tag == "0.1*f"
|
65
|
+
|
66
|
+
f_neg = -f
|
67
|
+
assert f_neg.tag == "-f"
|
68
|
+
|
69
|
+
f_truediv = f / 0.1
|
70
|
+
assert f_truediv.tag == "1/0.1*f"
|
71
|
+
|
72
|
+
|
73
|
+
def test_function_add_and_mul_tag(pep_context: pc.PEPContext) -> None:
|
74
|
+
f1 = fc.Function(is_basis=True, tags=["f1"])
|
75
|
+
f2 = fc.Function(is_basis=True, tags=["f2"])
|
76
|
+
|
77
|
+
f_add_mul = (f1 + f2) * 0.1
|
78
|
+
assert f_add_mul.tag == "0.1*(f1+f2)"
|
79
|
+
|
80
|
+
f_add_mul = f1 + f2 * 0.1
|
81
|
+
assert f_add_mul.tag == "f1+0.1*f2"
|
82
|
+
|
83
|
+
f_neg_add = -(f1 + f2)
|
84
|
+
assert f_neg_add.tag == "-(f1+f2)"
|
85
|
+
|
86
|
+
f_rmul_add = 0.1 * (f1 + f2)
|
87
|
+
assert f_rmul_add.tag == "0.1*(f1+f2)"
|
88
|
+
|
89
|
+
f_rmul_add = f1 + 5 * (f2 + 3 * f1)
|
90
|
+
assert f_rmul_add.tag == "f1+5*(f2+3*f1)"
|
91
|
+
|
92
|
+
f_multiple_add = f1 + f1 + f1 + f1 + f1 + f1
|
93
|
+
assert f_multiple_add.tag == "f1+f1+f1+f1+f1+f1"
|
94
|
+
|
95
|
+
|
96
|
+
def test_function_call(pep_context: pc.PEPContext) -> None:
|
97
|
+
f = fc.Function(is_basis=True, tags=["f"])
|
98
|
+
x = point.Point(is_basis=True, eval_expression=None, tags=["x"])
|
99
|
+
assert f.function_value(x) == f(x)
|
100
|
+
|
101
|
+
|
102
|
+
def test_function_repr(pep_context: pc.PEPContext):
|
103
|
+
f = fc.Function(
|
104
|
+
is_basis=True,
|
105
|
+
)
|
106
|
+
print(f) # it should be fine without tag
|
107
|
+
f.add_tag("f")
|
108
|
+
assert str(f) == "f"
|
109
|
+
|
110
|
+
|
111
|
+
def test_stationary_point(pep_context: pc.PEPContext):
|
112
|
+
f = fc.Function(
|
113
|
+
is_basis=True,
|
114
|
+
tags=["f"],
|
115
|
+
)
|
116
|
+
f.add_stationary_point("x_star")
|
117
|
+
|
118
|
+
assert len(pep_context.triplets) == 1
|
119
|
+
assert len(pep_context.triplets[f]) == 1
|
120
|
+
|
121
|
+
f_triplet = pep_context.triplets[f][0]
|
122
|
+
assert f_triplet.name == "x_star_f(x_star)_gradient_f(x_star)"
|
123
|
+
assert f_triplet.gradient.tag == "gradient_f(x_star)"
|
124
|
+
assert f_triplet.function_value.tag == "f(x_star)"
|
125
|
+
|
126
|
+
em = exm.ExpressionManager(pep_context)
|
127
|
+
np.testing.assert_allclose(em.eval_point(f_triplet.gradient).vector, np.array([0]))
|
128
|
+
np.testing.assert_allclose(em.eval_point(f_triplet.point).vector, np.array([1]))
|
129
|
+
|
130
|
+
|
131
|
+
def test_stationary_point_scaled(pep_context: pc.PEPContext):
|
132
|
+
f = fc.Function(
|
133
|
+
is_basis=True,
|
134
|
+
tags=["f"],
|
135
|
+
)
|
136
|
+
g = 5 * f
|
137
|
+
g.add_stationary_point("x_star")
|
138
|
+
|
139
|
+
assert len(pep_context.triplets) == 1
|
140
|
+
assert len(pep_context.triplets[f]) == 1
|
141
|
+
|
142
|
+
f_triplet = pep_context.triplets[f][0]
|
143
|
+
assert f_triplet.name == "x_star_f(x_star)_gradient_f(x_star)"
|
144
|
+
assert f_triplet.gradient.tag == "gradient_f(x_star)"
|
145
|
+
assert f_triplet.function_value.tag == "f(x_star)"
|
146
|
+
|
147
|
+
em = exm.ExpressionManager(pep_context)
|
148
|
+
np.testing.assert_allclose(em.eval_point(f_triplet.gradient).vector, np.array([0]))
|
149
|
+
np.testing.assert_allclose(em.eval_point(f_triplet.point).vector, np.array([1]))
|
150
|
+
|
151
|
+
|
152
|
+
def test_stationary_point_additive(pep_context: pc.PEPContext):
|
153
|
+
f = fc.Function(is_basis=True)
|
154
|
+
f.add_tag("f")
|
155
|
+
g = fc.Function(is_basis=True)
|
156
|
+
g.add_tag("g")
|
157
|
+
h = f + g
|
158
|
+
h.add_tag("h")
|
159
|
+
|
160
|
+
h.add_stationary_point("x_star")
|
161
|
+
assert len(pep_context.triplets) == 2
|
162
|
+
assert len(pep_context.triplets[f]) == 1
|
163
|
+
assert len(pep_context.triplets[g]) == 1
|
164
|
+
|
165
|
+
f_triplet = pep_context.triplets[f][0]
|
166
|
+
g_triplet = pep_context.triplets[g][0]
|
167
|
+
assert f_triplet.name == "x_star_f(x_star)_gradient_f(x_star)"
|
168
|
+
assert g_triplet.name == "x_star_g(x_star)_gradient_g(x_star)"
|
169
|
+
|
170
|
+
em = exm.ExpressionManager(pep_context)
|
171
|
+
np.testing.assert_allclose(
|
172
|
+
em.eval_point(f_triplet.gradient).vector, np.array([0, 1])
|
173
|
+
)
|
174
|
+
np.testing.assert_allclose(
|
175
|
+
em.eval_point(g_triplet.gradient).vector, np.array([0, -1])
|
176
|
+
)
|
177
|
+
|
178
|
+
|
179
|
+
def test_stationary_point_linear_combination(pep_context: pc.PEPContext):
|
180
|
+
f = fc.Function(
|
181
|
+
is_basis=True,
|
182
|
+
)
|
183
|
+
f.add_tag("f")
|
184
|
+
g = fc.Function(
|
185
|
+
is_basis=True,
|
186
|
+
)
|
187
|
+
g.add_tag("g")
|
188
|
+
h = 3 * f + 2 * g
|
189
|
+
h.add_tag("h")
|
190
|
+
|
191
|
+
h.add_stationary_point("x_star")
|
192
|
+
assert len(pep_context.triplets) == 2
|
193
|
+
assert len(pep_context.triplets[f]) == 1
|
194
|
+
assert len(pep_context.triplets[g]) == 1
|
195
|
+
|
196
|
+
f_triplet = pep_context.triplets[f][0]
|
197
|
+
g_triplet = pep_context.triplets[g][0]
|
198
|
+
assert f_triplet.name == "x_star_f(x_star)_gradient_f(x_star)"
|
199
|
+
assert g_triplet.name == "x_star_g(x_star)_gradient_g(x_star)"
|
200
|
+
|
201
|
+
em = exm.ExpressionManager(pep_context)
|
202
|
+
np.testing.assert_allclose(
|
203
|
+
em.eval_point(f_triplet.gradient).vector, np.array([0, 1])
|
204
|
+
)
|
205
|
+
np.testing.assert_allclose(
|
206
|
+
em.eval_point(g_triplet.gradient).vector, np.array([0, -1.5])
|
207
|
+
)
|
208
|
+
|
209
|
+
|
210
|
+
def test_function_generate_triplet(pep_context: pc.PEPContext):
|
211
|
+
f = fc.Function(is_basis=True)
|
212
|
+
f.add_tag("f")
|
213
|
+
g = fc.Function(is_basis=True)
|
214
|
+
g.add_tag("g")
|
215
|
+
h = 5 * f + 5 * g
|
216
|
+
h.add_tag("h")
|
217
|
+
|
218
|
+
p1 = point.Point(is_basis=True)
|
219
|
+
p1.add_tag("p1")
|
220
|
+
p1_triplet = h.generate_triplet(p1)
|
221
|
+
p1_triplet_1 = h.generate_triplet(p1)
|
222
|
+
|
223
|
+
pm = exm.ExpressionManager(pep_context)
|
224
|
+
|
225
|
+
np.testing.assert_allclose(pm.eval_point(p1).vector, np.array([1, 0, 0]))
|
226
|
+
|
227
|
+
np.testing.assert_allclose(
|
228
|
+
pm.eval_point(p1_triplet.gradient).vector, np.array([0, 5, 5])
|
229
|
+
)
|
230
|
+
np.testing.assert_allclose(
|
231
|
+
pm.eval_scalar(p1_triplet.function_value).vector, np.array([5, 5])
|
232
|
+
)
|
233
|
+
|
234
|
+
np.testing.assert_allclose(
|
235
|
+
pm.eval_point(p1_triplet_1.gradient).vector, np.array([0, 5, 5])
|
236
|
+
)
|
237
|
+
np.testing.assert_allclose(
|
238
|
+
pm.eval_scalar(p1_triplet_1.function_value).vector, np.array([5, 5])
|
239
|
+
)
|
240
|
+
|
241
|
+
|
242
|
+
def test_function_add_stationary_point(pep_context: pc.PEPContext):
|
243
|
+
f = fc.Function(is_basis=True)
|
244
|
+
f.add_tag("f")
|
245
|
+
x_opt = f.add_stationary_point("x_opt")
|
246
|
+
|
247
|
+
pm = exm.ExpressionManager(pep_context)
|
248
|
+
|
249
|
+
np.testing.assert_allclose(pm.eval_point(x_opt).vector, np.array([1]))
|
250
|
+
|
251
|
+
|
252
|
+
def test_smooth_interpolability_constraints(pep_context: pc.PEPContext):
|
253
|
+
f = fc.SmoothConvexFunction(L=1)
|
254
|
+
f.add_tag("f")
|
255
|
+
_ = f.add_stationary_point("x_opt")
|
256
|
+
|
257
|
+
x_0 = point.Point(is_basis=True)
|
258
|
+
x_0.add_tag("x_0")
|
259
|
+
_ = f.generate_triplet(x_0)
|
260
|
+
|
261
|
+
all_interpolation_constraints = f.get_interpolation_constraints()
|
262
|
+
|
263
|
+
pm = exm.ExpressionManager(pep_context)
|
25
264
|
|
265
|
+
np.testing.assert_allclose(
|
266
|
+
pm.eval_scalar(all_interpolation_constraints[1].scalar).vector, [1, -1]
|
267
|
+
)
|
268
|
+
np.testing.assert_allclose(
|
269
|
+
pm.eval_scalar(all_interpolation_constraints[1].scalar).matrix,
|
270
|
+
[[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.5]],
|
271
|
+
)
|
26
272
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
f = fc.Function(is_basis=True, reuse_gradient=False)
|
31
|
-
print(f) # it should be fine without tag
|
32
|
-
f.add_tag("f")
|
33
|
-
assert str(f) == "f"
|
34
|
-
|
35
|
-
|
36
|
-
def test_stationary_point():
|
37
|
-
pep_builder = pep.PEPBuilder()
|
38
|
-
with pep_builder.make_context("test") as ctx:
|
39
|
-
f = fc.Function(is_basis=True, reuse_gradient=False, tags=["f"])
|
40
|
-
f.add_stationary_point("x_star")
|
41
|
-
|
42
|
-
assert len(ctx.triplets) == 1
|
43
|
-
assert len(ctx.triplets[f]) == 1
|
44
|
-
|
45
|
-
f_triplet = ctx.triplets[f][0]
|
46
|
-
assert f_triplet.name == "x_star_f(x_star)_gradient_f(x_star)"
|
47
|
-
assert f_triplet.gradient.tag == "gradient_f(x_star)"
|
48
|
-
assert f_triplet.function_value.tag == "f(x_star)"
|
49
|
-
|
50
|
-
em = exm.ExpressionManager(ctx)
|
51
|
-
np.testing.assert_allclose(
|
52
|
-
em.eval_point(f_triplet.gradient).vector, np.array([0])
|
53
|
-
)
|
54
|
-
np.testing.assert_allclose(em.eval_point(f_triplet.point).vector, np.array([1]))
|
55
|
-
|
56
|
-
|
57
|
-
def test_stationary_point_scaled():
|
58
|
-
pep_builder = pep.PEPBuilder()
|
59
|
-
with pep_builder.make_context("test") as ctx:
|
60
|
-
f = fc.Function(is_basis=True, reuse_gradient=False, tags=["f"])
|
61
|
-
g = 5 * f
|
62
|
-
g.add_stationary_point("x_star")
|
63
|
-
|
64
|
-
assert len(ctx.triplets) == 1
|
65
|
-
assert len(ctx.triplets[f]) == 1
|
66
|
-
|
67
|
-
f_triplet = ctx.triplets[f][0]
|
68
|
-
assert f_triplet.name == "x_star_f(x_star)_gradient_f(x_star)"
|
69
|
-
assert f_triplet.gradient.tag == "gradient_f(x_star)"
|
70
|
-
assert f_triplet.function_value.tag == "f(x_star)"
|
71
|
-
|
72
|
-
em = exm.ExpressionManager(ctx)
|
73
|
-
np.testing.assert_allclose(
|
74
|
-
em.eval_point(f_triplet.gradient).vector, np.array([0])
|
75
|
-
)
|
76
|
-
np.testing.assert_allclose(em.eval_point(f_triplet.point).vector, np.array([1]))
|
77
|
-
|
78
|
-
|
79
|
-
def test_stationary_point_additive():
|
80
|
-
pep_builder = pep.PEPBuilder()
|
81
|
-
with pep_builder.make_context("test") as ctx:
|
82
|
-
f = fc.Function(is_basis=True, reuse_gradient=False)
|
83
|
-
f.add_tag("f")
|
84
|
-
g = fc.Function(is_basis=True, reuse_gradient=False)
|
85
|
-
g.add_tag("g")
|
86
|
-
h = f + g
|
87
|
-
h.add_tag("h")
|
88
|
-
|
89
|
-
h.add_stationary_point("x_star")
|
90
|
-
assert len(ctx.triplets) == 2
|
91
|
-
assert len(ctx.triplets[f]) == 1
|
92
|
-
assert len(ctx.triplets[g]) == 1
|
93
|
-
|
94
|
-
f_triplet = ctx.triplets[f][0]
|
95
|
-
g_triplet = ctx.triplets[g][0]
|
96
|
-
assert f_triplet.name == "x_star_f(x_star)_gradient_f(x_star)"
|
97
|
-
assert g_triplet.name == "x_star_g(x_star)_gradient_g(x_star)"
|
98
|
-
|
99
|
-
em = exm.ExpressionManager(ctx)
|
100
|
-
np.testing.assert_allclose(
|
101
|
-
em.eval_point(f_triplet.gradient).vector, np.array([0, 1])
|
102
|
-
)
|
103
|
-
np.testing.assert_allclose(
|
104
|
-
em.eval_point(g_triplet.gradient).vector, np.array([0, -1])
|
105
|
-
)
|
106
|
-
|
107
|
-
|
108
|
-
def test_stationary_point_linear_combination():
|
109
|
-
pep_builder = pep.PEPBuilder()
|
110
|
-
with pep_builder.make_context("test") as ctx:
|
111
|
-
f = fc.Function(is_basis=True, reuse_gradient=False)
|
112
|
-
f.add_tag("f")
|
113
|
-
g = fc.Function(is_basis=True, reuse_gradient=False)
|
114
|
-
g.add_tag("g")
|
115
|
-
h = 3 * f + 2 * g
|
116
|
-
h.add_tag("h")
|
117
|
-
|
118
|
-
h.add_stationary_point("x_star")
|
119
|
-
assert len(ctx.triplets) == 2
|
120
|
-
assert len(ctx.triplets[f]) == 1
|
121
|
-
assert len(ctx.triplets[g]) == 1
|
122
|
-
|
123
|
-
f_triplet = ctx.triplets[f][0]
|
124
|
-
g_triplet = ctx.triplets[g][0]
|
125
|
-
assert f_triplet.name == "x_star_f(x_star)_gradient_f(x_star)"
|
126
|
-
assert g_triplet.name == "x_star_g(x_star)_gradient_g(x_star)"
|
127
|
-
|
128
|
-
em = exm.ExpressionManager(ctx)
|
129
|
-
np.testing.assert_allclose(
|
130
|
-
em.eval_point(f_triplet.gradient).vector, np.array([0, 1])
|
131
|
-
)
|
132
|
-
np.testing.assert_allclose(
|
133
|
-
em.eval_point(g_triplet.gradient).vector, np.array([0, -1.5])
|
134
|
-
)
|
273
|
+
np.testing.assert_allclose(
|
274
|
+
pm.eval_scalar(all_interpolation_constraints[1].scalar).constant, 0
|
275
|
+
)
|