source: git/Singular/LIB/surfex.lib @ 7d56875

spielwiese
Last change on this file since 7d56875 was d7b07b, checked in by Hans Schönemann <hannes@…>, 16 years ago
*hannes: better surfex path finding git-svn-id: file:///usr/local/Singular/svn/trunk@10404 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 48.0 KB
Line 
1//last change: 2007/07/06 (Oliver Labs)
2///////////////////////////////////////////////////////////////////////////////
3version="$Id: surfex.lib,v 1.6 2007-11-13 17:26:14 Singular Exp $";
4category="Visualization";
5info="
6LIBRARY: surfex.lib      Procedures for visualizing and rotating surfaces.
7@*         It is still an alpha version (see http://www.AlgebraicSurface.net)
8AUTHOR: Oliver Labs
9        This library uses the program surf
10        (written by Stefan Endrass and others)
11        and surfex (written by Oliver Labs and others, mainly Stephan Holzer).
12
13NOTE:
14 This library requires the program surfex, surf and java to be installed.
15 The software is used for producing raytraced images of surfaces.
16 You can download @code{surfex} from http://www.surfex.AlgebraicSurface.net
17
18 surfex is a front-end for surf which aims to be easier to use than
19 the original tool.
20
21SEE ALSO: surf_lib
22
23PROCEDURES:
24plotRotated(poly,coord); Plot the surface given by the polynomial p
25               with the coordinates coords(list)
26plotRot(poly);           Similar to plotRotated,
27                         but guesses automatically
28                         which coordinates should be used
29plotRotatedList(varieties, coords); Plot the varieties given by the list varieties
30                                    with the coordinates coords
31plotRotatedDirect(varieties);       Plot the varieties given by the list varietiesList
32plotRotatedListFromSpecifyList(varietiesList);  Plot the varieties given by the list varietiesList
33";
34
35LIB "solve.lib";
36LIB "primdec.lib";
37LIB "sing.lib";
38
39///////////////////////////////////////////////////////////
40//
41// the main procedures:
42//
43
44proc plotRot(poly p, list #)
45"
46USAGE: plotRot(poly p, list #)
47Similar to plotRotated, but guesses automatically
48which coordinates should be used.
49
50It opens the external program surfex for drawing the surface given by p,
51seen as a surface in the real affine space with coordinates coords.
52
53ASSUME: The basering is of characteristic zero and without parameters.
54"
55{
56    list coords = list();
57    if(num_vars_id(p)==3)
58    {
59        execute("coords = "+string_of_vars(p)+";");
60    }
61    else
62    {
63        if(num_vars_id(p)<3)
64        {
65            if(nvars(basering)==3)
66            {
67                execute("coords = "+varstr(basering)+";");
68            }
69            else
70            {
71                if(nvars(basering)<3) {
72                    "Could not guess the coordinates because the number of variables in the basering is smaller than 3!";
73                    "Please use plotRotated() instead of plotRot() and specify the coordinates explicitly.";
74                    return(0);
75                } else {
76                    "Could not guess the coordinates because the number of variables in the polynomial is smaller than 3 and the number of variables in the basering is greater than three!";
77                    "Please use plotRotated() instead of plotRot() and specify the coordinates explicitly.";
78                    return(0);
79                }
80            }
81        } else {
82            "Could not guess the coordinates because the number of variables in the polynomial is greater than 3!";
83                    "Please use plotRotated() instead of plotRot() and specify the coordinates explicitly.";
84            return(0);
85        }
86    }
87    return(plotRotatedList(list(p), coords, #));
88}
89example
90{
91    "Example:"; echo=2;
92
93    // More variables in the basering, but only 3 variables in the polynomial:
94    ring r1 = 0, (w,x,y,z), dp;
95    poly cayley_cubic = x^3+y^3+z^3+1^3-1/4*(x+y+z+1)^3;
96    plotRot(cayley_cubic);
97
98    // Three variables in the basering, but fewer variables in the polynomial:
99    ring r2 = 0, (x,y,z), dp;
100    plotRot(x^2+y^2-1);
101    plotRot(y^2+z^2-1);
102
103    // A cubic surface with a solitary point:
104    // Use the additional parameter 3 to ask singular
105    // to compute the singular locus before calling surfex.
106    ring r3 = 0, (x,y,z), dp;
107    poly kn_10 = x^3-3*x*y^2+z^3+3*x^2+3*y^2+z^2;
108    plotRot(kn_10, 3);
109
110    // The swallowtail:
111    // a surface with a real solitary curve sticking out of the surface.
112    // Use the additional parameter 3 to ask singular
113    // to compute the singular locus before calling surfex.
114    poly swallowtail = -4*y^2*z^3-16*x*z^4+27*y^4+144*x*y^2*z+128*x^2*z^2-256*x^3;
115}
116
117proc plotRotated(poly p, list coords, list #)
118"
119USAGE: plotRotated(poly p, list coords, list #)
120This opens the external program surfex for drawing the surface given by p,
121seen as a surface in the real affine space with coordinates coords.
122
123ASSUME: coords is a list of three variables.
124The basering is of characteristic zero and without parameters.
125"
126{
127    return(plotRotatedList(list(p), coords, #));
128}
129example
130{
131    "Example:"; echo=2;
132
133    // An easy example: a surface with four conical nodes.
134    ring r = 0, (x,y,z), dp;
135    poly cayley_cubic = x^3+y^3+z^3+1^3-1/4*(x+y+z+1)^3;
136//     plotRotated(cayley_cubic, list(x,y,z));
137
138    // A difficult example: a surface with a one-dimensional real component!
139    poly whitney_umbrella = x^2*z-y^2;
140    // The Whitney Umbrella without its handle:
141    plotRotated(whitney_umbrella, list(x,y,z));
142
143    // The Whitney Umbrella together with its handle:
144    plotRotated(whitney_umbrella, list(x,y,z), 2);
145}
146
147
148proc plotRotatedList(list varieties, list coords, list #)
149"
150USAGE: plotRotatedList(list varieties, list coords, list #)
151This opens the external program surfex for drawing the surfaces given by varieties,
152seen as a surface in the real affine space with coordinates coords.
153
154ASSUME: coords is a list of three variables, varieties is a list of ideals
155describing the varieties to be shown.
156The basering is of characteristic zero and without parameters.
157"
158{
159    def oring = basering;
160
161    int plotquality = 0;
162    if(size(#)>0) {
163        plotquality = #[1];
164    }
165
166    list varietiesList = list(list(), list(), list(), list());
167    list usedSurfaces = list();
168    list curveColors = list();
169
170    // go through the list of varieties
171    // produce a list which can be used as input for plotRotatedListFromList()
172    int i;
173    int j;
174    list indList;
175    int ind;
176    ideal itmp;
177    int ncurves;
178    list pd;
179    int k;
180    int surfind;
181    list curSurfColors = list();
182
183    list listOfPoints = list();
184    string str_I = "";
185
186    for(i=1; i<=size(varieties); i++) {
187        itmp = varieties[i];
188        if(plotquality>=3) {
189            itmp = radical(itmp);
190        }
191        itmp = simplify(itmp,1);
192        itmp = simplify(itmp,2);
193        if(size(itmp)==1) { // i.e.: a surface given by one equation
194            surfind = findInList(surfEqn(itmp[1],coords), usedSurfaces);
195            if(surfind==0) {
196                usedSurfaces = usedSurfaces + list(surfEqn(itmp[1],coords));
197                curSurfColors = list(list("insidecolor:",getInsideColorStr(size(varietiesList[1])+1)),
198                                     list("outsidecolor:",getOutsideColorStr(size(varietiesList[1])+1)));
199                varietiesList[1] = varietiesList[1] +
200                    list(list(list("eqno:",string(size(varietiesList[1])+1)),
201                              list("equation:",surfEqn(itmp[1], coords)),
202                              curSurfColors[1],
203                              curSurfColors[2],
204                              list("showcbox:","true"),
205                              list("transparency:","0")));
206                surfind = size(varietiesList[1]);
207
208            }
209            if(plotquality==1) {
210                varieties = varieties + list(slocus(itmp[1]));
211            }
212            if(plotquality==2 || plotquality==3) {
213                // remove doubled components and
214                // add the 1-dimensional singular components
215                // of the surface to the list of curves:
216                int dsl = dim_slocus(itmp[1]);
217                dsl;
218                if(dsl>=0) { // i.e. there is a singular locus
219                    "compute singular locus...";
220                    list eqd;
221                    //
222                    eqd = equidim(slocus(itmp[1]));
223                    ideal tmp_l;
224                    tmp_l = std(eqd[size(eqd)]);
225                    "dim:",dim(tmp_l);
226                    if(dim(tmp_l)==(nvars(basering)-3+2)) {
227                        "--- 2-dim.";
228                        // we have found a multiple component;
229                        // replace it by a simple copy of it
230                        itmp = quotient(itmp[1], tmp_l);
231                        varieties[i] = itmp[1];
232                        eqd = delete(eqd,size(eqd));
233                        if(size(eqd)>0) {
234                            tmp_l = std(eqd[size(eqd)]);
235                        }
236                    }
237                    if(dim(tmp_l)==(nvars(basering)-3+1)) {
238                        "--- 1-dim.";
239                        // we have found a 1-dimensional singular locus
240                        pd = std_primdecGTZ(tmp_l,2);
241                        for(k=1; k<=size(pd); k++) {
242                            if(pd[k][3]==(nvars(basering)-3+1)) {
243                                varieties = varieties + list(pd[k][2]);
244                                curveColors[size(varieties)] = curSurfColors;
245                            } else {
246                                "???";
247                            }
248                        }
249                        eqd = delete(eqd,size(eqd));
250                        if(size(eqd)>0) {
251                            tmp_l = std(eqd[size(eqd)]);
252                        }
253                    }
254                    if(dim(tmp_l)==(nvars(basering)-3+0)) {
255                        "--- 0-dim.";
256                        // we have found a 0-dimensional singular locus
257                        // we compute floating point approximations of the
258                        // coordinates of all singular points
259                        if(npars(oring)>0) {
260                            "str:",parstr(1),rootminpoly();
261                            list all_real_sols = allroots_minpoly();
262//                            "all sols:";all_real_sols;
263//                            sprintf("number %s = %s; ", parstr(1), rootminpoly());
264                            int minp;
265                            if((npars(basering) == 1) && (minpoly != 0)) {
266                                minp = 1;
267                            } else {
268                                minp = 0;
269                            }
270                            str_I = "";
271                            if(minp==1) {
272                                "minp=1";
273                                string str_para = parstr(1);
274                                string str_tmp_l;
275                                def cur_ring = basering;
276                                if(1) {
277                                    short=0;
278                                    str_tmp_l = "ideal eqd_tmp = "+
279//                                        string(tmp_l)+","+string(minpoly)+";";
280                                        string(tmp_l);
281                                    "str:",str_tmp_l;
282                                    string str_num_mp = "number "+parstr(1)+"="+
283                                        decstr2ratstr(rootminpoly())+";";
284                                    execute("ring Iring = 0,("
285//                                            +string(coords)+","+str_para+"),dp;");
286                                            +string(coords)+"),dp;");
287                                    basering;
288                                    execute(str_num_mp);
289                                    execute(str_tmp_l);
290                                    eqd_tmp;
291                                    list real_sols = real_solve(eqd_tmp);
292                                    real_sols;
293                                    $;
294                                    setring cur_ring;
295                                }
296                            } else {
297                                // minp==0: we do not know how to handle this
298                                "???";
299                            }
300                        } else {
301                            "no pars";
302                            ideal eqd_tmp = tmp_l;
303                            short=0;
304                            string str_tmp_l = "ideal eqd_tmp = "+string(tmp_l)+";";
305                            def cur_ring = basering;
306                            execute("ring Iring = (real,30),("+string(coords)+"),("+ordstr(oring)+");");
307//                            basering;
308                            execute(str_I);
309                            execute(str_tmp_l);
310                            list real_sols = real_solve(eqd_tmp);
311                            setring cur_ring;
312                        }
313                        "real_sols:";real_sols;
314                        for(k=1; k<=size(real_sols); k++) {
315                            "search point:";
316                             string(list(real_sols[k][1],real_sols[k][2],real_sols[k][3],string(surfind)));
317//                             listOfPoints;
318                            if(findInList(string(list(list(real_sols[k][1],real_sols[k][2],real_sols[k][3],string(surfind)))),
319                                          listOfPoints)==0) {
320                                "add pt";
321                                varietiesList[4] = varietiesList[4] +
322                                    list(list(real_sols[k][1],real_sols[k][2],real_sols[k][3],string(surfind)));
323                                listOfPoints = listOfPoints +
324                                    list(string(list(real_sols[k][1],real_sols[k][2],real_sols[k][3],string(surfind))));
325                            }
326                        }
327                    }
328                }
329            }
330        } else {
331            // i.e.: more than one equation
332            varietiesList[2] = varietiesList[2] +
333                list(list(list("surfaces:"),
334                          list("curveno:",
335                               string(size(varietiesList[2])+1)),
336                          list("showcbox:","true")));
337            if(size(curveColors) >= i) {
338                varietiesList[2][size(varietiesList[2])][4] = curveColors[i][1];
339                varietiesList[2][size(varietiesList[2])][4][1] = "color:";
340            }
341            ncurves = size(varietiesList[2]);
342            for(j=1; j<=size(itmp); j++) {
343                ind = findInList(surfEqn(itmp[j],coords), usedSurfaces);
344                usedSurfaces = usedSurfaces + list(surfEqn(itmp[1],coords));
345//                "indList:";indList;
346                if(ind == 0) {
347//                    "--------> not in list", surfEqn(itmp[j], coords);
348                    if(j==1) {
349                        varietiesList[1] = varietiesList[1] +
350                            list(list(list("eqno:",string(size(varietiesList[1])+1)),
351                                      list("equation:",surfEqn(itmp[j], coords)),
352                                      list("insidecolor:",getInsideColorStr(size(varietiesList[1])+1)),
353                                      list("outsidecolor:",getOutsideColorStr(size(varietiesList[1])+1)),
354                                      list("showcbox:","true"),
355                                      list("transparency:","100")));
356                    } else {
357                        varietiesList[1] = varietiesList[1] +
358                            list(list(list("eqno:",string(size(varietiesList[1])+1)),
359                                      list("equation:",surfEqn(itmp[j], coords)),
360                                      list("insidecolor:",getInsideColorStr(size(varietiesList[1])+1)),
361                                      list("outsidecolor:",getOutsideColorStr(size(varietiesList[1])+1)),
362                                      list("showcbox:","false"),
363                                      list("transparency:","0")));
364                    }
365                    ind = size(varietiesList[1]);
366                } else {
367                }
368                varietiesList[2][ncurves][1] = varietiesList[2][ncurves][1] + list(string(ind));
369            }
370        }
371    }
372
373//      "------------";
374//      varietiesList;
375//      "------------";
376    return(plotRotatedListFromSpecifyList(varietiesList, coords, #));
377}
378example {
379    "Example:"; echo=2;
380
381    // A cubic surface together with a tritangent plane
382    // (i.e. a plane which cuts out three lines).
383    ring r = 0, (x,y,z), dp;
384    poly cayley_cubic = x^3+y^3+z^3+1^3-1/4*(x+y+z+1)^3;
385    poly plane = 1-x-y-z;
386    plotRotatedList(list(cayley_cubic, plane), list(x,y,z));
387
388    // The same cubic and plane.
389    // The plane is not shown but only its intersection with the surface.
390    plotRotatedList(list(cayley_cubic, ideal(cayley_cubic, plane)), list(x,y,z));
391}
392
393
394proc plotRotatedListFromSpecifyList(list varietiesList, list #)
395"
396USAGE: plotRotatedListFromSpecifyList(list varietiesList, list #);
397varietiesList has a complicated format (not documented yet);
398see the example.
399
400ASSUME: The basering is of characteristic zero.
401
402EXAMPLE: example plotRotatedListFromSpecifyList;
403"
404{
405    // make the surfex file
406    string str = getSurfexCodeFromSpecifyList(varietiesList, #);
407
408    return(plotRotatedFromCode(str, #));
409}
410example
411{
412    "Example:"; echo=2;
413
414    // A cubic surface depending on a parameter:
415    ring r = (0,p1), (x,y,z), dp;
416    poly cayley_cubic = x^3+y^3+z^3+1^3-p1*(x+y+z+1)^3;
417    poly plane = 1-x-y-z;
418    plotRotatedListFromSpecifyList(list(list(list(list("eqno:","1"),
419                                                  list("equation:",
420                                                       string(cayley_cubic))
421                                                 )
422                                            ),
423                                        list(),
424                                        list(list(1,"0.0","1.0","500","0.25+0.25*sin(PI*p1)")),
425                                        list()
426                                       ));
427}
428
429
430proc plotRotatedListFromStringList(list varieties, list #)
431"
432RETURN: the return code of the system command which executes surfex.
433
434USAGE: not documented yet.
435"
436{
437    // make the surfex file
438    getSurfexCodeFromStringList(varieties, #);
439    string str = getSurfexCodeFromStringList(varieties, #);
440
441    return(plotRotatedFromCode(str, #));
442}
443
444
445proc plotRotatedDirect(list varieties, list #)
446"
447USAGE: plotRotatedDirect(list varieties, list #)
448This opens the external program surfex for drawing the surfaces given by varieties,
449seen as a surface in the real affine space with coordinates x,y,z.
450The format for the list varieties is not fully documented yet;
451please, see the examples below and try to adapt the examples to your needs.
452
453ASSUME:
454Passes the equations directly to surfex, i.e., the variable names should
455be x,y,z.
456The advantage is that one can use parameters p1, p2, ...;
457these will be passed to surfex.
458"
459{
460    string str = getSurfexCodeFromListDirect(varieties, #);
461
462    return(plotRotatedFromCode(str, #));
463}
464example
465{
466    "Example:"; echo=2;
467
468    // A cubic surface depending on a parameter:
469    ring r = (0,p1), (x,y,z), dp;
470    poly cayley_cubic = x^3+y^3+z^3+1^3-p1*(x+y+z+1)^3;
471    // The entries of the list of varieties can either be polynomials
472    plotRotatedDirect(list(list(list(cayley_cubic)),
473                           list(),
474                           list(list(1,"0.0","1.0","500","0.25+0.25*sin(PI*p1)"))
475                           ));
476
477    // or strings which represent surfex-readable polynomials
478    plotRotatedDirect(list(list(list("x^3+y^3+z^3+1^3-p1*(x+y+z+1)^3")),
479                           list(),
480                           list(list("1","0.0","1.0","500","0.25+0.25*sin(PI*p1)"))
481                           ));
482
483    // More complicated varieties
484    plotRotatedDirect(list(list(list("x^2+y^2-z^2-3^2"),
485                                list("x*sin(p1)+y*cos(p1)-3")),
486                           list(list(list(1,2))),
487                           list(list("1","0.0","1.0","500","2*PI*p1"))
488                           ));
489}
490
491proc plotRotatedFromCode(string str, list #)
492"
493USAGE: plotRotatedFromCode(string str, list #);
494
495This procedure is only for internal usage;
496it takes the surfex-code as a string and calls surfex.
497
498"
499{
500     // we need a temporary .sux file for surfex
501    string tmpd = "/tmp";
502    string l="surf"+string(system("pid"))+".sux";
503    // a temporary file which stores the output of surfex
504    string erg="/tmp/surferg"+string(system("pid"));
505
506    write(":w "+tmpd+"/"+l, str);
507
508    string surfex_path=system("Singular");
509    while(surfex_path[size(surfex_path)]!="/") { surfex_path=surfex_path[1..size(surfex_path)-1]; }
510    surfex_path=surfex_path+"../LIB/surfex";
511    if (status(surfex_path,"exists")=="no")
512    {
513    // search in SINGULAR_PATH:
514       string surfex_path1=system("SingularLib");
515       string surfex_path2=surfex_path1;
516       while (find(surfex_path1,":")!=0)
517       {
518         surfex_path2=surfex_path1[1..find(surfex_path1,":")-1];
519         if (status(surfex_path2+"/surfex","exists")=="yes") break;
520         surfex_path1=surfex_path1[find(surfex_path1,":")+1,size(surfex_path1)];
521       }
522       surfex_path=surfex_path2;
523    }
524
525    int i=system("sh","surfex \""+surfex_path+"\" -d "+tmpd+" -i " + l +" >"+erg+" 2>/dev/null");
526
527    // delete the temporary file
528    i = system("sh","rm " + l +" 2>/dev/null");
529    return(read(erg));
530}
531
532
533///////////////////////////////////////////////////////////
534//
535// procedures used to produce the surf-code:
536//
537
538
539proc getSurfexCodeFromListDirect(list varieties, list #)
540"
541USAGE: getSurfexCodeFromListDirect(list varieties, list #)
542
543ASSUME: varieties has four components,
544        - the first is a list of polynomials, say f_1, ..., f_k
545        - the second is a list of lists of numbers in {1, ..., k} describing the curves
546          as intersections of the corresponding f_i
547        - the third is a list of lists describing the parameters used in the polynomials f_i
548        - the fourth is a list of lists of points given by their approximate coordinates (three decimal numbers)
549
550RETURN: the surfex code (.sux)
551"
552{
553    int i;
554    int j;
555    string str = "this is surfex v0.89.07"+newline;
556
557    str = str + "TYPE:" + newline;
558    str = str + "specify"+newline;
559    str = str + "EQUATIONS:"+newline;
560    str = str + string(size(varieties[1])) + newline;
561    for(i=1; i<=size(varieties[1]); i++) {
562        str = str + "Equation:"+newline;
563        str = str + "eqno:"+newline;
564        str = str + string(i) + newline;
565        str = str + "equation:"+newline;
566        str = str + surfEqnDir(varieties[1][i][1]) + newline;
567        if(size(varieties[1][i])>=2) {
568            str = str + "showcbox:"+newline;
569            str = str + varieties[1][i][2] + newline;     // show it or not
570            if(size(varieties[1][i])>=3) {
571                str = str + "transparency:"+newline;
572                str = str + string(varieties[1][i][3]) + newline;     // transparency
573            }
574        }
575    }
576    str = str + "CURVES:"+newline;
577    str = str + string(size(varieties[2])) + newline;
578    for(i=1; i<=size(varieties[2]); i++) {
579        str = str + "Curve:"+newline;
580        str = str + "curveno:"+newline;
581        str = str + string(i) + newline;
582        str = str + "surfaces:"+newline;
583//        "curves:";varieties[2][i];
584        for(j=1; j<=size(varieties[2][i][1]); j++) {
585            str = str + string(varieties[2][i][1][j]) + newline;
586        }
587        if(size(varieties[2][i])>=2) {
588            str = str + "showcbox:"+newline;
589            str = str + varieties[2][i][2] + newline;     // show it or not
590        }
591    }
592    str = str + "PARAMETERS:"+newline;
593    str = str + string(size(varieties[3])) + newline;
594    for(i=1; i<=size(varieties[3]); i++) {
595        str = str + "Parameter:"+newline;
596        str = str + "parno:"+newline;
597        str = str + string(varieties[3][i][1]) + newline;
598        str = str + "fromtoval:"+newline;
599        str = str + varieties[3][i][2] + newline;
600        str = str + varieties[3][i][3] + newline;
601        str = str + string(varieties[3][i][4]) + newline;
602        if(size(varieties[3][i])>=5) {
603            str = str + "function:"+newline;
604            str = str + varieties[3][i][5]+newline;
605        }
606    }
607//     str = str + "////////////////// Parameter: /////////////////////////"+newline;
608//     str = str + "1" + newline;
609//     str = str + "0.0" + newline;
610//     str = str + "1.0" + newline;
611//     str = str + "1000" + newline;
612//    str = str + string(size(varieties[3])) + newline;
613    return(str);
614}
615
616proc getSurfexCodeFromList(list varieties, list coords, list #)
617"
618ASSUME: varieties has four components,
619        - the first is a list of polynomials, say f_1, ..., f_k
620        - the second is a list of lists of numbers in {1, ..., k} describing the curves
621          as intersections of the corresponding f_i
622        - the third is a list of lists describing the parameters used in the polynomials f_i
623        - the fourth is a list of lists of points given by their approximate coordinates (three decimal numbers)
624
625RETURN: the surfex code (.sux)
626"
627{
628    int i;
629    int j;
630    string str = "this is surfex v0.89.07"+newline;
631
632    str = str + "TYPE:" + newline;
633    str = str + "specify"+newline;
634    str = str + "EQUATIONS:"+newline;
635    str = str + string(size(varieties[1])) + newline;
636    for(i=1; i<=size(varieties[1]); i++) {
637        str = str + "Equation:"+newline;
638        str = str + "eqno:"+newline;
639        str = str + string(i) + newline;
640        str = str + "equation:"+newline;
641        str = str + surfEqn(varieties[1][i][1], coords) + newline;
642        str = str + "showcbox:"+newline;
643        str = str + varieties[1][i][2] + newline;     // show it or not
644        str = str + "transparency:"+newline;
645        str = str + string(varieties[1][i][3]) + newline;     // transparency
646    }
647    str = str + "CURVES:"+newline;
648    str = str + string(size(varieties[2])) + newline;
649    for(i=1; i<=size(varieties[2]); i++) {
650        str = str + "Curve:"+newline;
651        str = str + "curveno:"+newline;
652        str = str + string(i) + newline;
653        str = str + "surfaces:"+newline;
654        for(j=1; j<=size(varieties[2][i]); j++) {
655            str = str + string(varieties[2][i][1][j]) + newline;
656        }
657        str = str + "showcbox:"+newline;
658        str = str + varieties[2][i][2] + newline;     // show it or not
659    }
660    str = str + "PARAMETERS:"+newline;
661    str = str + string(size(varieties[3])) + newline;
662    for(i=1; i<=size(varieties[3]); i++) {
663        str = str + "Parameter:"+newline;
664        str = str + "parno:"+newline;
665        str = str + string(varieties[3][i][1]) + newline;
666        str = str + "fromtoval:"+newline;
667        str = str + surfEqn(varieties[3][i][2], coords) + newline;
668        str = str + surfEqn(varieties[3][i][3], coords) + newline;
669        str = str + string(varieties[3][i][4]) + newline;
670        if(size(varieties[3][i])>=5) {
671            str = str + "function:"+newline;
672            str = str + varieties[3][i][5]+newline;
673        }
674    }
675//     str = str + "////////////////// Parameter: /////////////////////////"+newline;
676//     str = str + "1" + newline;
677//     str = str + "0.0" + newline;
678//     str = str + "1.0" + newline;
679//     str = str + "1000" + newline;
680//    str = str + string(size(varieties[3])) + newline;
681    return(str);
682}
683
684proc getSurfexCodeFromStringList(list varieties, list #)
685"
686ASSUME: varieties has three components,
687        - the first is a list of polynomials, say f_1, ..., f_k
688        - the second is a list of lists of numbers in {1, ..., k} describing the curves
689          as intersections of the corresponding f_i
690        - the third is a list of lists describing the parameters used in the polynomials f_i
691
692RETURN: the surfex code (.sux)
693"
694{
695    int i;
696    int j;
697    string str = "this is surfex v0.89.07"+newline;
698
699    str = str + "TYPE:" + newline;
700    str = str + "specify"+newline;
701    str = str + "EQUATIONS:"+newline;
702    str = str + string(size(varieties[1])) + newline;
703    for(i=1; i<=size(varieties[1]); i++) {
704        str = str + "Equation:"+newline;
705        str = str + "eqno:"+newline;
706        str = str + string(i) + newline;
707        str = str + "equation:"+newline;
708        str = str + varieties[1][i][1] + newline;
709        str = str + "showcbox:"+newline;
710        str = str + varieties[1][i][2] + newline;     // show it or not
711        str = str + "transparency:"+newline;
712        str = str + varieties[1][i][3] + newline;     // transparency
713    }
714    str = str + "CURVES:"+newline;
715    str = str + string(size(varieties[2])) + newline;
716    for(i=1; i<=size(varieties[2]); i++) {
717        str = str + "Curve:"+newline;
718        str = str + "curveno:"+newline;
719        str = str + string(i) + newline;
720        str = str + "surfaces:"+newline;
721        for(j=1; j<=size(varieties[2][i][1]); j++) {
722            str = str + string(varieties[2][i][1][j]) + newline;
723        }
724        str = str + "showcbox:"+newline;
725        str = str + varieties[2][i][2] + newline;     // show it or not
726    }
727    str = str + "PARAMETERS:"+newline;
728    str = str + string(size(varieties[3])) + newline;
729    for(i=1; i<=size(varieties[3]); i++) {
730        str = str + "Parameter:"+newline;
731        str = str + "parno:"+newline;
732        str = str + string(varieties[3][i][1]) + newline;
733        str = str + "fromtoval:"+newline;
734        str = str + varieties[3][i][2] + newline;
735        str = str + varieties[3][i][3] + newline;
736        str = str + string(varieties[3][i][4]) + newline;
737        if(size(varieties[3][i])>=5) {
738            str = str + "function:"+newline;
739            str = str + varieties[3][i][5]+newline;
740        }
741    }
742    return(str);
743}
744
745
746proc getSurfexCodeFromSpecifyList(list varieties, list #)
747"
748ASSUME: varieties has three components,
749        - the first is a list of polynomials, say f_1, ..., f_k
750        - the second is a list of lists of numbers in {1, ..., k} describing the curves
751          as intersections of the corresponding f_i
752        - the third is a list of lists describing the parameters used in the polynomials f_i
753        - the fourth is a list of lists describing the singular points to be shown as spheres
754
755RETURN: the surfex code (.sux)
756"
757{
758    int i;
759    int j;
760    int k;
761    string str = "this is surfex v0.89.07"+newline;
762
763    str = str + "TYPE:" + newline;
764    str = str + "specify"+newline;
765    str = str + "EQUATIONS:"+newline;
766    str = str + string(size(varieties[1])) + newline;
767    for(i=1; i<=size(varieties[1]); i++) {
768        str = str + "Equation:"+newline;
769        for(j=1; j<=size(varieties[1][i]); j++) {
770            str = str + varieties[1][i][j][1] +newline;
771            str = str + varieties[1][i][j][2] +newline;
772        }
773    }
774    str = str + "CURVES:"+newline;
775    str = str + string(size(varieties[2])) + newline;
776    for(i=1; i<=size(varieties[2]); i++) {
777        str = str + "Curve:"+newline;
778        for(j=1; j<=size(varieties[2][i]); j++) {
779            str = str + varieties[2][i][j][1] +newline;
780            if(varieties[2][i][j][1] == "surfaces:") {
781                for(k=2; k<=size(varieties[2][i][j]); k++) {
782                    str = str + string(varieties[2][i][j][k]) + newline;
783                }
784            } else {
785                str = str + varieties[2][i][j][2] +newline;
786            }
787        }
788//         str = str + "curveno:"+newline;
789//         str = str + string(i) + newline;
790//         str = str + "surfaces:"+newline;
791//         for(j=1; j<=size(varieties[2][i][1]); j++) {
792//             str = str + string(varieties[2][i][1][j]) + newline;
793//         }
794//         str = str + "showcbox:"+newline;
795//         str = str + varieties[2][i][2] + newline;     // show it or not
796    }
797    str = str + "PARAMETERS:"+newline;
798    str = str + string(size(varieties[3])) + newline;
799    for(i=1; i<=size(varieties[3]); i++) {
800        str = str + "Parameter:"+newline;
801        str = str + "parno:"+newline;
802        str = str + string(varieties[3][i][1]) + newline;
803        str = str + "fromtoval:"+newline;
804        str = str + varieties[3][i][2] + newline;
805        str = str + varieties[3][i][3] + newline;
806        str = str + string(varieties[3][i][4]) + newline;
807        if(size(varieties[3][i])>=5) {
808            str = str + "function:"+newline;
809            str = str + varieties[3][i][5]+newline;
810        }
811    }
812    string str_from = "0.0";
813    string str_to = "5.0";
814    string str_radius = "50";
815    str = str + "SOLITARY POINTS:"+newline;
816    str = str + string(size(varieties[4])) + newline;
817    for(i=1; i<=size(varieties[4]); i++) {
818        str = str + "SolitaryPoint:"+newline;
819        str = str + "solPtNo:"+newline;
820        str = str + string(i) + newline;
821        str = str + "surface:"+newline;
822        str = str + varieties[4][i][4] + newline;
823        str = str + "fromtoval:"+newline;
824        str = str + str_from + newline;
825        str = str + str_to + newline;
826        str = str + str_radius + newline;
827        str = str + "coords:" + newline;
828        str = str + varieties[4][i][1] + newline;
829        str = str + varieties[4][i][2] + newline;
830        str = str + varieties[4][i][3] + newline;
831    }
832    return(str);
833}
834
835///////////////////////////////////////////////////////////
836//
837// procedures for standard colors:
838//
839
840proc numBaseColors()
841"
842USAGE: numBaseColors()
843
844RETURN: the number of predefined surface colors.
845"
846{
847    return(6);
848}
849
850proc baseSurfaceColors(int no)
851"
852USAGE: baseSurfaceColors(int no)
853
854REMARK: There are currently 6=numBaseColors() basic surface colors.
855You can modify them according to your wishes
856by just redefining this procedure in your Singular-script.
857
858If you want more colors, then you also have to redefine numBaseColors() accordingly.
859
860RETURN: a list of three integers describing the RGB values of a color.
861"
862{
863    if(no%numBaseColors()==1) {
864        return(list(240,160,0));
865    }
866    if(no%numBaseColors()==2) {
867        return(list(160,240,0));
868    }
869    if(no%numBaseColors()==3) {
870        return(list(0,160,240));
871    }
872    if(no%numBaseColors()==4) {
873        return(list(240,0,160));
874    }
875    if(no%numBaseColors()==5) {
876        return(list(0,240,160));
877    }
878    if(no%numBaseColors()==0) {
879        return(list(160,0,240));
880    }
881}
882
883proc getInsideColorStr(int no)
884"
885USAGE: getInsideColorStr(int no)
886
887RETURN: a string describing inside color number no
888where the three integer RGB values are in one line each.
889"
890{
891    list bc = baseSurfaceColors(no);
892    string str = string(bc[1])+newline+string(bc[2])+newline+string(bc[3]);
893    return(str);
894}
895
896proc getOutsideColorStr(int no)
897"
898USAGE: getOutsideColorStr(int no)
899
900RETURN: a string describing outside color number no
901where the three integer RGB values are in one line each.
902"
903{
904    list bc = baseSurfaceColors(no);
905    string str = string(bc[1])+newline+string(bc[2])+newline+string(bc[3]);
906    return(str);
907}
908
909///////////////////////////////////////////////////////////
910//
911// procedures used by the plot procedures:
912//
913
914proc surfEqnDir(list #)
915"
916USAGE: surfEqnDir(list #) without any checks etc.
917
918RETURN: string(#[1]) where short=0.
919"
920{
921    int stmp = short; short = 0;
922    string str = string(#[1]);
923    short = stmp;
924    return(str);
925}
926
927proc surfEqn(poly p, list coords, list #)
928"
929USAGE: surfEqn(poly p, list coords)
930       Tries to produce a string for the equation of p which is convenient for surfex.
931ASSUME: - p defines a plane curve or a surface,
932         - coords is a list of the three coordinates to use, e.g. list(x,y,z),
933           in this way, it is possible to distinguish between x^2+y^2-1 and y^2+z^2-1
934RETURN: a string, that one can use with the external program surf
935EXAMPLE: example surfEqn; shows an example
936"
937{
938    int params=0;
939    if(size(#)>0) {
940        params = #[1];
941    }
942    string err_mes; // string containing error messages
943    def base=basering;
944    int mynvars = nvars(basering);
945
946    intvec ind=num_of_vars(p);
947
948    int i,j,n;
949    int minp = 0;
950    n=0;
951    for(i=size(ind);i>0;i--)
952    {
953          if (ind[i]!=0) {
954            n++;
955        } else {
956            if(var(i)==coords[1] || var(i)==coords[2] || var(i)==coords[3]) {
957                ind[i]=1;
958                n++;
959            }
960        }
961    }
962
963    params = params + npars(basering);
964    n = n + npars(basering);
965    if((npars(basering) == 1) && (minpoly != 0)) {
966        minp = 1;
967    } else {
968        minp = 0;
969    }
970    string str_I = "";
971    for(i=1; i<=npars(basering); i=i+1) {
972        if(!(parstr(i) == "i")) {
973            if(minp==1) {
974                str_I = str_I + sprintf("number %s = %s; ", parstr(i), rootminpoly());
975            } else {
976            }
977        }
978    }
979    int bshort = short; short = 0;
980    if(!(minp==1 || npars(basering)==0)) {
981        p=cleardenom(p);
982        err_mes="Cannot plot equations with a parameter without a specified minpoly";
983        ERROR(err_mes);
984    }
985    str_I = str_I + "poly p = " + string(p) + ";";
986
987    short = bshort;
988
989    if(params==0) {
990        if (n<=2 or n>=4)
991        {
992            err_mes="Cannot plot equations with "+string(n)+" variables";
993            ERROR(err_mes);
994//            return("0");
995        }
996        if(n==4) {
997            ring r=(real,30,30),(xx,yy,zz,ww),dp;
998        } else {
999            ring r=(real,30,30),(x,y,z),dp;
1000        }
1001    } else {
1002        if(n-params<=2 || n-params>=4) {
1003            err_mes="Cannot plot equations with "+string(n-params)+" variables";
1004            ERROR(err_mes);
1005//            return("0");
1006        } else {
1007            if(params == 1) {
1008                if(n-params==3) {
1009                    if(minp==1) {
1010                        // switch to a ring without minimal polynomial:
1011                        execute("ring rr = (real,30,30),("+varstr(base)+"), dp;");
1012//                        rr;
1013//                        "str_I",str_I;
1014                        execute(str_I);
1015                        def base = rr;
1016                        ring r=(real,30,30),(x,y,z),dp;
1017                    } else {
1018                        p=cleardenom(p);
1019                        ring r=(real,30,30),(x,y,z,p1),dp;
1020                    }
1021                }
1022            }
1023            if(params == 2) {
1024                if(n-params==3) {
1025                    p=cleardenom(p);
1026                    ring r=(real,30,30),(x,y,z,p1,p2),dp;
1027                }
1028            }
1029            if(params == 3) {
1030                if(n-params==3) {
1031                    p=cleardenom(p);
1032                    execute("ring rr = (real,30,30),("+varstr(base)+","+parstr(base)+"), dp;");
1033                    rr;
1034                    "str_I",str_I;
1035                    execute(str_I);
1036                    "pnew:",p;
1037                    def base = rr;
1038
1039                    ring r=(real,30,30),(x,y,z,p1,p2,p3),dp;
1040                }
1041            }
1042        }
1043    }
1044//    basering;
1045    short=0;
1046    map phi=base,0;
1047    j=1;
1048
1049    for(i=1;i<=mynvars;i++)
1050    {
1051        if (ind[i]!=0)
1052        {
1053            phi[i]=var(j);
1054            j++;
1055        }
1056    }
1057    poly p=(simplify(phi(p),1));
1058    if (leadcoef(p) <0) {
1059        if(size(#)>1) {
1060            if(#[2]!=0) {
1061                p=-p;
1062            }
1063        } else {
1064            p=-p;
1065        }
1066    }
1067    if(leadcoef(p)!=0) {
1068        p = p/leadcoef(p);
1069    }
1070    string thesurfstr = string(p);
1071    if(minp == 1) {
1072        // replace k by rootRepl
1073    }
1074
1075    return (thesurfstr);
1076} // end of surfEqn()
1077example
1078{ "EXAMPLE:"; echo =2;
1079
1080  ring rr0 = 0,(x(1..3)),dp;
1081  poly p = x(1)^3 - x(2)^2;
1082  print(surfEqn(p,list(x(1),x(2),x(3))));
1083
1084  ring rr1 = 0,(x,y,z),dp;
1085  poly I(1) = 2x2-1/2x3 +1-y+1;
1086  print(surfEqn(I(1),list(x,y,z)));
1087
1088  // Steiner surface
1089  poly J(2) = x^2*y^2+x^2*z^2+y^2*z^2-17*x*y*z;
1090  print(surfEqn(J(2),list(x,y,z)));
1091} // end of example surfEqn()
1092
1093
1094proc num_of_vars(ideal I)
1095"
1096USAGE: num_of_vars(ideal I)
1097
1098RETURN: an intvec containing one entry for each ring variable.
1099each contains the sums of all degrees in this variable of all monomials
1100occuring in the ideal.
1101An entry is zero iff the corresponding variable does not occur in the ideal.
1102"
1103{
1104  intvec v;
1105  int i;
1106  poly p;
1107  for(i=size(I);i>0;i--)
1108  {
1109    p=I[i];
1110    while(p!=0)
1111    {
1112        v=v+leadexp(p);
1113        p=p-lead(p);
1114    }
1115  }
1116  return(v);
1117}
1118example {
1119    "EXAMPLE:"; echo = 2;
1120    ring r = 0, (x,y,z),dp;
1121    ideal j0 = x^2-x*y;
1122    num_of_vars(j0);
1123    ideal j1 = x^2-x*y-y;
1124    num_of_vars(j1);
1125    ideal j2 = x^2-x*y-y, x^3-2*y;
1126    num_of_vars(j2);
1127}
1128
1129
1130proc num_vars_id(ideal I)
1131"
1132USAGE: num_vars_id(ideal I)
1133
1134RETURN: The number of ring-variables occurring in the ideal I.
1135"
1136{
1137    intvec v = num_of_vars(I);
1138    int num = 0;
1139    for(int i=size(v);i>0;i--)
1140    {
1141        if (v[i]!=0) { num++; }
1142    }
1143    return(num);
1144}
1145example {
1146    "EXAMPLE:"; echo = 2;
1147    ring r = 0, (x,y,z),dp;
1148    ideal j = x^2-y, x^3-2;
1149    num_vars_id(j);
1150}
1151
1152proc findInList(list obj, list l)
1153"
1154USAGE: findInList(list obj, list l)
1155       Tries to find the object obj in the list l.
1156
1157ASSUME: the object obj[1] can be compared to the objects in the list l
1158
1159RETURN: if obj[1]=l[i] for some i, then return the first such i,
1160        otherwise return 0
1161"
1162{
1163    for(int i=1; i<=size(l); i++) {
1164        if(l[i]==obj[1]) {
1165            return(i);
1166        }
1167    }
1168
1169    return(0);
1170}
1171example {
1172    "EXAMPLE:"; echo = 2;
1173    ring r = 0,(x,y,z), dp;
1174    list a = list(x^2+y^2+z^2+1, x^2+y^2+z^2-1, x^2+y^2-z^2+1, x^2+y^2-z^2-1);
1175    findInList(x^2+y^2+z^2-1, a);
1176    findInList(x^2+y^2+z^2, a);
1177}
1178
1179proc std_primdecGTZ(ideal I, list #)
1180"
1181USAGE: std_primdecGTZ(ideal I, list #)
1182Computes a primdary decomposition pd of I using primdecGTZ and then
1183calls std_for_pd(pd).
1184For the output and options, consult the help of std_for_pd.
1185
1186RETURN: see std_for_pd.
1187"
1188{
1189    list pd = primdecGTZ(I);
1190    return(std_for_pd(pd, #));
1191}
1192example {
1193    "EXAMPLE:"; echo = 2;
1194
1195    ring r = 0, (x,y), dp;
1196    ideal j = y-x^2,z-x^3;
1197    primdecGTZ(j);
1198    std_primdecGTZ(j);
1199    std_primdecGTZ(j,1);
1200}
1201
1202proc std_for_pd(list pd, list #)
1203"
1204USAGE: std_for_pd(list pd, list #)
1205Call std for each of the prime ideals in the list pd
1206replace the prime ideals by their standard-basis.
1207Compute dim() and mult() of each prime component using these standard bases.
1208If an additional argument is given then do the same for the primary components.
1209
1210ASSUME:
1211pd is in the format produced by primdecGTZ() or primdecSY().
1212
1213RETURN: A list, say l, of lists, similar to a list returned by primdecSY() or primdecGTZ().
1214However, each of the entries of l (which is a list l[i]) contains some additional entries:
1215l[1]: the primary ideal
1216l[2]: a standard basis of the associated prime ideal
1217l[3]: dim() of this prime ideal
1218l[4]: mult() of this prime ideal
1219
1220If an additional argument # is given then l[1] changes:
1221l[1]: a standard basis of the primary ideal
1222Morever, there are some more entries:
1223l[5]: dim() of this primary ideal
1224l[6]: mult() of this primary ideal
1225l[7]: l[6] / l[5]
1226"
1227{
1228
1229    if(typeof(pd[1])=="ideal") {
1230        // this is a Singular bug!?
1231//        "bug!";pd;"---";
1232        pd = list(list(pd[1], pd[1]));
1233//        pd;$;
1234    }
1235    list pd_neu;
1236    int i;
1237    list coords;
1238    ideal stdtmp;
1239    ideal stdtmp2;
1240    for(i=1; i<=size(pd); i++) {
1241        stdtmp = std(pd[i][2]);
1242        stdtmp2 = pd[i][1];
1243        if(size(#)>0) {
1244            stdtmp2 = std(stdtmp2);
1245            if(mult(stdtmp)==0) {
1246                pd_neu[i] = list(stdtmp2,
1247                                 stdtmp,
1248                                 dim(stdtmp), mult(stdtmp),
1249                                 dim(stdtmp2), mult(stdtmp2),
1250                                 0);
1251            } else {
1252                pd_neu[i] = list(stdtmp2,
1253                                 stdtmp,
1254                                 dim(stdtmp), mult(stdtmp),
1255                                 dim(stdtmp2), mult(stdtmp2),
1256                                 mult(stdtmp2)/mult(stdtmp));
1257            }
1258        } else {
1259            pd_neu[i] = list(stdtmp2,
1260                             stdtmp,
1261                             dim(stdtmp), mult(stdtmp));
1262        }
1263    }
1264    return(pd_neu);
1265}
1266example {
1267    "EXAMPLE:"; echo = 2;
1268
1269    ring r = 0, (x,y,z), dp;
1270    ideal j = y-x^2,z-x^3;
1271    list pd = primdecGTZ(j);
1272    pd;
1273    std_for_pd(pd, 1);
1274}
1275
1276proc real_solve(ideal to_solve)
1277"
1278USAGE: real_solve(ideal to_solve)
1279
1280RETURN: a list of all real solutions (as strings)
1281of the zero-dimensional ideal to_solve (without multiplicities).
1282
1283REMARK: Until now, it may happen that some points appear more than once.
1284"
1285{
1286    int k;
1287    int i;
1288
1289//    def Isolring = solve(to_solve,30,0,60,"nodisplay");
1290    def Isolring = solve(to_solve,9,0,13,"nodisplay");
1291    setring Isolring;
1292//    list SOL = solve(to_solve, "oldring", "nodisplay");
1293    list real_sols = list();
1294    list tmpl;
1295    for(k=1; k<=size(SOL); k++) {
1296        if(find(string(SOL[k]),"I")==0 && find(string(SOL[k]),"i")==0) {
1297            tmpl = list();
1298            for(i=1; i<=size(SOL[k]); i++) {
1299                tmpl = tmpl + list(string(SOL[k][i]));
1300            }
1301            real_sols = real_sols + list(tmpl);
1302        }
1303    }
1304    return(real_sols);
1305}
1306example {
1307    "EXAMPLE:"; echo = 2;
1308    ring r = 0, (x,y), dp;
1309    number a = 2;
1310    number b = 3;
1311    ideal j = (x^2-a),(y^3-b);
1312    real_solve(j);
1313}
1314
1315proc rootminpoly(list #)
1316"
1317USAGE: rootminpoly(list #)
1318
1319RETURN: A root of the current minpoly
1320as a string representation of a complex number with
1321the given precision #[1] (default: 30).
1322E.g. ring r=(0,s),x,dp; minpoly = s^2-2; => rootminpoly() 1.41421356237309504880168872421
1323
1324ASSUME: The current minpoly is non-zero.
1325"
1326{
1327    int prec = 30;
1328    int k, done;
1329    if(size(#)>0) {
1330        prec = #[1];
1331    }
1332    short = 0;
1333    string str_lag = sprintf("list lag = laguerre_solve(%s);", minpoly);
1334    string str_ring = sprintf("ring r_sqrt = (complex,prec,I),(%s),lp;", parstr(basering));
1335    execute(str_ring);
1336    execute(str_lag);
1337//    lag;
1338    // choose a real solution, if it exists:
1339    done = 0;
1340    for(k=1; k<=size(lag) && done==0; k++) {
1341        if(find(string(lag[k]),"I")==0) {
1342            done = k;
1343        }
1344    }
1345    if(done==0) {
1346//        "no real solution.";
1347    }
1348
1349    if(size(lag)>2) {
1350        // return the first real solution
1351        return(sprintf("%s",lag[done]));
1352    }
1353
1354    if(sprintf("%s",lag[1])[1] == "-") {
1355        return(sprintf("%s",lag[2]));
1356    } else {
1357        if(sprintf("%s",lag[1])[1] == "(") {
1358            if(sprintf("%s",lag[1])[2] == "-") {
1359                return(sprintf("%s",lag[2]));
1360            } else {
1361                return(sprintf("%s",lag[1]));
1362            }
1363        } else {
1364            return(sprintf("%s",lag[1]));
1365        }
1366    }
1367    short = 1;
1368}
1369example
1370{
1371   "EXAMPLE:"; echo =2;
1372   ring r=(0,s),x,dp;
1373   minpoly = s^2-2;
1374   rootminpoly();
1375
1376   ring R=(0,s),x,dp;
1377   minpoly = s^2+2;
1378   rootminpoly();
1379}
1380
1381proc allroots_minpoly(list #)
1382"
1383USAGE: allroots_minpoly(list #)
1384
1385RETURN: a list of strings containing all real roots of the minimal polynomial of the active ring.
1386
1387ASSUME: The current minpoly is non-zero.
1388"
1389{
1390    int prec = 30;
1391    int k, done;
1392    if(size(#)>0) {
1393        prec = #[1];
1394    }
1395    short = 0;
1396    string str_lag = sprintf("list lag = laguerre_solve(%s);", minpoly);
1397    string str_ring = sprintf("ring r_sqrt = (complex,prec,I),(%s),lp;", parstr(basering));
1398    execute(str_ring);
1399    execute(str_lag);
1400
1401    // only take the real solutions:
1402    done = 0;
1403    list real_sols = list();
1404    for(k=1; k<=size(lag) && done==0; k++) {
1405        if(find(string(lag[k]),"I")==0) {
1406            real_sols = real_sols + list(string(lag[k]));
1407        }
1408    }
1409    return(real_sols);
1410}
1411example {
1412    "EXAMPLE:"; echo = 2;
1413   ring r=(0,s),x,dp;
1414   minpoly = s^3-2;
1415   allroots_minpoly();
1416
1417   ring R=(0,s),x,dp;
1418   minpoly = s^2-2;
1419   allroots_minpoly();
1420}
1421
1422proc decstr2ratstr(string str)
1423"
1424USAGE: decstr2ratstr(string str)
1425Convert a decimal number of not more than 30 digits to a rational number with 14 digits.
1426
1427REMARK: This procedure still has to be adapted to accept other precisions!
1428"
1429{
1430    ring decR = (complex,30,I),(x),lp;
1431    execute("number r="+str+";");
1432    execute("r = "+truncdec(r,14)+";");
1433    return(real2ratstr(r));
1434}
1435
1436proc real2ratstr(number r)
1437"
1438USAGE: real2ratstr(number r)
1439
1440RETURN: A string containing a rational number representing the decimal number r.
1441
1442ASSUME: The current ring has either real or complex base field.
1443"
1444{
1445    string ratstr = "number("+string(r*number(10000000000000000))+")/number(10000000000000000)";
1446    return(ratstr);
1447}
1448
1449proc truncdec(number r, int decs)
1450"
1451USAGE: truncdec(number r, int decs)
1452Truncates a decimal number r to the given number (decs) of digits.
1453
1454RETURN: A string representing the truncated number.
1455"
1456{
1457    string str = string(r);
1458    return(str[1,(decs+2)]);
1459}
1460
1461proc string_of_vars(ideal I)
1462"
1463USAGE: string_of_vars(ideal I)
1464
1465RETURN: A string of all variables contained in the ideal I, separated by commas.
1466"
1467{
1468    list listvars = list();
1469    intvec v;
1470    int i;
1471    poly p;
1472    for(i=size(I);i>0;i--)
1473    {
1474        p=I[i];
1475        while(p!=0)
1476        {
1477            v=v+leadexp(p);
1478            p=p-lead(p);
1479        }
1480    }
1481    for(i=1; i<=nvars(basering); i++) {
1482        if(v[i] > 0) {
1483            listvars = listvars + list(var(i));
1484        }
1485    }
1486    string strvars = string(listvars);
1487    return(strvars);
1488}
Note: See TracBrowser for help on using the repository browser.