source: git/Singular/LIB/surfex.lib @ 6dbad9d

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