Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download
Views: 19204
1
r"""
2
Classification in parallel using fork
3
=====================================
4
5
The ``classify_in_parallel`` module defines functions that use ``sage.parallel`` and ``fork``
6
to save Cayley graph classifications or partial classifications in parallel.
7
8
AUTHORS:
9
10
- Paul Leopardi (2017-05-22)
11
12
"""
13
#*****************************************************************************
14
# Copyright (C) 2016 Paul Leopardi [email protected]
15
#
16
# Distributed under the terms of the GNU General Public License (GPL)
17
# as published by the Free Software Foundation; either version 2 of
18
# the License, or (at your option) any later version.
19
# http://www.gnu.org/licenses/
20
#*****************************************************************************
21
22
from sage.functions.other import Function_ceil
23
from sage.parallel.decorate import parallel
24
25
from boolean_cayley_graphs.bent_function_cayley_graph_classification import BentFunctionCayleyGraphClassification
26
from boolean_cayley_graphs.bent_function_cayley_graph_classification import BentFunctionCayleyGraphClassPart
27
from boolean_cayley_graphs.bent_function import BentFunction
28
29
30
def call_in_parallel(
31
f,
32
list_of_tuples,
33
ncpus):
34
r"""
35
Call the function `f` in parallel
36
37
INPUT:
38
39
- ``f`` -- Function to call.
40
- ``list_of_tuples`` -- A list of tuples to use as arguments to ``f``.
41
- ``ncpus`` -- Integer. Default=4. The number of cpus to use in parallel.
42
43
OUTPUT: A list of tuples. Each tuple contains an (args,keywds) pair, and a result.
44
45
EFFECT:
46
47
.. Note:
48
49
::
50
51
See http://doc.sagemath.org/html/en/reference/parallel/sage/parallel/decorate.html
52
53
EXAMPLE:
54
55
::
56
57
sage: from boolean_cayley_graphs.classify_in_parallel import call_in_parallel
58
sage: summ = lambda L: add(L)
59
sage: call_in_parallel(summ,[((1,2),),((5,4),),((3,3),)],2)
60
[((((1, 2),), {}), 3), ((((5, 4),), {}), 9), ((((3, 3),), {}), 6)]
61
"""
62
parallelize = parallel(p_iter='fork', ncpus=ncpus)
63
return list(parallelize(f)(list_of_tuples))
64
65
66
def classify(
67
n,
68
form):
69
r"""
70
Given an algebraic normal form of a bent function,
71
construct the corresponding Cayley graph classification.
72
73
INPUT:
74
75
- ``n`` -- Integer. Tuple number.
76
- ``form`` -- A Boolean function or an algebraic normal form.
77
78
OUTPUT:
79
80
The Cayley graph classification corresponding to the bent function
81
defined by ``form``.
82
83
.. Note:
84
85
::
86
87
The parameters ``n`` and ``form`` as used here conform to the interface used by
88
``parallel``.
89
See http://doc.sagemath.org/html/en/reference/parallel/sage/parallel/decorate.html
90
91
EXAMPLE:
92
93
::
94
95
sage: from boolean_cayley_graphs.bent_function import BentFunction
96
sage: from boolean_cayley_graphs.classify_in_parallel import classify
97
sage: bentf = BentFunction([0,0,0,1])
98
sage: bentf.algebraic_normal_form()
99
x0*x1
100
sage: classify(0, bentf).report()
101
Algebraic normal form of Boolean function: x0*x1
102
Function is bent.
103
<BLANKLINE>
104
<BLANKLINE>
105
SDP design incidence structure t-design parameters: (True, (1, 4, 1, 1))
106
<BLANKLINE>
107
Classification of Cayley graphs and classification of Cayley graphs of duals are the same:
108
<BLANKLINE>
109
There are 2 extended Cayley classes in the extended translation class.
110
"""
111
return BentFunctionCayleyGraphClassification.from_function(BentFunction(form))
112
113
114
def classify_in_parallel(
115
list_of_f,
116
start=0,
117
stop=None,
118
ncpus=4):
119
r"""
120
In parallel, construct a list of Cayley graph classifications
121
corresponding to a list of bent functions.
122
123
INPUT:
124
125
- ``list_of_f`` -- List of forms or bent functions.
126
- ``start`` -- Integer. Default=0. Index of start position in the list.
127
- ``stop`` -- Integer. Default=None. Index after end position, or ``None`` if whole remaining list.
128
- ``ncpus`` -- Integer. Default=4. The number of cpus to use in parallel.
129
130
OUTPUT: A list of tuples. Each tuple contains an (args,keywds) pair of arguments to `classify`,
131
and a classification result.
132
133
EXAMPLE:
134
135
::
136
137
sage: from boolean_cayley_graphs.bent_function import BentFunction
138
sage: from boolean_cayley_graphs.classify_in_parallel import classify_in_parallel
139
sage: bentf0 = BentFunction([0,0,0,1])
140
sage: bentf0.algebraic_normal_form()
141
x0*x1
142
sage: bentf1 = BentFunction([0,0,1,0])
143
sage: bentf1.algebraic_normal_form()
144
x0*x1 + x1
145
sage: classes = classify_in_parallel([bentf0,bentf1],ncpus=2)
146
sage: cl = classes[0][1] if classes[0][0][0][0] == 0 else classes[1][1]
147
sage: cl.report()
148
Algebraic normal form of Boolean function: x0*x1
149
Function is bent.
150
<BLANKLINE>
151
<BLANKLINE>
152
SDP design incidence structure t-design parameters: (True, (1, 4, 1, 1))
153
<BLANKLINE>
154
Classification of Cayley graphs and classification of Cayley graphs of duals are the same:
155
<BLANKLINE>
156
There are 2 extended Cayley classes in the extended translation class.
157
"""
158
if stop == None:
159
stop = len(list_of_f)
160
list_of_tuples = [
161
((n, list_of_f[n]))
162
for n in range(start, stop)]
163
return call_in_parallel(
164
classify,
165
list_of_tuples,
166
ncpus)
167
168
169
def save_one_classification(
170
name,
171
form,
172
dir=None):
173
r"""
174
Given an algebraic normal form of a bent function,
175
construct and save the corresponding Cayley graph classification.
176
177
INPUT:
178
179
- ``name`` -- String. Name to use with ``save_mangled`` to save the classification.
180
- ``form`` -- A Boolean function or an algebraic normal form.
181
- ``dir`` -- string, optional. The directory where the object
182
is to be saved. Default is None, meaning the current directory.
183
184
OUTPUT: A copy of the string ``name``.
185
186
EFFECT: Uses ``name`` to save the classification corresponding to ``form``.
187
188
EXAMPLE:
189
190
::
191
192
sage: import os
193
sage: from boolean_cayley_graphs.bent_function import BentFunction
194
sage: from boolean_cayley_graphs.bent_function_cayley_graph_classification import BentFunctionCayleyGraphClassification as BFC
195
sage: from boolean_cayley_graphs.classify_in_parallel import save_one_classification
196
sage: R2.<x1,x2> = BooleanPolynomialRing(2)
197
sage: p = x1+x2+x1*x2
198
sage: f = BentFunction(p)
199
sage: name = 'test_save_one_classification'
200
sage: d = tmp_dir()
201
sage: s = save_one_classification(name, f, dir=d)
202
sage: c = BFC.load_mangled(name, dir=d)
203
sage: c.report()
204
Algebraic normal form of Boolean function: x0*x1 + x0 + x1
205
Function is bent.
206
<BLANKLINE>
207
<BLANKLINE>
208
SDP design incidence structure t-design parameters: (True, (1, 4, 1, 1))
209
<BLANKLINE>
210
Classification of Cayley graphs and classification of Cayley graphs of duals are the same:
211
<BLANKLINE>
212
There are 2 extended Cayley classes in the extended translation class.
213
sage: print(BFC.mangled_name(name))
214
BentFunctionCayleyGraphClassification__test_save_one_classification
215
sage: BFC.remove_mangled(name, dir=d)
216
sage: os.rmdir(d)
217
"""
218
c = BentFunctionCayleyGraphClassification.from_function(
219
BentFunction(form))
220
c.save_mangled(
221
name,
222
dir=dir)
223
return name
224
225
226
def save_classifications_in_parallel(
227
name_prefix,
228
list_of_f,
229
start=0,
230
stop=None,
231
ncpus=4,
232
dir=None):
233
r"""
234
In parallel, construct and save a number of Cayley graph classifications
235
corresponding to a list of bent functions.
236
237
INPUT:
238
239
- ``name_prefix`` -- String. Name prefix to use with ``save_mangled`` to save each classification.
240
- ``list_of_f`` -- List of forms or bent functions.
241
- ``start`` -- Integer. Default=0. Index of start position in the list.
242
- ``stop`` -- Integer. Default=None. Index after end position, or ``None`` if whole remaining list.
243
- ``ncpus`` -- Integer. Default=4. The number of cpus to use in parallel.
244
- ``dir`` -- string, optional. The directory where the object
245
is to be saved. Default is None, meaning the current directory.
246
247
OUTPUT:
248
249
EFFECT: Uses ``name`` to save the classifications corresponding to ``list_of_f``.
250
251
252
EXAMPLE:
253
254
::
255
256
sage: from boolean_cayley_graphs.bent_function import BentFunction
257
sage: from boolean_cayley_graphs.bent_function_cayley_graph_classification import BentFunctionCayleyGraphClassification as BFC
258
sage: from boolean_cayley_graphs.classify_in_parallel import save_classifications_in_parallel
259
sage: bentf0 = BentFunction([0,0,0,1])
260
sage: bentf0.algebraic_normal_form()
261
x0*x1
262
sage: bentf1 = BentFunction([0,0,1,0])
263
sage: bentf1.algebraic_normal_form()
264
x0*x1 + x1
265
sage: name_prefix = 'test_save_classifications_in_parallel'
266
sage: d = tmp_dir()
267
sage: names = save_classifications_in_parallel(name_prefix, [bentf0,bentf1], ncpus=2, dir=d)
268
sage: name_1 = name_prefix + '_1'
269
sage: c = BFC.load_mangled(name_1, dir=d)
270
sage: c.report()
271
Algebraic normal form of Boolean function: x0*x1 + x1
272
Function is bent.
273
<BLANKLINE>
274
<BLANKLINE>
275
SDP design incidence structure t-design parameters: (True, (1, 4, 1, 1))
276
<BLANKLINE>
277
Classification of Cayley graphs and classification of Cayley graphs of duals are the same:
278
<BLANKLINE>
279
There are 2 extended Cayley classes in the extended translation class.
280
sage: for n in range(2):
281
....: name = name_prefix + '_' + str(n)
282
....: print(BFC.mangled_name(name))
283
....: BFC.remove_mangled(name, dir=d)
284
....:
285
BentFunctionCayleyGraphClassification__test_save_classifications_in_parallel_0
286
BentFunctionCayleyGraphClassification__test_save_classifications_in_parallel_1
287
sage: os.rmdir(d)
288
"""
289
if stop == None:
290
stop = len(list_of_f)
291
list_of_tuples = [
292
((name_prefix + '_' + str(n), list_of_f[n], dir))
293
for n in range(start, stop)]
294
return call_in_parallel(
295
save_one_classification,
296
list_of_tuples,
297
ncpus)
298
299
300
def save_one_class_part(
301
name,
302
bentf,
303
c_start,
304
c_stop,
305
dir=None):
306
r"""
307
Construct and save a partial Cayley graph classification
308
corresponding to a given bent function.
309
310
INPUT:
311
312
- ``name`` -- Name to use with ``save_mangled`` to save the class part.
313
- ``bentf`` -- A Bent function.
314
- ``c_start`` -- smallest value of `c` to use for
315
extended translates. Integer. Default is 0.
316
- ``c_stop`` -- one more than largest value of `c`
317
to use for extended translates. Integer.
318
Default is ``None``, meaning use all remaining values.
319
- ``dir`` -- string, optional. The directory where the object
320
is to be saved. Default is None, meaning the current directory.
321
322
OUTPUT: A copy of the string ``name``.
323
324
EFFECT: Uses ``name`` to save the partial classification corresponding to ``bentf``.
325
326
EXAMPLE:
327
328
::
329
330
sage: import os
331
sage: from boolean_cayley_graphs.bent_function import BentFunction
332
sage: from boolean_cayley_graphs.bent_function_cayley_graph_classification import BentFunctionCayleyGraphClassPart as BFCP
333
sage: from boolean_cayley_graphs.classify_in_parallel import save_one_class_part
334
sage: R2.<x1,x2> = BooleanPolynomialRing(2)
335
sage: p = x1+x2+x1*x2
336
sage: f = BentFunction(p)
337
sage: name = 'test_save_one_class_part'
338
sage: d = tmp_dir()
339
sage: s = save_one_class_part(name, f, c_start=1, c_stop=2, dir=d)
340
sage: p1 = BFCP.load_mangled(name, dir=d)
341
sage: dict(sorted(p1.__dict__.items()))
342
{'algebraic_normal_form': x0*x1 + x0 + x1,
343
'bent_cayley_graph_index_matrix': [0 0 1 0],
344
'c_start': 1,
345
'cayley_graph_class_list': ['CK', 'C~'],
346
'dual_cayley_graph_index_matrix': [0 0 1 0],
347
'weight_class_matrix': [0 0 1 0]}
348
sage: print(BFCP.mangled_name(name))
349
BentFunctionCayleyGraphClassPart__test_save_one_class_part
350
sage: BFCP.remove_mangled(name, dir=d)
351
sage: os.rmdir(d)
352
"""
353
p = BentFunctionCayleyGraphClassPart.from_function(
354
bentf,
355
c_start=c_start,
356
c_stop=c_stop)
357
p.save_mangled(
358
name,
359
dir=dir)
360
return name
361
362
363
def save_class_parts_in_parallel(
364
name_prefix,
365
form,
366
c_len=1,
367
ncpus=4,
368
dir=None):
369
r"""
370
In parallel, construct a complete list of the partial Cayley graph classifications
371
corresponding to a given bent function or algebraic normal form.
372
373
INPUT:
374
375
- ``name_prefix`` -- String. Name prefix to use with ``save_mangled`` to save each class part.
376
- ``form`` -- A bent function or an algebraic normal form.
377
- ``c_len`` -- Integer. Default=1. The number of values of `c` to use in each class part.
378
- ``ncpus`` -- Integer. Default=4. The number of cpus to use in parallel.
379
- ``dir`` -- string, optional. The directory where the object
380
is to be saved. Default is None, meaning the current directory.
381
382
OUTPUT: A list containing tuples, with names.
383
384
EFFECT: Uses ``name_prefix`` to save all partial classifications corresponding to ``bentf``.
385
386
EXAMPLE:
387
388
::
389
390
sage: import glob
391
sage: import os
392
sage: from boolean_cayley_graphs.bent_function import BentFunction
393
sage: from boolean_cayley_graphs.bent_function_cayley_graph_classification import BentFunctionCayleyGraphClassPart as BFCP
394
sage: from boolean_cayley_graphs.classify_in_parallel import save_class_parts_in_parallel
395
sage: R2.<x1,x2> = BooleanPolynomialRing(2)
396
sage: p = x1+x2+x1*x2
397
sage: f = BentFunction(p)
398
sage: name_prefix = 'test_save_class_parts_in_parallel'
399
sage: d = tmp_dir()
400
sage: s = save_class_parts_in_parallel(name_prefix, f, dir=d)
401
sage: p1=BFCP.load_mangled(name_prefix + '_1', dir=d)
402
sage: dict(sorted(p1.__dict__.items()))
403
{'algebraic_normal_form': x0*x1 + x0 + x1,
404
'bent_cayley_graph_index_matrix': [0 0 1 0],
405
'c_start': 1,
406
'cayley_graph_class_list': ['CK', 'C~'],
407
'dual_cayley_graph_index_matrix': [0 0 1 0],
408
'weight_class_matrix': [0 0 1 0]}
409
sage: for n in range(4):
410
....: name = name_prefix + '_' + str(n)
411
....: print(BFCP.mangled_name(name))
412
....: BFCP.remove_mangled(name, dir=d)
413
....:
414
BentFunctionCayleyGraphClassPart__test_save_class_parts_in_parallel_0
415
BentFunctionCayleyGraphClassPart__test_save_class_parts_in_parallel_1
416
BentFunctionCayleyGraphClassPart__test_save_class_parts_in_parallel_2
417
BentFunctionCayleyGraphClassPart__test_save_class_parts_in_parallel_3
418
sage: os.rmdir(d)
419
"""
420
bentf = BentFunction(form)
421
dim = bentf.nvariables()
422
v = 2 ** dim
423
ceil = Function_ceil()
424
nbr_parts = ceil(v * 1.0 / c_len)
425
list_of_tuples = [
426
((name_prefix + '_' + str(n), bentf, c_len * n, c_len * (n+1), dir))
427
for n in range(nbr_parts)]
428
return call_in_parallel(
429
save_one_class_part,
430
list_of_tuples,
431
ncpus)
432
433