/* Output from p2c 1.21alpha-07.Dec.93, the Pascal-to-C translator */ /* From input file "coscurve.p" */ #include /* coscurve: compute the length of the cosine curve Dr. Thomas D. Schneider National Cancer Institute Laboratory of Experimental and Computational Biology Frederick, Maryland 21702-1201 toms@ncifcrf.gov permanent email: toms@alum.mit.edu http://www.lecb.ncifcrf.gov/~toms/ National Cancer Institute Laboratory of Experimental and Computational Biology */ /* end of program */ /* begin module version */ #define version 1.05 /* of coscurve.p 2000 Oct 31 2000 Oct 31, 1.00: origin */ #define updateversion 1.03 /* defines lowest acceptable current parameter file */ /* end module version */ /* begin module describe.coscurve */ /* name coscurve: compute the length of the cosine curve synopsis coscurve(coscurvep: in, output: out) files coscurvep: parameters to control the program. The file must contain the following parameters, one per line: parameterversion: The version number of the program. This allows the user to be warned if an old parameter file is used. second line: intervals (integer): number of intervals to use third line: wid (integer): width of the output real numbers (in characters) fourth line: printcontrol: the first character determines how or whether to print the values during the summation. P: print x, y, dy, L, L/2pi at each step p: print L/2pi at each step m: print L/2pi at each successively larger power of 10 -: no printing (fastest compute) output: messages to the user description The cosine wave on a sequence logo can have dashes. These are implemented in PostScript using the PostScript dash function. To make the dashes line up with the wavelength the length of the curve must be known. So the problem is to compute length of y = cos(x) from 0 to 2 pi. Setting ds = sqrt(dx^2 +dy^2) (Thomas, pages 203-204) we find that the total length is L = integral sqrt(1 + sin^2(x)) dx. This is not solvable in terms of elementary functions (Thomas, page 308) and so must be determined numerically. That is the purpose of this program. Rather than integrate the function, it is easier just to sum the ds for the interval 0 to 2 pi. The value L/(2pi) is reported so that this need not be computed in the final program, which uses the constant. The user may then multiply L/(2pi) by the amplitude and wavelength of a given cosine or sine wave to get its contour length. examples for cocurvep being: 1.03 version of coscurve that this parameter file is designed for. 100000000 number of intervals to use 20 width of output real numbers in characters m 2 printing: P: all, p: just L/2pi, m: multiples of k, - no printing. the output is: coscurve 1.05 pi = 3.14159265358979312 intervals = 100000000 2, L/(2pi) = 1.18544706105728359 4, L/(2pi) = 1.18544706105728359 8, L/(2pi) = 1.20642353304458783 16, L/(2pi) = 1.21356557113189623 32, L/(2pi) = 1.21539466952667086 64, L/(2pi) = 1.21585359980789032 128, L/(2pi) = 1.21596843563495249 256, L/(2pi) = 1.21599715104708350 512, L/(2pi) = 1.21600433030360899 1024, L/(2pi) = 1.21600612514295325 2048, L/(2pi) = 1.21600657385437816 4096, L/(2pi) = 1.21600668603233197 8192, L/(2pi) = 1.21600671407678718 16384, L/(2pi) = 1.21600672108796770 32768, L/(2pi) = 1.21600672284060907 65536, L/(2pi) = 1.21600672327877302 131072, L/(2pi) = 1.21600672338823634 262144, L/(2pi) = 1.21600672341558114 524288, L/(2pi) = 1.21600672342506755 1048576, L/(2pi) = 1.21600672342277272 2097152, L/(2pi) = 1.21600672342234084 4194304, L/(2pi) = 1.21600672341971094 8388608, L/(2pi) = 1.21600672346093108 16777216, L/(2pi) = 1.21600672339648463 33554432, L/(2pi) = 1.21600672338265259 67108864, L/(2pi) = 1.21600672333825899 L = 7.64039557751054144 L/(2pi) = 1.21600672333825899 ========== documentation George B. Thomas, Jr. Calculus and Analytic Genometry, 4th Ed Addison-Wesley Publishing Co. Reading, MA. 1968. see also {Parameter file: } coscurvep {The program that uses this number:} makelogo.p author Thomas Dana Schneider bugs technical notes */ /* end module describe.coscurve */ Static _TEXT coscurvep; /* parameter file */ Static jmp_buf _JL1; /* begin module halt */ Static Void halt() { /* stop the program. the procedure performs a goto to the end of the program. you must have a label: label 1; declared, and also the end of the program must have this label: 1: end. examples are in the module libraries. this is the only goto in the delila system. */ printf(" program halt.\n"); longjmp(_JL1, 1); } /* Local variables for themain: */ struct LOC_themain { long dec; /* decimals of output numbers */ double dx; /* change in x */ double dy; /* change in y */ double L; /* total length */ Char printcontrol; /* control of printing */ boolean printing; /* if true, print intermediate values */ double twopi; /* twice pi */ long wid; /* width of output numbers */ } ; Local Void compute(intervals, LINK) long intervals; struct LOC_themain *LINK; { /* compute the length for a given number of intervals */ long i; /* index to intervals */ double x = 0.0; /* x axis value */ double y; /* y axis value */ double xold = 0.0; /* previous value of x */ double yold; /* previous value of y */ LINK->dx = LINK->twopi / intervals; if (LINK->printcontrol == 'p' || LINK->printcontrol == 'P') printf("dx = % .*E\n", P_max((int)LINK->wid - 7, 1), LINK->dx); LINK->L = 0.0; yold = cos(xold); for (i = 1; i <= intervals; i++) { x += LINK->dx; y = cos(x); LINK->dy = y - yold; LINK->L += sqrt(LINK->dx * LINK->dx + LINK->dy * LINK->dy); if (LINK->printing) { if (LINK->printcontrol == 'p' || LINK->printcontrol == 'P') { if (LINK->printcontrol == 'P') { printf(" x = %*.*f", (int)LINK->wid, (int)LINK->dec, x); printf(" y = %*.*f", (int)LINK->wid, (int)LINK->dec, y); printf(" dy = %*.*f", (int)LINK->wid, (int)LINK->dec, LINK->dy); printf(" L = %*.*f\n", (int)LINK->wid, (int)LINK->dec, LINK->L); } printf(" L/(2pi) = %*.*f\n", (int)LINK->wid, (int)LINK->dec, LINK->L / LINK->twopi); } } xold = x; yold = y; } } /* end module halt version = 'delmod 6.16 84 mar 12 tds/gds'; */ /* begin module coscurve.themain */ Static Void themain(coscurvep) _TEXT *coscurvep; { /* the main procedure of the program */ struct LOC_themain V; long intervals; /* number of intervals to compute over */ long multiple; /* multiple increase density of points by */ double parameterversion; /* parameter version number */ double pi = 4.0 * atan(1.0); /* 3.1415... */ long target; /* next target number of intervals at which to print at */ printf("coscurve %4.2f\n", version); if (*coscurvep->name != '\0') { if (coscurvep->f != NULL) coscurvep->f = freopen(coscurvep->name, "r", coscurvep->f); else coscurvep->f = fopen(coscurvep->name, "r"); } else rewind(coscurvep->f); if (coscurvep->f == NULL) _EscIO2(FileNotFound, coscurvep->name); RESETBUF(coscurvep->f, Char); fscanf(coscurvep->f, "%lg%*[^\n]", ¶meterversion); getc(coscurvep->f); if ((long)floor(100 * parameterversion + 0.5) < (long)floor(100 * updateversion + 0.5)) { printf("You have an old parameter file!\n"); halt(); } fscanf(coscurvep->f, "%ld%*[^\n]", &intervals); getc(coscurvep->f); fscanf(coscurvep->f, "%ld%*[^\n]", &V.wid); getc(coscurvep->f); V.printcontrol = getc(coscurvep->f); if (V.printcontrol == '\n') V.printcontrol = ' '; if (V.printcontrol == 'm') { fscanf(coscurvep->f, "%ld", &multiple); if (multiple <= 1) { printf("multiple must be >= 1 \n"); halt(); } } else multiple = 1; fscanf(coscurvep->f, "%*[^\n]"); getc(coscurvep->f); if (V.printcontrol != '-' && V.printcontrol != 'm' && V.printcontrol != 'p' && V.printcontrol != 'P') { printf("printcontrol must be one of: Ppm-\n"); halt(); } V.printing = (V.printcontrol != '-'); V.dec = V.wid - 3; V.twopi = 2.0 * pi; printf("pi = %*.*f\n", (int)V.wid, (int)V.dec, pi); printf("intervals = %ld\n", intervals); if (V.printcontrol == 'm') { target = multiple; while (target <= intervals) { compute(target, &V); printf("%*ld, L/(2pi) = %*.*f\n", (int)V.wid, target, (int)V.wid, (int)V.dec, V.L / V.twopi); target *= multiple; } } else compute(intervals, &V); printf("L = %*.*f\n", (int)V.wid, (int)V.dec, V.L); printf("L/(2pi) = %*.*f\n", (int)V.wid, (int)V.dec, V.L / V.twopi); printf("==========\n"); } /* end module coscurve.themain */ main(argc, argv) int argc; Char *argv[]; { PASCAL_MAIN(argc, argv); if (setjmp(_JL1)) goto _L1; coscurvep.f = NULL; strcpy(coscurvep.name, "coscurvep"); themain(&coscurvep); _L1: if (coscurvep.f != NULL) fclose(coscurvep.f); exit(EXIT_SUCCESS); } /* End. */