Ilya Zakharevich on Sat, 5 Dec 1998 03:29:51 -0500 (EST) |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
[PATCH] Splines for parametric plot |
This patch cleans up my previous patch (which added splines support for plotting), and allows splines with parametric plotting, It should be applied *after* my previous plotting patches. Try it with ploth(x=0,6,[x*sin(x),x*cos(x)],128+256,9) ploth(x=0,6,[x*sin(x),x*cos(x)],128+256+1,9) Enjoy, Ilya P.S. If the lines in the highlvl.c patch are too long, all it does is an addition of ", 256 use cubic splines". --- ./src/graph/plotport.c.with_splines Sun Nov 8 21:26:24 1998 +++ ./src/graph/plotport.c Sat Dec 5 03:16:52 1998 @@ -67,6 +67,11 @@ dsprintf9(double d, char *buf) return buf; /* Should not happen? */ } +static const char * const quark = "quark"; /* Used as a special-case */ +static GEN quark_gen; + +#define READ_EXPR(s) ((s)==quark? quark_gen : lisexpr(s)) + void plot(entree *ep, GEN a, GEN b, char *ch) { @@ -93,7 +98,7 @@ plot(entree *ep, GEN a, GEN b, char *ch) av2=avma; limite=(av2+bot)>>1; for (i=1; i<=ISCR; i++) { - gaffect(lisexpr(ch),y[i]); + gaffect(READ_EXPR(ch),y[i]); if (gcmp(y[i],ysml)<0) ysml=y[i]; if (gcmp(y[i],ybig)>0) ybig=y[i]; x = addrr(x,dx); @@ -826,7 +831,7 @@ single_recursion(dblPointList *pl,char * if (depth==RECUR_MAXDEPTH) return; yy=cgetr(3); xx=gmul2n(gadd(xleft,xright),-1); - ep->value = (void*) xx; gaffect(lisexpr(ch), yy); + ep->value = (void*) xx; gaffect(READ_EXPR(ch), yy); if (dy) { @@ -855,7 +860,7 @@ param_recursion(dblPointList *pl,char *c if (depth==PARAMR_MAXDEPTH) return; xx=cgetr(3); yy=cgetr(3); tt=gmul2n(gadd(tleft,tright),-1); - ep->value = (void*)tt; p1=lisexpr(ch); + ep->value = (void*)tt; p1=READ_EXPR(ch); gaffect((GEN)p1[1],xx); gaffect((GEN)p1[2],yy); if (dx && dy) @@ -907,7 +912,7 @@ rectplothin(entree *ep, GEN a, GEN b, ch dx=gdivgs(gsub(b,a),testpoints-1); x = cgetr(prec); gaffect(a,x); push_val(ep, x); - av2=avma; p1=lisexpr(ch); tx=typ(p1); + av2=avma; p1=READ_EXPR(ch); tx=typ(p1); if (!is_matvec_t(tx)) { xsml = gtodouble(a); xbig=gtodouble(b); @@ -957,14 +962,14 @@ rectplothin(entree *ep, GEN a, GEN b, ch { tleft=cgetr(prec); tright=cgetr(prec); av2=avma; - gaffect(a,tleft); ep->value = (void*)tleft; p1=lisexpr(ch); + gaffect(a,tleft); ep->value = (void*)tleft; p1=READ_EXPR(ch); gaffect((GEN)p1[1],xleft); gaffect((GEN)p1[2],yleft); for (i=0; i<testpoints-1; i++) { if (i) { gaffect(tright,tleft); gaffect(xright,xleft); gaffect(yright,yleft); } - gaddz(tleft,dx,tright); ep->value = (void*)tright; p1=lisexpr(ch); + gaddz(tleft,dx,tright); ep->value = (void*)tright; p1=READ_EXPR(ch); gaffect((GEN)p1[1],xright); gaffect((GEN)p1[2],yright); Appendx(&pl[0],&pl[0],rtodbl(xleft)); @@ -980,11 +985,11 @@ rectplothin(entree *ep, GEN a, GEN b, ch { av2=avma; gaffect(a,xleft); ep->value = (void*) xleft; - gaffect(lisexpr(ch),yleft); + gaffect(READ_EXPR(ch),yleft); for (i=0; i<testpoints-1; i++) { gaddz(xleft,dx,xright); ep->value = (void*) xright; - gaffect(lisexpr(ch),yright); + gaffect(READ_EXPR(ch),yright); Appendx(&pl[0],&pl[0],rtodbl(xleft)); Appendy(&pl[0],&pl[1],rtodbl(yleft)); @@ -1002,7 +1007,7 @@ rectplothin(entree *ep, GEN a, GEN b, ch if (single_c) for (i=0; i<testpoints; i++) { - p1 = lisexpr(ch); + p1 = READ_EXPR(ch); pl[0].d[i]=gtodouble(x); Appendy(&pl[0],&pl[1],gtodouble(p1)); gaddz(x,dx,x); avma=av2; @@ -1014,7 +1019,7 @@ rectplothin(entree *ep, GEN a, GEN b, ch for (i=0; i<testpoints; i++) { - p1 = lisexpr(ch); + p1 = READ_EXPR(ch); for (j=0; j<nl; j=k) { k=j+1; z=gtodouble((GEN)p1[k]); @@ -1029,7 +1034,7 @@ rectplothin(entree *ep, GEN a, GEN b, ch else /* plothmult */ for (i=0; i<testpoints; i++) { - p1 = lisexpr(ch); + p1 = READ_EXPR(ch); pl[0].d[i]=gtodouble(x); for (j=1; j<nl; j++) { Appendy(&pl[0],&pl[j],gtodouble((GEN)p1[j])); } gaddz(x,dx,x); avma=av2; @@ -1039,65 +1044,59 @@ rectplothin(entree *ep, GEN a, GEN b, ch return pl; } -/* Uses highlevel functions to implement splines in low-level functions. - +/* Uses highlevel plotting functions to implement splines as + a low-level plotting function. Most probably one does not need to make varn==0 into pure variable, since plotting functions should take care of this. */ static void rectsplines(long ne, double *x, double *y, long lx, long flag) { - long i, j, oldavma = avma, dokill = 0; + long i, j, oldavma = avma; GEN xa = cgetg(lx + 1, t_VEC), ya = cgetg(lx + 1, t_VEC); GEN xas = cgetg(4 + 1, t_VEC), yas = cgetg(4 + 1, t_VEC); - void *old1; - entree *var0 = varentries[ordvar[0]], *var1 = varentries[ordvar[1]]; - char *name = 0; - static const char * const fakename = "splines__"; + GEN ttas = cgetg(4 + 1, t_VEC); + GEN param = cgetg(2 + 1, t_VEC); + GEN tas; + entree *var0 = varentries[ordvar[0]]; - if (!var1) { - GEN res = lisexpr((char*)fakename); - dokill = 1; - var1 = varentries[ordvar[1]]; - if (!var1 || !(name = var1->name) && strcmp(name, fakename)) - err(talker, "panic: no new var in splines"); - } if (lx < 4) err(talker, "Too few points (%ld) for spline plot", lx); - old1 = var1->value; - if (!name) - name = var1->name; for (i = 1; i <= lx; i++) { xa[i] = (long) dbltor(x[i-1]); ya[i] = (long) dbltor(y[i-1]); } + if (flag & PLOT_PARAMETRIC) { + for (j = 1; j <= 4; j++) + ttas[j] = (long)stoi(j); + tas = ttas; + quark_gen = param; + } else + tas = xas; for (i = 0; i <= lx - 4; i++) { long oavma = avma; - GEN poly; - for (j = 1; j <= 4; j++) { + for (j = 1; j <= 4; j++) { /* Need to copy to have + correct headers of xas and yas. */ xas[j] = xa[i + j]; - yas[j] = ya[i + j]; + yas[j] = ya[i + j]; } - poly = polint(xas, yas, polx[0], NULL); - var1->value = (void*)poly; /* Temporary make it into expr */ + if (flag & PLOT_PARAMETRIC) { + param[1] = (long)polint(ttas, xas, polx[0], NULL); + param[2] = (long)polint(ttas, yas, polx[0], NULL); + } else + quark_gen = polint(xas, yas, polx[0], NULL); + rectploth( ne, var0, - (GEN)(i==0 ? xa[1] : xa[i+2]), - (GEN)(i==lx-4 ? xa[lx] : xa[i+3]), - name, 4, /* XXXX precision */ + (GEN)(i==0 ? tas[1] : tas[2]), + (GEN)(i==lx-4 ? tas[4] : tas[3]), + (char*)quark, /* Remove const */ + 4, /* XXXX precision */ (PLOT_RECURSIVE | PLOT_NO_RESCALE | PLOT_NO_FRAME - | PLOT_NO_AXE_Y | PLOT_NO_AXE_X), + | PLOT_NO_AXE_Y | PLOT_NO_AXE_X) + | (flag & PLOT_PARAMETRIC), 2); /* Start with 3 points */ avma = oavma; } - var1->value = old1; /* Restore the old value */ - -#if 0 /* XXXX Does not work??? */ - if (dokill) { - kill0(var1); - manage_var(1,NULL); - } -#endif - avma = oldavma; } @@ -1216,11 +1215,17 @@ rectplothrawin(long stringrect, long dra rectpoints0(drawrect,x.d,y.d,nbpoints); } if ((flags & PLOT_POINTS_LINES) || !(flags & PLOT_POINTS)) { - rectlinetype(drawrect, rectline_itype + ltype); /* Graphs. */ - if ((flags & PLOT_PARAMETRIC) || !(flags & PLOT_SPLINES)) - rectlines0(drawrect,x.d,y.d,nbpoints,0); - else - rectsplines(drawrect,x.d,y.d,nbpoints,0); + if (flags & PLOT_SPLINES) { + /* rectsplines will call us back with ltype == 0 */ + int old = rectline_itype; + + rectline_itype = rectline_itype + ltype; + rectsplines(drawrect,x.d,y.d,nbpoints,flags); + rectline_itype = old; + } else { + rectlinetype(drawrect, rectline_itype + ltype); /* Graphs. */ + rectlines0(drawrect,x.d,y.d,nbpoints,0); + } } ltype++; /* Graphs. */ } --- ./src/language/highlvl.c~ Sun Nov 8 21:26:30 1998 +++ ./src/language/highlvl.c Sat Dec 5 03:22:56 1998 @@ -177,7 +177,7 @@ char *helpmessages_highlevel[]={ "plotcursor(w): current position of cursor in rectwindow w", "plotdraw(list): draw vector of rectwindows list at indicated x,y positions; list is a vector w1,x1,y1,w2,x2,y2,etc. . ", "plotfile(filename): set the output file for plotting output. \"-\" redirects to the same place as PARI output", - "ploth(X=a,b,expr,{flags=0},{n=0}): plot of expression expr, X goes from a to b in high resolution. Both flags and n are optional. Binary digits of flags mean : 1 parametric plot, 2 recursive plot, 8 omit x-axis, 16 omit y-axis, 32 omit frame, 64 do not join points, 128 plot both lines and points. n specifies number of reference points on the graph (0=use default value). Returns a vector for the bounding box", + "ploth(X=a,b,expr,{flags=0},{n=0}): plot of expression expr, X goes from a to b in high resolution. Both flags and n are optional. Binary digits of flags mean : 1 parametric plot, 2 recursive plot, 8 omit x-axis, 16 omit y-axis, 32 omit frame, 64 do not join points, 128 plot both lines and points, 256 use cubic splines. n specifies number of reference points on the graph (0=use default value). Returns a vector for the bounding box", "plothraw(listx,listy,{flag=0}): plot in high resolution points whose x (resp. y) coordinates are in listx (resp. listy). If flag is non zero, join points", "plothsizes(): returns array of 6 elements: terminal width and height, sizes for ticks in horizontal and vertical directions (in pixels), width and height of characters", "plotinit(w,x,y): initialize rectwindow w to size x,y",