/* Copyright (C) 2015 Alejandro Mujica (amujica en cenditel.gob.ve) José Angel Contreras (jancontreras en cenditel.gob.ve) Antonio Araujo (aaraujo en cenditel.gob.ve) Pedro Buitrago (pbuitrago en cenditel.gob.ve) CENDITEL Fundación Centro Nacional de Desarrollo e Investigación en Tecnologías Libres Este programa es software libre; Usted puede usarlo bajo los términos de la licencia de software GPL versión 2.0 de la Free Software Foundation. Este programa se distribuye con la esperanza de que sea útil, pero SIN NINGUNA GARANTÍA; tampoco las implícitas garantías de MERCANTILIDAD o ADECUACIÓN A UN PROPÓSITO PARTICULAR. Consulte la licencia GPL para más detalles. Usted debe recibir una copia de la GPL junto con este programa; si no, escriba a la Free Software Foundation Inc. 51 Franklin Street,5 Piso, Boston, MA 02110-1301, USA. */ /* Este archivo contiene la definición de una plantilla para basar implementaciones de campos de Galois (campos finitos). Creado por: Alejandro J. Mujica Fecha de creación: */ # ifndef FINITEFIELD_H # define FINITEFIELD_H # include # include /** Plantilla base para crear especializaciones de Campos de Galois. * * Contiene la interfaz que debe contener una clase particular de campo * para poder usarla con la clase que representa un número dentro de un campo. * * @tparam NumberT Tipo numérico que se va a restringir. * @tparam P Valor constante que define la característica del campo. * @tparam N Valor constante para la potencia a la cual se elevará la * característica que definirá el tamaño del campo. Por lo tanto, * el tamaño del campo estará definido por @f$P^N@f$. * * @pre NumberT debe ser un tipo de los enteros sin signo de la biblioteca * estándar de C++ * @pre P > 0 * @pre N >= 0 * * @see FiniteField2 FieldNumber */ template class FiniteField { static_assert(std::is_integral::value and std::is_unsigned::value, "First template argument is not an unsigned integral type"); static_assert(P > 0, "P must be greater than 0."); static_assert(N >= 0, "N must be greater or equal than 0."); NumberT field_size; public: using NumberType = NumberT; FiniteField() : field_size(positive_int_power(P, N)) { // Empty } /// Retorna la característica del campo. unsigned short characteristic() const { return P; } /// Retorna el valor de potencia al cual está elevada la característica. unsigned short power() const { return N; } /// Retorna la cardinalidad del campo. NumberT size() const { return field_size; } /// Retorna el máximo valor del campo. NumberT max_value() const { return field_size - 1; } /// Interfaz para la operación de suma de dos números dentro del campo. virtual NumberType sum(const NumberType &, const NumberType &) const = 0; /// Interfaz para la operación de resta de dos números dentro del campo. virtual NumberType sub(const NumberType &, const NumberType &) const = 0; /** Interfaz para la operación de multiplicación de dos números dentro del campo. */ virtual NumberType mul(const NumberType &, const NumberType &) const = 0; /// Interfaz para la operación de división de dos números dentro del campo. virtual NumberType div(const NumberType &, const NumberType &) const = 0; /// Interfaz para la operación que retorna el opuesto aditivo de un número. virtual NumberType op(const NumberType &) const = 0; /** Interfaz para la operación que retorna el inverso multiplicativo de un número. */ virtual NumberType inv(const NumberType &) const = 0; /** Genera un número aleatorio dentro del campo. * * @tparam RandomNumberGenerator Tipo de generador de números aleatorios. * * @pre RandomNumberGenerator debe ser un un tipo de generador de números * aleatorios de la biblioteca estándar de C++. * * @param rng Generador de números aleatorios. * @return Número aleatorio dentro del campo distribuido uniformemente. */ template NumberType get_random(RandomNumberGenerator & rng) const { std::uniform_int_distribution unif_dist(0, max_value()); return unif_dist(rng); } /** Trunca un número dentro del campo. * * @param n Número con cualquier valor. * @return número dentro del campo. */ NumberType operator () (const NumberType & n) { return n % field_size; } }; # endif // FINITEFIELD_H