/******************************************************************* poin.c -- started 8-26-96 by Eric R. Weeks email: weeks@physics.emory.edu web: http://www.physics.emory.edu/~weeks/software/poincare.html home page: http://www.physics.emory.edu/~weeks/ This program is public domain, but please leave my name & contact information intact. I make no guarantees about bugs, but if you find a problem with this program and contact me, I may fix it. Currently there is no guarantee this program will work for anything but 3-D. ---------------------------------------- Why reinvent the wheel? There's already a program called "ponsec" on my computer to do this same thing. Well, the man page for ponsec does not match the current version of ponsec, and I can't quite figure out how to make it work. So, I'm writing my own. v01: 8-26-96: started from shell.c 3-30-97: wow, discovered I had already started writing this program last summer. Let's see what it does. Added -o option added -abcxyzd options v02: 4-11-97: add in ability to read in 3-D data (-M) 4-11-97: add in uvec, vvec (-V); added -O v03: 4-15-97: modify command line options (replace -abc with -n, replace -xyz with -x). Add -T 6-16-97: modify -P output slightly *******************************************************************/ #include #include #include #define PI 3.14159265358979323846264338328 #define EE 2.71828182845904523536 #define MAX 200000 /* limit of 10-dimensional vectors */ #define MAXDIM 10 char *prgname; main(argc,argv) int argc; char **argv; { int c,numpts,delay,embed; double x,y,z,w; FILE *fp; extern int optind; extern char *optarg; float data[MAX][MAXDIM]; int t,r,n; float coord[MAXDIM],lastcoord[MAXDIM]; int side,lastside,timeseriesonly,psdraw; float vx,vy,vz; float qvec[MAXDIM],proj,proj1,proj2; float pvec[MAXDIM],nvec[MAXDIM]; int direction,count1=0,count2=0,indim,usevecs,oneside=0; float uvec[MAXDIM],vvec[MAXDIM]; float strobeperiod=-1.0,tt=0.0; delay = 1; embed = 3; indim = 1; timeseriesonly = 0; psdraw = 0; usevecs = 0; pvec[0] = 0.0; pvec[1] = 0.0; pvec[2] = 0.0; nvec[0] = 0.0; nvec[1] = 0.0; nvec[2] = 1.0; direction = 0; while ((c = getopt(argc, argv, "ht:m:oPnxd:M:VOT:")) != EOF) switch (c) { case 'h': fprintf(stderr,"Usage: %s [options] [<] [file]\n\n",argv[0]); fprintf(stderr," -h : this help message\n"); fprintf(stderr,"INPUT:\n"); fprintf(stderr," -t # : delay in samples [%d]\n",delay); fprintf(stderr," -m # : embedding dimension [%d]\n",embed); fprintf(stderr," -M # : input data is this dimension -"); fprintf(stderr," don't embed [%d]\n",indim); fprintf(stderr,"POINCARE INFORMATION:\n"); fprintf(stderr," -n # # # : normal to poincare plane:"); fprintf(stderr," [(%.1f, %.1f, %.1f)]\n",nvec[0],nvec[1],nvec[2]); fprintf(stderr," -x # # # : point plane passes through:"); fprintf(stderr," [(%.1f, %.1f, %.1f)]\n",pvec[0],pvec[1],pvec[2]); fprintf(stderr," -T # : print out points with this strobing period"); fprintf(stderr," [default:plane]\n"); fprintf(stderr," -d # : direction (0=norm, 1=-norm, 2=both) [%d]\n",direction); fprintf(stderr," -V : output coordinates in Poincare plane"); fprintf(stderr," [default: 3D pts]\n"); fprintf(stderr,"OUTPUT:\n"); fprintf(stderr," -o : output time series only (with delay coords)\n"); fprintf(stderr," -O : print data points on one side of plane\n"); fprintf(stderr," -P : make output psdraw compatible:\n"); fprintf(stderr," poin -P data | psdraw -C -c 0.1 > pic.ps\n"); fprintf(stderr,"\nInput data must be in one column only unless -M used!\n"); exit(1); break; case 't': delay = atoi(optarg); break; case 'm': embed = atoi(optarg); break; case 'o': timeseriesonly = 1; break; case 'P': psdraw = 1; break; case 'x': pvec[0] = atof(argv[optind]); optind++; pvec[1] = atof(argv[optind]); optind++; pvec[2] = atof(argv[optind]); optind++; break; case 'n': nvec[0] = atof(argv[optind]); optind++; nvec[1] = atof(argv[optind]); optind++; nvec[2] = atof(argv[optind]); optind++; break; case 'd': direction = atoi(optarg); if ((direction<0) || (direction>2)) { fprintf(stderr,"error: -d option can be 0, 1, or 2\n"); fprintf(stderr,"only. Setting to default (0)\n"); direction = 0; } break; case 'M': indim = atoi(optarg); delay = 0; embed = indim; break; case 'V': usevecs = 1; break; case 'O': oneside = 1; break; case 'T': strobeperiod = atof(optarg); break; } if (embed>3) { fprintf(stderr,"Currently program not designed for\n"); fprintf(stderr,"> 3 dimensions. Trying anyway...\n"); } if (embed>MAXDIM) { fprintf(stderr,"Sorry, dimension must be less than\n"); fprintf(stderr,"%d. Change MAXDIM in program to fix.\n",MAXDIM); exit(1); } argc -= (optind-1) ; argv += (optind-1) ; fp = (argc > 1) ? fopen(*++argv, "r") : stdin; numpts = 0; switch (indim) { case 1: while ((fscanf(fp,"%lf",&x)) == 1) { data[numpts][0] = x; ++numpts; } break; case 2: while ((fscanf(fp,"%lf %lf",&x,&y)) == 2) { data[numpts][0] = x; data[numpts][1] = y; ++numpts; } break; case 3: while ((fscanf(fp,"%lf %lf %lf",&x,&y,&z)) == 3) { data[numpts][0] = x; data[numpts][1] = y; data[numpts][2] = z; ++numpts; } break; case 4: while ((fscanf(fp,"%lf %lf %lf %lf",&x,&y,&z,&w)) == 4) { data[numpts][0] = x; data[numpts][1] = y; data[numpts][2] = z; data[numpts][3] = w; ++numpts; } break; default: fprintf(stderr,"I don't know how to read in more than 4\n"); fprintf(stderr,"dimensions. Exiting...\n"); exit(1); break; } if (numpts<=delay*embed) { fprintf(stderr,"ERROR: not enough points for delay coords\n"); fprintf(stderr,"ERROR: numpts = %d\n",numpts); fprintf(stderr,"ERROR: delay = %d\n",delay ); exit(1); } if (timeseriesonly==1) { if (indim>1) { fprintf(stderr,"not quite sure what to do: -M option used\n"); fprintf(stderr,"with -o option. Taking my best guess.\n"); } for (t=0;t 0.01) { uvec[0] = -nvec[1]/nvec[0]; uvec[1] = 1.0; uvec[2] = 0.0; } else if (fabs(nvec[1]) > 0.01) { uvec[0] = 1.0; uvec[1] = -nvec[0]/nvec[1]; uvec[2] = 0.0; } else { uvec[0] = 1.0; uvec[1] = 0.0; uvec[2] = -nvec[0]/nvec[2]; } x = sqrt(uvec[0]*uvec[0]+uvec[1]*uvec[1]+uvec[2]*uvec[2]); for (r=0;r<3;r++) uvec[r] /= x; vvec[0] = nvec[1]*uvec[2] - nvec[2]*uvec[1]; vvec[1] = nvec[2]*uvec[0] - nvec[0]*uvec[2]; vvec[2] = nvec[0]*uvec[1] - nvec[1]*uvec[0]; fprintf(stderr,"nvec: %f %f %f\n",nvec[0],nvec[1],nvec[2]); fprintf(stderr,"uvec: %f %f %f\n",uvec[0],uvec[1],uvec[2]); fprintf(stderr,"vvec: %f %f %f\n",vvec[0],vvec[1],vvec[2]); } for (t=0;t0)&&( ((side>lastside)&&(direction != 1)) || ((sidelastside)&&(direction != 1)) count1++; if ((sidelastside) printf("1 0 0.2\n"); else printf("0 0.2 1\n"); } } lastside = side; } else { /* strobeperiod > 0.0 */ tt+=1.0; if (tt>strobeperiod) { count1++; count2++; tt -= strobeperiod; /* now tt is between 0 and 1 */ for (r=0;r