Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-07 10:15:17

0001 /*
0002     Copyright (C) 2022 Fredrik Johansson
0003 
0004     This file is part of FLINT.
0005 
0006     FLINT is free software: you can redistribute it and/or modify it under
0007     the terms of the GNU Lesser General Public License (LGPL) as published
0008     by the Free Software Foundation; either version 3 of the License, or
0009     (at your option) any later version.  See <https://www.gnu.org/licenses/>.
0010 */
0011 
0012 #ifndef FMPZI_H
0013 #define FMPZI_H
0014 
0015 #ifdef FMPZI_INLINES_C
0016 #define FMPZI_INLINE
0017 #else
0018 #define FMPZI_INLINE static inline
0019 #endif
0020 
0021 #include "fmpz.h"
0022 
0023 #ifdef __cplusplus
0024 extern "C" {
0025 #endif
0026 
0027 #define fmpzi_realref(x) (&((x)->a))
0028 #define fmpzi_imagref(x) (&((x)->b))
0029 
0030 FMPZI_INLINE void
0031 fmpzi_init(fmpzi_t x)
0032 {
0033     fmpz_init(fmpzi_realref(x));
0034     fmpz_init(fmpzi_imagref(x));
0035 }
0036 
0037 FMPZI_INLINE void
0038 fmpzi_clear(fmpzi_t x)
0039 {
0040     fmpz_clear(fmpzi_realref(x));
0041     fmpz_clear(fmpzi_imagref(x));
0042 }
0043 
0044 FMPZI_INLINE int
0045 fmpzi_equal(const fmpzi_t x, const fmpzi_t y)
0046 {
0047     return fmpz_equal(fmpzi_realref(x), fmpzi_realref(y)) &&
0048            fmpz_equal(fmpzi_imagref(x), fmpzi_imagref(y));
0049 }
0050 
0051 FMPZI_INLINE void
0052 fmpzi_zero(fmpzi_t x)
0053 {
0054     fmpz_zero(fmpzi_realref(x));
0055     fmpz_zero(fmpzi_imagref(x));
0056 }
0057 
0058 FMPZI_INLINE void
0059 fmpzi_one(fmpzi_t x)
0060 {
0061     fmpz_one(fmpzi_realref(x));
0062     fmpz_zero(fmpzi_imagref(x));
0063 }
0064 
0065 FMPZI_INLINE void
0066 fmpzi_set(fmpzi_t res, const fmpzi_t x)
0067 {
0068     fmpz_set(fmpzi_realref(res), fmpzi_realref(x));
0069     fmpz_set(fmpzi_imagref(res), fmpzi_imagref(x));
0070 }
0071 
0072 FMPZI_INLINE void
0073 fmpzi_conj(fmpzi_t res, const fmpzi_t x)
0074 {
0075     fmpz_set(fmpzi_realref(res), fmpzi_realref(x));
0076     fmpz_neg(fmpzi_imagref(res), fmpzi_imagref(x));
0077 }
0078 
0079 FMPZI_INLINE void
0080 fmpzi_swap(fmpzi_t x, fmpzi_t y)
0081 {
0082     FLINT_SWAP(fmpzi_struct, *x, *y);
0083 }
0084 
0085 void fmpzi_print(const fmpzi_t x);
0086 
0087 FMPZI_INLINE void
0088 fmpzi_set_si_si(fmpzi_t res, slong a, slong b)
0089 {
0090     fmpz_set_si(fmpzi_realref(res), a);
0091     fmpz_set_si(fmpzi_imagref(res), b);
0092 }
0093 
0094 FMPZI_INLINE void
0095 fmpzi_randtest(fmpzi_t res, flint_rand_t state, flint_bitcnt_t bits)
0096 {
0097     fmpz_randtest(fmpzi_realref(res), state, bits);
0098     fmpz_randtest(fmpzi_imagref(res), state, bits);
0099 }
0100 
0101 /* Special values */
0102 
0103 FMPZI_INLINE int
0104 fmpzi_is_unit(const fmpzi_t x)
0105 {
0106     if (fmpz_is_zero(fmpzi_imagref(x)))
0107         return fmpz_is_pm1(fmpzi_realref(x));
0108     if (fmpz_is_zero(fmpzi_realref(x)))
0109         return fmpz_is_pm1(fmpzi_imagref(x));
0110     return 0;
0111 }
0112 
0113 FMPZI_INLINE int fmpzi_is_zero(const fmpzi_t x)
0114 {
0115     return fmpz_is_zero(fmpzi_realref(x)) && fmpz_is_zero(fmpzi_imagref(x));
0116 }
0117 
0118 FMPZI_INLINE int fmpzi_is_one(const fmpzi_t x)
0119 {
0120     return fmpz_is_one(fmpzi_realref(x)) && fmpz_is_zero(fmpzi_imagref(x));
0121 }
0122 
0123 /* Norms */
0124 
0125 slong fmpzi_bits(const fmpzi_t x);
0126 
0127 FMPZI_INLINE void fmpzi_norm(fmpz_t res, const fmpzi_t x)
0128 {
0129     fmpz_fmma(res, fmpzi_realref(x), fmpzi_realref(x), fmpzi_imagref(x), fmpzi_imagref(x));
0130 }
0131 
0132 /* Arithmetic */
0133 
0134 FMPZI_INLINE void
0135 fmpzi_neg(fmpzi_t res, const fmpzi_t x)
0136 {
0137     fmpz_neg(fmpzi_realref(res), fmpzi_realref(x));
0138     fmpz_neg(fmpzi_imagref(res), fmpzi_imagref(x));
0139 }
0140 
0141 FMPZI_INLINE void
0142 fmpzi_add(fmpzi_t res, const fmpzi_t x, const fmpzi_t y)
0143 {
0144     fmpz_add(fmpzi_realref(res), fmpzi_realref(x), fmpzi_realref(y));
0145     fmpz_add(fmpzi_imagref(res), fmpzi_imagref(x), fmpzi_imagref(y));
0146 }
0147 
0148 FMPZI_INLINE void
0149 fmpzi_sub(fmpzi_t res, const fmpzi_t x, const fmpzi_t y)
0150 {
0151     fmpz_sub(fmpzi_realref(res), fmpzi_realref(x), fmpzi_realref(y));
0152     fmpz_sub(fmpzi_imagref(res), fmpzi_imagref(x), fmpzi_imagref(y));
0153 }
0154 
0155 void fmpzi_sqr(fmpzi_t res, const fmpzi_t x);
0156 void fmpzi_mul(fmpzi_t res, const fmpzi_t x, const fmpzi_t y);
0157 void fmpzi_pow_ui(fmpzi_t res, const fmpzi_t x, ulong exp);
0158 
0159 void fmpzi_mul_i(fmpzi_t z, const fmpzi_t x);
0160 void fmpzi_div_i(fmpzi_t z, const fmpzi_t x);
0161 void fmpzi_mul_i_pow_si(fmpzi_t res, const fmpzi_t z, slong k);
0162 
0163 /* todo */
0164 slong fmpzi_canonical_unit_i_pow(const fmpzi_t x);
0165 
0166 FMPZI_INLINE void
0167 fmpzi_canonicalise_unit(fmpzi_t res, const fmpzi_t x)
0168 {
0169     fmpzi_mul_i_pow_si(res, x, fmpzi_canonical_unit_i_pow(x));
0170 }
0171 
0172 /* Division */
0173 void fmpzi_divrem(fmpzi_t q, fmpzi_t r, const fmpzi_t x, const fmpzi_t y);
0174 void fmpzi_divrem_approx(fmpzi_t q, fmpzi_t r, const fmpzi_t x, const fmpzi_t y);
0175 
0176 void fmpzi_divexact(fmpzi_t q, const fmpzi_t x, const fmpzi_t y);
0177 
0178 slong fmpzi_remove_one_plus_i(fmpzi_t res, const fmpzi_t x);
0179 
0180 /* GCD */
0181 void fmpzi_gcd_euclidean(fmpzi_t res, const fmpzi_t x, const fmpzi_t y);
0182 void fmpzi_gcd_euclidean_improved(fmpzi_t res, const fmpzi_t x, const fmpzi_t y);
0183 void fmpzi_gcd_binary(fmpzi_t res, const fmpzi_t x, const fmpzi_t y);
0184 void fmpzi_gcd_shortest(fmpzi_t g, const fmpzi_t x, const fmpzi_t y);
0185 void fmpzi_gcd(fmpzi_t g, const fmpzi_t x, const fmpzi_t y);
0186 
0187 /* Primality check */
0188 int fmpzi_is_prime(const fmpzi_t n);
0189 int fmpzi_is_probabprime(const fmpzi_t n);
0190 
0191 #ifdef __cplusplus
0192 }
0193 #endif
0194 
0195 #endif