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