/*============================================================================= This file is part of FLINT. FLINT is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. FLINT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with FLINT; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =============================================================================*/ /****************************************************************************** Copyright (C) 2011 Sebastian Pancratz ******************************************************************************/ #ifndef PERM_H #define PERM_H #undef ulong #define ulong ulongxx /* interferes with system includes */ #include #include #undef ulong #include #define ulong mp_limb_t #include "flint.h" #ifdef __cplusplus extern "C" { #endif /* Memory management *********************************************************/ static __inline__ slong * _perm_init(slong n) { slong i, *vec; vec = (slong *) flint_malloc(n * sizeof(slong)); if (!vec) { flint_printf("ERROR (_perm_init).\n\n"); abort(); } for (i = 0; i < n; i++) vec[i] = i; return vec; } static __inline__ void _perm_clear(slong * vec) { flint_free(vec); } /* Assignment ****************************************************************/ static __inline__ slong _perm_equal(const slong *vec1, const slong *vec2, slong n) { slong i; for (i = 0; i < n; i++) if (vec1[i] != vec2[i]) return 0; return 1; } static __inline__ void _perm_set(slong *res, const slong *vec, slong n) { slong i; for (i = 0; i < n; i++) res[i] = vec[i]; } static __inline__ void _perm_set_one(slong *vec, slong n) { slong i; for (i = 0; i < n; i++) vec[i] = i; } static __inline__ void _perm_inv(slong *res, const slong *vec, slong n) { slong i; if (res == vec) { slong *t = (slong *) flint_malloc(n * sizeof(slong)); if (!t) { flint_printf("ERROR (_perm_inv).\n\n"); abort(); } for (i = 0; i < n; i++) t[i] = vec[i]; for (i = 0; i < n; i++) res[t[i]] = i; flint_free(t); } else { for (i = 0; i < n; i++) res[vec[i]] = i; } } /* Composition ***************************************************************/ static __inline__ void _perm_compose(slong *res, const slong *vec1, const slong *vec2, slong n) { slong i; if (res == vec1) { slong *t = (slong *) flint_malloc(n * sizeof(slong)); for (i = 0; i < n; i++) t[i] = vec1[i]; for (i = 0; i < n; i++) res[i] = t[vec2[i]]; flint_free(t); } else { for (i = 0; i < n; i++) res[i] = vec1[vec2[i]]; } } /* Randomisation *************************************************************/ int _perm_randtest(slong * vec, slong n, flint_rand_t state); /* Parity ********************************************************************/ int _perm_parity(const slong * vec, slong n); /* Input and output **********************************************************/ static __inline__ int _long_vec_print(const slong * vec, slong len) { slong i; flint_printf("%wd", len); if (len > 0) { flint_printf(" "); for (i = 0; i < len; i++) flint_printf(" %wd", vec[i]); } return 1; } static __inline__ int _perm_print(const slong * vec, slong n) { slong i; flint_printf("%wd", n); if (n > 0) { flint_printf(" "); for (i = 0; i < n; i++) flint_printf(" %wd", vec[i]); } return 1; } #ifdef __cplusplus } #endif #endif