Line data Source code
1 : /* Copyright (C) 2000-2003 The PARI group.
2 :
3 : This file is part of the PARI/GP package.
4 :
5 : PARI/GP is free software; you can redistribute it and/or modify it under the
6 : terms of the GNU General Public License as published by the Free Software
7 : Foundation; either version 2 of the License, or (at your option) any later
8 : version. It is distributed in the hope that it will be useful, but WITHOUT
9 : ANY WARRANTY WHATSOEVER.
10 :
11 : Check the License for details. You should have received a copy of it, along
12 : with the package; see the file 'COPYING'. If not, write to the Free Software
13 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
14 :
15 : #include "pari.h"
16 : #include "paripriv.h"
17 :
18 : /********************************************************************/
19 : /** **/
20 : /** MEMBER FUNCTIONS **/
21 : /** **/
22 : /********************************************************************/
23 : INLINE int
24 9562 : is_ell5(GEN x) {
25 : long lx;
26 9562 : if (typ(x) != t_VEC) return 0;
27 9177 : lx = lg(x);
28 9177 : return lx == 17 || (lx == 6 && !is_vec_t(typ(gel(x,2))));
29 : }
30 3444 : INLINE int is_ell(GEN x) {
31 3444 : long lx = lg(x);
32 3444 : return (typ(x) == t_VEC && lx == 17);
33 : }
34 :
35 : static void
36 7574 : member_err(const char *s, GEN y) { pari_err_TYPE(s,y); }
37 :
38 : GEN
39 203 : member_e(GEN x)
40 : {
41 203 : GEN y = get_prid(x);
42 203 : if (!y) member_err("e",x);
43 14 : return gel(y,3);
44 : }
45 :
46 : GEN
47 7329 : member_f(GEN x)
48 : {
49 7329 : GEN y = get_prid(x);
50 7329 : if (!y)
51 : {
52 294 : if (typ(x) == t_FFELT) return utoipos(FF_f(x));
53 168 : member_err("f",x);
54 : }
55 7035 : return gel(y,4);
56 : }
57 :
58 : GEN
59 98245 : member_p(GEN x)
60 : {
61 98245 : long t; GEN y = get_nf(x,&t);
62 98245 : if (y)
63 : {
64 28 : if (t == typ_RNF) return rnf_get_ramified_primes(x);
65 28 : return nf_get_ramified_primes(y);
66 : }
67 98217 : switch(t)
68 : {
69 7 : case typ_GAL: return gal_get_p(x);
70 196 : case typ_ELL: switch(ell_get_type(x))
71 : {
72 119 : case t_ELL_Fp:
73 119 : case t_ELL_Fq: return ellff_get_p(x);
74 7 : case t_ELL_Qp: return ellQp_get_p(x);
75 70 : default: member_err("p",x);
76 : }
77 7 : case typ_MODPR: x = get_prid(x);
78 97678 : case typ_PRID: return pr_get_p(x);
79 : }
80 336 : switch(typ(x)) {
81 63 : case t_PADIC: return gel(x,2);
82 175 : case t_FFELT: return FF_p_i(x);
83 : }
84 98 : member_err("p",x);
85 0 : return NULL;
86 : }
87 :
88 : GEN
89 210 : member_bid(GEN x)
90 : {
91 210 : long t; (void)get_nf(x,&t);
92 210 : switch(t) {
93 14 : case typ_BNR: return bnr_get_bid(x);
94 14 : case typ_BIDZ:
95 14 : case typ_BID: return x;
96 : }
97 182 : member_err("bid",x);
98 0 : return NULL;
99 : }
100 :
101 : GEN
102 203 : member_bnf(GEN x)
103 : {
104 203 : long t; GEN y = get_bnf(x,&t);
105 203 : if (!y) {
106 189 : if (t == typ_ELL && ell_get_type(x) == t_ELL_NF)
107 : {
108 0 : y = ellnf_get_bnf(x);
109 0 : if (y) return y;
110 : }
111 189 : member_err("bnf",x);
112 : }
113 14 : return y;
114 : }
115 :
116 : GEN
117 434 : member_nf(GEN x)
118 : {
119 434 : long t; GEN y = get_nf(x,&t);
120 434 : if (!y) {
121 371 : if (t == typ_RNF) return gel(x,10);
122 350 : if (t == typ_ELL && ell_get_type(x) == t_ELL_NF) return ellnf_get_nf(x);
123 168 : member_err("nf",x);
124 : }
125 63 : return y;
126 : }
127 :
128 : /* integral basis */
129 : GEN
130 245 : member_zk(GEN x)
131 : {
132 245 : long t; GEN y = get_nf(x,&t);
133 245 : if (!y)
134 : {
135 175 : switch(t)
136 : {
137 7 : case typ_Q:
138 7 : y = cgetg(3,t_VEC);
139 7 : gel(y,1) = gen_1;
140 7 : gel(y,2) = pol_x(varn(gel(x,1))); return y;
141 7 : case typ_RNF:
142 7 : return gel(x,7);
143 : }
144 161 : member_err("zk",x);
145 : }
146 70 : return nf_get_zk(y);
147 : }
148 :
149 : GEN
150 2744 : member_disc(GEN x) /* discriminant */
151 : {
152 2744 : long t; GEN y = get_nf(x,&t);
153 2744 : if (!y)
154 : {
155 2695 : switch(t)
156 : {
157 7 : case typ_Q : return quad_disc(x);
158 7 : case typ_QFB: return qfb_disc(x);
159 2492 : case typ_ELL: return ell_get_disc(x);
160 63 : case typ_RNF: return rnf_get_disc(x);
161 : }
162 126 : member_err("disc",x);
163 : }
164 49 : return nf_get_disc(y);
165 : }
166 :
167 : GEN
168 1974 : member_pol(GEN x) /* polynomial */
169 : {
170 1974 : long t; GEN y = get_nf(x,&t);
171 1974 : if (!y)
172 : {
173 1561 : switch(t)
174 : {
175 7 : case typ_POL: return x;
176 7 : case typ_Q : return deg1pol_shallow(gel(x,3), gel(x,2), varn(gel(x,1)));
177 308 : case typ_GAL: return gal_get_pol(x);
178 119 : case typ_RNF: return rnf_get_pol(x);
179 : }
180 1120 : if (typ(x)==t_POLMOD) return gel(x,2);
181 987 : if (typ(x)==t_FFELT) return FF_to_FpXQ(x);
182 119 : member_err("pol",x);
183 : }
184 413 : return nf_get_pol(y);
185 : }
186 :
187 : GEN
188 238 : member_polabs(GEN x)
189 : {
190 238 : long t; (void)get_nf(x,&t);
191 238 : if (t != typ_RNF) member_err("pol",x);
192 42 : return rnf_get_polabs(x);
193 : }
194 :
195 : GEN
196 8281 : member_mod(GEN x) /* modulus */
197 : {
198 8281 : long t; (void)get_nf(x,&t);
199 8281 : switch(t) {
200 7 : case typ_GAL: return gal_get_mod(x);
201 7035 : case typ_BNR: return bnr_get_mod(x);
202 0 : case typ_GCHAR: return gchar_get_mod(x);
203 749 : case typ_BIDZ: return bid_get_ideal(x);
204 14 : case typ_BID: return bid_get_mod(x);
205 : }
206 476 : switch(typ(x))
207 : {
208 70 : case t_INTMOD: case t_POLMOD: case t_QUAD: break;
209 7 : case t_PADIC: return gel(x,3);
210 273 : case t_FFELT: return FF_mod(x);
211 98 : case t_VEC:
212 98 : if (checkmf_i(x))
213 : {
214 7 : GEN T = mf_get_field(x), CHI = mf_get_CHI(x), P = mfcharpol(CHI);
215 7 : return (degpol(T) == 1)? P: (degpol(P) > 1? gmodulo(T, P): T);
216 : }
217 91 : else if (checkMF_i(x))
218 7 : return mfcharpol(MF_get_CHI(x));
219 112 : default: member_err("mod",x);
220 : }
221 70 : return gel(x,1);
222 : }
223 :
224 : GEN
225 609 : member_sign(GEN x) /* signature */
226 : {
227 609 : long t; GEN y = get_nf(x,&t);
228 609 : if (!y) member_err("sign",x);
229 84 : return gel(y,2);
230 : }
231 : GEN
232 203 : member_r1(GEN x) { return gel(member_sign(x), 1); }
233 : GEN
234 203 : member_r2(GEN x) { return gel(member_sign(x), 2); }
235 :
236 : GEN
237 210 : member_index(GEN x)
238 : {
239 210 : long t; GEN y = get_nf(x,&t);
240 210 : if (!y)
241 : {
242 175 : if (t == typ_RNF) return rnf_get_index(x);
243 168 : member_err("index",x);
244 : }
245 35 : return nf_get_index(y);
246 : }
247 :
248 : /* x assumed to be output by get_nf: ie a t_VEC with length 11 */
249 : static GEN
250 616 : nfmats(GEN x)
251 : {
252 : GEN y;
253 616 : if (!x) return NULL;
254 91 : y = gel(x,5);
255 91 : if (typ(y) == t_VEC && lg(y) < 8) return NULL;
256 91 : return y;
257 : }
258 :
259 : GEN
260 203 : member_t2(GEN x) /* T2 matrix */
261 : {
262 203 : long t; GEN y = nfmats(get_nf(x,&t));
263 203 : if (!y) member_err("t2",x);
264 28 : return gram_matrix(gel(y,2));
265 : }
266 :
267 : GEN
268 203 : member_diff(GEN x) /* different */
269 : {
270 203 : long t; GEN y = nfmats(get_nf(x,&t));
271 203 : if (!y) member_err("diff",x);
272 28 : return gel(y,5);
273 : }
274 :
275 : GEN
276 210 : member_codiff(GEN x) /* codifferent */
277 : {
278 : long t;
279 210 : GEN T, d, Di, nf = get_nf(x,&t), y = nfmats(nf);
280 210 : if (!y) member_err("codiff",x);
281 35 : T = gel(y,4);
282 35 : Di = ZM_inv(T, &d); if (!d) return matid(lg(Di)-1);
283 35 : return RgM_Rg_div(ZM_hnfmodid(Di, d), d);
284 : }
285 :
286 : GEN
287 231 : member_roots(GEN x) /* roots */
288 : {
289 231 : long t; GEN y = get_nf(x,&t);
290 231 : if (!y)
291 : {
292 203 : if (t == typ_GAL) return gal_get_roots(x);
293 196 : if (t == typ_ELL)
294 56 : switch(ell_get_type(x))
295 : {
296 21 : case t_ELL_Qp: return mkcol( ellQp_root(x, ellQp_get_prec(x)) );
297 21 : case t_ELL_Q:
298 21 : case t_ELL_Rg: return ellR_roots(x, ellR_get_prec(x));
299 : }
300 154 : member_err("roots",x);
301 : }
302 28 : return nf_get_roots(y);
303 : }
304 :
305 : /* assume x output by get_bnf: ie a t_VEC with length 10 */
306 : static GEN
307 357 : check_RES(GEN x, const char *s)
308 : {
309 357 : GEN y = gel(x,8);
310 357 : if (typ(y) != t_VEC || lg(y) < 4) member_err(s,x);
311 357 : return y;
312 : }
313 :
314 : /* y = get_bnf(x, &t) */
315 : static GEN
316 20335 : _member_clgp(GEN x, GEN y, long t) /* class group (3-component row vector) */
317 : {
318 20335 : if (!y)
319 : {
320 17731 : switch(t)
321 : {
322 4361 : case typ_QUA: return mkvec3(gel(x,1), gel(x,2), gel(x,3));
323 6041 : case typ_BIDZ:
324 6041 : case typ_BID: return gel(x,2);
325 : }
326 7329 : if (typ(x)==t_VEC)
327 7042 : switch(lg(x))
328 : {
329 6776 : case 3: /* no gen */
330 6776 : case 4: return x;
331 : }
332 553 : member_err("clgp",x);
333 : }
334 2604 : if (t==typ_BNR) return gel(x,5);
335 322 : y = check_RES(y, "clgp"); return gel(y,1);
336 : }
337 : static GEN
338 20335 : _check_clgp(GEN x, GEN y, long t)
339 20335 : { GEN c = _member_clgp(x,y,t); checkabgrp(c); return c; }
340 : GEN
341 273 : member_clgp(GEN x)
342 273 : { long t; GEN y = get_bnf(x,&t); return _check_clgp(x,y,t); }
343 :
344 : GEN
345 231 : member_reg(GEN x) /* regulator */
346 : {
347 231 : long t; GEN y = get_bnf(x,&t);
348 231 : if (!y)
349 : {
350 189 : if (t == typ_QUA) return gel(x,4);
351 182 : member_err("reg",x);
352 : }
353 42 : if (t == typ_BNR) pari_err_IMPL("ray regulator");
354 35 : y = check_RES(y, "reg");
355 35 : return gel(y,2);
356 : }
357 :
358 : GEN
359 252 : member_fu(GEN x) /* fundamental units */
360 : {
361 252 : long t; GEN fu, y = get_bnf(x,&t);
362 252 : if (!y)
363 : {
364 189 : switch(t)
365 : {
366 7 : case typ_Q:
367 7 : x = quad_disc(x);
368 7 : return (signe(x)<0)? cgetg(1,t_VEC): quadunit(x);
369 : }
370 182 : member_err("fu",x);
371 : }
372 63 : if (t == typ_BNR) pari_err_IMPL("ray units");
373 56 : fu = bnf_get_fu_nocheck(y);
374 56 : if (typ(fu) == t_MAT)
375 : { /*missing units*/
376 21 : GEN SUnits = bnf_get_sunits(y);
377 21 : if (!SUnits) return gen_0;
378 21 : fu = bnf_build_units(y);
379 21 : fu = vecslice(fu, 2, lg(fu)-1); /* remove torsion unit */
380 : }
381 56 : return matbasistoalg(y, fu);
382 : }
383 :
384 : /* torsion units. return [w,e] where w is the number of roots of 1, and e a
385 : * polmod (or integer) generator */
386 : GEN
387 217 : member_tu(GEN x)
388 : {
389 217 : long t; GEN bnf = get_bnf(x,&t), res = cgetg(3,t_VEC);
390 217 : if (!bnf)
391 : {
392 : GEN y;
393 189 : if (t != typ_Q) member_err("tu",x);
394 7 : y = quad_disc(x);
395 7 : if (signe(y) > 0 || abscmpiu(y,4) > 0) return mkvec2(gen_m1, gen_2);
396 :
397 7 : gel(res,1) = utoipos((itos(y) == -4)? 4: 6);
398 7 : gel(res,2) = gcopy(x);
399 : }
400 : else
401 : {
402 28 : GEN z = bnf_get_tuU(bnf);
403 28 : if (t == typ_BNR) pari_err_IMPL("ray torsion units");
404 21 : gel(res,1) = utoipos( bnf_get_tuN(bnf) );
405 21 : gel(res,2) = typ(z)==t_INT? gen_m1: basistoalg(bnf,z);
406 : }
407 28 : return res;
408 : }
409 :
410 : /* structure of (Z_K/m)^*, where x is an idealstarinit (with or without gen)
411 : * or a bnrinit (with or without gen) */
412 : GEN
413 203 : member_zkst(GEN x)
414 : {
415 203 : long t; (void)get_nf(x,&t);
416 203 : switch(t)
417 : {
418 14 : case typ_BIDZ:
419 14 : case typ_BID: return bid_get_grp(x);
420 7 : case typ_BNR: {
421 7 : GEN bid = bnr_get_bid(x);
422 7 : if (typ(bid) == t_VEC && lg(bid) > 2) return bid_get_grp(bid);
423 : }
424 : }
425 182 : member_err("zkst",x);
426 : return NULL; /* LCOV_EXCL_LINE */
427 : }
428 :
429 : GEN
430 3059 : member_no(GEN x) /* number of elements of a group (of type clgp) */
431 : {
432 3059 : pari_sp av = avma;
433 3059 : long t; GEN y = get_bnf(x,&t);
434 3059 : if (t == typ_ELL) switch(ell_get_type(x))
435 : {
436 14 : case t_ELL_Fp:
437 14 : case t_ELL_Fq: return ellcard(x, NULL);
438 : }
439 3045 : x = _check_clgp(x,y,t);
440 2891 : return gc_const(av, abgrp_get_no(x));
441 : }
442 :
443 : GEN
444 14798 : member_cyc(GEN x) /* cyclic decomposition (SNF) of a group (of type clgp) */
445 : {
446 14798 : pari_sp av = avma;
447 14798 : long t; GEN y = get_bnf(x,&t);
448 14798 : if (t == typ_ELL) switch(ell_get_type(x))
449 : {
450 14 : case t_ELL_Fp:
451 14 : case t_ELL_Fq: return ellgroup(x, NULL);
452 : }
453 14784 : if (t == typ_GCHAR)
454 140 : return gchar_get_cyc(x);
455 14644 : x = _check_clgp(x,y,t);
456 14483 : return gc_const(av, abgrp_get_cyc(x));
457 : }
458 :
459 : /* SNF generators of a group (of type clgp), or generators of a prime
460 : * ideal */
461 : GEN
462 2569 : member_gen(GEN x)
463 : {
464 : pari_sp av;
465 2569 : long t; GEN y = get_bnf(x,&t);
466 2569 : switch(t)
467 : {
468 7 : case typ_MODPR: x = get_prid(x);
469 70 : case typ_PRID: return mkvec2(gel(x,1), gel(x,2));
470 35 : case typ_GAL: return gal_get_gen(x);
471 70 : case typ_ELL: return ellgenerators(x);
472 2275 : case typ_NULL:
473 2275 : if (typ(x)==t_FFELT) return FF_gen(x);
474 2254 : break;
475 : }
476 2373 : av = avma;
477 2373 : x = _check_clgp(x,y,t);
478 2275 : if (lg(x)!=4) member_err("gen",x);
479 2261 : return gc_const(av, abgrp_get_gen(x));
480 : }
481 : GEN
482 448 : member_group(GEN x)
483 : {
484 448 : long t; (void)get_nf(x,&t);
485 448 : if (t == typ_GAL) return gal_get_group(x);
486 308 : if (t == typ_ELL) return ellgroup0(x, NULL, 1);
487 168 : member_err("group",x);
488 : return NULL; /* LCOV_EXCL_LINE */
489 : }
490 : GEN
491 203 : member_orders(GEN x)
492 : {
493 203 : long t; (void)get_nf(x,&t);
494 203 : if (t == typ_GAL) return gal_get_orders(x);
495 196 : member_err("orders",x);
496 : return NULL; /* LCOV_EXCL_LINE */
497 : }
498 :
499 : GEN
500 1918 : member_a1(GEN x)
501 : {
502 1918 : if (!is_ell5(x)) member_err("a1",x);
503 1750 : return ell_get_a1(x);
504 : }
505 :
506 : GEN
507 1911 : member_a2(GEN x)
508 : {
509 1911 : if (!is_ell5(x)) member_err("a2",x);
510 1743 : return ell_get_a2(x);
511 : }
512 :
513 : GEN
514 1911 : member_a3(GEN x)
515 : {
516 1911 : if (!is_ell5(x)) member_err("a3",x);
517 1743 : return ell_get_a3(x);
518 : }
519 :
520 : GEN
521 1911 : member_a4(GEN x)
522 : {
523 1911 : if (!is_ell5(x)) member_err("a4",x);
524 1743 : return ell_get_a4(x);
525 : }
526 :
527 : GEN
528 1911 : member_a6(GEN x)
529 : {
530 1911 : if (!is_ell5(x)) member_err("a6",x);
531 1743 : return ell_get_a6(x);
532 : }
533 :
534 : GEN
535 203 : member_b2(GEN x)
536 : {
537 203 : if (!is_ell(x)) member_err("b2",x);
538 28 : return ell_get_b2(x);
539 : }
540 :
541 : GEN
542 203 : member_b4(GEN x)
543 : {
544 203 : if (!is_ell(x)) member_err("b4",x);
545 28 : return ell_get_b4(x);
546 : }
547 :
548 : GEN
549 203 : member_b6(GEN x)
550 : {
551 203 : if (!is_ell(x)) member_err("b6",x);
552 28 : return ell_get_b6(x);
553 : }
554 :
555 : GEN
556 203 : member_b8(GEN x)
557 : {
558 203 : if (!is_ell(x)) member_err("b8",x);
559 28 : return ell_get_b8(x);
560 : }
561 :
562 : GEN
563 210 : member_c4(GEN x)
564 : {
565 210 : if (!is_ell(x)) member_err("c4",x);
566 35 : return ell_get_c4(x);
567 : }
568 :
569 : GEN
570 210 : member_c6(GEN x)
571 : {
572 210 : if (!is_ell(x)) member_err("c6",x);
573 35 : return ell_get_c6(x);
574 : }
575 :
576 : GEN
577 1120 : member_j(GEN x)
578 : {
579 1120 : if (!is_ell(x)) member_err("j",x);
580 945 : return ell_get_j(x);
581 : }
582 :
583 : static int
584 182 : ell_is_complex(GEN x)
585 182 : { long t = ell_get_type(x); return t == t_ELL_Q || t == t_ELL_Rg; }
586 :
587 : static long
588 98 : ellnf_get_prec(GEN x) { return nf_get_prec(ellnf_get_nf(x)); }
589 :
590 : GEN
591 287 : member_omega(GEN x)
592 : {
593 287 : if (!is_ell(x)) member_err("omega",x);
594 112 : if (ell_get_type(x)==t_ELL_NF)
595 35 : return ellnf_vecomega(x, ellnf_get_prec(x));
596 77 : if (!ell_is_complex(x)) pari_err_TYPE("omega [not defined over C]",x);
597 42 : return ellR_omega(x, ellR_get_prec(x));
598 : }
599 :
600 : GEN
601 266 : member_eta(GEN x)
602 : {
603 266 : if (!is_ell(x)) member_err("eta",x);
604 91 : if (ell_get_type(x)==t_ELL_NF)
605 28 : return ellnf_veceta(x, ellnf_get_prec(x));
606 63 : if (!ell_is_complex(x)) pari_err_TYPE("eta [not defined over C]",x);
607 35 : return ellR_eta(x, ellR_get_prec(x));
608 : }
609 :
610 : GEN
611 252 : member_area(GEN x)
612 : {
613 252 : if (!is_ell(x)) member_err("area",x);
614 77 : if (ell_get_type(x)==t_ELL_NF)
615 35 : return ellnf_vecarea(x, ellnf_get_prec(x));
616 42 : if (!ell_is_complex(x)) pari_err_TYPE("area [not defined over C]",x);
617 14 : return ellR_area(x, ellR_get_prec(x));
618 : }
619 :
620 : GEN
621 287 : member_tate(GEN x)
622 : {
623 : long prec;
624 287 : if (!is_ell(x)) member_err("tate",x);
625 112 : if (ell_get_type(x) != t_ELL_Qp)
626 28 : pari_err_TYPE("tate [not defined over Qp]",x);
627 84 : prec = ellQp_get_prec(x);
628 84 : return ellQp_Tate_uniformization(x, prec);
629 : }
|