User:AnatolV/Helper Functions: Difference between revisions

From Rosetta Code
Content added Content deleted
(adding gnuplot sample, editing)
m (just minor edit)
Line 2: Line 2:
;Note:
;Note:
* Good helper function usually encapsulates typical set of actions for current tasks, supplies often used default values, interacting with other helper functions, etc.
* Good helper function usually encapsulates typical set of actions for current tasks, supplies often used default values, interacting with other helper functions, etc.
* Many samples of using presented functions can be found here on RC.<br><br>
* Many samples of using presented functions can be found here on RC.
* Many of these functions are already here on RC. But some of them are upgraded. So, this is the place to get latest versions.
<br><br>
=R Helper Functions=
=R Helper Functions=
One of the R's great powers is its unlimited number of great and good packages, virtually thousands of them. For any applications big or small you can find a package.<br>
One of the R's great powers is its unlimited number of great and good packages, virtually thousands of them. For any applications big or small you can find a package.<br>
Line 101: Line 103:
function pmat01(mat, color) {
function pmat01(mat, color) {
// DCLs
// DCLs
var cvs = document.getElementById('canvId');
var cvs = document.getElementById('cvsId');
var ctx = cvs.getContext("2d");
var ctx = cvs.getContext("2d");
var w = cvs.width; var h = cvs.height;
var w = cvs.width; var h = cvs.height;
Line 121: Line 123:
Not to mention bad color support and scaling.<br>
Not to mention bad color support and scaling.<br>
In addition, there are no built-in string manipulation functions, except of concatenation.<br>
In addition, there are no built-in string manipulation functions, except of concatenation.<br>
So, presented here helper functions help to fix some of these shortcomings. At the same time, they simplify
So, presented here helper functions help to fix some of these shortcomings. At the same time, they simplify some often used common actions.
==Plotting Helper Functions==
==Plotting Helper Functions==
Functions presented here are directly or inderectly related to plotting.
Many of these functions are already here on RC.
<lang parigp>
<lang parigp>
\\ 2 old plotting helper functions 3/2/16
\\ 2 old plotting helper functions 3/2/16
Line 205: Line 207:
</lang>
</lang>
==String Functions==
==String Functions==
The first 4 are already here on RC. A few others I will keep on hold (hoping to create a tasks later).
The first 4 are already here on RC. A few others I will keep on hold (hoping to create tasks later).


<lang parigp>
<lang parigp>

Revision as of 21:52, 10 April 2017

This page presents only helper functions that are generic enough. They were used in one or more contributions on RC and will be used again and again.

Note
  • Good helper function usually encapsulates typical set of actions for current tasks, supplies often used default values, interacting with other helper functions, etc.
  • Many samples of using presented functions can be found here on RC.
  • Many of these functions are already here on RC. But some of them are upgraded. So, this is the place to get latest versions.



R Helper Functions

One of the R's great powers is its unlimited number of great and good packages, virtually thousands of them. For any applications big or small you can find a package.
E.g., in the case of Voronoi diagram there are many of packages: deldir, alphahull, dismo, ggplot, ggplot2, tripack, CGAL, etc. Not to mention all linked packages. Do you need random colors? Again, find a few packages more...
So, sometimes you can save time and a hard drive space avoiding downloading and installing packages, and using a few helper functions instead.

Note
  • All plotting helper functions are using matrix mat or 2 vectors X,Y from the dump file created by plotmat().
  • The file names used are without extension (which will be added as ".png", ".dmp" and ".dat" when needed).
  • Requesting dump file is useful if the generating/plotting time is big. Having a dump file makes it easy and fast to repeat plotting with different colors, titles, etc.
  • If number of generated dots is very big then plotting from a dump file could be very slow too. Actually, plotv2() shows almost "pure" plotting time.

Works with: R version 3.3.1 and above

<lang r>

    1. HFR#1 plotmat(): Simple plotting using matrix mat (filled with 0/1). v. 8/31/16
  1. Where: mat - matrix; fn - file name; clr - color; ttl - plot title;
  2. dflg - writing dump file flag (0-no/1-yes): psz - picture size.

plotmat <- function(mat, fn, clr, ttl, dflg=0, psz=600) {

 m <- nrow(mat); d <- 0;
 X=NULL; Y=NULL;
 pf = paste0(fn, ".png"); df = paste0(fn, ".dmp");
 for (i in 1:m) {
   for (j in 1:m) {if(mat[i,j]==0){next} else {d=d+1; X[d] <- i; Y[d] <- j;} }
 };
 cat(" *** Matrix(", m,"x",m,")", d, "DOTS\n");
 # Dumping if requested (dflg=1).
 if (dflg==1) {dump(c("X","Y"), df); cat(" *** Dump file:", df, "\n")};
 # Plotting
 plot(X,Y, main=ttl, axes=FALSE, xlab="", ylab="", col=clr, pch=20);
 dev.copy(png, filename=pf, width=psz, height=psz);
 # Cleaning 
 dev.off(); graphics.off();

}

    1. HFR#2 plotv2(): Simple plotting using 2 vectors (dumped into ".dmp" file).
  1. Where: fn - file name; clr - color; ttl - plot title; psz - picture size.
  2. v. 8/31/16

plotv2 <- function(fn, clr, ttl, psz=600) {

 cat(" *** START:", date(), "clr=", clr, "psz=", psz, "\n");
 cat(" *** File name -", fn, "\n");
 pf = paste0(fn, ".png"); df = paste0(fn, ".dmp");
 source(df);
 d <- length(X);
 cat(" *** Source dump-file:", df, d, "DOTS\n");
 cat(" *** Plot file -", pf, "\n");
 # Plotting
 plot(X, Y, main=ttl, axes=FALSE, xlab="", ylab="", col=clr, pch=20);
 # Writing png-file
 dev.copy(png, filename=pf, width=psz, height=psz);
 # Cleaning 
 dev.off(); graphics.off();
 cat(" *** END:", date(), "\n");

}

    1. HFR#3 randHclr(): Return random hex color.

randHclr <- function() {

 m=255; r=g=b=0;
 r <- sample(0:m, 1, replace=TRUE);
 g <- sample(0:m, 1, replace=TRUE);
 b <- sample(0:m, 1, replace=TRUE);
 return(rgb(r,g,b,maxColorValue=m));

} </lang>

JavaScript Helper Functions

JavaScript has many standard libraries becoming embedded objects. e.g., Math, Date, Array, RegExp, etc. But also there are many custom "monster" like (in size and documentation) libraries, e.g., D3.js, Node.js, Riot.js, jQuery, Dojo, YUI, etc.
The problem with these libraries is that they are forcing you to learn, actually, "new" language. In addition, there is no guarantee, that they would be stable and maintained well.
The good alternative is always to use just 2-3 small helper functions if it is possible for your task.

The same I would suggest JavaScript users about "declarative JavaScript". It reminds me OOP (Object Oriented Programming) hype! But OOP is dead already, and now declarative JavaScript is hyped?? Don't let you be foolish again. Remember: you need to learn and use "monster" libraries!?

What "declarative JavaScript" is promising (and actually giving you by presented new functions, tags, etc.)?
This is a fantastically sounding: "You are telling JavaScript what to do, but not programming actually". Think! It is the same as good HFJS is doing! For example, using randhclr() and pmat01() is the same as "telling JavaScript": "Use random hex color and plot matrix you have". It's just 1 statement: pmat01(mat,randhclr()).

In other words, look at these new libraries as a set of good helper functions for your projects.
So, all these new libraries are good for certain type of projects, especially if company have created this particular library and using it for inner projects. The good such sample is Facebook JavaScript library React.js, which is having/supporting a lot of unique functions and tags. Think again: do you need all of them?

<lang javascript> // HFJS#1 Like in PARI/GP: return random number 0..max-1. function randgp(max) {return Math.floor(Math.random()*max)}

// HFJS#2 Return random hex color. function randhclr() {

 return "#"+
 ("00"+randgp(256).toString(16)).slice(-2)+
 ("00"+randgp(256).toString(16)).slice(-2)+
 ("00"+randgp(256).toString(16)).slice(-2)

}

// HFJS#3: Plot any matrix mat (filled with 0,1) function pmat01(mat, color) {

 // DCLs
 var cvs = document.getElementById('cvsId');
 var ctx = cvs.getContext("2d"); 
 var w = cvs.width; var h = cvs.height;
 var m = mat[0].length; var n = mat.length;
 // Cleaning canvas and setting plotting color 
 ctx.fillStyle="white"; ctx.fillRect(0,0,w,h);
 ctx.fillStyle=color;
 // MAIN LOOP
 for(var i=0; i<m; i++) {
   for(var j=0; j<n; j++) {
     if(mat[i][j]==1) { ctx.fillRect(i,j,1,1)};
   }//fend j
 }//fend i

}//func end </lang>

PARI/GP Helper Functions

PARI/GP built-in plotting functions are good only for instant draft math function curves plotting. Not to mention bad color support and scaling.
In addition, there are no built-in string manipulation functions, except of concatenation.
So, presented here helper functions help to fix some of these shortcomings. At the same time, they simplify some often used common actions.

Plotting Helper Functions

Functions presented here are directly or inderectly related to plotting. <lang parigp> \\ 2 old plotting helper functions 3/2/16 \\ HFGP#1 insm(): Check if x,y are inside matrix mat (+/- p deep). insm(mat,x,y,p=0)={my(xz=#mat[1,],yz=#mat[,1]);

 return(x+p>0 && x+p<=xz && y+p>0 && y+p<=yz && x-p>0 && x-p<=xz && y-p>0 && y-p<=yz)}

\\ HFGP#2 plotmat(): Simple plotting using a square matrix mat (filled with 0/1). plotmat(mat)={

 my(xz=#mat[1,],yz=#mat[,1],vx=List(),vy=vx,x,y);
 for(i=1,yz, for(j=1,xz, if(mat[i,j]==0, next, listput(vx,i); listput(vy,j))));
 print(" *** matrix(",xz,"x",yz,") ",#vy, " DOTS");
 plothraw(Vec(vx),Vec(vy));

}

\\ 2 new plotting helper functions 11/27/16 \\ HFGP#3 wrtmat(): Writing file fn containing X,Y coordinates from matrix mat. \\ Created primarily for using file in Gnuplot, also for re-plotting. wrtmat(mat, fn)={

 my(xz=#mat[1,],yz=#mat[,1],ws,d=0);
 for(i=1,yz, for(j=1,xz, if(mat[i,j]==0, next, d++; ws=Str(i," ",j); write(fn,ws))));
 print(" *** matrix(",xz,"x",yz,") ",d, " DOTS put in ",fn);

}

\\ HFGP#4 plotff(): Plotting from a file written by the wrtmat(). \\ Saving possibly huge generation time if re-plotting needed. plotff(fn)={

 my(F,nf,vx=List(),vy=vx,Vr);
 F=readstr(fn); nf=#F;
 print(" *** Plotting from: ", fn, " - ", nf, " DOTS");
 for(i=1,nf, Vr=stok(F[i],","); listput(vx,eval(Vr[1])); listput(vy,eval(Vr[2])));
 plothraw(Vec(vx),Vec(vy));

}

\\ HFGP#5 iPlotmat() Improved simple plotting using matrix mat (color and scaling added). \\ Matrix should be filled with 0/1. 7/6/16 \\ Writing a dump file fn according to the flag - dflg (0-no/1-yes). \\ A dump file added mostly for the gnuplot plotting, also for re-plotting. iPlotmat(mat,clr,fn="dfn.dat",dflg=0)={

 my(xz=#mat[1,],yz=#mat[,1],vx=List(),vy=vx,xmin,xmax,ymin,ymax,c=0.625);
 \\ Dumping if requested (dflg=1).
 if (dflg==1,wrtmat(mat, fn));
 for(i=1,yz, for(j=1,xz, if(mat[i,j]==0, next, listput(vx,i); listput(vy,j))));
 xmin=listmin(vx); xmax=listmax(vx); ymin=listmin(vy); ymax=listmax(vy);
 plotinit(0); plotcolor(0,clr);
 plotscale(0, xmin,xmax,ymin,ymax);
 plotpoints(0, Vec(vx)*c,Vec(vy));
 plotdraw([0,xmin,ymin]);
 if (dflg==0, print(" *** matrix: ",xz,"x",yz,", ",#vy," DOTS"));

}

\\ HFGP#6 iPlotV2(): Improved plotting from a file written by the wrtmat(). (color added) \\ Saving possibly huge generation time if re-plotting needed. 7/6/16 iPlotV2(fn, clr)={

 my(F,nf,vx=List(),vy=vx,Vr,xmin,xmax,ymin,ymax,c=0.625);
 F=readstr(fn); nf=#F;
 print(" *** Plotting from: ", fn, " - ", nf, " DOTS");
 for(i=1,nf, Vr=stok(F[i]," "); listput(vx,eval(Vr[1])); listput(vy,eval(Vr[2])));
 xmin=listmin(vx); xmax=listmax(vx); ymin=listmin(vy); ymax=listmax(vy);
 plotinit(0); plotcolor(0,clr);
 plotscale(0, xmin,xmax,ymin,ymax);  
 plotpoints(0, Vec(vx)*c,Vec(vy));
 plotdraw([0,xmin,ymin]);

}

\\ HFGP#7 Plot the line from x1,y1 to x2,y2. 4/11/16 plotline(x1,y1,x2,y2,w=0)={plotmove(w, x1,y1);plotrline(w,x2-x1,y2-y1);}

\\ HFGP#8 Convert value expressed in degrees to radians. 5/7/16 (next 3 - same date) rad2(degs)={return(degs*Pi/180.0)}

\\ HFGP#9 Convert value expressed in radians to degrees. deg2(rads)={return(rads*180.0/Pi)} \\value in rads×180.0 /p

\\ HFGP#10 Convert Polar coordinates r,a to Cartesian. cartes2(r,a,rndf=0)={my(v,x,y); x=r*cos(a); y=r*sin(a);

 if(rndf==0, return([x,y]), return(round([x,y])))}

\\ HFGP#11 Convert Cartesian coordinates x,y to polar. polar2(x,y)={my(v,r,a); r=sqrt(x^2+y^2); a=atan(y/x); return([r,a])} </lang>

String Functions

The first 4 are already here on RC. A few others I will keep on hold (hoping to create tasks later).

<lang parigp> \\ SF#1 ssubstr(): Returns the substring of the string str specified by the start \\ position s and a length n. If n=0 then to the end of str. 3/5/16 ssubstr(str,s=1,n=0)={

 my(vt=Vecsmall(str),ve,vr,vtn=#str,n1);
 if(vtn==0,return(""));
 if(s<1||s>vtn,return(str));
 n1=vtn-s+1; if(n==0,n=n1); if(n>n1,n=n1);
 ve=vector(n,z,z-1+s); vr=vecextract(vt,ve); return(Strchr(vr));

}

\\ SF#2 stok(): Tokenize a string str according to 1 character delimiter d. \\ Return a list of tokens. 3/5/16 \\ Note: It is using ssubstr(). stok(str,d)={

 my(d1c=ssubstr(d,1,1),str=Str(str,d1c),vt=Vecsmall(str),d1=sasc(d1c),
    Lr=List(),sn=#str,v1,p1=1,vo=32);
 if(sn==1, return(List(""))); if(vt[sn-1]==d1,sn--);
 for(i=1,sn, v1=vt[i];
   if(v1!=d1, vo=v1; next);
   if(vo==d1||i==1, listput(Lr,""); p1=i+1; vo=v1; next);
   if(i-p1>0, listput(Lr,ssubstr(str,p1,i-p1)); p1=i+1);
   vo=v1;
 ); 
 return(Lr);

}

\\ SF#3 sreverse(): Return the reversed string str. 3/3/2016 sreverse(str)={return(Strchr(Vecrev(Vecsmall(str))))}

\\ SF#4 srepeat(): Repeat a string str the specified number of times ntimes \\ and return composed string. 3/3/2016 srepeat(str,ntimes)={

 my(srez=str,nt=ntimes-1);
 if(ntimes<1||#str==0,return("")); 
 if(ntimes==1,return(str)); 
 for(i=1,nt, srez=concat(srez,str));
 return(srez);

}

\\ SF#5 <<coming soon>> </lang>

gnuplot Helper File-Functions

File for the load command is the only possible imitation of the fine function in the gnuplot.

plotff.gp - Plotting from any data-file with 2 columns (space delimited), and writing to png-file.
Especially useful to plot colored fractals using points, also for re-plotting.

Works with: gnuplot version 5.0 (patchlevel 3) and above

<lang gnuplot>

    1. plotff.gp 11/27/16 aev
    2. Plotting from any data-file with 2 columns (space delimited), and writing to png-file.
    3. Especially useful to plot colored fractals using points.
    4. Note: assign variables: clr, filename and ttl (before using load command).

reset set terminal png font arial 12 size 640,640 ofn=filename.".png" set output ofn unset border; unset xtics; unset ytics; unset key; set size square dfn=filename.".dat" set title ttl font "Arial:Bold,12" plot dfn using 1:2 with points pt 7 ps 0.5 lc @clr set output </lang>