File: gp2c.html

package info (click to toggle)
gp2c 0.0.12-2
  • links: PTS
  • area: main
  • in suites: bullseye
  • size: 2,916 kB
  • sloc: ansic: 8,592; sh: 1,606; lex: 346; yacc: 226; makefile: 107
file content (647 lines) | stat: -rw-r--r-- 60,597 bytes parent folder | download
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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
<!DOCTYPE html>
<html >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<meta name="generator" content="hevea 2.32">
<style type="text/css">
.li-itemize{margin:1ex 0ex;}
.li-enumerate{margin:1ex 0ex;}
.dd-description{margin:0ex 0ex 1ex 4ex;}
.dt-description{margin:0ex;}
.toc{list-style:none;}
.footnotetext{margin:0ex; padding:0ex;}
div.footnotetext P{margin:0px; text-indent:1em;}
.thefootnotes{text-align:left;margin:0ex;}
.dt-thefootnotes{margin:0em;}
.dd-thefootnotes{margin:0em 0em 0em 2em;}
.footnoterule{margin:1em auto 1em 0px;width:50%;}
.caption{padding-left:2ex; padding-right:2ex; margin-left:auto; margin-right:auto}
.title{margin:2ex auto;text-align:center}
.titlemain{margin:1ex 2ex 2ex 1ex;}
.titlerest{margin:0ex 2ex;}
.center{text-align:center;margin-left:auto;margin-right:auto;}
.flushleft{text-align:left;margin-left:0ex;margin-right:auto;}
.flushright{text-align:right;margin-left:auto;margin-right:0ex;}
div table{margin-left:inherit;margin-right:inherit;margin-bottom:2px;margin-top:2px}
td table{margin:auto;}
table{border-collapse:collapse;}
td{padding:0;}
.cellpadding0 tr td{padding:0;}
.cellpadding1 tr td{padding:1px;}
pre{text-align:left;margin-left:0ex;margin-right:auto;}
blockquote{margin-left:4ex;margin-right:4ex;text-align:left;}
td p{margin:0px;}
.boxed{border:1px solid black}
.textboxed{border:1px solid black}
.vbar{border:none;width:2px;background-color:black;}
.hbar{border:none;height:2px;width:100%;background-color:black;}
.hfill{border:none;height:1px;width:200%;background-color:black;}
.vdisplay{border-collapse:separate;border-spacing:2px;width:auto; empty-cells:show; border:2px solid red;}
.vdcell{white-space:nowrap;padding:0px; border:2px solid green;}
.display{border-collapse:separate;border-spacing:2px;width:auto; border:none;}
.dcell{white-space:nowrap;padding:0px; border:none;}
.dcenter{margin:0ex auto;}
.vdcenter{border:solid #FF8000 2px; margin:0ex auto;}
.minipage{text-align:left; margin-left:0em; margin-right:auto;}
.marginpar{border:solid thin black; width:20%; text-align:left;}
.marginparleft{float:left; margin-left:0ex; margin-right:1ex;}
.marginparright{float:right; margin-left:1ex; margin-right:0ex;}
.theorem{text-align:left;margin:1ex auto 1ex 0ex;}
.part{margin:2ex auto;text-align:center}
</style>
<title>An introduction to gp2c
</title>
</head>
<body >
<!--HEVEA command line is: /usr/bin/hevea -fix ./gp2c.tex -->
<!--CUT STYLE article--><!--CUT DEF section 1 --><table class="title"><tr><td style="padding:1ex"><h1 class="titlemain">An introduction to <span style="font-family:monospace">gp2c</span></h1><h3 class="titlerest">By Bill Allombert and Ariel Pacetti</h3></td></tr>
</table><!--TOC section id="sec1" Contents-->
<h2 id="sec1" class="section">Contents</h2><!--SEC END --><ul class="toc"><li class="li-toc">
<a href="#sec2">1What is <span style="font-family:monospace">gp2c</span>?</a>
<ul class="toc"><li class="li-toc">
<a href="#sec3">1.1Installing <span style="font-family:monospace">gp2c</span></a>
</li></ul>
</li><li class="li-toc"><a href="#sec4">2A <span style="font-family:monospace">gp2c</span> tutorial</a>
<ul class="toc"><li class="li-toc">
<a href="#sec5">2.1How can I compile and run my scripts?</a>
</li><li class="li-toc"><a href="#sec6">2.2How can I compile directly with <span style="font-family:monospace">gp2c</span>?</a>
</li><li class="li-toc"><a href="#sec7">2.3Using <span style="font-family:monospace">gp2c</span> to find errors in GP scripts</a>
</li><li class="li-toc"><a href="#sec8">2.4Using compiled functions in a new program</a>
</li><li class="li-toc"><a href="#sec9">2.5Hand-editing the C file generated by <span style="font-family:monospace">gp2c</span></a>
</li></ul>
</li><li class="li-toc"><a href="#sec10">3Advanced use of <span style="font-family:monospace">gp2c</span></a>
<ul class="toc"><li class="li-toc">
<a href="#sec11">3.1<span style="font-family:monospace">gp2c</span> types</a>
</li><li class="li-toc"><a href="#sec12">3.2Type declaration</a>
</li><li class="li-toc"><a href="#sec13">3.3Effect of types declaration on default values</a>
</li><li class="li-toc"><a href="#sec14">3.4Type casting</a>
</li><li class="li-toc"><a href="#sec15">3.5Example of optimisation</a>
</li><li class="li-toc"><a href="#sec16">3.6Types and member functions</a>
</li></ul>
</li><li class="li-toc"><a href="#sec17">4Common problems</a>
<ul class="toc"><li class="li-toc">
<a href="#sec18">4.1Meta-commands.</a>
</li><li class="li-toc"><a href="#sec19">4.2Unsupported functions.</a>
</li><li class="li-toc"><a href="#sec20">4.3Dynamically-scoped local variables.</a>
</li><li class="li-toc"><a href="#sec21">4.4Memory handling and global variables.</a>
</li><li class="li-toc"><a href="#sec22">4.5Support for <span style="font-family:sans-serif">t_VECSMALL</span></a>
</li><li class="li-toc"><a href="#sec23">4.6GP lists</a>
</li><li class="li-toc"><a href="#sec24">4.7The <span style="font-style:italic">install</span> command</a>
</li><li class="li-toc"><a href="#sec25">4.8What about <span style="font-family:sans-serif">main()</span> ?</a>
</li></ul>
</li><li class="li-toc"><a href="#sec26">5Command-line options of <span style="font-family:monospace">gp2c</span></a>
</li></ul>
<!--TOC section id="sec2" What is <span style="font-family:monospace">gp2c</span>?-->
<h2 id="sec2" class="section">1What is <span style="font-family:monospace">gp2c</span>?</h2><!--SEC END --><p>The <span style="font-family:monospace">gp2c</span> compiler is a package for translating GP routines into the C
programming language, so that they can be compiled and used with the
<a href="http://pari.math.u-bordeaux.fr">PARI</a> system or the GP calculator.</p><p>The main advantage of doing this is to speed up computations and
to include your own routines within the preexisting GP ones. It may also
find bugs in GP scripts.</p><p>This package (including the latest versions) can be obtained at the
URL:<br>
<a href="http://pari.math.u-bordeaux.fr/download.html#gp2c"><span style="font-family:monospace">http://pari.math.u-bordeaux.fr/download.html#gp2c</span></a></p>
<!--TOC subsection id="sec3" Installing <span style="font-family:monospace">gp2c</span>-->
<h3 id="sec3" class="subsection">1.1Installing <span style="font-family:monospace">gp2c</span></h3><!--SEC END --><p>After downloading the file <span style="font-family:monospace">gp2c-</span><span style="font-family:monospace"><em>x.y.z</em></span><span style="font-family:monospace">pl</span><span style="font-family:monospace"><em>t</em></span><span style="font-family:monospace">.tar.gz</span> (where
<em>x,y,z</em> and <em>t</em> depend on the version), you first have to unzip the
file with the command:</p><p><span style="font-weight:bold">gunzip gp2c-</span><span style="font-weight:bold"><em>x.y.z</em></span><span style="font-weight:bold">pl</span><span style="font-weight:bold"><em>t</em></span><span style="font-weight:bold">.tar.gz</span></p><p>This will create the new file <span style="font-family:monospace">gp2c-</span><span style="font-family:monospace"><em>x.y.z</em></span><span style="font-family:monospace">pl</span><span style="font-family:monospace"><em>t</em></span><span style="font-family:monospace">.tar</span>.
Next you have to extract the files with the <span style="font-weight:bold">tar</span> program:</p><p><span style="font-weight:bold">tar -xvf gp2c-</span><span style="font-weight:bold"><em>x.y.z</em></span><span style="font-weight:bold">pl</span><span style="font-weight:bold"><em>t</em></span><span style="font-weight:bold">.tar</span></p><p>Note: You can do both steps at once with GNU <span style="font-weight:bold">tar</span> by using the command:</p><p><span style="font-weight:bold">tar -zxvf gp2c-</span><span style="font-weight:bold"><em>x.y.z</em></span><span style="font-weight:bold">pl</span><span style="font-weight:bold"><em>t</em></span><span style="font-weight:bold">.tar.gz</span></p><p>This creates a directory <span style="font-family:monospace">gp2c-</span><span style="font-family:monospace"><em>x.y.z</em></span><span style="font-family:monospace">pl</span><span style="font-family:monospace"><em>t</em></span>, which contains the
main <span style="font-family:monospace">gp2c</span> files. Now you have to install the program.</p><p>You need the file <span style="font-family:monospace">pari.cfg</span>. This file can be found in the PARI object
directory and is installed in $prefix/lib/pari/.</p><p>Copy or link this file in the <span style="font-family:monospace">gp2c</span> directory, be sure to call it
<span style="font-family:monospace">pari.cfg</span>.</p><p><span style="font-weight:bold">ln -s .../lib/pari/pari.cfg pari.cfg</span></p><p>Run <span style="font-weight:bold">./configure</span>, which will search for the PARI version and some
other configuration tools of the system. To install the program, type
<span style="font-weight:bold">make</span>, and the program will be compiled. You can then run <span style="font-weight:bold">make check</span> to verify that everything has gone fine (a bunch of OK&#X2019;s should show up).
All of this is completely standard, and you are now ready to use <span style="font-family:monospace">gp2c</span>.</p><p>You can use <span style="font-family:monospace">gp2c</span> directly from this directory or you can install it by
running <span style="font-weight:bold">make install</span> as root. If you do not install it, you can run it
from the <span style="font-family:monospace">gp2c</span> directory by typing <span style="font-weight:bold">./gp2c</span></p>
<!--TOC section id="sec4" A <span style="font-family:monospace">gp2c</span> tutorial-->
<h2 id="sec4" class="section">2A <span style="font-family:monospace">gp2c</span> tutorial</h2><!--SEC END -->
<!--TOC subsection id="sec5" How can I compile and run my scripts?-->
<h3 id="sec5" class="subsection">2.1How can I compile and run my scripts?</h3><!--SEC END --><p><a id="compile_and_run"></a></p><p>The simplest way to use <span style="font-family:monospace">gp2c</span> is to call <span style="font-family:monospace">gp2c-run</span>. If you want to
know what happens in detail, see next section.</p><p>To make the examples easier to follow, please move to the <span style="font-family:monospace">gp2c</span> directory
and link the root of your PARI source there:</p><p><span style="font-weight:bold">ln -s .../pari .</span></p><p>As an example, we will take the file <span style="font-family:monospace">pari/examples/squfof.gp</span>, which is a
simple implementation of the well-known SQUFOF factoring method of D.Shanks.</p><p>We just run the command:</p><p><span style="font-weight:bold">./gp2c-run pari/examples/squfof.gp</span></p><p>After a little processing we get a GP session. But this session is special,
because it contains the compiled <span style="font-style:italic">squfof</span> function. Hence we can do the
following:</p><pre class="verbatim">parisize = 4000000, primelimit = 500000
? squfof(3097180303181)
[419]
i = 596
Qfb(133225, 1719841, -261451, 0.E-28)
%1 = 1691693
</pre><p>
Let&#X2019;s try a bigger example:
</p><pre class="verbatim">? squfof(122294051504814979)
[20137]
  ***   the PARI stack overflows !
  current stack size: 4.0 Mbytes
  [hint] you can increase GP stack with allocatemem()
? allocatemem()
  ***   Warning: doubling stack size; new stack = 8.0 MBytes.
? squfof(122294051504814979)
[20137]
[20137, 3445]
i = 46474
Qfb(321233929, 131349818, -367273962, 0.E-28)
%2 = 73823023
</pre><p>
We need a large stack because by default <span style="font-family:monospace">gp2c</span> does not generate code to
handle the stack (the so-called <span style="font-family:sans-serif">gerepile</span> code). To instruct <span style="font-family:monospace">gp2c</span>
to add <span style="font-family:monospace">gerepile</span> code automatically, we must use the <span style="font-weight:bold">-g</span> option.
So quit this GP session and launch a new one with -g. Oh well, before that type</p><p><span style="font-weight:bold">ls pari/examples/squfof.gp*</span>
</p><pre class="verbatim">pari/examples/squfof.gp    pari/examples/squfof.gp.run
pari/examples/squfof.gp.c  pari/examples/squfof.gp.so
pari/examples/squfof.gp.o
</pre><p>These are the files generated by <span style="font-family:monospace">gp2c-run</span>:
</p><ul class="itemize"><li class="li-itemize">
pari/examples/squfof.gp.c is the C file generated by <span style="font-family:monospace">gp2c</span>.
</li><li class="li-itemize">pari/examples/squfof.gp.o is the object file generated by the C compiler.
</li><li class="li-itemize">pari/examples/squfof.gp.so is the shared library generated by the linker.
</li><li class="li-itemize">pari/examples/squfof.gp.run is a file that contains the commands needed
to load the compiled functions inside GP.
</li></ul><p>
It is the shared library which is used by GP.</p><p>Now let&#X2019;s continue:</p><p><span style="font-weight:bold">./gp2c-run -g pari/examples/squfof.gp</span>
</p><pre class="verbatim">parisize = 4000000, primelimit = 500000
? squfof(122294051504814979)
[20137]
[20137, 3445]
i = 46474
Qfb(321233929, 131349818, -367273962, 0.E-28)
%1 = 73823023
</pre><p>This time it works with no difficulty using the default stack. We would like
to know how much faster the compiled code runs, so we need to load the non
compiled <span style="font-style:italic">squfof</span> file in GP:</p><pre class="verbatim">? \r pari/examples/squfof.gp
  ***   unexpected character: squfof(n)=if(isprime(n),retur
                                       ^--------------------
</pre><p>
Why?? Because <span style="font-style:italic">squfof</span> already exists as an installed function and GP
refuses to overwrite it. To solve this problem, we will add a suffix to the
name of the compiled function under GP. Quit the session and type:</p><p><span style="font-weight:bold">./gp2c-run -g -s_c pari/examples/squfof.gp</span></p><p>Now the function squfof is named squfof_c instead, so we can do
</p><pre class="verbatim">parisize = 4000000, primelimit = 500000
? \r pari/examples/squfof.gp
? #
   timer = 1 (on)
? squfof(122294051504814979)
[20137]
[20137, 3445]
i = 46474
Qfb(321233929, 131349818, -367273962, 0.E-28)
time = 5,810 ms.
%1 = 73823023
? squfof_c(122294051504814979)
[20137]
[20137, 3445]
i = 46474
Qfb(321233929, 131349818, -367273962, 0.E-28)
time = 560 ms.
%2 = 73823023
</pre><p>
So the compiled version is more than ten times faster than the noncompiled one.
However for more complex examples, compiled code usually runs only
three times faster on average.</p><p>An extra trick: once you have run <span style="font-family:monospace">gp2c-run</span> on your script, it is
compiled and you can use the compiled version outside <span style="font-family:monospace">gp2c-run</span> in any GP
session by loading the file with extension <span style="font-family:monospace">.gp.run</span>. For example quit the
<span style="font-family:monospace">gp2c-run</span> session and start <span style="font-family:monospace">gp</span> and do</p><pre class="verbatim">parisize = 4000000, primelimit = 500000
? \r pari/examples/squfof.gp.run
</pre><p>Now you have access to the compiled function <span style="font-style:italic">squfof_c</span> as well.</p>
<!--TOC subsection id="sec6" How can I compile directly with <span style="font-family:monospace">gp2c</span>?-->
<h3 id="sec6" class="subsection">2.2How can I compile directly with <span style="font-family:monospace">gp2c</span>?</h3><!--SEC END --><p><a id="compile_directly"></a></p><p>Now we want to compile directly with <span style="font-family:monospace">gp2c</span> to understand what happens.
We should run the command</p><p><span style="font-weight:bold">./gp2c pari/examples/squfof.gp </span><code><span style="font-weight:bold">&gt;</span></code><span style="font-weight:bold"> squfof.gp.c</span></p><p>This creates a file squfof.gp.c in the <span style="font-family:monospace">gp2c</span> directory. Now read this
file with your favorite editor.</p><p>The first line is highly system-dependent, but should be similar to:</p><pre class="verbatim"><span style="font-size:small">/*-*- compile-command: "/usr/bin/gcc -c -o pari/examples/squfof.gp.o
  -O3 -Wall -I/usr/local/include pari/examples/squfof.gp.c
  &amp;&amp; /usr/bin/gcc -o pari/examples/squfof.gp.so
  -shared   pari/examples/squfof.gp.o"; -*-*/
</span></pre><p><span style="font-size:small"> </span>
This is the command needed to compile this C file to an object file with the
C compiler and then to make a shared library with the linker. If you use
<span style="font-family:monospace">emacs</span>, typing &#X2019;M-x compile&#X2019; will know about this command, so you will
just need to type <span style="font-family:monospace">Return</span> to compile.</p><p>The second line is
</p><pre class="verbatim">#include &lt;pari/pari.h&gt;
</pre><p>
This includes the PARI header files. It is important that the header files come
from the same PARI version as GP, else it will create problems.</p><p>The next lines are
</p><pre class="verbatim"><span style="font-size:small">/*
GP;install("squfof","D0,G,p","squfof","./pari/examples/squfof.gp.so");
GP;install("init_squfof","v","init_squfof","./pari/.../squfof.gp.so");
*/
</span></pre><p>The characters "GP;" denote a command that should be read by GP at start-up.
Here, the <span style="font-style:italic">install()</span> commands above must be given to GP to let it know
about functions defined by the library. <span style="font-family:monospace">gp2c-run</span> copy such commands
to the file <span style="font-family:monospace">./pari/examples/squfof.gp.run</span>.</p><p>Please read the entry about the <span style="font-style:italic">install()</span> command in the PARI manual.</p><p>The <span style="font-style:italic">init_squfof</span> function is an initialization function that is created
automatically by <span style="font-family:monospace">gp2c</span> to hold codes that is outside any function. Since
in our case there are none, this is a dummy function. In other cases, it is
essential. The next lines are</p><pre class="verbatim">GEN squfof(GEN n, long prec);
void init_squfof(void);
/*End of prototype*/
</pre><p>
This is the C prototypes of your functions. The rest of the file is
the C code proper.</p><p>For teaching purpose, let&#X2019;s run the command</p><p><span style="font-weight:bold">./gp2c -s_c pari/examples/squfof.gp </span><code><span style="font-weight:bold">&gt;</span></code><span style="font-weight:bold"> squfof2.gp.c</span></p><p>and look at the difference between squfof.gp.c and squfof2.gp.c:</p><p><span style="font-weight:bold">diff -u squfof.gp.c squfof2.gp.c</span>
</p><pre class="verbatim"><span style="font-size:small">--- squfof.gp.c Tue Feb 26 13:44:42 2002
+++ squfof2.gp.c        Tue Feb 26 13:44:49 2002
@@ -1,8 +1,8 @@
 /*-*- compile-command: "/usr/bin/gcc -c -o pari/examples/squfof.gp.o
  -DMEMSTEP=1048576 -g -Wall -Wno-implicit  -I/usr/local/include
  pari/examples/squfof.gp.c &amp;&amp; /usr/bin/ld -o pari/examples/squfof.gp.so
  -shared   pari/examples/squfof.gp.o"; -*-*/
 #include &lt;pari/pari.h&gt;
 /*
-GP;install("squfof","D0,G,p","squfof","./pari/examples/squfof.gp.so");
-GP;install("init_squfof","v","init_squfof","./pari/.../squfof.gp.so");
+GP;install("squfof","D0,G,p","squfof_c","./pari/...les/squfof.gp.so");
+GP;install("init_squfof","v","init_squfof_c","./par.../squfof.gp.so");
 */
 GEN squfof(GEN n, long prec);
 void init_squfof(void);
</span></pre><p><span style="font-size:small"> </span>
If you are not familiar with the <span style="font-family:monospace">diff</span> utility, the above means that only
the two lines starting with <span style="font-style:italic">GP;install</span> have changed. In fact <span style="font-style:italic">squfof</span> is
still named <span style="font-style:italic">squfof</span> in the C file, but the install command tells GP to
rename it <span style="font-style:italic">squfof_c</span> in the GP session.</p>
<!--TOC subsection id="sec7" Using <span style="font-family:monospace">gp2c</span> to find errors in GP scripts-->
<h3 id="sec7" class="subsection">2.3Using <span style="font-family:monospace">gp2c</span> to find errors in GP scripts</h3><!--SEC END --><p><a id="find_errors"></a></p><p>The <span style="font-family:monospace">gp2c</span> compiler can also be used to find errors in GP programs. For
that we should use the -W option like in</p><p><span style="font-weight:bold">./gp2c -W pari/examples/squfof.gp </span><code><span style="font-weight:bold">&gt;</span></code><span style="font-weight:bold"> squfof.gp.c</span>
</p><pre class="verbatim">Warning:pari/examples/squfof.gp:7:variable undeclared
p
Warning:pari/examples/squfof.gp:11:variable undeclared
dd
Warning:pari/examples/squfof.gp:11:variable undeclared
d
Warning:pari/examples/squfof.gp:11:variable undeclared
b
...
Warning:pari/examples/squfof.gp:45:variable undeclared
b1
</pre><p>This option lists variables that are used but not declared. It is important
to declare all your variables with <span style="font-style:italic">my()</span>, or with <span style="font-style:italic">global()</span>.
For <span style="font-family:monospace">gp2c</span>, undeclared variables are taken to be &#X201C;formal variables&#X201D; for
polynomials. For example if you write a function to build a second degree
polynomial like
</p><div class="center">
<code>pol(a,b,c)=a*x^2+b*x+c</code>
</div><p>
you must not declare &#X2019;x&#X2019; here, since it stands for the formal variable <span style="font-style:italic">x</span>.</p>
<!--TOC subsection id="sec8" Using compiled functions in a new program-->
<h3 id="sec8" class="subsection">2.4Using compiled functions in a new program</h3><!--SEC END --><p><a id="compiled_in_new_program"></a></p><p>One you have successfully compiled and tested your functions you may want to
reuse them in another GP program.</p><p>The best way is to copy the install commands of the functions you use at the
start of the new program so that reading it will automatically load the
compiled functions.</p><p>As an example, we write a simple program <span style="font-family:monospace">fact.gp</span> that reads
</p><pre class="verbatim"><span style="font-size:small">install("squfof","D0,G,p","squfof","./pari/examples/squfof.gp.so");
fact_mersenne(p)=squfof(2^p-1)
</span></pre><p><span style="font-size:small"> </span>
and run GP:
</p><pre class="verbatim">parisize = 4000000, primelimit = 500000
? \rfact
? fact_mersenne(67)
i = 2418
Qfb(10825778209, 4021505768, -13258245519, 0.E-28)
%1 = 193707721
</pre><p>So all goes well. But what is even better is that <span style="font-family:monospace">gp2c</span> understands the
<span style="font-style:italic">install</span> command and will be able to compile this new program.</p><p>Also this particular example will fail because as stated above, PARI/GP already
has a <span style="font-family:sans-serif">squfof</span> function, and the linker will pick the wrong one, which is
unfortunate.</p><p>So use the -p option to <span style="font-family:monospace">gp2c-run</span> to change <span style="font-style:italic">squfof</span> to
<span style="font-style:italic">my_squfof</span>.</p><p><span style="font-weight:bold"> ./gp2c-run -pmy_ -g pari/examples/squfof.gp</span></p><p>This option prefixes my_ to every GP name in the program so as to
avoid name clashes. Change <span style="font-family:monospace">fact.gp</span> to
</p><pre class="verbatim"><span style="font-size:small">install("my_squfof","D0,G,p","squfof","./pari/examples/squfof.gp.so");
fact_mersenne(p)=squfof(2^p-1)
</span></pre><p><span style="font-size:small"> </span>
and run</p><p><span style="font-weight:bold">./gp2c-run -g fact.gp</span>
</p><pre class="verbatim">parisize = 4000000, primelimit = 500000
? fact_mersenne(67)
i = 2418
Qfb(10825778209, 4021505768, -13258245519, 0.E-28)
%1 = 193707721
</pre><p>Nice isn&#X2019;t it?</p><p>But it gets even better: instead of writing the <span style="font-style:italic">install</span> command directly
in your script you can just load the <span style="font-family:monospace">squfof.gp.run</span> using
<code>\r</code>: just change <span style="font-family:monospace">fact.gp</span> to
</p><pre class="verbatim"><span style="font-size:small">\r ./pari/examples/squfof.gp.run
fact_mersenne(p)=squfof(2^p-1)
</span></pre>
<!--TOC subsection id="sec9" Hand-editing the C file generated by <span style="font-family:monospace">gp2c</span>-->
<h3 id="sec9" class="subsection">2.5Hand-editing the C file generated by <span style="font-family:monospace">gp2c</span></h3><!--SEC END --><p>If you have some experience in PARI programming, you may want to manually
edit the C file generated by <span style="font-family:monospace">gp2c</span>, for example to improve memory handling.
Here some tips:
</p><ul class="itemize"><li class="li-itemize">
If you preserve the <span style="font-style:italic">install()</span> at the start of the file, you can use
the command <span style="font-weight:bold">gp2c-run </span><span style="font-weight:bold"><span style="font-style:italic">file</span></span><span style="font-weight:bold">.c</span> to recompile your file and start a
new GP session with your functions added, just as you use <span style="font-weight:bold">gp2c-run</span> with
GP scripts.</li><li class="li-itemize">More generally, <span style="font-weight:bold">gp2c-run</span> automatically passes any line in the C
file starting with &#X2019;GP;&#X2019; to GP at start-up.</li><li class="li-itemize">As explained in Section<a href="#compile_directly">2.2</a>, under <span style="font-weight:bold">emacs</span> you
can type &#X2019;M-x compile&#X2019; to recompile the shared library.
</li></ul>
<!--TOC section id="sec10" Advanced use of <span style="font-family:monospace">gp2c</span>-->
<h2 id="sec10" class="section">3Advanced use of <span style="font-family:monospace">gp2c</span></h2><!--SEC END --><p><a id="advanced"></a>
</p>
<!--TOC subsection id="sec11" <span style="font-family:monospace">gp2c</span> types-->
<h3 id="sec11" class="subsection">3.1<span style="font-family:monospace">gp2c</span> types</h3><!--SEC END --><p>Internally <span style="font-family:monospace">gp2c</span> assign types to objects. The most common types
are given below:</p><table border=1  style="border-spacing:0;" class="cellpadding1"><tr><td style="text-align:left;border:solid 1px;white-space:nowrap" >name</td><td style="text-align:left;border:solid 1px;white-space:nowrap" >description </td></tr>
<tr><td style="text-align:left;border:solid 1px;white-space:nowrap" ><span style="font-style:italic">void</span></td><td style="text-align:left;border:solid 1px;white-space:nowrap" >like in C </td></tr>
<tr><td style="text-align:left;border:solid 1px;white-space:nowrap" ><span style="font-style:italic">bool</span></td><td style="text-align:left;border:solid 1px;white-space:nowrap" >boolean, true (1) or false (0) </td></tr>
<tr><td style="text-align:left;border:solid 1px;white-space:nowrap" ><span style="font-style:italic">negbool</span></td><td style="text-align:left;border:solid 1px;white-space:nowrap" >antiboolean, true (0) or false (1) </td></tr>
<tr><td style="text-align:left;border:solid 1px;white-space:nowrap" ><span style="font-style:italic">small</span></td><td style="text-align:left;border:solid 1px;white-space:nowrap" >C integer <span style="font-family:sans-serif">long</span> </td></tr>
<tr><td style="text-align:left;border:solid 1px;white-space:nowrap" ><span style="font-style:italic">int</span></td><td style="text-align:left;border:solid 1px;white-space:nowrap" >multiprecision integer </td></tr>
<tr><td style="text-align:left;border:solid 1px;white-space:nowrap" ><span style="font-style:italic">real</span></td><td style="text-align:left;border:solid 1px;white-space:nowrap" >multiprecision floating point </td></tr>
<tr><td style="text-align:left;border:solid 1px;white-space:nowrap" ><span style="font-style:italic">mp</span></td><td style="text-align:left;border:solid 1px;white-space:nowrap" >multiprecision number </td></tr>
<tr><td style="text-align:left;border:solid 1px;white-space:nowrap" ><span style="font-style:italic">var</span></td><td style="text-align:left;border:solid 1px;white-space:nowrap" >variable </td></tr>
<tr><td style="text-align:left;border:solid 1px;white-space:nowrap" ><span style="font-style:italic">pol</span></td><td style="text-align:left;border:solid 1px;white-space:nowrap" >polynomial </td></tr>
<tr><td style="text-align:left;border:solid 1px;white-space:nowrap" ><span style="font-style:italic">vecsmall</span></td><td style="text-align:left;border:solid 1px;white-space:nowrap" >vector of C long (<span style="font-family:sans-serif">t_VECSMALL</span>) </td></tr>
<tr><td style="text-align:left;border:solid 1px;white-space:nowrap" ><span style="font-style:italic">vec</span></td><td style="text-align:left;border:solid 1px;white-space:nowrap" >vector and matrices (excluding <span style="font-style:italic">vecsmall</span>)</td></tr>
<tr><td style="text-align:left;border:solid 1px;white-space:nowrap" ><span style="font-style:italic">list</span></td><td style="text-align:left;border:solid 1px;white-space:nowrap" >GP lists </td></tr>
<tr><td style="text-align:left;border:solid 1px;white-space:nowrap" ><span style="font-style:italic">str</span></td><td style="text-align:left;border:solid 1px;white-space:nowrap" >characters string as a <span style="font-family:sans-serif">char *</span></td></tr>
<tr><td style="text-align:left;border:solid 1px;white-space:nowrap" ><span style="font-style:italic">genstr</span></td><td style="text-align:left;border:solid 1px;white-space:nowrap" >characters string as a <span style="font-family:sans-serif">GEN</span> (<span style="font-family:sans-serif">t_STR</span>)</td></tr>
<tr><td style="text-align:left;border:solid 1px;white-space:nowrap" ><span style="font-style:italic">gen</span></td><td style="text-align:left;border:solid 1px;white-space:nowrap" >generic PARI object (<span style="font-family:sans-serif">GEN</span>)</td></tr>
<tr><td style="text-align:left;border:solid 1px;white-space:nowrap" ><span style="font-style:italic">lg</span></td><td style="text-align:left;border:solid 1px;white-space:nowrap" >length of object (returned by <span style="font-style:italic">length</span>) </td></tr>
<tr><td style="text-align:left;border:solid 1px;white-space:nowrap" ><span style="font-style:italic">typ</span></td><td style="text-align:left;border:solid 1px;white-space:nowrap" >type of object (returned by <span style="font-style:italic">type</span>) </td></tr>
</table><blockquote class="table"><div class="center"><hr style="width:80%;height:2"></div>
<table class="display dcenter"><tr style="vertical-align:middle"><td class="dcell">
<img src="gp2c001.png">
</td></tr>
</table>
<div class="caption"><table style="border-spacing:6px;border-collapse:separate;" class="cellpading0"><tr><td style="vertical-align:top;text-align:left;" >Table 1: Types preorder</td></tr>
</table></div><a id="preorder"></a>
<div class="center"><hr style="width:80%;height:2"></div></blockquote><p>Types are preordered as in Table<a href="#preorder">1</a>. The complete preorder
known by <span style="font-family:monospace">gp2c</span> can be accessed by running <span style="font-weight:bold">gp2c -t</span>.</p><p>Variables are typed. A variable can only take values having a type equal or
lower than its type. By default, variables are of type <span style="font-style:italic">gen</span>.</p>
<!--TOC subsection id="sec12" Type declaration-->
<h3 id="sec12" class="subsection">3.2Type declaration</h3><!--SEC END --><p>To declare a variable as belonging to type <span style="font-style:italic">type</span>, use:
</p><blockquote class="quote">
<span style="font-style:italic">function</span>(x<span style="font-style:italic">:type</span>,y<span style="font-style:italic">:type</span>=2) <br>
my(x<span style="font-style:italic">:type</span>, y<span style="font-style:italic">:type</span>=2) <br>
global(x<span style="font-style:italic">:type</span>, y<span style="font-style:italic">:type</span>=2) <br>
for(i<span style="font-style:italic">:type</span>=...
</blockquote><p>To declare several variables of the same type <span style="font-style:italic">type</span> at once, use:
</p><blockquote class="quote">
my(x, y=2)<span style="font-style:italic">:type</span><br>
global(x, y=2)<span style="font-style:italic">:type</span>
</blockquote><p>You can even mix the two ways:
</p><blockquote class="quote">
my(x, y:<span style="font-style:italic">type2</span>=2)<span style="font-style:italic">:type1</span>
</blockquote><p>
will declare <span style="font-style:italic">x</span> to be of type <span style="font-style:italic">type1</span> and <span style="font-style:italic">y</span> of type <span style="font-style:italic">type2</span>.</p>
<!--TOC subsection id="sec13" Effect of types declaration on default values-->
<h3 id="sec13" class="subsection">3.3Effect of types declaration on default values</h3><!--SEC END --><p>Under GP, all GP variables start with a default value, which is <span style="font-style:italic">0</span> for a
local variable and <span style="font-style:italic">&#X2019;v</span> for a global variable <span style="font-style:italic">v</span>.</p><p>The <span style="font-family:monospace">gp2c</span> compiler follows this rule for variables declared without a type.
However, when a variable is declared with a type, <span style="font-family:monospace">gp2c</span> will not assign it a
default value. This means that the declaration <span style="font-style:italic">my(g)</span> is equivalent to
<span style="font-style:italic">my(g:gen=0)</span>, but not to <span style="font-style:italic">my(g:gen)</span>, <span style="font-style:italic">my(g)</span> is equivalent
to <span style="font-style:italic">my(g:gen=&#X2019;g)</span>, but not to <span style="font-style:italic">my(g:gen)</span>, and <span style="font-style:italic">f(g)=...</span> is
equivalent to <span style="font-style:italic">f(g:gen=0)=...</span>, but not to <span style="font-style:italic">f(g:gen)=...</span>.</p><p>This rule was chosen for several reasons:
</p><ul class="itemize"><li class="li-itemize">
The default value (<span style="font-style:italic">0</span> or <span style="font-style:italic">&#X2019;v</span>) might not be an object suitable for
the type in question. For example, <span style="font-style:italic">my(v:vec)</span> declares <span style="font-style:italic">v</span> as being
of type <span style="font-style:italic">vec</span>. It would make no sense to initialize <span style="font-style:italic">v</span> to <span style="font-style:italic">0</span> since
<span style="font-style:italic">0</span> does not belong to type <span style="font-style:italic">vec</span>. Similarly <span style="font-style:italic">global(N:int)</span> declares
<span style="font-style:italic">N</span> as being of type <span style="font-style:italic">int</span>. It would make no sense to initialize <span style="font-style:italic">N</span>
to <span style="font-style:italic">&#X2019;N</span> since <span style="font-style:italic">&#X2019;N</span> does not belong to type <span style="font-style:italic">int</span>.</li><li class="li-itemize">This allows defining GP functions with mandatory arguments.
This way, GP will issue an error if a mandatory argument is missing.
Without this rule, there is no way to tell apart <span style="font-style:italic">0</span> from a missing argument.</li><li class="li-itemize">This allows telling <span style="font-family:monospace">gp2c</span> not to generate useless default values.
</li></ul>
<!--TOC subsection id="sec14" Type casting-->
<h3 id="sec14" class="subsection">3.4Type casting</h3><!--SEC END --><p>Sometimes, we know a more precise type than the one the transtyping algorithm
can derive. For example if <span style="font-style:italic">x</span> is a real number, its logarithm might be
complex. However, if we are sure <span style="font-style:italic">x</span> is positive, the logarithm will be
real.</p><p>To force an expression to belong to type <span style="font-style:italic">type</span>, use
the syntax: <br>
<span style="font-style:italic">expr</span><span style="font-style:italic">:type</span><br>
<span style="font-family:monospace">gp2c</span> will check types consistency and output warnings if necessary.
For example<br>
<span style="font-style:italic">f(x:int)=my(r:real); r=log(x^2+1)</span><br>
<span style="font-family:monospace">gp2c</span> will complain that the logarithm might not be real. Since <span style="font-style:italic">x^2+1</span>
is always positive, we can write:<br>
<span style="font-style:italic">f(x:int)=my(r:real); r=log(x^2+1):real</span></p>
<!--TOC subsection id="sec15" Example of optimisation-->
<h3 id="sec15" class="subsection">3.5Example of optimisation</h3><!--SEC END --><p>Declaring the types of variables allow <span style="font-family:monospace">gp2c</span> to perform some optimisations.
For example, the following piece of GP code</p><pre class="verbatim">
rho(n)=
{
  my(x,y);

  x=2; y=5;
  while(gcd(y-x,n)==1,
    x=(x^2+1)%n;
    y=(y^2+1)%n; y=(y^2+1)%n
   );
  gcd(n,y-x)
}
</pre><p>generates the following output:</p><pre class="verbatim">GEN
rho(GEN n)
{
  GEN x = gen_0, y = gen_0;
  x = gen_2;
  y = stoi(5);
  while (gequal1(ggcd(gsub(y, x), n)))
  {
    x = gmod(gaddgs(gsqr(x), 1), n);
    y = gmod(gaddgs(gsqr(y), 1), n);
    y = gmod(gaddgs(gsqr(y), 1), n);
  }
  return ggcd(n, gsub(y, x));
}
</pre><p>The functions <span style="font-family:sans-serif">gsqr</span>, <span style="font-family:sans-serif">gaddgs</span>, <span style="font-family:sans-serif">gmod</span>, <span style="font-family:sans-serif">ggcd</span> are generic
PARI functions that handle <span style="font-style:italic">gen</span> objects. Since we only want to factor
integers with this method, we can declare <span style="font-style:italic">n</span>, <span style="font-style:italic">x</span> <span style="font-style:italic">y</span> of type
<span style="font-style:italic">int</span>:</p><p><span style="font-family:monospace">rho(n</span><span style="font-family:monospace"><span style="font-style:italic">:int</span></span><span style="font-family:monospace">)=<br>
</span><code><span style="font-family:monospace">{</span></code><span style="font-family:monospace"><br>
</span><code><span style="font-family:monospace">  my</span></code><span style="font-family:monospace">(x</span><span style="font-family:monospace"><span style="font-style:italic">:int</span></span><span style="font-family:monospace">,y</span><span style="font-family:monospace"><span style="font-style:italic">:int</span></span><span style="font-family:monospace">);</span>
</p><pre class="verbatim">  x=2; y=5;
  while(gcd(y-x,n)==1,
    x=(x^2+1)%n;
    y=(y^2+1)%n; y=(y^2+1)%n
   );
  gcd(n,y-x)
}
</pre><p>The new C code output by <span style="font-family:monospace">gp2c</span> is:</p><pre class="verbatim">GEN
rho(GEN n)        /* int */
{
  GEN x, y;       /* int */
  if (typ(n) != t_INT)
    pari_err(typeer, "rho");
  x = gen_2;
  y = stoi(5);
  while (gequal1(gcdii(subii(y, x), n)))
  {
    x = modii(addis(sqri(x), 1), n);
    y = modii(addis(sqri(y), 1), n);
    y = modii(addis(sqri(y), 1), n);
  }
  return gcdii(n, subii(y, x));
}
</pre><p>Now, the code now uses the more specific functions <span style="font-family:sans-serif">sqri</span>, <span style="font-family:sans-serif">addis</span>,
<span style="font-family:sans-serif">modii</span> and <span style="font-family:sans-serif">gcdii</span>.</p><p>The most efficient way to use typing is to declare some variables of type
<span style="font-style:italic">small</span>. This way, these variables will be implemented by C <span style="font-family:sans-serif">long</span>
variables, which are faster than PARI integers and do not require garbage
collecting. However, you will not be protected from integer overflow. For
that reason, <span style="font-family:monospace">gp2c</span> will automatically declare some loop indices of type
<span style="font-style:italic">small</span> when the range cannot cause overflow. Sometimes <span style="font-family:monospace">gp2c</span> can be too
conservative but you can force a loop index to be <span style="font-style:italic">small</span> with the syntax
<span style="font-style:italic">for(i:small=a,b,...)</span>.</p>
<!--TOC subsection id="sec16" Types and member functions-->
<h3 id="sec16" class="subsection">3.6Types and member functions</h3><!--SEC END --><p>For use with members functions, <span style="font-family:monospace">gp2c</span> provides the following types:</p><dl class="description"><dt class="dt-description">
<span style="font-weight:bold">nf</span></dt><dd class="dd-description"> for ordinary number fields, i.e., a result given by the GP function <span style="font-style:italic">nfinit</span>.
</dd><dt class="dt-description"><span style="font-weight:bold">bnf</span></dt><dd class="dd-description"> for big number fields, i.e., a result given by the GP function <span style="font-style:italic">bnfinit</span> which includes class and unit group data.
</dd><dt class="dt-description"><span style="font-weight:bold">bnr</span></dt><dd class="dd-description"> for ray class groups, i.e., a result given by the GP function <span style="font-style:italic">bnrinit</span>.
</dd><dt class="dt-description"><span style="font-weight:bold">ell</span></dt><dd class="dd-description"> for elliptic curves, i.e., a result given by the GP function <span style="font-style:italic">ellinit</span>.
</dd><dt class="dt-description"><span style="font-weight:bold">gal</span></dt><dd class="dd-description"> for galois extensions, i.e., a result given by the GP function <span style="font-style:italic">galoisinit</span>.
</dd><dt class="dt-description"><span style="font-weight:bold">prid</span></dt><dd class="dd-description"> for prime ideals, i.e., a component of the result given by the GP function <span style="font-style:italic">idealprimedec</span>.
</dd></dl><p>Members functions on typed objects are much more efficient.</p>
<!--TOC section id="sec17" Common problems-->
<h2 id="sec17" class="section">4Common problems</h2><!--SEC END -->
<!--TOC subsection id="sec18" Meta-commands.-->
<h3 id="sec18" class="subsection">4.1Meta-commands.</h3><!--SEC END --><p>Meta-commands (commands starting with a <code>\</code>) other than <code>\r</code> are
currently ignored by <span style="font-family:monospace">gp2c</span>, though a warning will be issued, because it
is not clear what they should do in a compiled program. Instead you probably
want to run the meta-command in the GP session itself.</p><p>The meta-command <code>\r</code><span style="font-style:italic">include</span> is replaced with the content of the
file <span style="font-style:italic">include</span> (or <span style="font-style:italic">include</span>.gp) when <span style="font-family:monospace">gp2c</span> reads the file.
If you would prefer <span style="font-family:monospace">gp2c</span> to link <span style="font-style:italic">include</span>.so to the program instead,
see Section<a href="#compiled_in_new_program">2.4</a>.</p>
<!--TOC subsection id="sec19" Unsupported functions.-->
<h3 id="sec19" class="subsection">4.2Unsupported functions.</h3><!--SEC END --><p><a id="unsupported_funcs"></a></p><p>Some GP functions are not yet available to C programs, so the compiler cannot
handle them. If you use them you will get the error "unhandled letter in
prototype". These are currently <span style="font-style:italic">forfactored</span> and <span style="font-style:italic">forsquarefree</span>.</p><p>The functions <span style="font-style:italic">forell</span>, <span style="font-style:italic">forsubgroup</span> and <span style="font-style:italic">forqfvec</span> are currently not
implemented as an iterator but as a procedure with callbacks, which limits what
you can do inside the loop.</p><p>The <span style="font-style:italic">forstep</span> function is supported when the step is a number. If
it is a vector, you must add a tag <span style="font-style:italic">:vec</span> to make GP know about it like in</p><pre class="verbatim">f(x)=
{
  my(v);
  v=[2,4,6,6,6,6,6,2,4,6,6]
  forstep(y=7,x,v:vec,print(y))
}
</pre><p>This is not needed if the step is a vector or a variable of type vec,
but is needed if the step is only an expression which evaluates to a vector.</p><p>Some functions are passed to GP by <span style="font-family:monospace">gp2c-run</span> at start-up (using the
<span style="font-family:sans-serif">GP;</span> syntax) instead of being translated in C: <span style="font-style:italic">install</span> and
<span style="font-style:italic">addhelp</span>. In practice, they can be considered as supported.</p><p>Also the functions <span style="font-style:italic">read, eval, kill</span> may compile fine but have a
surprising behaviour in some case, because they may modify the state of the GP
interpreter, not of the compiled program. Please see
Section<a href="#global_variables">4.4</a> for details. For example
<code>f(n)=eval("n^2")</code> is very different from <code>f(n)=n^2</code>.
To read files at compile-time use <code>\r</code> instead of <span style="font-style:italic">read</span>.</p>
<!--TOC subsection id="sec20" Dynamically-scoped local variables.-->
<h3 id="sec20" class="subsection">4.3Dynamically-scoped local variables.</h3><!--SEC END --><p><a id="dynamic_variables"></a></p><p>Currenlty <span style="font-family:monospace">gp2c</span> does not support dynamically-scoped local variables
declared with <span style="font-style:italic">local()</span>. Instead <span style="font-style:italic">local()</span> is treated as an
alias for <span style="font-style:italic">my()</span> which declares statically-scoped local variables.</p><p>Supporting dynamically-scoped local variables is cumbersome to do in C.</p>
<!--TOC subsection id="sec21" Memory handling and global variables.-->
<h3 id="sec21" class="subsection">4.4Memory handling and global variables.</h3><!--SEC END --><p><a id="global_variables"></a></p><p>While a lot of work has been done to ensure that <span style="font-family:monospace">gp2c</span> handles global
variables properly, the use of global variables is still a lot of trouble, so
try to avoid them if you do not understand the implications on memory handling.</p><p>First, there is a common practice to use undeclared variables as formal
variables, for example we assume <span style="font-style:italic">x=&#X2019;x</span> and write <span style="font-style:italic">a*x+b</span> instead of
<span style="font-style:italic">a*&#X2019;x+b</span>. So <span style="font-family:monospace">gp2c</span> will not raise an undeclared variable to the rank of
global variable unless you declare it with the <span style="font-style:italic">global()</span> command, or you
use it at toplevel (i.e. outside any function). See also
Section<a href="#find_errors">2.3</a></p><p>Second, global variables seen by a compiled function are C variables, not GP
variables. There is no connection between the two. You may well have two
variables with the same name and a different content. Currently GP knows only
how to install functions, not variables, so you need to write compiled
functions in order to access global variables under GP.</p><p>Basically, global variables are allocated in the main stack which is destroyed
each time GP prints a new prompt. This means you must put all your commands on
the same line. Also global variables must be initialized using the
<span style="font-style:italic">init_</span><code>&lt;filename&gt;</code> function before being used, and are only supported
with the -g flag.</p><p>So you end up doing
<span style="font-weight:bold">gp2c-run -g global.gp</span>
</p><pre class="verbatim">parisize = 4000000, primelimit = 500000
? init_global();myfunction(args);
</pre><p>Note that nothing prevents you from calling <span style="font-style:italic">init_global</span> in the GP
program. In that case, you can omit the parentheses (i.e, write
<span style="font-style:italic">init_global</span>, not <span style="font-style:italic">init_global()</span>) so that you can still run your
noncompiled program.</p><p>Another way to handle global variables is to use the <span style="font-style:italic">clone</span> function which
copies a PARI object to the heap, hence avoids its destruction when GP
prints a new prompt. You can use <span style="font-style:italic">unclone</span> to free a clone. Please read the
PARI/GP manual for more information about <span style="font-style:italic">clone</span>.</p><p>A good use of <span style="font-style:italic">clone</span> is for initializing constant variables:
for example in <span style="font-family:monospace">test/gp/initfunc.gp</span>, the vector <span style="font-style:italic">T</span> is initialized by
</p><pre class="verbatim">T=clone([4,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0])
</pre><p>
You must still run the <span style="font-style:italic">init_</span><code>&lt;filename&gt;</code> after starting GP, but after
that you can use <span style="font-style:italic">T</span> safely.</p><p>GP itself currently does not know about <span style="font-style:italic">clone</span> and <span style="font-style:italic">unclone</span>, but you
can use dummy functions
</p><pre class="verbatim">clone(x)=x
unclone(x)=while(0,)
</pre><p>
when running uncompiled.</p>
<!--TOC subsection id="sec22" Support for <span style="font-family:sans-serif">t_VECSMALL</span>-->
<h3 id="sec22" class="subsection">4.5Support for <span style="font-family:sans-serif">t_VECSMALL</span></h3><!--SEC END --><p>
When accessing the component of a <span style="font-family:sans-serif">t_VECSMALL</span>, it is necessary that
that the object has been declared of type <span style="font-style:italic">vecsmall</span>.</p><p>For example <span style="font-style:italic"> my(v); v = vecsort(V,,1); print(v[1]) </span> does not work, but
<span style="font-style:italic"> my(v:vecsmall); v = vecsort(V,,1); print(v[1]) </span> or
<span style="font-style:italic"> my(v:vecsmall); v = vecsort(V,,1); print(v:vecsmall[1]) </span> works.</p>
<!--TOC subsection id="sec23" GP lists-->
<h3 id="sec23" class="subsection">4.6GP lists</h3><!--SEC END --><p>GP lists and maps are not fully supported by <span style="font-family:monospace">gp2c</span>. A partial support is
available with the <span style="font-style:italic">list</span> type. You must tell <span style="font-family:monospace">gp2c</span> that a variable will
contain a list or a map by using <span style="font-style:italic">L:list</span> inside a declaration, where <span style="font-style:italic">L</span>
is the name of the variable as explained in Section<a href="#advanced">3</a>.</p><p>Currently, assigning to a list element (<span style="font-style:italic">L[2]=x</span>) will not work and lists and
maps will not be freed unless you explicitly use <span style="font-style:italic">listkill</span>.</p><p>Note: The PARI user&#X2019;s manual states that lists are useless in library mode.</p>
<!--TOC subsection id="sec24" The <span style="font-style:italic">install</span> command-->
<h3 id="sec24" class="subsection">4.7The <span style="font-style:italic">install</span> command</h3><!--SEC END --><p>The <span style="font-style:italic">install</span> command is interpreted as a <span style="font-family:monospace">gp2c</span> directive. This allows
using installed function in compiled programs, see
Section<a href="#compiled_in_new_program">2.4</a>.</p><p>However this has some side-effects:
</p><ul class="itemize"><li class="li-itemize">
If present, the <span style="font-style:italic">lib</span> argument must be a string, not an expression that
evaluate to a string.
</li><li class="li-itemize">The <span style="font-style:italic">install</span> command is not compiled, instead it is added to the list
of functions to install.
</li></ul>
<!--TOC subsection id="sec25" What about <span style="font-family:sans-serif">main()</span> ?-->
<h3 id="sec25" class="subsection">4.8What about <span style="font-family:sans-serif">main()</span> ?</h3><!--SEC END --><p>
There are two different issues with <span style="font-family:sans-serif">main()</span>: first this is reserved
function name in C, so using it with <span style="font-family:monospace">gp2c</span> will cause a name clash.
To avoid this, either rename it or use the flag -p.</p><p>Secondy <span style="font-family:monospace">gp2c</span> has no support for generating stand-alone GP programs.
However adding manually a <span style="font-family:sans-serif">main()</span> C function is not difficult in
general.</p>
<!--TOC section id="sec26" Command-line options of <span style="font-family:monospace">gp2c</span>-->
<h2 id="sec26" class="section">5Command-line options of <span style="font-family:monospace">gp2c</span></h2><!--SEC END --><p>Here is a brief description of the main options of <span style="font-family:monospace">gp2c</span>, which can be
seen with <span style="font-family:monospace">./gp2c -h</span>.</p><p>In Section<a href="#compile_and_run">2.1</a> we saw how to use the <span style="font-family:monospace">-g</span> option.
</p><ul class="itemize"><li class="li-itemize">
-g tells <span style="font-family:monospace">gp2c</span> to generate <span style="font-family:sans-serif">gerepile</span> calls to clean up the
PARI stack and reduce memory usage. You will probably need this option,
although the C code will be easier to read or hand-edit without it.</li><li class="li-itemize">-o<span style="font-style:italic">file</span> tells <span style="font-family:monospace">gp2c</span> to write the generated C file
to the file <span style="font-style:italic">file</span> instead of the standard output.</li><li class="li-itemize">-iN allows you to change the indentation of the generated C
file. So if you want 4 spaces, just use the <span style="font-family:monospace">-i4</span> option with
<span style="font-family:monospace">gp2c</span>. The default is 2.</li><li class="li-itemize">-C adds code to perform range checking for GP constructs like
<span style="font-style:italic">x[a]</span> and <span style="font-style:italic">x[a,b]</span>. This also checks whether <span style="font-style:italic">x</span> has the
correct type. By default <span style="font-family:monospace">gp2c</span> does not perform such check, which can
lead to a runtime crash with invalid code. This option causes a small
runtime penalty and a large C code readability penalty.</li><li class="li-itemize">-L adds compiler directives to the code so that warning and
error found by the compiler are prefixed with the line number in
the original GP file instead of the C file.</li><li class="li-itemize">-W is useful for debugging the .gp file, in the sense
that it detects if some local variables are undeclared. For
example, if the file <span style="font-family:monospace">algorithm.gp</span> has a routine like<pre class="verbatim">radical(x)=F=factor(x)[,1];prod(i=1,length(F),F[i])
</pre><p>The variable &#X2019;F&#X2019; is undeclared in this routine, so when running
<span style="font-family:monospace">gp2c</span> with the <span style="font-family:monospace">-W</span> option it prints</p><p><span style="font-weight:bold">Warning:algorithm.gp:1:variable undeclared F</span></p><p>At present, an undeclared variable is taken to be a "formal variable" for
polynomials by <span style="font-family:monospace">gp2c</span>, so do not declare it if that is what you intend.
For example in <code>pol(a,b,c)=a*x^2+b*x+c</code> you must not declare <span style="font-style:italic">x</span> since
it stands for the formal variable <span style="font-style:italic">&#X2019;x</span>.</p></li><li class="li-itemize">-p<span style="font-style:italic">prefix</span> A problem with C is that it is subject to name clashes,
i.e., if a GP variable in your routine has the same name as a C symbol
in the pari library, the compiler will report strange errors. So this option
changes ALL user variables and user routine names by adding a prefix
<span style="font-style:italic">prefix</span> to them. For example the GP routine <span style="font-style:italic">add(x,y)</span> with <span style="font-weight:bold">-pmy_</span> will become the C function <span style="font-family:sans-serif">my_add(x,y)</span>.<p>Try this option each time the compiler fails to compile <span style="font-family:monospace">gp2c</span> output to
see if there is a name conflict. If this is the case, change the name
in your GP script.
It may be difficult to find conflicting names if your compiler is not verbose
enough and if you are not familiar with the PARI code and C in general.</p><p>Example of conflicting names are <span style="font-family:sans-serif">top</span>,<span style="font-family:sans-serif">bot</span>,<span style="font-family:sans-serif">prec</span>,<span style="font-family:sans-serif">un</span>,
but there are thousands of others and they may be system-dependent.</p></li><li class="li-itemize">-s<span style="font-style:italic">suffix</span>: Add <span style="font-style:italic">suffix</span> to the names of the installed
functions under GP. This is to avoid clashes with the original GP script. For
example, if you want to compare timings you may want to use the option
<span style="font-weight:bold">-s_c</span> This does not affect the C code, only the <span style="font-style:italic">install</span> commands.</li><li class="li-itemize">-S: Assume strict prototypes for functions. This is related to the
&#X2019;strictargs&#X2019; GP default. This makes all arguments of functions defined in
the file mandatory unless the function supplies an explicit default value.
This does not affect the C code, only the prototype code in the
<span style="font-style:italic">install</span> commands.
In this example, the prototype code changes from "D0,G,DG" to "GDG".
<pre class="verbatim">test(data,flag=0)={CODE}
</pre></li><li class="li-itemize">-h gives the help.</li><li class="li-itemize">-v gives the <span style="font-family:monospace">gp2c</span> version.</li><li class="li-itemize">-l prints a list of all the GP functions known by the
compiler. So if a routine contains a GP routine not on this list, <span style="font-family:monospace">gp2c</span>
will show an error when trying to translate it.<p>Reasons why a GP function may not be known by the compiler are:
</p><ul class="itemize"><li class="li-itemize">The function is not part of the PARI library. See
Section<a href="#unsupported_funcs">4.2</a></li><li class="li-itemize">You use the old PARI 1.39 function names instead of the new ones.
<span style="font-family:monospace">gp2c</span> currently does not know about the &#X2019;compat&#X2019; default. Use
<span style="font-style:italic">whatnow</span> under GP to get the current name. For example, <span style="font-style:italic">mod()</span> is now
<span style="font-style:italic">Mod()</span>.</li><li class="li-itemize">You use a GP function that does not exists in the GP version <span style="font-family:monospace">gp2c</span>
was compiled against. Please recompile <span style="font-family:monospace">gp2c</span> against this GP version.<p>Normally no functions are added between two stable releases of GP with the same
minor version number (say 2.1.1 and 2.1.2) so there is no need to recompile
<span style="font-family:monospace">gp2c</span> when you upgrade. But if you use the developement versions, you
need to recompile. Also some new developement versions may break old
versions of <span style="font-family:monospace">gp2c</span>, so upgrade gp2c at the same time.</p><p>However, if you want to compile scripts which do not use the new functions,
you do not need to recompile. Note that you may use the GP environment
variables to tell <span style="font-family:monospace">gp2c-run</span> which GP to use.
</p></li></ul></li><li class="li-itemize">-t Output the table of types known to the compiler, see
Section<a href="#advanced">3</a>.</li></ul><!--CUT END -->
<!--HTMLFOOT-->
<!--ENDHTML-->
<!--FOOTER-->
<hr style="height:2"><blockquote class="quote"><em>This document was translated from L<sup>A</sup>T<sub>E</sub>X by
</em><a href="http://hevea.inria.fr/index.html"><em>H</em><em><span style="font-size:small"><sup>E</sup></span></em><em>V</em><em><span style="font-size:small"><sup>E</sup></span></em><em>A</em></a><em>.</em></blockquote></body>
</html>