source: git/Singular/LIB/surfex.lib @ 72382c2

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