-
Notifications
You must be signed in to change notification settings - Fork 142
/
fmpzi.h
211 lines (170 loc) · 4.84 KB
/
fmpzi.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/*
Copyright (C) 2022 Fredrik Johansson
This file is part of Arb.
Arb is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License (LGPL) as published
by the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version. See <http://www.gnu.org/licenses/>.
*/
#ifndef FMPZI_H
#define FMPZI_H
#ifdef FMPZI_INLINES_C
#define FMPZI_INLINE
#else
#define FMPZI_INLINE static __inline__
#endif
#include "flint/fmpz.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
fmpz a;
fmpz b;
}
fmpzi_struct;
typedef fmpzi_struct fmpzi_t[1];
#define fmpzi_realref(x) (&((x)->a))
#define fmpzi_imagref(x) (&((x)->b))
FMPZI_INLINE void
fmpzi_init(fmpzi_t x)
{
fmpz_init(fmpzi_realref(x));
fmpz_init(fmpzi_imagref(x));
}
FMPZI_INLINE void
fmpzi_clear(fmpzi_t x)
{
fmpz_clear(fmpzi_realref(x));
fmpz_clear(fmpzi_imagref(x));
}
FMPZI_INLINE int
fmpzi_equal(const fmpzi_t x, const fmpzi_t y)
{
return fmpz_equal(fmpzi_realref(x), fmpzi_realref(y)) &&
fmpz_equal(fmpzi_imagref(x), fmpzi_imagref(y));
}
FMPZI_INLINE void
fmpzi_zero(fmpzi_t x)
{
fmpz_zero(fmpzi_realref(x));
fmpz_zero(fmpzi_imagref(x));
}
FMPZI_INLINE void
fmpzi_one(fmpzi_t x)
{
fmpz_one(fmpzi_realref(x));
fmpz_zero(fmpzi_imagref(x));
}
FMPZI_INLINE void
fmpzi_set(fmpzi_t res, const fmpzi_t x)
{
fmpz_set(fmpzi_realref(res), fmpzi_realref(x));
fmpz_set(fmpzi_imagref(res), fmpzi_imagref(x));
}
FMPZI_INLINE void
fmpzi_conj(fmpzi_t res, const fmpzi_t x)
{
fmpz_set(fmpzi_realref(res), fmpzi_realref(x));
fmpz_neg(fmpzi_imagref(res), fmpzi_imagref(x));
}
FMPZI_INLINE void
fmpzi_swap(fmpzi_t x, fmpzi_t y)
{
fmpzi_struct t;
t = *x;
*x = *y;
*y = t;
}
FMPZI_INLINE void
fmpzi_print(const fmpzi_t x)
{
fmpz_print(fmpzi_realref(x));
if (fmpz_sgn(fmpzi_imagref(x)) >= 0)
flint_printf("+");
fmpz_print(fmpzi_imagref(x));
flint_printf("*I");
}
FMPZI_INLINE void
fmpzi_set_si_si(fmpzi_t res, slong a, slong b)
{
fmpz_set_si(fmpzi_realref(res), a);
fmpz_set_si(fmpzi_imagref(res), b);
}
FMPZI_INLINE void
fmpzi_randtest(fmpzi_t res, flint_rand_t state, mp_bitcnt_t bits)
{
fmpz_randtest(fmpzi_realref(res), state, bits);
fmpz_randtest(fmpzi_imagref(res), state, bits);
}
/* Special values */
FMPZI_INLINE int
fmpzi_is_unit(const fmpzi_t x)
{
if (fmpz_is_zero(fmpzi_imagref(x)))
return fmpz_is_pm1(fmpzi_realref(x));
if (fmpz_is_zero(fmpzi_realref(x)))
return fmpz_is_pm1(fmpzi_imagref(x));
return 0;
}
FMPZI_INLINE int fmpzi_is_zero(const fmpzi_t x)
{
return fmpz_is_zero(fmpzi_realref(x)) && fmpz_is_zero(fmpzi_imagref(x));
}
FMPZI_INLINE int fmpzi_is_one(const fmpzi_t x)
{
return fmpz_is_one(fmpzi_realref(x)) && fmpz_is_zero(fmpzi_imagref(x));
}
/* Norms */
slong fmpzi_bits(const fmpzi_t x);
FMPZI_INLINE void fmpzi_norm(fmpz_t res, const fmpzi_t x)
{
fmpz_fmma(res, fmpzi_realref(x), fmpzi_realref(x), fmpzi_imagref(x), fmpzi_imagref(x));
}
/* Arithmetic */
FMPZI_INLINE void
fmpzi_neg(fmpzi_t res, const fmpzi_t x)
{
fmpz_neg(fmpzi_realref(res), fmpzi_realref(x));
fmpz_neg(fmpzi_imagref(res), fmpzi_imagref(x));
}
FMPZI_INLINE void
fmpzi_add(fmpzi_t res, const fmpzi_t x, const fmpzi_t y)
{
fmpz_add(fmpzi_realref(res), fmpzi_realref(x), fmpzi_realref(y));
fmpz_add(fmpzi_imagref(res), fmpzi_imagref(x), fmpzi_imagref(y));
}
FMPZI_INLINE void
fmpzi_sub(fmpzi_t res, const fmpzi_t x, const fmpzi_t y)
{
fmpz_sub(fmpzi_realref(res), fmpzi_realref(x), fmpzi_realref(y));
fmpz_sub(fmpzi_imagref(res), fmpzi_imagref(x), fmpzi_imagref(y));
}
void fmpzi_sqr(fmpzi_t res, const fmpzi_t x);
void fmpzi_mul(fmpzi_t res, const fmpzi_t x, const fmpzi_t y);
void fmpzi_pow_ui(fmpzi_t res, const fmpzi_t x, ulong exp);
void fmpzi_mul_i(fmpzi_t z, const fmpzi_t x);
void fmpzi_div_i(fmpzi_t z, const fmpzi_t x);
void fmpzi_mul_i_pow_si(fmpzi_t res, const fmpzi_t z, slong k);
/* todo */
slong fmpzi_canonical_unit_i_pow(const fmpzi_t x);
FMPZI_INLINE void
fmpzi_canonicalise_unit(fmpzi_t res, const fmpzi_t x)
{
fmpzi_mul_i_pow_si(res, x, fmpzi_canonical_unit_i_pow(x));
}
/* Division */
void fmpzi_divrem(fmpzi_t q, fmpzi_t r, const fmpzi_t x, const fmpzi_t y);
void fmpzi_divrem_approx(fmpzi_t q, fmpzi_t r, const fmpzi_t x, const fmpzi_t y);
void fmpzi_divexact(fmpzi_t q, const fmpzi_t x, const fmpzi_t y);
slong fmpzi_remove_one_plus_i(fmpzi_t res, const fmpzi_t x);
/* GCD */
void fmpzi_gcd_euclidean(fmpzi_t res, const fmpzi_t x, const fmpzi_t y);
void fmpzi_gcd_euclidean_improved(fmpzi_t res, const fmpzi_t x, const fmpzi_t y);
void fmpzi_gcd_binary(fmpzi_t res, const fmpzi_t x, const fmpzi_t y);
void fmpzi_gcd_shortest(fmpzi_t g, const fmpzi_t x, const fmpzi_t y);
void fmpzi_gcd(fmpzi_t g, const fmpzi_t x, const fmpzi_t y);
#ifdef __cplusplus
}
#endif
#endif