source: git/Singular/LIB/surfex.lib @ 526587

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