This site is supported by donations to The OEIS Foundation.

User:Anatoly E. Voevudko/VoeLib.gp

From OeisWiki
Jump to: navigation, search

VoeLib.gp is the General Purpose PARI Scripts Library (presentation, lists/vectors/matrices handling, testing, calculating metrics, handling strings, plotting helper functions).

Notes for those who are new to MediaWiki pages:

  • Everyone is allowed to view and copy source.
  • To copy or save a page without HTML tags click "view source" tab (at the top of this Wiki page).
  • Then select all code inside Wiki page sub-window with source (depends on browser and OS), "Copy" it and save.
  • Clean-up rules: delete all rows having at position 1 not a whitespace.
  • You may add "\\" in front of such rows instead of deleting. Or you can use cleanwsf() & clean4gpf() from VoeLib.gp to do this hard job for you. Note: both cleanwsf() & clean4gpf() work fine only here (with my style of formatting and PARI/GP scripts).


Generic Functions (presentation, lists/vectors/matrices handling)

  /* Author: Anatoly E. Voevudko 
   * Library of small functions useful for text presentation of numbers, working 
   * with lists/vectors, testing, calculating metrics and handling strings.
   * This PARI/GP library of scripts is a free software, covered by the GNU 
   * General Public License, and comes WITHOUT ANY WARRANTY WHATSOEVER.
   * NOTE: 1. Functions #2-#10 work with lists only/mostly. List items are mostly
   *          positive integers.
   *          If you need vector, then convert vector to list (simple assignment),
   *          apply function, and convert result (if it is a list) back to vector.
   *       2. Functions #2.1 - #2.5 were tested only for Win XP, but OK for any Windows. 
   *       3. Functions #3.1 - #3.9 calculate the most popular metrics applied 
   *          to equations like a+b=c, including A^x+B^y=C^z. They are used
   *          for definition of conjectures, estimation, selection etc.
   *       4. Functions #4.1 - #4.15 represent the set of basic string functions. 
   *          This is a very basic set of string functions, - just for presentation purposes,
   *          not for heavy text processing.
   *          Note: 1. Results can vary from results of similarly looking string functions 
   *          ====     you are using in C/C++, VB, Perl, PHP, etc.
   *                2. Some functions are using another functions from this set.
   *                   So, load the whole set.
   *       5. Functions #5.1 - #5.7 are simple plotting helper functions (see samples 
   *          of using in MyMixedPariScripts.gp).
   *       ## Functions working with files are using Windows conventions. Update them or
   *          delete them together with testing samples.
   * Updates: 9/11/2015 - 04/27/2016
   */
  addhelp(VoeLib, "VoeLib.gp: Library of small functions useful for text presentation of numbers, working with lists/vectors/matrices, testing, calculating metrics and handling strings.");
  \\* #1 Last updated: 9/11/2015
  addhelp(factintxt, "factintxt(n): Factors of n in the text form.");
  factintxt(n)=
  {my(F=factor(n), m="", fit="", pend="", fn);
    if(n==1, return("1")); 
    fn=#F[,1];
    for(i=1, fn, if(i>1,m="*"); pend=""; if(F[i,2]>1, pend=Str("^", F[i,2]));
        fit = Str(fit, m, F[i,1],pend));
    return(fit);
  }
  
  \\* #2 - #3 Last updated: 9/11/2015
  addhelp(findinlist, "findinlist(list,item,sind=1): Find the first item in any list starting with sind index (return 0 or index).");
  findinlist(list, item, sind=1)=
  {my(idx=0, ln=#list);
    if(ln==0 || sind<1 || sind>ln, return(0)); 
    for(i=sind, ln, if(list[i]==item, idx=i; break;)); 
    return(idx);
  }
  addhelp(findinlista, "findinlista(list,item,sind=1): Find all items in any list starting with sind index (return List() or List([ind1, ind2,...])).");
  findinlista(list, item, sind=1)=
  {my(ln=#list, Li=List());
    if(ln==0 || sind<1 || sind>ln, return(Li)); 
    for(i=sind, ln, if(list[i]==item, listput(Li,i))); 
    return(Li);
  }
  \\* #4 - #5 Last updated: 9/17/2015
  \\* NOTE: Error token et must be < min(list[i]) to avoid confusion.
  \\* ====  E.g., -1 for positive integers.
  \\*       Usually, et means bad parameters (also known as the list of formal 
  \\*       variables or arguments) in function call, so nothing done yet.
  addhelp(listmax, "listmax(list, sind=1, et=-1): Return max number in the list of integers starting with sind index.");
  listmax(list, sind=1, et=-1)= 
  {my(ln=#list, li, mn);
     if(ln==0 || sind<1 || sind>ln, return(et)); 
     mn=list[sind];
     for(i=sind+1, ln, li=list[i]; if(li>mn, mn=li););
     return(mn);
  }
  addhelp(listmin, "listmin(list, sind=1, et=-1): Return min number in the list of integers starting with sind index.");
  listmin(list, sind=1, et=-1)= 
  {my(ln=#list, li, mn);
     if(ln==0 || sind<1 || sind>ln, return(et));
     mn=list[sind];
     for(i=sind+1, ln, li=list[i]; if(li<mn, mn=li););
     return(mn);
  }
  \\* #6 Last updated: 9/21/2015
  \\* NOTE: Returns error token et: -1,0,ind>0 
  \\*       (bad parameters/identical/NOT identical @ind). 
  addhelp(volcomp, "volcomp(v1,v2): Vectors or lists compare, i.e., compare 2 vectors v1 and v2 (or 2 lists, or vector & list).");
  volcomp(v1,v2)=
     {my(v1n=#v1,v2n=#v2,vmn=min(v1n,v2n),ip,cr=1,et=0);
     if(v1n<1||v2n<1, return(-1)); \\ wrong size(s)
     print(" *** COMPARE v1&v2 w/types: ",type(v1),"/",type(v2),"; w/sizes: ",v1n,"/",v2n);
     if(v1n!=v2n, print(" *** can compare only first ",vmn," elements."));
     for(i=1, vmn, if(v1[i]!=v2[i], ip=i; et=ip; cr=0; break));
     if(cr, print(" *** v1 and v2 are identical!"),
            print(" *** v1 and v2 are NOT identical at v1[",ip,"]!?"));
     return(et);
  }
  \\* #7 Last updated: 9/26/2015
  \\* This is to help sorting text lists, and other non numeric objects in the list,
  \\* which are related to (unsorted) input list.
  \\* Note: If an input list has multiple equal items, then first of all convert it 
  \\*       using listwui(list).
  addhelp(sortlstgind, "sortlstgind(list): Sort an input list of integers and get list of indices in the input list (a.k.a. inderect sorting).");
  sortlstgind(list)=
  {my(Ls=List(),Li=List(), j, lsn=#list);
  if(lsn==0, return(Ls));
  Ls=list; listsort(Ls); 
  for(i=1, lsn, j=findinlist(list, Ls[i]); listput(Li, j)); 
  return(Li);
  } 

  \\* #8 Last updated: 9/27/2015
  \\* This is to sort text lists, and other non numeric objects in the list.
  addhelp(sortlstbyind, "sortlstbyind(inlist,indlist): Sort any input list using list of indices, and return sorted list. Both lists MUST have equal sizes.");
  sortlstbyind(inlist,indlist)=
  {my(Ls=List(), in=#inlist, iln=#indlist);
  if(in==0 || iln==0 || in<>iln, print("*** Error: list sizes are not equal!"); return(Ls));
  for(i=1, iln, listput(Ls, inlist[indlist[i]])); 
  return(Ls);
  } 
  \\* #9 Last updated: 10/3/2015
  addhelp(topp10, "topp10(n): Top power of 10 (tp) that is covering integer n (in other words 10^tp > n).");
  topp10(n) = {my(sn,tp); if(n==0, return(0)); sn=Str(n); tp=10^#sn; return(tp);}
  \\* #10 Last updated: 10/4/2015
  addhelp(listwui, "listwui(list): Return reformatted input list of integers with all unique items.");
  listwui(list)=
  {my(Lu=List(),Li=Lu, lmn,tp, ii,im, ln=#list,lin);
   if(ln==0, return(Lu));
   lmn=listmax(list); tp=topp10(lmn);
   for(i=1, ln, listput(Lu, list[i]*tp));
   for(i=1, ln, ii=Lu[i];
     Li=findinlista(Lu, ii); lin=#Li;
     if(lin==0, next); if(lin==1, next); 
     for(j=1, lin, im=Li[j]; Lu[im]=Lu[im]+j);
   );
   return(Lu);
  }
  \\* #11 - #12 Last updated: 10/20/2015
  addhelp(fmis, "fmis(mis): Return reformatted mis milliseconds.");
  fmis(mis)=
  {my(sec,ms,mn,sc,res);
   sec=floor(mis/1000); ms=mis-sec*1000; mn=floor(sec/60); sc=sec-mn*60;
   res = concat([mn,"min ", sc, "sec ", ms,"ms"]); return(res);  
  }
  addhelp(gettf, "gettf(pf=0): Return reformatted gettime() result. Print if pf=1.");
  gettf(pf=0)=
  {my(gt,res); gt=gettime(); res=fmis(gt); if(pf==1, print(res)); return(res);}

Matrix Handling Functions

  \\* NOTE: insm() and plotmat() are matrix handling functions too.
  \\* #14 Last updated: 4/23/2016. Upgraded: 5/30/2016
  matkronprod(a,b,pflg=0)={
  my(m=#a[,1],n=#a[1,],p=#b[,1],q=#b[1,],r,rtn,ctn);
  rtn=m*p; ctn=n*q;
  if(pflg,print(" *** Kronecker product - a: ",m," x ",n," b: ",p," x ",q," result r: ",rtn," x ",ctn));
  r=matrix(rtn,ctn);
  for(i=1,m, for(j=1,n, for(k=1,p, for(l=1,q,
      r[p*(i-1)+k,q*(j-1)+l]=a[i,j]*b[k,l];
  ))));\\fends
  if(pflg,print(r)); return(r);
  }

Operating System Dependent Functions (for testing mostly)

  \\* #2.1 - #2.5 Last updated: 9/27/2015
  \\*  NOTE: Thes functions were tested only for Win XP, but OK for any Windows (according
  \\*  ====  to Microsoft). So, delete them if you have a different OS.
  \\*        Also, you can adopt them to your OS, if you need them for scripting.
  \\*        Additionally, fpathname MUST be using "\\" like in the following sample: 
  \\*        "c:\\pariData\\testfile1.txt".
  \\*  #2.1 delfile  
  addhelp(delfile, "delfile(fpathname): Delete fpathname file that already exists (Windows).");
  delfile(fpathname)={my(cmd="del "); cmd=concat([cmd,fpathname]); system(cmd);}
  \\*  #2.2 renfile 
  addhelp(renfile, "renfile(fpathname,fnewname): Rename fpathname file that already exists (Windows).");
  renfile(fpathname,fnewname)={my(cmd="ren "); cmd=concat([cmd,fpathname," ",fnewname]); system(cmd);}
  \\*  #2.3 currdate  
  addhelp(currdate, "currdate(): Print current system date (Windows).");
  currdate()={system("date /t");}
  \\*  #2.4 currtime 
  addhelp(currtime, "currtime(): Print current system time (Windows).");
  currtime()={system("time /t");}
  \\*  #2.5 shutdown
  \\*  NOTE: This one is useful if you are leaving your script to run overnight.
  addhelp(shutdown, "shutdown(sec=20): Shut down your computer after sec seconds (Windows).");
  shutdown(sec=20)={my(cmd="shutdown -s -f -t "); cmd=concat([cmd,sec]); system(cmd);}

Functions Calculating Popular Equation Metrics

  \\* NOTE: The following set of functions #3.1 - #3.9 contains all the most popular
  \\* ****  metrics calculated and applied to equations like a+b=c, including A^x+B^y=C^z.
  \\*       They are used for definition of conjectures, estimation, selection etc.
  \\* #3.1 - #3.9 Last updated: 11/11/2015
  \\* #3.1 sizec 
  addhelp(sizec, "sizec(a,b): Size c in a sum a+b=c.");
  sizec(a,b)={my(c=a+b); return(#Str(c));}
  \\* #3.2 srecip
  addhelp(srecip, "srecip(x,y,z): Sum of x,y,z reciprocals: 1/x+1/y+1/z.");
  srecip(x,y,z)={return(1./x+1/y+1/z);}
  \\* #3.3 rad
  addhelp(rad, "rad(n): Radical of n (product of the distinct prime factors of n).");
  rad(n)=
  {my(F=factor(n),fn);
    if(n==1, return(1)); 
    fn=#F[,1]; return(prod(i=1,fn,F[i,1]));
  }
  \\* #3.4 merit
  addhelp(merit, "merit(a,b): Merit of a sum a+b=c.");
  merit(a,b)=
  {my(c=a+b,lr=log(rad(a*b*c)),m);
   m=(qual(a,b)-1)^2*lr*log(lr);
   return(m);
  }
  \\* #3.5 qual
  addhelp(qual, "qual(a,b): Quality (a.k.a. Power) of a sum a+b=c.");
  qual(a,b)=
  {my(c=a+b,h=log(c));
   return(h/log(rad(a*b*c)));
  }
  \\* #3.6 gqual
  addhelp(gqual, "gqual(a,b): Granville quality of a sum a+b=c.");
  gqual(a,b)=
  {my(c=a+b,p=a*b*c,gq);
   gq=(qual(a,b)-1)*log(rad(p))/bigomega(p);
   return(gq);
  }
  \\* #3.7 squal
  addhelp(squal, "squal(a,b): Szpiro quality of a sum a+b=c.");
  squal(a,b)=
  {my(c=a+b,p=a*b*c,h=log(p));
   return(h/rad(p));
  }
  \\* #3.8 gsqual
  addhelp(gsqual, "gsqual(a,b): Granville-Szpiro quality of a sum a+b=c.");
  gsqual(a,b)=
  {my(c=a+b,p=a*b*c,gsq);
   gsq=(squal(a,b)-3)*rad(p)/bigomega(p);
   return(gsq);
  }
  \\* #3.9 popmetrics
  addhelp(popmetrics, "popmetrics(a,b): Popular metrics of a sum a+b=c in 1 string: gcd, size, rad, merit, qual");
  popmetrics(a,b)=
  {my(c=a+b,gc,sz,sr,r,mr,q,pm);
   gc=gcd(a,b);
   sz=sizec(a,b);
   r=rad(a*b*c);
   mr=merit(a,b);
   q=qual(a,b);
   pm=Strprintf("*%d*|sz%d|r%d|mr%.2f|q%.4f",gc,sz,r,mr,q);
   return(pm);
  }
  

Basic string functions

  \\* #4.1 - #4.15 *** Basic string functions ***
  \\* This is a very basic set of string functions, - just for presentation purposes,
  \\* not for heavy text processing.
  \\* #4.1 - #4.2 schr(), sasc() 3/1/16
  addhelp(schr, "schr(): Returns a one-character string containing the character specified by ASCII code ascii.");
  schr(ascii)={return(Strchr(ascii))}
  addhelp(sasc, "sasc(str): Returns the ASCII code of the first character of the str string.");
  sasc(str)={my(vt=Vecsmall(str),sn=#str); if(sn>0, return(vt[1]), return(-1))}
  
  \\* #4.3 srepeat() 3/3/16
  addhelp(srepeat, "srepeat(str,ntimes): Repeat a string str the specified number of times ntimes and return composed string.");
  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);
  }
  \\* #4.4 sreverse() 3/3/16
  addhelp(sreverse, "sreverse(str): Return reversed string str.");
  sreverse(str)={return(Strchr(Vecrev(Vecsmall(str))))}
  \\* #4.5  spad() 3/3/16
  addhelp(spad, "spad(str,newsize,padchr=\" \",sflag=2): Returns the input string str padded on the right or left to the specified length newsize using character padchr. Side flag sflag = 1/2 (left/right).");
  spad(str,newsize,padchr=" ",sflag=2)={
  my(sn=#str,pn=newsize-sn,p,sr=srepeat(padchr,pn));
  if(newsize<=sn,return(str));
  if(sflag<1||sflag>2,sflag=2);
  if(sflag==2,p=concat(str,sr),p=concat(sr,str));
  return(p);
  }
  
  \\* #4.6 ssubstr() 3/5/16
  addhelp(ssubstr, "ssubstr(str,s=1,n=0): Returns the substring of string str specified by the start position s and length n. If n=0 then to the end of str.");
  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));
  }
  \\* #4.7 sfind1s() 3/5/16
  \\ Upgraded contains() script from http://rosettacode.org/wiki/String_matching#PARI.2FGP
  addhelp(sfind1s, "sfind1s(str,substr,s): Within string str find first substring substr beginning the start position s.. Return position or 0 if not found.");
  sfind1s(str,substr,s=1)={
  my(vs=Vecsmall(str),vss=Vecsmall(substr),sn=#str,ssn=#substr,dn=sn-ssn,is=s-1,ok);
  if(s<1||s>sn,return(0)); if(ssn>sn,return(0));
  for(i=is,dn, ok=1; for(j=1,ssn, if(vs[i+j]!=vss[j], ok=0; break)); 
      if(ok, return(i+1))
  );\\fend i
  }
  \\* #4.8 sfindalls() 3/5/16
  addhelp(sfindalls, "sfindalls(str,substr): Within string str find all substrings substr. Return all found positions in vector or empty vector if found none.");
  sfindalls(str,substr)={
  my(sn=#str,ssn=#substr,dn=sn-ssn,is=1,L=List());
  if(ssn>sn,return([]));
  if(dn==0,dn=1);
  for(i=1,dn, is=sfind1s(str,substr,is);
      if(is!=0, listput(L,is); is++; next, break);
  );\\fend i
  return(Vec(L));    
  }
  \\* #4.9 stok() 3/5/16
  \\* Delimiter is allowed in any place. In addition, multiple delimiters are allowed too.
  \\* This is really useful for considering omitted data. 
  \\* This version can be used for positional parameters processing, or for processing data from tables with string rows.
  addhelp(stok, "stok(str,d): Tokenize a string str according to 1 character delimiter d. Return a vector of tokens.");
  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([""])); 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(Vec(Lr));
  }
  
  \\* #4.10 sstripchars() 3/6/16
  \\* Upgraded from the script in:
  \\* http://rosettacode.org/wiki/Strip_a_set_of_characters_from_a_string#PARI.2FGP
  addhelp(sstripchars, "sstripchars(str,chrs): From str string strip a set of characters given in the string chrs and return result.");
  sstripchars(str,chrs)={
  my(vs=Vecsmall(str),vc=Set(Vec(Vecsmall(chrs))),v=[],vsn=#str,vch=#chrs);
  if(vsn==0||vch==0, return(str));
  for(i=1,vsn,if(!setsearch(vc,vs[i]),v=concat(v,vs[i])));
  return(Strchr(v));
  };
  \\* #4.11 strim() 3/6/16
  addhelp(strim, "strim(str,sflag=2): Removes str string whitespace(s) from specifide by sflag side(s) of a string. sflag = 1/2/3 (left, right, both).");
  strim(str,sflag=2)={
  my(vt=Vecsmall(str),sn=#str,stp=-1,k=-1,ws=32,rs,rsn=0);
  if(sn==0, return(""));
  if(sflag<1||sflag>3, sflag=2);
  if(sflag==2||sflag==3, k=0;
     forstep(i=sn,1,stp, if(vt[i]==ws, k++, break));
     if(k>0, rs=ssubstr(str,,sn-k); rsn=#rs; if(rsn==0,return("")));
     if(k==0, rs=str; rsn=sn);
  );
  if(k==-1, rs=str; rsn=sn);
  if(sflag==1||sflag==3, k=0;
     for(i=1,rsn, if(vt[i]==ws, k++, break));
     if(k>0, rs=ssubstr(rs,k+1,rsn-k));
  );
  return(rs);
  }
  
  \\* #4.12 sreplace() 3/8/16
  addhelp(sreplace, "sreplace(str,ssrch,srepl): In str string replace all occurrences of the search string ssrch with the replacement string srepl.");
  sreplace(str,ssrch,srepl)={
  my(sn=#str,ssn=#ssrch,srn=#srepl,sres="",Vi,Vs,Vz,vin,vin1,vi,L=List(),tok,zi,js=1);
  if(sn==0,return("")); if(ssn==0||ssn>sn,return(str));
  \\ Vi - found ssrch indexes
  Vi=sfindalls(str,ssrch); vin=#Vi;
  if(vin==0,return(str));
  vin1=vin+1; Vi=Vec(Vi,vin1); Vi[vin1]=sn+1;
  for(i=1,vin1, vi=Vi[i];
  for(j=js,sn, \\print("ij:",i,"/",j,": ",sres);
      if(j!=vi, sres=concat(sres,ssubstr(str,j,1)),
                sres=concat(sres,srepl); js=j+ssn; break) 
     ); \\fend j
  ); \\fend i
  return(sres);
  }
  \\* #4.14 cleanwsf() 3/10/16
  \\* Read the file of strings A.txt (e.g., from OEIS Wiki source containing PARI scripts), clean up it
  \\* from Wiki tags, etc., by inserting "\\*" in the beginning of each row starting in the first position,
  \\* i.e., if the first position is not a whitespace. Otherwise, and if nw>0, then trim nw first whitespaces.
  \\* Write result in the B.txt file.
  \\* NOTE: Works only for PARI/GP scripts, and only for my stile of formatting.
  addhelp(cleanwsf, "cleanwsf(fpath=\"\"): Using file path fpath and nw as number of whitespaces to trim, - clean up the OEIS Wiki source file A.txt containing PARI scripts. Write result in the B.txt file.");
  cleanwsf(fpath="",nw=3)={
  my(fin="A.txt",fon="B.txt",fipn=Str(fpath,fin),fopn=Str(fpath,fon),Vin,c="\\\\*",vifn,x,nw1=nw+1);
  Vif=readstr(fipn); vifn=#Vif;
  for(i=1,vifn, x=sasc(Vif[i]);
      if(x!=32&&x!=-1, Vif[i]=Str(c,Vif[i])); 
      if(x==32, Vif[i]=ssubstr(Vif[i],nw1));
      write(fopn,Vif[i]);
  );\\fend i
  }
  \\* #4.15 clean4gpf() 3/14/16
  \\* Read the file of strings B.txt (containing PARI scripts with a lot of comments like \\*), delete all rows
  \\* starting with such comments and write result in the C.txt file.
  \\* NOTE: Works only for PARI/GP scripts, and only for my stile of formatting.
  addhelp(clean4gpf, "clean4gpf(fpath=\"\"): Using file path fpath read the file of strings B.txt, delete all rows starting \\\\*, and write result in the C.txt file.");
  clean4gpf(fpath="")={
  my(fin="B.txt",fon="C.txt",fipn=Str(fpath,fin),fopn=Str(fpath,fon),Vin,c="\\\\*",vifn,x,nw1=nw+1);
  Vif=readstr(fipn); vifn=#Vif;
  for(i=1,vifn, x=ssubstr(Vif[i],1,3);
      if(x!=c, write(fopn,Vif[i])); 
  );\\fend i
  }

Plotting helper functions

  \\* #5.1 - #5.7 *** Plotting helper functions ***
  \\* These are very simple and handy functions. See samples of using in 
  \\* MyMixedPariScripts.gp
  \\* #5.1 - #5.2 3/24/16
  addhelp(insm, "insm(mat,x,y,p=0): 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)}
  addhelp(plotmat, "plotmat(mat): Simple plotting using 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))));
  plothraw(Vec(vx),Vec(vy));
  print(" *** matrix(",xz,"x",yz,") ",#vy, " DOTS");
  }
  \\ * #5.2i 7/7/16
  \\ Improved plotmat (with color and normal scaling for x axis).
  addhelp(iPlotmat, "iPlotmat(mat): Improved simple plotting using matrix mat (filled with 0/1). Now with color clr and normal scaling for x axis.");
  iPlotmat(mat,clr)={
    my(xz=#mat[1,],yz=#mat[,1],vx=List(),vy=vx,xmin,xmax,ymin,ymax,c=0.625);
    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]);
    print(" *** matrix: ",xz,"x",yz,", ",#vy," DOTS");
  }
  \\* #5.3 - #5.8 4/21/16  
  addhelp(plotline, "plotline(x1,y1,x2,y2,w=0): Plot the line from x1,y1 to x2,y2 in the window w.");
  plotline(x1,y1,x2,y2,w=0)={plotmove(w, x1,y1);plotrline(w,x2-x1,y2-y1);}
  addhelp(getxsc, "getxsc(): Get x axis scale coefficient.");
  getxsc()={my(v=plothsizes(),c=v[2]/v[1]);return(c)}
  addhelp(rad2(degs), "rad2(degs): Convert value expressed in degrees to radians.");
  rad2(degs)={return(degs*Pi/180.0)}
  addhelp(deg2(rads), "deg2(rads): Convert value expressed in radians to degrees.");
  deg2(rads)={return(rads*180.0/Pi)}
  addhelp(polar2(x,y), "polar2(x,y): Convert Cartesian coordinates (x,y) to Polar (r,angle [in rads]).");
  polar2(x,y)={my(v,r,a); r=sqrt(x^2+y^2); a=atan(y/x); return([r,a])}
  addhelp(cartes2(r,a,rndf=0), "cartes2(r,a,rndf=0): Convert Polar coordinates (r,angle [in rads]) to Cartesian (x,y). Round result if rndf!=0.");
  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])))}
  \\* ################################   
  \\* END OF VoeLib. Note testing samples now in TestingVoeLib.gp page.
  \\* ################################   
  print("*** VoeLib.gp loaded ***"); 
  \\currdate(); currtime(); \\ for Windows only!