| Download
Project: Bent-functions
Path: Boolean-Cayley-graphs / boolean_cayley_graphs / boolean_function_extended_translate_classification.py
Views: 19204r"""1Classification of boolean functions within an extended translation class2========================================================================34The ``boolean_function_extended_translate_classification`` module defines:56* the ``BooleanFunctionExtendedTranslateClassification`` class;7which represents the classification of the general linear classes8within the extended translation class of a boolean function; and9* the ``BooleanFunctionExtendedTranslateClassPart`` class,10which represents part of an extended translate classification.1112AUTHORS:1314- Paul Leopardi (2023-01-26): initial version1516EXAMPLES:1718::1920The classification of the boolean function defined by the polynomial x2 + x1*x2.2122sage: from boolean_cayley_graphs.boolean_function_improved import BooleanFunctionImproved23sage: from boolean_cayley_graphs.boolean_function_extended_translate_classification import (24....: BooleanFunctionExtendedTranslateClassification as BooleanFunctionETC)25sage: R2.<x1,x2> = BooleanPolynomialRing(2)26sage: p = x2+x1*x227sage: f = BooleanFunctionImproved(p)28sage: c = BooleanFunctionETC.from_function(f)29sage: dict(sorted(c.__dict__.items()))30{'algebraic_normal_form': x0*x1 + x1,31'boolean_function_index_matrix': [0 2 1 3]32[1 3 0 2]33[2 0 3 1]34[3 1 2 0],35'boolean_function_list': [Boolean function with 2 variables,36Boolean function with 2 variables,37Boolean function with 2 variables,38Boolean function with 2 variables],39'general_linear_class_index_matrix': [0 0 1 0]40[1 0 0 0]41[0 0 0 1]42[0 1 0 0],43'general_linear_class_list': [Boolean function with 2 variables,44Boolean function with 2 variables]}4546REFERENCES:4748The extended translation equivalence class and the general linear equivalence class49of a boolean function are defined by Leopardi [Leo2017]_.50"""51#*****************************************************************************52# Copyright (C) 2016-2023 Paul Leopardi [email protected]53#54# Distributed under the terms of the GNU General Public License (GPL)55# as published by the Free Software Foundation; either version 2 of56# the License, or (at your option) any later version.57# http://www.gnu.org/licenses/58#*****************************************************************************596061from datetime import datetime62from numpy import array, argwhere63from sage.functions.log import log64from sage.graphs.graph import Graph65from sage.matrix.constructor import matrix66from sage.misc.latex import latex67from sage.misc.persist import load68from sage.plot.matrix_plot import matrix_plot69from sage.rings.integer import Integer70from sage.structure.sage_object import SageObject71from sys import stdout7273import glob74import numpy as np7576from boolean_cayley_graphs.boolean_function_improved import (77BooleanFunctionImproved)78from boolean_cayley_graphs.boolean_function_general_linear_class import (79BooleanFunctionGeneralLinearClass)80from boolean_cayley_graphs.containers import (81BijectiveList, List, ShelveBijectiveList)82from boolean_cayley_graphs.saveable import Saveable8384import boolean_cayley_graphs.cayley_graph_controls as controls85import csv86import os.path8788default_algorithm = "sage"899091class BooleanFunctionExtendedTranslateClassPart(SageObject, Saveable):92r"""93Partial classification of the general linear classes within the94extended translation equivalence class of a boolean function.9596EXAMPLES:9798::99100sage: from boolean_cayley_graphs.boolean_function_improved import BooleanFunctionImproved101sage: from boolean_cayley_graphs.boolean_function_extended_translate_classification import (102....: BooleanFunctionExtendedTranslateClassPart as BooleanFunctionETCPart)103sage: R2.<x1,x2> = BooleanPolynomialRing(2)104sage: p = x1+x2+x1*x2105sage: f = BooleanFunctionImproved(p)106sage: c1 = BooleanFunctionETCPart.from_function(f, c_stop=1)107sage: print(c1)108BooleanFunctionExtendedTranslateClassPart.from_function(BooleanFunctionImproved(x0*x1 + x0 + x1, c_start=0, c_stop=1))109sage: latex(c1)110\text{\texttt{BooleanFunctionExtendedTranslateClassPart.from{\char`\_}function(BooleanFunctionImproved(x0*x1{ }+{ }x0{ }+{ }x1,{ }c{\char`\_}start=0,{ }c{\char`\_}stop=1))}}111112"""113114def __init__(self, *args, **kwargs):115r"""116Constructor from an object or from class attributes.117118INPUT:119120- ``algebraic_normal_form`` -- a polynomial of the type121returned by ``BooleanFunction.algebraic_normal_form()``,122representing the ``BooleanFunction`` whose classification this is.123- ``boolean_function_index_matrix`` -- a ``Matrix` of integers,124which are indices into ``boolean_function_list`` representing the125distinct boolean functions.126- ``boolean_function_list`` -- a list of boolean functions.127- ``general_linear_class_index_matrix`` -- a ``Matrix` of integers,128which are indices into ``general_linear_class_list`` representing the129general linear equivalence classes.130- ``general_linear_class_list`` -- a list of matrices representing the131general linear equivalence classes.132- ``c_start`` -- an integer representing the index of133the first row of each matrix.134135OUTPUT:136137None.138139EFFECT:140141The current object ``self`` is initialized as follows.142143Each of144- ``algebraic_normal_form``145- ``boolean_function_index_matrix``146- ``boolean_function_list``147- ``general_linear_class_index_matrix``148- ``general_linear_class_list``149- ``c_start``150is set to the corresponding input parameter.151152EXAMPLES:153154The partial classification of the boolean function defined by the polynomial155:math:`x_1 + x_2 + x_1 x_2` is copied from `c1` to `c2`.156157::158159sage: from boolean_cayley_graphs.boolean_function_improved import BooleanFunctionImproved160sage: from boolean_cayley_graphs.boolean_function_extended_translate_classification import (161....: BooleanFunctionExtendedTranslateClassPart as BooleanFunctionETCPart)162sage: R2.<x1,x2> = BooleanPolynomialRing(2)163sage: p = x1+x2+x1*x2164sage: f = BooleanFunctionImproved(p)165sage: c1 = BooleanFunctionETCPart.from_function(f, c_stop=1)166sage: c2 = BooleanFunctionETCPart(c1)167sage: print(c1 == c2)168True169"""170try:171sobj = args[0]172self.algebraic_normal_form = sobj.algebraic_normal_form173self.boolean_function_index_matrix = sobj.boolean_function_index_matrix174self.boolean_function_list = sobj.boolean_function_list175self.general_linear_class_index_matrix = sobj.general_linear_class_index_matrix176self.general_linear_class_list = sobj.general_linear_class_list177self.c_start=sobj.c_start178except:179self.algebraic_normal_form = kwargs.pop(180'algebraic_normal_form')181self.boolean_function_index_matrix = kwargs.pop(182'boolean_function_index_matrix')183self.boolean_function_list = kwargs.pop(184'boolean_function_list')185self.general_linear_class_index_matrix = kwargs.pop(186'general_linear_class_index_matrix')187self.general_linear_class_list = kwargs.pop(188'general_linear_class_list')189self.c_start = kwargs.pop(190'c_start')191192193def _repr_(self):194r"""195Sage string representation.196197INPUT:198199- ``self`` -- the current object.200201EXAMPLES:202203::204205sage: from boolean_cayley_graphs.boolean_function_improved import BooleanFunctionImproved206sage: from boolean_cayley_graphs.boolean_function_extended_translate_classification import (207....: BooleanFunctionExtendedTranslateClassPart as BooleanFunctionETCPart)208sage: R2.<x1,x2> = BooleanPolynomialRing(2)209sage: p = x1+x2+x1*x2210sage: f = BooleanFunctionImproved(p)211sage: c1 = BooleanFunctionETCPart.from_function(f, c_stop=1)212sage: print(c1)213BooleanFunctionExtendedTranslateClassPart.from_function(BooleanFunctionImproved(x0*x1 + x0 + x1, c_start=0, c_stop=1))214"""215c_stop = self.c_start + self.boolean_function_index_matrix.nrows()216return (217type(self).__name__ +218".from_function(BooleanFunctionImproved(" +219repr(self.algebraic_normal_form) +220", c_start=" +221repr(self.c_start) +222", c_stop=" +223repr(c_stop) +224"))")225226227@classmethod228def from_function(229cls,230boolf,231c_start=0,232c_stop=None,233limited_memory=False):234r"""235Constructor from the ``BooleanFunction`` ``boolf``.236237INPUT:238239- ``boolf`` -- an object of class ``BooleanFunction``.240- ``c_start`` -- integer (default: 0).241The smallest value of `c` to use for extended translates.242- ``c_stop`` -- integer (default: ``None``).243One more than largest value of `c` to use for extended244translates. ``None`` means use all remaining values.245- ``limited_memory`` -- boolean (default: ``False``).246A flag indicating whether the classification might be247too large to fit into memory.248249OUTPUT:250251An object of class BooleanFunctionExtendedTranslateClassPart,252initialized as follows.253254- ``algebraic_normal_form`` is set to ``boolf.algebraic_normal_form()``,255- ``boolean_function_index_matrix`` -- a ``Matrix` of integers,256which are indices into ``boolean_function_list`` representing the257distinct boolean functions.258- ``boolean_function_list`` -- a list of boolean functions.259- ``general_linear_class_index_matrix`` -- a ``Matrix` of integers,260which are indices into ``general_linear_class_list`` representing the261general linear equivalence classes.262- ``general_linear_class_list`` -- a list of matrices representing the263general linear equivalence classes.264- ``c_start`` is set to smallest value of `c` used for extended translates.265266Each entry ``boolean_function_index_matrix[c-c_start,b]`` corresponds to267the boolean function268:math:`x \mapsto \mathtt{boolf}(x+b) + \langle c, x \rangle + \mathtt{boolf}(b)`.269This enumerates all of the extended translates of ``boolf`` having ``c``270from ``c_start`` to but not including ``c_stop``.271272EXAMPLES:273274A partial classification of the boolean function defined by the polynomial275:math:`x_1 + x_2 + x_1 x_2`.276277::278279sage: from boolean_cayley_graphs.boolean_function_improved import BooleanFunctionImproved280sage: from boolean_cayley_graphs.boolean_function_extended_translate_classification import (281....: BooleanFunctionExtendedTranslateClassPart as BooleanFunctionETCPart)282sage: R2.<x1,x2> = BooleanPolynomialRing(2)283sage: p = x1+x2+x1*x2284sage: f = BooleanFunctionImproved(p)285sage: c1 = BooleanFunctionETCPart.from_function(f,c_start=2,c_stop=4)286sage: dict(sorted(c1.__dict__.items()))287{'algebraic_normal_form': x0*x1 + x0 + x1,288'boolean_function_index_matrix': [0 2 1 3]289[1 3 0 2],290'boolean_function_list': [Boolean function with 2 variables,291Boolean function with 2 variables,292Boolean function with 2 variables,293Boolean function with 2 variables],294'c_start': 2,295'general_linear_class_index_matrix': [0 1 0 0]296[0 0 0 1],297'general_linear_class_list': [Boolean function with 2 variables,298Boolean function with 2 variables]}299"""300checking = controls.checking301timing = controls.timing302303dim = boolf.nvariables()304v = 2 ** dim305306if c_stop == None:307c_stop = v308else:309c_stop = min(c_stop, v)310algebraic_normal_form = boolf.algebraic_normal_form()311312use_shelve = dim > 8 or (dim == 8 and limited_memory)313boolean_function_bijection = (314ShelveBijectiveList()315if use_shelve else316BijectiveList())317318c_len = c_stop - c_start319boolean_function_index_matrix = matrix(c_len, v)320general_linear_class_index_matrix = matrix(c_len, v)321general_linear_class_list = List()322323f = boolf.extended_translate()324for b in range(v):325if timing:326print(datetime.now(), b, end=' ')327print(len(boolean_function_bijection.get_list()))328stdout.flush()329for c in range(c_start, c_stop):330f = boolf.zero_translate(b, c)331tt = tuple(f(x) for x in range(v))332bf_tt = BooleanFunctionImproved(tt)333bf_tt_index = boolean_function_bijection.index_append(bf_tt)334boolean_function_index_matrix[c - c_start, b] = bf_tt_index335336bf_etc = BooleanFunctionGeneralLinearClass(tt)337glc_index = general_linear_class_list.index_append(bf_etc)338general_linear_class_index_matrix[c - c_start, b] = glc_index339340if checking:341pass342boolean_function_bijection.sync()343344# Retain the list part of boolean_function_bijection, and345# close and remove the dict part.346boolean_function_list = boolean_function_bijection.get_list()347boolean_function_bijection.close_dict()348boolean_function_bijection.remove_dict()349350if checking:351pass352353if timing:354print(datetime.now())355stdout.flush()356357return cls(358algebraic_normal_form=algebraic_normal_form,359boolean_function_index_matrix=boolean_function_index_matrix,360boolean_function_list=boolean_function_list,361general_linear_class_index_matrix=general_linear_class_index_matrix,362general_linear_class_list=general_linear_class_list,363c_start=c_start)364365366def __eq__(self, other):367"""368Test for equality between partial classifications.369370WARNING:371372This test is for strict equality rather than mathematical equivalence.373374INPUT:375376- ``other`` - BooleanFunctionExtendedTranslateClassPart: another partial classification.377378OUTPUT:379380A Boolean value indicating whether ``self`` strictly equals ``other``.381382EXAMPLES:383384::385386sage: from boolean_cayley_graphs.boolean_function_improved import BooleanFunctionImproved387sage: from boolean_cayley_graphs.boolean_function_extended_translate_classification import (388....: BooleanFunctionExtendedTranslateClassPart as BooleanFunctionETCPart)389sage: R2.<x0,x1> = BooleanPolynomialRing(2)390sage: p = x0*x1391sage: f1 = BooleanFunctionImproved(p)392sage: c1 = BooleanFunctionETCPart.from_function(f1, c_stop=1)393sage: f2 = BooleanFunctionImproved([0,0,0,1])394sage: c2 = BooleanFunctionETCPart.from_function(f2, c_stop=1)395sage: print(c2.algebraic_normal_form)396x0*x1397sage: print(c1 == c2)398True399"""400if other is None:401return False402return (403self.algebraic_normal_form == other.algebraic_normal_form and404self.boolean_function_list == other.boolean_function_list and405self.boolean_function_index_matrix == other.boolean_function_index_matrix and406self.general_linear_class_list == other.general_linear_class_list and407self.general_linear_class_index_matrix == other.general_linear_class_index_matrix and408self.c_start == other.c_start)409410411class BooleanFunctionExtendedTranslateClassification(BooleanFunctionExtendedTranslateClassPart):412r"""413Classification of the Cayley graphs within the414extended translation equivalence class of a boolean function.415416EXAMPLES:417418::419420sage: from boolean_cayley_graphs.boolean_function_improved import BooleanFunctionImproved421sage: from boolean_cayley_graphs.boolean_function_extended_translate_classification import (422....: BooleanFunctionExtendedTranslateClassification as BooleanFunctionETC)423sage: R2.<x1,x2> = BooleanPolynomialRing(2)424sage: p = x1+x2+x1*x2425sage: f = BooleanFunctionImproved(p)426sage: c1 = BooleanFunctionETC.from_function(f)427sage: print(c1)428BooleanFunctionExtendedTranslateClassification.from_function(BooleanFunctionImproved(x0*x1 + x0 + x1))429sage: latex(c1)430\text{\texttt{BooleanFunctionExtendedTranslateClassification.from{\char`\_}function(BooleanFunctionImproved(x0*x1{ }+{ }x0{ }+{ }x1))}}431"""432433# Suffixes used by from_csv() and save_as_csv().434bent_function_csv_suffix = "_bent_function.csv"435cg_class_list_csv_suffix = "_cg_class_list.csv"436matrices_csv_suffix = "_matrices.csv"437438439def __init__(self, *args, **kwargs):440r"""441Constructor from an object or from class attributes.442443INPUT:444445- ``sobj`` -- BooleanFunctionExtendedTranslateClassification: object to copy.446447- ``algebraic_normal_form`` -- a polynomial of the type448returned by ``BooleanFunction.algebraic_normal_form()``,449representing the ``BooleanFunctionImproved`` whose classification this is.450- ``boolean_function_index_matrix`` -- a ``Matrix` of integers,451which are indices into ``boolean_function_list`` representing the452distinct boolean functions.453- ``boolean_function_list`` -- a list of boolean functions.454- ``general_linear_class_index_matrix`` -- a ``Matrix` of integers,455which are indices into ``general_linear_class_list`` representing the456general linear equivalence classes.457- ``general_linear_class_list`` -- a list of matrices representing the458general linear equivalence classes.459460OUTPUT:461462None.463464EFFECT:465466The current object ``self`` is initialized as follows.467468Each of469- ``algebraic_normal_form``470- ``boolean_function_index_matrix``471- ``boolean_function_list``472- ``general_linear_class_index_matrix``473- ``general_linear_class_list``474is set to the corresponding input parameter.475476EXAMPLES:477478The classification of the boolean function defined by the polynomial479:math:`x_1 + x_2 + x_1 x_2` is copied from `c1` to `c2`.480481::482483sage: from boolean_cayley_graphs.boolean_function_improved import BooleanFunctionImproved484sage: from boolean_cayley_graphs.boolean_function_extended_translate_classification import (485....: BooleanFunctionExtendedTranslateClassification as BooleanFunctionETC)486sage: R2.<x1,x2> = BooleanPolynomialRing(2)487sage: p = x1+x2+x1*x2488sage: f = BooleanFunctionImproved(p)489sage: c1 = BooleanFunctionETC.from_function(f)490sage: c2 = BooleanFunctionETC(c1)491sage: print(c1 == c2)492True493"""494try:495sobj = args[0]496self.algebraic_normal_form=sobj.algebraic_normal_form497self.boolean_function_index_matrix=sobj.boolean_function_index_matrix498self.boolean_function_list=sobj.boolean_function_list499self.general_linear_class_index_matrix=sobj.general_linear_class_index_matrix500self.general_linear_class_list=sobj.general_linear_class_list501except:502self.algebraic_normal_form = kwargs.pop(503'algebraic_normal_form')504self.boolean_function_index_matrix = kwargs.pop(505'boolean_function_index_matrix')506self.boolean_function_list = kwargs.pop(507'boolean_function_list')508self.general_linear_class_index_matrix = kwargs.pop(509'general_linear_class_index_matrix')510self.general_linear_class_list = kwargs.pop(511'general_linear_class_list')512513514def _repr_(self):515r"""516Sage string representation.517518INPUT:519520- ``self`` -- the current object.521522EXAMPLES:523524::525526sage: from boolean_cayley_graphs.boolean_function_improved import BooleanFunctionImproved527sage: from boolean_cayley_graphs.boolean_function_extended_translate_classification import (528....: BooleanFunctionExtendedTranslateClassification as BooleanFunctionETC)529sage: R2.<x1,x2> = BooleanPolynomialRing(2)530sage: p = x1+x2+x1*x2531sage: f = BooleanFunctionImproved(p)532sage: c1 = BooleanFunctionETC.from_function(f)533sage: print(c1)534BooleanFunctionExtendedTranslateClassification.from_function(BooleanFunctionImproved(x0*x1 + x0 + x1))535"""536return (537type(self).__name__ +538".from_function(BooleanFunctionImproved(" +539repr(self.algebraic_normal_form) +540"))")541542543@classmethod544def from_function(545cls,546boolf,547list_dual_graphs=True,548limited_memory=False):549r"""550Constructor from the ``BooleanFunctionImproved`` ``boolf``.551552INPUT:553554- ``boolf`` -- an object of class ``BooleanFunctionImproved``.555- ``list_dual_graphs`` -- boolean. a flag indicating556whether to list dual graphs.557- ``limited_memory`` -- boolean. A flag indicating558whether the classification might be too large559to fit into memory. Default is False.560561OUTPUT:562563An object of class BooleanFunctionExtendedTranslateClassification,564initialized as follows.565566- ``algebraic_normal_form`` is set to ``boolf.algebraic_normal_form()``,567- ``boolean_function_index_matrix`` -- a ``Matrix` of integers,568which are indices into ``boolean_function_list`` representing the569distinct boolean functions.570- ``boolean_function_list`` -- a list of boolean functions.571- ``general_linear_class_index_matrix`` -- a ``Matrix` of integers,572which are indices into ``general_linear_class_list`` representing the573general linear equivalence classes.574- ``general_linear_class_list`` -- a list of matrices representing the575general linear equivalence classes.576577Each entry ``boolean_function_index_matrix[c,b]`` corresponds to578the Cayley graph of the boolean function579:math:`x \mapsto \mathtt{boolf}(x+b) + \langle c, x \rangle + \mathtt{boolf}(b)`.580This enumerates all of the extended translates of ``boolf``.581582EXAMPLES:583584The classification of the boolean function defined by the polynomial585:math:`x_1 + x_2 + x_1 x_2`.586587::588589sage: from boolean_cayley_graphs.boolean_function_improved import BooleanFunctionImproved590sage: from boolean_cayley_graphs.boolean_function_extended_translate_classification import (591....: BooleanFunctionExtendedTranslateClassification as BooleanFunctionETC)592sage: R2.<x1,x2> = BooleanPolynomialRing(2)593sage: p = x1+x2+x1*x2594sage: f = BooleanFunctionImproved(p)595sage: c3 = BooleanFunctionETC.from_function(f)596sage: dict(sorted(c3.__dict__.items()))597{'algebraic_normal_form': x0*x1 + x0 + x1,598'boolean_function_index_matrix': [0 2 1 3]599[1 3 0 2]600[2 0 3 1]601[3 1 2 0],602'boolean_function_list': [Boolean function with 2 variables,603Boolean function with 2 variables,604Boolean function with 2 variables,605Boolean function with 2 variables],606'general_linear_class_index_matrix': [0 1 1 1]607[1 1 0 1]608[1 0 1 1]609[1 1 1 0],610'general_linear_class_list': [Boolean function with 2 variables,611Boolean function with 2 variables]}612613TESTS:614615The classification of the boolean function defined by the polynomial616:math:`x_1 + x_2 + x_1 x_2`, but with list_dual_graphs=False.617618::619620sage: from boolean_cayley_graphs.boolean_function_improved import BooleanFunctionImproved621sage: from boolean_cayley_graphs.boolean_function_extended_translate_classification import (622....: BooleanFunctionExtendedTranslateClassification as BooleanFunctionETC)623sage: R2.<x1,x2> = BooleanPolynomialRing(2)624sage: p = x1+x2+x1*x2625sage: f = BooleanFunctionImproved(p)626sage: c4 = BooleanFunctionETC.from_function(f,list_dual_graphs=False)627sage: dict(sorted(c4.__dict__.items()))628{'algebraic_normal_form': x0*x1 + x0 + x1,629'boolean_function_index_matrix': [0 2 1 3]630[1 3 0 2]631[2 0 3 1]632[3 1 2 0],633'boolean_function_list': [Boolean function with 2 variables,634Boolean function with 2 variables,635Boolean function with 2 variables,636Boolean function with 2 variables],637'general_linear_class_index_matrix': [0 1 1 1]638[1 1 0 1]639[1 0 1 1]640[1 1 1 0],641'general_linear_class_list': [Boolean function with 2 variables,642Boolean function with 2 variables]}643"""644cp = BooleanFunctionExtendedTranslateClassPart.from_function(645boolf,646limited_memory=limited_memory)647return cls(cp)648649650def __eq__(self, other):651"""652Test for equality between classifications.653654WARNING:655656This test is for strict equality rather than mathematical equivalence.657658INPUT:659660- ``other`` - BooleanFunctionExtendedTranslateClassification: another classification.661662OUTPUT:663664A Boolean value indicating whether ``self`` strictly equals ``other``.665666EXAMPLES:667668::669670sage: from boolean_cayley_graphs.boolean_function_improved import BooleanFunctionImproved671sage: from boolean_cayley_graphs.boolean_function_extended_translate_classification import (672....: BooleanFunctionExtendedTranslateClassification as BooleanFunctionETC)673sage: R2.<x0,x1> = BooleanPolynomialRing(2)674sage: p = x0*x1675sage: f1 = BooleanFunctionImproved(p)676sage: c1 = BooleanFunctionETC.from_function(f1)677sage: f2 = BooleanFunctionImproved([0,0,0,1])678sage: c2 = BooleanFunctionETC.from_function(f2)679sage: print(c2.algebraic_normal_form)680x0*x1681sage: print(c1 == c2)682True683"""684if other is None:685return False686return (687self.algebraic_normal_form == other.algebraic_normal_form and688self.boolean_function_index_matrix == other.boolean_function_index_matrix and689self.boolean_function_list == other.boolean_function_list and690self.general_linear_class_index_matrix == other.general_linear_class_index_matrix and691self.general_linear_class_list == other.general_linear_class_list)692693694