Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download
Views: 19204
1
r"""
2
Boolean graphs
3
==============
4
5
The ``boolean_graph`` module defines
6
the ``BooleanGraph`` class,
7
which represents a Graph whose order is a power of 2.
8
9
AUTHORS:
10
11
- Paul Leopardi (2017-11-11): initial version
12
13
"""
14
#*****************************************************************************
15
# Copyright (C) 2017 Paul Leopardi [email protected]
16
#
17
# Distributed under the terms of the GNU General Public License (GPL)
18
# as published by the Free Software Foundation; either version 2 of
19
# the License, or (at your option) any later version.
20
# http://www.gnu.org/licenses/
21
#*****************************************************************************
22
23
from math import log
24
25
from sage.graphs.graph import Graph
26
from sage.matrix.constructor import matrix
27
from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF
28
from sage.rings.integer import Integer
29
30
from boolean_cayley_graphs.integer_bits import base2
31
from boolean_cayley_graphs.linear import is_linear
32
from boolean_cayley_graphs.saveable import Saveable
33
34
default_algorithm = "sage"
35
36
37
class BooleanGraph(Graph, Saveable):
38
"""
39
A Graph whose order is a power of 2.
40
41
EXAMPLES:
42
43
::
44
45
sage: from boolean_cayley_graphs.boolean_graph import BooleanGraph
46
sage: g16 = BooleanGraph(16)
47
sage: g16.order()
48
16
49
50
TESTS:
51
52
::
53
54
sage: from boolean_cayley_graphs.boolean_graph import BooleanGraph
55
sage: g16 = BooleanGraph(16)
56
sage: print(g16)
57
Graph on 16 vertices
58
"""
59
60
61
def __init__(self, *args, **kwargs):
62
"""
63
A Graph whose order is a power of 2.
64
65
EXAMPLES:
66
67
::
68
69
sage: from boolean_cayley_graphs.boolean_graph import BooleanGraph
70
sage: g16 = BooleanGraph(8)
71
sage: g16.order()
72
8
73
"""
74
super(BooleanGraph, self).__init__(*args, **kwargs)
75
76
if not log(self.order(),2).is_integer():
77
raise ValueError
78
79
80
def is_linear_isomorphic(
81
self,
82
other,
83
certificate=False,
84
algorithm=default_algorithm):
85
r"""
86
Check that the two BooleanGraphs ``self`` and ``other`` are isomorphic
87
and that the isomorphism is given by a GF(2) linear mapping on the
88
vector space of vertices.
89
90
INPUT:
91
92
- ``self`` -- the current object.
93
- ``other`` -- another object of class BooleanFunctionImproved.
94
- ``certificate`` -- bool (default False). If true, return a GF(2) matrix
95
that defines the isomorphism.
96
97
OUTPUT:
98
99
If ``certificate`` is false, a bool value.
100
If ``certificate`` is true, a tuple consisting of either (False, None)
101
or (True, M), where M is a GF(2) matrix that defines the isomorphism.
102
103
EXAMPLES:
104
105
::
106
107
sage: from boolean_cayley_graphs.boolean_function_improved import BooleanFunctionImproved
108
sage: from boolean_cayley_graphs.boolean_graph import BooleanGraph
109
sage: bf1 = BooleanFunctionImproved([0,1,0,0])
110
sage: cg1 = BooleanGraph(bf1.cayley_graph())
111
sage: bf2 = BooleanFunctionImproved([0,0,1,0])
112
sage: cg2 = BooleanGraph(bf2.cayley_graph())
113
sage: cg1.is_linear_isomorphic(cg2)
114
True
115
sage: cg2.is_linear_isomorphic(cg1, certificate=True)
116
(
117
[0 1]
118
True, [1 0]
119
)
120
121
122
"""
123
# Check the isomorphism between self and other via canonical labels.
124
# This is to work around the slow speed of is_isomorphic in some cases.
125
if self.canonical_label() != other.canonical_label():
126
return (False, None) if certificate else False
127
128
# Obtain the mapping that defines the isomorphism.
129
is_isomorphic, mapping_dict = self.is_isomorphic(other, certificate=True)
130
131
# If self is not isomorphic to other, it is not linear equivalent.
132
if not is_isomorphic:
133
return (False, None) if certificate else False
134
135
mapping = lambda x: mapping_dict[x]
136
137
v = self.order()
138
dim = Integer(log(v, 2))
139
140
# Check that mapping is linear.
141
if certificate:
142
linear, mapping_matrix = is_linear(dim, mapping, certificate)
143
else:
144
linear = is_linear(dim, mapping)
145
if linear:
146
return (True, mapping_matrix) if certificate else True
147
148
# For each permutation p in the automorphism group of self,
149
# check that the permuted mapping is linear.
150
auto_group = self.automorphism_group()
151
test_group = auto_group.stabilizer(0) if mapping(0) == 0 else auto_group
152
linear = False
153
for p in test_group:
154
p_mapping = lambda x: p(mapping(x))
155
156
# Check that p_mapping is linear.
157
if certificate:
158
linear, mapping_matrix = is_linear(dim, p_mapping, certificate)
159
else:
160
linear = is_linear(dim, p_mapping)
161
# We only need to find one linear p_mapping that preserves other.
162
if linear:
163
break
164
165
if certificate:
166
return (True, mapping_matrix) if linear else (False, None)
167
else:
168
return linear
169
170