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/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
- def test_function_repr():
28
- pep_builder = pep.PEPBuilder()
29
- with pep_builder.make_context("test"):
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
+ )