home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume16 / lyap / part01 < prev    next >
Encoding:
Internet Message Format  |  1992-02-12  |  55.1 KB

  1. Path: uunet!spool.mu.edu!mips!msi!dcmartin
  2. From: rr@sco.COM (Renaldo Recuerdo)
  3. Newsgroups: comp.sources.x
  4. Subject: v16i083: Lyapunov exponent calculator (MOTIF), Part01/02
  5. Message-ID: <csx-16i083-lyap@uunet.UU.NET>
  6. Date: 13 Feb 92 18:50:50 GMT
  7. Article-I.D.: uunet.csx-16i083-lyap
  8. Sender: dcmartin@msi.com (David C. Martin - Moderator)
  9. Organization: Molecular Simulations, Inc.
  10. Lines: 1845
  11. Approved: dcmartin@msi.com
  12. Originator: dcmartin@fascet
  13.  
  14. Submitted-by: Renaldo Recuerdo <rr@sco.COM>
  15. Posting-number: Volume 16, Issue 83
  16. Archive-name: lyap/part01
  17.  
  18. # into a shell via "sh file" or similar.  To overwrite existing files,
  19. # type "sh file -c".
  20. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  21. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  22. # If this archive is complete, you will see the following message at the end:
  23. #        "End of archive 1 (of 2)."
  24. # Contents:  README lyap.6X lyap.c params patchlevel.h
  25. # Wrapped by dcmartin@fascet on Fri Jan 24 08:41:37 1992
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'README' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'README'\"
  29. else
  30. echo shar: Extracting \"'README'\" \(3045 characters\)
  31. sed "s/^X//" >'README' <<'END_OF_FILE'
  32. X
  33. X
  34. XWritten by Ronald Joe Record (rr@sco) 03 Sep 1991
  35. X
  36. XINTRO
  37. X-----
  38. X
  39. XThe idea here is to calculate the Lyapunov exponent for a periodically
  40. Xforced logistic map (later i added several other nonlinear maps of the unit
  41. Xinterval). In order to turn the 1-dimensional parameter space of the
  42. Xlogistic map into a 2-dimensional parameter space, select two parameter
  43. Xvalues (a and b) then alternate the iterations of the logistic map using
  44. Xfirst a then b as the parameter. This program accepts an argument to 
  45. Xspecify a forcing function, so instead of just alternating a and b, you
  46. Xcan use a as the parameter for say 6 iterations, then b for 6 iterations
  47. Xand so on. An interesting forcing function to look at is abbabaab (the
  48. XMorse-Thue sequence, an aperiodic self-similar, self-generating sequence).
  49. XAnyway, you step through all the values of a and b in the ranges you want,
  50. Xcalculating the Lyapunov exponent for each pair of values. The exponent
  51. Xis calculated by iterating out a ways (specified by the variable "settle")
  52. Xthen on subsequent iterations calculating an average of the logarithm of
  53. Xthe absolute value of the derivative at that point. Points in parameter
  54. Xspace with a negative Lyapunov exponent are colored one way (using the
  55. Xvalue of the exponent to index into a color map) while points with a
  56. Xnon-negative exponent are colored differently. 
  57. X
  58. XACKNOWLEDGEMENTS
  59. X----------------
  60. X
  61. XThe algorithm was taken from the September 1991 Scientific American article
  62. Xby A. K. Dewdney who gives credit to Mario Markus of the Max Planck Institute
  63. Xfor its creation. Additional information and ideas were gleaned from the
  64. Xdiscussion on alt.fractals involving Stephen Hall, Ed Kubaitis, Dave Platt
  65. Xand Baback Moghaddam. Assistance with colormaps and spinning color wheels
  66. Xand X was gleaned from Hiram Clawson. Rubber band code was adapted from 
  67. XStacey Campbell's xmandel source.
  68. X
  69. XBUILD
  70. X-----
  71. X
  72. XTo build the lyap binary, either use the Imakefile or one of the sample 
  73. Xmakefiles - Makefile.ODT or Makefile.OSF. Makefile.ODT is a sample makefile
  74. Xused to build lyap on an SCO ODT system. Makefile.OSF was used as a makefile
  75. Xon a DECstation 3100 running OSF/1. If your system has only 16 colors, 
  76. Xuncomment the COLORDEFINE line of the Imakefile and/or add a -DSIXTEEN_COLORS 
  77. Xto the appropriate makefile. The manual page can be formatted by typing 
  78. X"nroff -man lyap.man > lyap.doc".
  79. X
  80. XINSTALL
  81. X-------
  82. X
  83. XTo install lyap, copy the lyap binary to the desired location (the sample
  84. Xmakefiles put it in /usr/games/X11) and copy the lyap resource file Lyap
  85. Xto /usr/lib/X11/app-defaults/Lyap (or append it to your home .Xresources
  86. Xor read it into your environment with xrdb).
  87. XCopy the formatted man page to wherever you keep your local doc (i use
  88. X/usr/games/X11/doc for games and imaging software), then add that location
  89. Xto your MANPATH.
  90. X
  91. XSome "interesting" runs of lyap are included as simple shell scripts in the
  92. X"params" subdirectory.
  93. X
  94. X
  95. XIdeas, comments, additions, deletions, suggestions, bug reports, code review,...
  96. Xe-mail Ronald Record at rr@sco.com or ...uunet!sco!rr.
  97. X
  98. END_OF_FILE
  99. if test 3045 -ne `wc -c <'README'`; then
  100.     echo shar: \"'README'\" unpacked with wrong size!
  101. fi
  102. # end of 'README'
  103. fi
  104. if test -f 'lyap.6X' -a "${1}" != "-c" ; then 
  105.   echo shar: Will not clobber existing file \"'lyap.6X'\"
  106. else
  107. echo shar: Extracting \"'lyap.6X'\" \(6545 characters\)
  108. sed "s/^X//" >'lyap.6X' <<'END_OF_FILE'
  109. X
  110. X
  111. X
  112. XLYAP(6X)                                                             LYAP(6X)
  113. X
  114. X
  115. X
  116. XNAME
  117. X  lyap - display an array of Lyapunov exponents graphically
  118. X
  119. XSYNOPSIS
  120. X  lyap [-BLps][-W width][-H height][-o filename][-a n ] [-b n ] [-w n ] [-h n
  121. X          ] [-x xstart] [-M n ] [-S n ] [-D n ] [-F string][-f string][-r n ]
  122. X          [-O n ] [-C n ] [-c n ] [-m n ]
  123. X
  124. XDESCRIPTION
  125. X  lyap generates and graphically displays an array of Lyapunov exponents for
  126. X  a variety of iterated periodically forced non-linear maps of the unit
  127. X  interval.
  128. X
  129. XOPTIONS
  130. X
  131. X  -C n    Specifies the minimum color index to be used for negative exponents
  132. X
  133. X  -D n    Specifies the "dwell" or number of iterations over which to average
  134. X          in order to calculate the Lyapunov exponent. Default is 400.
  135. X
  136. X  -B      Causes the stop, go, spin and quit buttons to be displayed.
  137. X
  138. X  -H n    Specifies the height of the window. Default is 256.
  139. X
  140. X  -L      Indicates use log(x) + log(y) rather than log(xy).
  141. X
  142. X  -M r    Specifies the real value to compare exponent values to for indexing
  143. X          into a color wheel. The default value is 1.0.
  144. X
  145. X  -O n    Specifies the minimum color index to be used for positive exponents
  146. X
  147. X  -S n    Specifies the "settle" or number of iterations prior to the begin-
  148. X          ning of the calculation of the Lyapunov exponent. Default is 200.
  149. X
  150. X  -W n    Specifies the width of the window. Default is 256.
  151. X
  152. X  -a r    Specifies the real value to use as the minimum parameter value of
  153. X          the horizontal axis. Default is 3.0 for the logistic map.
  154. X
  155. X  -b n    Specifies the real value to use as the minimum parameter value of
  156. X          the vertical axis. Default is 3.0 for the logistic map.
  157. X
  158. X  -c n    Selects one of six different color wheels to use. The default color
  159. X          wheel is a rainbow palette.
  160. X
  161. X  -F 10101010
  162. X          Specifies the "Function" forcing function to use. The example above
  163. X          would alternate between iterating the circle and logistic maps. An
  164. X          argument of "-F 2323" would alternate between left and right logis-
  165. X          tic maps. The default is to only use the single specified map (see
  166. X          the description of -m).
  167. X
  168. X  -f abbabaab
  169. X          Specifies the forcing function to use. The default is to alternate
  170. X          between the "a" parameter and the "b" parameter.
  171. X
  172. X  -h r    Specifies the real value to be used as the range over which the
  173. X          vertical parameter values vary. The default is 1.0.
  174. X
  175. X  -m n    Selects between available non-linear maps of the unit interval. A
  176. X          value of 0 specifies the logistic map. A value of 1, the circle
  177. X          map. A value of 2, the left-logistic. A value of 3, the right-
  178. X          logistic. A value of 4, the double-logistic. The default is 0, the
  179. X          logistic map.
  180. X
  181. X  -o filename
  182. X          Specifies the output filename to be used. If the -o option is
  183. X          given, this file will automatically be written out at the comple-
  184. X          tion of the drawing.  If it is not specified, a default filename of
  185. X          lyap.out is used and only written if the 'f' or 'F' keys are
  186. X          pressed during a run. The format of the output file is PPM for
  187. X          color and PGM for monochrom. The parameters used to calculate the
  188. X          picture are included as comments at the beginning of the output
  189. X          file.
  190. X
  191. X  -p      Switches color indices for negative and positive exponents. Gen-
  192. X          erally, causes negative exponents to be displayed in more detail
  193. X          while darkening and narrowing the color range for positive
  194. X          exponents. This can be toggled during runtime by pressing the 'p'
  195. X          key.
  196. X
  197. X  -r n    Specifies the maximum rgb value to be used. Default is 35000.
  198. X
  199. X  -s n    Specifies the length of the color wheel spin.
  200. X
  201. X  -u      Produces a usage message.
  202. X
  203. X  -v      Prints out the various values to be used and exits.
  204. X
  205. X  -w r    Specifies the real value to be used as the range over which the
  206. X          horizontal parameter values vary. The default is 1.0.
  207. X
  208. X  -x r    Specifies the real value of the initial condition to use. Default
  209. X          is 0.05.
  210. X
  211. X
  212. X
  213. XNOTES
  214. X
  215. X  During display, pressing any mouse button allows you to select the area to
  216. X  be investigated with the mouse. The upper left hand corner of the desired
  217. X  area is the location of the cursor when the button is pressed. The lower
  218. X  right hand corner is specified by the cursor when the button is released.
  219. X
  220. X
  221. X  Use of the keys bBeEfFkKjJmnrRsSwWxXqQ indicates:
  222. X
  223. X          (<) Halve dwell value.
  224. X          (>) Double dwell value.
  225. X          ([) Halve settle value.
  226. X          (]) Double settle value.
  227. X          (B or b) Toggle button display on/off
  228. X          (E or e) Recalculate the indices into the color wheel using a dif-
  229. X  ferent method
  230. X          (F or f) Save current screen to ouput file (not yet implemented)
  231. X          (i) Decrement the interval between stripes for the striped color
  232. X  map.
  233. X          (I) Increment the interval between stripes for the striped color
  234. X  map.
  235. X          (K or k) Decrease value exponents are compared against by 0.05.
  236. X          (J or j) Increase value exponents are compared against by 0.05.
  237. X          (m) Decrease value exponents are compared against by 0.005.
  238. X          (n) Increase value exponents are compared against by 0.005.
  239. X          (P or p) Toggle positive/negative exponent display.
  240. X          (r) Redraw the window using previously calculated exponents.
  241. X          (R) Redraw the window using the newly set dwell and/or settle
  242. X  values.
  243. X          (S) Spin the color wheel
  244. X          (s) Halve the length of the spin and spin the color wheel
  245. X          (u) Go up to the window just prior to the most recent zoom.
  246. X          (U) Go all the way up to the original window.
  247. X          (W or w) Use next color map.
  248. X          (X or x) Clear window
  249. X          (Q or q) quit
  250. X
  251. X
  252. X
  253. XAUTHOR
  254. X          Ronald Joe Record
  255. X       The Santa Cruz Operation
  256. X            P.O. Box 1900
  257. X         Santa Cruz, CA 95061
  258. X              rr@sco.com
  259. X
  260. X
  261. X
  262. XACKNOWLEDGEMENTS
  263. X
  264. X  The algorithm was taken from the September 1991 Scientific American article
  265. X  by A. K. Dewdney who gives credit to Mario Markus of the Max Planck Insti-
  266. X  tute for its creation. Additional information and ideas were gleaned from
  267. X  the discussion on alt.fractals involving Stephen Hall, Ed Kubaitis, Dave
  268. X  Platt and Baback Moghaddam. Assistance with colormaps and spinning color
  269. X  wheels and X was gleaned from Hiram Clawson. Rubber banding code was
  270. X  adapted from an existing Mandelbrot program written by Stacey Campbell.
  271. X
  272. X
  273. X
  274. X
  275. X
  276. X
  277. X
  278. X
  279. X
  280. X
  281. X
  282. X
  283. X
  284. X
  285. X
  286. X
  287. X
  288. X
  289. X
  290. X
  291. X
  292. X
  293. X
  294. X
  295. X
  296. X
  297. X
  298. X
  299. X
  300. X
  301. X
  302. X
  303. X
  304. X
  305. X
  306. X
  307. END_OF_FILE
  308. if test 6545 -ne `wc -c <'lyap.6X'`; then
  309.     echo shar: \"'lyap.6X'\" unpacked with wrong size!
  310. fi
  311. # end of 'lyap.6X'
  312. fi
  313. if test -f 'lyap.c' -a "${1}" != "-c" ; then 
  314.   echo shar: Will not clobber existing file \"'lyap.c'\"
  315. else
  316. echo shar: Extracting \"'lyap.c'\" \(41792 characters\)
  317. sed "s/^X//" >'lyap.c' <<'END_OF_FILE'
  318. X
  319. X/* Written by Ron Record (rr@sco) 03 Sep 1991 */
  320. X
  321. X/* The idea here is to calculate the Lyapunov exponent for a periodically
  322. X * forced logistic map (later i added several other nonlinear maps of the unit
  323. X * interval). In order to turn the 1-dimensional parameter space of the
  324. X * logistic map into a 2-dimensional parameter space, select two parameter
  325. X * values (a and b) then alternate the iterations of the logistic map using
  326. X * first a then b as the parameter. This program accepts an argument to 
  327. X * specify a forcing function, so instead of just alternating a and b, you
  328. X * can use a as the parameter for say 6 iterations, then b for 6 iterations
  329. X * and so on. An interesting forcing function to look at is abbabaab (the
  330. X * Morse-Thue sequence, an aperiodic self-similar, self-generating sequence).
  331. X * Anyway, you step through all the values of a and b in the ranges you want,
  332. X * calculating the Lyapunov exponent for each pair of values. The exponent
  333. X * is calculated by iterating out a ways (specified by the variable "settle")
  334. X * then on subsequent iterations calculating an average of the logarithm of
  335. X * the absolute value of the derivative at that point. Points in parameter
  336. X * space with a negative Lyapunov exponent are colored one way (using the
  337. X * value of the exponent to index into a color map) while points with a
  338. X * non-negative exponent are colored differently. 
  339. X * 
  340. X * The algorithm was taken from the September 1991 Scientific American article
  341. X * by A. K. Dewdney who gives credit to Mario Markus of the Max Planck Institute
  342. X * for its creation. Additional information and ideas were gleaned from the
  343. X * discussion on alt.fractals involving Stephen Hall, Ed Kubaitis, Dave Platt
  344. X * and Baback Moghaddam. Assistance with colormaps and spinning color wheels
  345. X * and X was gleaned from Hiram Clawson. Rubber banding code was adapted from
  346. X * an existing Mandelbrot program written by Stacey Campbell.
  347. X */
  348. X
  349. X#include "lyap.h"
  350. X
  351. Xstatic char *version = LYAP_VERSION;
  352. X
  353. Xmain(ac, av)
  354. X    int ac;
  355. X    char **av;
  356. X{
  357. X    int i;
  358. X    unsigned char wname[256];
  359. X    Arg wargs[1];
  360. X
  361. X    parseargs(ac, av);
  362. X    toplevel = XtInitialize(av[0], "Lyap", NULL, 0, &ac, av);
  363. X    framework = XtCreateManagedWidget("framework", 
  364. X                         xmFormWidgetClass, toplevel, NULL, 0);
  365. X    /*
  366. X     * Create the canvas widget to display the Lyapunov exponents 
  367. X     */
  368. X    canvas = XtCreateManagedWidget("drawing_canvas", 
  369. X                   xmDrawingAreaWidgetClass, framework, NULL, 0);
  370. X        dpy = XtDisplay(canvas);
  371. X        screen = XtScreen(canvas);
  372. X    /* 
  373. X     * Create the pushbutton widgets. 
  374. X     */ 
  375. X    button[0] =  XtCreateManagedWidget("go_button",
  376. X                                xmPushButtonWidgetClass,
  377. X                                framework, NULL, 0);
  378. X    button[1] =  XtCreateManagedWidget("stop_button",
  379. X                                xmPushButtonWidgetClass,
  380. X                                framework, NULL, 0);
  381. X    button[2] =  XtCreateManagedWidget("quit_button",
  382. X                                xmPushButtonWidgetClass,
  383. X                                framework, NULL, 0);
  384. X    button[3] =  XtCreateManagedWidget("warp_button",
  385. X                                xmPushButtonWidgetClass,
  386. X                                framework, NULL, 0);
  387. X    init_data();
  388. X    init_canvas();
  389. X    /*  
  390. X     * Add callbacks. 
  391. X     */ 
  392. X    XtAddCallback(button[0],XmNactivateCallback,start_iterate,NULL);
  393. X    XtAddCallback(button[1],XmNactivateCallback,stop_iterate,NULL);
  394. X    XtAddCallback(button[2], XmNactivateCallback, quit, NULL);
  395. X    XtAddCallback(button[3], XmNactivateCallback, Spin, NULL);
  396. X    XtRealizeWidget(toplevel);
  397. X    if (displayplanes > 1) {
  398. X        init_color();
  399. X        /* install new color map */
  400. X        XSetWindowColormap(dpy, XtWindow(toplevel), cmap);
  401. X    }
  402. X    else {
  403. X        XQueryColors(dpy, DefaultColormap(dpy, DefaultScreen(dpy)), 
  404. X                Colors, numcolors);
  405. X    }
  406. X    /* Title */
  407. X    sprintf((char *) wname, "Lyap by Ron Record");
  408. X     XChangeProperty(dpy, XtWindow(toplevel), XA_WM_NAME, XA_STRING, 8, 
  409. X         PropModeReplace, wname, strlen(wname));
  410. X    if (NoShowButtons) {
  411. X        for (i=0;i<4;i++)
  412. X            XtUnrealizeWidget(button[i]);
  413. X        XtSetArg(wargs[0], XmNbottomPosition, &bottom);
  414. X        XtGetValues(canvas, wargs, 1);
  415. X        XtSetArg(wargs[0], XmNbottomPosition, 99);
  416. X        XtSetValues(canvas, wargs, 1);
  417. X    }
  418. X    pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy), 
  419. X            width, height, DefaultDepthOfScreen(screen));
  420. X    XtAddCallback(canvas, XmNexposeCallback, redisplay, NULL); 
  421. X    XtAddCallback(canvas, XmNresizeCallback, resize, NULL); 
  422. X    XtAddEventHandler(canvas, KeyPressMask,
  423. X             FALSE, Getkey, NULL);
  424. X    XtAddEventHandler(button[0], KeyPressMask,
  425. X             FALSE, Getkey, NULL);
  426. X    XtAddEventHandler(button[1], KeyPressMask,
  427. X             FALSE, Getkey, NULL);
  428. X    XtAddEventHandler(button[2], KeyPressMask,
  429. X             FALSE, Getkey, NULL);
  430. X    XtAddEventHandler(button[3], KeyPressMask,
  431. X             FALSE, Getkey, NULL);
  432. X    XtAddEventHandler(canvas, ButtonPressMask, FALSE, StartRubberBand, 
  433. X            &rubber_data);
  434. X    XtAddEventHandler(canvas, ButtonMotionMask, FALSE, TrackRubberBand,
  435. X                &rubber_data);
  436. X    XtAddEventHandler(canvas, ButtonReleaseMask, FALSE, EndRubberBand,
  437. X             &rubber_data);
  438. X    rubber_data.band_cursor=XCreateFontCursor(XtDisplay(canvas), XC_hand2);
  439. X    XGrabButton(XtDisplay(canvas), AnyButton, AnyModifier, XtWindow(canvas),
  440. X        TRUE, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
  441. X        GrabModeAsync, GrabModeAsync, XtWindow(canvas),
  442. X        rubber_data.band_cursor);
  443. X    CreateXorGC(canvas);
  444. X      work_proc_id = XtAddWorkProc(complyap, canvas);
  445. X    resize(canvas, (struct image_data_t *) NULL, (XmDrawingAreaCallbackStruct *)NULL);
  446. X    XtMainLoop();
  447. X}
  448. X
  449. X/* complyap() is the guts of the program. This is where the Lyapunov exponent
  450. X * is calculated. For each iteration (past some large number of iterations)
  451. X * calculate the logarithm of the absolute value of the derivative at that
  452. X * point. Then average them over some large number of iterations. Some small
  453. X * speed up is achieved by utilizing the fact that log(a*b) = log(a) + log(b).
  454. X */
  455. XBoolean
  456. Xcomplyap(w, data, call_data)
  457. XWidget    w;
  458. Xstruct image_data    *data[];
  459. XXmDrawingAreaCallbackStruct    *call_data;
  460. X{
  461. X    register i, bindex, findex;
  462. X    double total, prod, x, r;
  463. X    extern Boolean sendpoint();
  464. X
  465. X    a += a_inc;
  466. X    if (a >= max_a)
  467. X        if (sendpoint(lyapunov))
  468. X            return FALSE;
  469. X        else {
  470. X            FlushBuffer();
  471. X            if (savefile)
  472. X                save_to_file();
  473. X            work_proc_id = (XtWorkProcId) NULL; 
  474. X            return TRUE;
  475. X        }
  476. X    if (b >= max_b) {
  477. X        FlushBuffer();
  478. X        if (savefile)
  479. X            save_to_file();
  480. X        work_proc_id = (XtWorkProcId) NULL; 
  481. X        return TRUE;
  482. X    }
  483. X    prod = 1.0;
  484. X    total = 0.0;
  485. X    bindex = 0;
  486. X    x = start_x;
  487. X    r = (forcing[bindex]) ? b : a;
  488. X#ifdef MAPS
  489. X    findex = 0;
  490. X    map = Maps[Forcing[findex]];
  491. X#endif
  492. X    for (i=0;i<settle;i++) {       /* Here's where we let the thing */
  493. X        x = (*map)(x, r);       /* "settle down". There is usually */
  494. X        if (++bindex >= maxindex)  /* some initial "noise" in the */
  495. X            bindex = 0;       /* iterations. How can we optimize */
  496. X        r = (forcing[bindex]) ? b : a; /* the value of settle ??? */
  497. X#ifdef MAPS
  498. X        if (++findex >= funcmaxindex)
  499. X            findex = 0;
  500. X        map = Maps[Forcing[findex]];
  501. X#endif
  502. X    }
  503. X#ifdef MAPS
  504. X    deriv = Derivs[Forcing[findex]];
  505. X#endif
  506. X    if (useprod) {            /* using log(a*b) */
  507. X        for (i=0;i<dwell;i++) {
  508. X            x = (*map)(x, r);
  509. X            prod *= ABS((*deriv)(x, r));
  510. X            /* we need to prevent overflow and underflow */
  511. X            if ((prod > 1.0e12) || (prod < 1.0e-12)) {
  512. X                total += log(prod);
  513. X                prod = 1.0;
  514. X            }
  515. X            if (++bindex >= maxindex)
  516. X                bindex = 0;
  517. X            r = (forcing[bindex]) ? b : a;
  518. X#ifdef MAPS
  519. X            if (++findex >= funcmaxindex)
  520. X                findex = 0;
  521. X            map = Maps[Forcing[findex]];
  522. X            deriv = Derivs[Forcing[findex]];
  523. X#endif
  524. X        }
  525. X        total += log(prod);
  526. X        lyapunov = (total * invlog2) / (double)dwell;
  527. X    }
  528. X    else {                /* use log(a) + log(b) */
  529. X        for (i=0;i<dwell;i++) {
  530. X            x = (*map)(x, r);
  531. X            total += log(ABS((*deriv)(x, r)));
  532. X            if (++bindex >= maxindex)
  533. X                bindex = 0;
  534. X            r = (forcing[bindex]) ? b : a;
  535. X#ifdef MAPS
  536. X            if (++findex >= funcmaxindex)
  537. X                findex = 0;
  538. X            map = Maps[Forcing[findex]];
  539. X            deriv = Derivs[Forcing[findex]];
  540. X#endif
  541. X        }
  542. X        lyapunov = (total * invlog2) / (double)dwell;
  543. X    }
  544. X    if (sendpoint(lyapunov))
  545. X        return FALSE;
  546. X    else {
  547. X        FlushBuffer();
  548. X        if (savefile)
  549. X            save_to_file();
  550. X        work_proc_id = (XtWorkProcId) NULL; 
  551. X        return TRUE;
  552. X    }
  553. X}
  554. X
  555. Xdouble
  556. Xlogistic(x, r)            /* the familiar logistic map */
  557. Xdouble x, r;
  558. X{
  559. X    return(r * x * (1.0 - x));
  560. X}
  561. X
  562. Xdouble
  563. Xdlogistic(x, r)            /* the derivative of logistic map */
  564. Xdouble x, r;
  565. X{
  566. X    return(r - (2.0 * r * x));
  567. X}
  568. X
  569. Xdouble
  570. Xcircle(x, r)            /* sin() hump or sorta like the circle map */
  571. Xdouble x, r;
  572. X{
  573. X    extern double sin();
  574. X
  575. X    return(r * sin(M_PI * x));
  576. X}
  577. X
  578. Xdouble
  579. Xdcircle(x, r)            /* derivative of the "sin() hump" */
  580. Xdouble x, r;
  581. X{
  582. X    extern double cos();
  583. X
  584. X    return(r * M_PI * cos(M_PI * x));
  585. X}
  586. X
  587. Xdouble
  588. Xleftlog(x, r)            /* left skewed logistic */
  589. Xdouble x, r;
  590. X{
  591. X    double d;
  592. X
  593. X    d = 1.0 - x;
  594. X    return(r * x * d * d);
  595. X}
  596. X
  597. Xdouble
  598. Xdleftlog(x, r)            /* derivative of the left skewed logistic */
  599. Xdouble x, r;
  600. X{
  601. X    return(r * (1.0 - (4.0 * x) + (3.0 * x * x)));
  602. X}
  603. X
  604. Xdouble
  605. Xrightlog(x, r)            /* right skewed logistic */
  606. Xdouble x, r;
  607. X{
  608. X    return(r * x * x * (1.0 - x));
  609. X}
  610. X
  611. Xdouble
  612. Xdrightlog(x, r)            /* derivative of the right skewed logistic */
  613. Xdouble x, r;
  614. X{
  615. X    return(r * ((2.0 * x) - (3.0 * x * x)));
  616. X}
  617. X
  618. Xdouble
  619. Xdoublelog(x, r)            /* double logistic */
  620. Xdouble x, r;
  621. X{
  622. X    double d;
  623. X
  624. X    d = 1.0 - x;
  625. X    return(r * x * x * d * d);
  626. X}
  627. X
  628. Xdouble
  629. Xddoublelog(x, r)        /* derivative of the double logistic */
  630. Xdouble x, r;
  631. X{
  632. X    double d;
  633. X
  634. X    d = x * x;
  635. X    return(r * ((2.0 * x) - (6.0 * d) + (4.0 * x * d)));
  636. X}
  637. X
  638. Xinit_data()
  639. X{
  640. X    static int i;
  641. X
  642. X    numcolors = XDisplayCells(dpy, XDefaultScreen(dpy));
  643. X    displayplanes = DisplayPlanes(dpy, XDefaultScreen(dpy));
  644. X    if (numcolors > MAXCOLOR)
  645. X        numcolors = MAXCOLOR;
  646. X    numfreecols = numcolors - mincolindex;
  647. X    lowrange = mincolindex - STARTCOLOR;
  648. X    if (exponents)
  649. X        free(exponents);
  650. X    if((exponents=(double *)malloc(sizeof(double)*width*height))==NULL){
  651. X        fprintf(stderr,"Error malloc'ing exponent array.\n");
  652. X        exit(-1);
  653. X    }
  654. X    if (o_exponents)
  655. X        free(o_exponents);
  656. X    if((o_exponents=(double *)malloc(sizeof(double)*width*height))==NULL){
  657. X        fprintf(stderr,"Error malloc'ing o_exponent array.\n");
  658. X        exit(-1);
  659. X    }
  660. X    if (i_exponents)
  661. X        free(i_exponents);
  662. X    if((i_exponents=(double *)malloc(sizeof(double)*width*height))==NULL){
  663. X        fprintf(stderr,"Error malloc'ing i_exponent array.\n");
  664. X        exit(-1);
  665. X    }
  666. X    a_inc = a_range / (double)width;
  667. X    b_inc = b_range / (double)height;
  668. X    invlog2 = 1.0 / log(2.0);
  669. X    point.x = -1;
  670. X    point.y = 0;
  671. X    a = rubber_data.p_min = min_a;
  672. X    b = rubber_data.q_min = min_b;
  673. X    rubber_data.p_max = max_a;
  674. X    rubber_data.q_max = max_b;
  675. X    if (show)
  676. X        show_defaults();
  677. X    InitBuffer();
  678. X}
  679. X
  680. Xinit_canvas()
  681. X{
  682. X    Arg wargs[4];
  683. X    static int i;
  684. X
  685. X    /*
  686. X     * Set the size of the drawing areas.
  687. X     */
  688. X    XtSetArg(wargs[0], XtNwidth, width);
  689. X    XtSetArg(wargs[1], XtNheight, height);
  690. X    XtSetValues(framework, wargs,2);
  691. X    /*
  692. X     * create default, writable, graphics contexts for the canvas.
  693. X     */
  694. X        for (i=0; i<MAXCOLOR; i++) {
  695. X            Data_GC[i] = XCreateGC(dpy, DefaultRootWindow(dpy),
  696. X                (unsigned long) NULL, (XGCValues *) NULL);
  697. X            /* set the background to black */
  698. X            XSetBackground(dpy,Data_GC[i],BlackPixel(dpy,XDefaultScreen(dpy)));
  699. X            /* set the foreground of the ith context to i */
  700. X            XSetForeground(dpy, Data_GC[i], i);
  701. X        }
  702. X        if (displayplanes == 1) {
  703. X            XSetForeground(dpy,Data_GC[0],BlackPixel(dpy,XDefaultScreen(dpy)));
  704. X            XSetForeground(dpy,Data_GC[1],WhitePixel(dpy,XDefaultScreen(dpy)));
  705. X        }
  706. X}
  707. X
  708. Xinit_color()
  709. X{
  710. X    static int i, j, colgap, leg, step;
  711. X    static Visual *visual;
  712. X    Colormap def_cmap;
  713. X    int hls[3], rgb[3];
  714. X    extern void hls2rgb( int[3], int[3]);
  715. X
  716. X    def_cmap = DefaultColormap(dpy, DefaultScreen(dpy));
  717. X    for (i=0; i<numcolors; i++) {
  718. X        Colors[i].pixel = i;
  719. X        Colors[i].flags = DoRed|DoGreen|DoBlue;
  720. X    }
  721. X
  722. X    /* Try to write into a new color map */
  723. X    visual = DefaultVisual(dpy, DefaultScreen(dpy));
  724. X    cmap = XCreateColormap(dpy, XtWindow(canvas), visual, AllocAll);
  725. X    XQueryColors(dpy, def_cmap, Colors, numcolors);
  726. X    if (mincolindex)
  727. X        colgap = rgb_max / mincolindex;
  728. X    else
  729. X        colgap = rgb_max;
  730. X    hls[0] = 50;    /* Hue in low range */
  731. X    hls[2] = 1000;    /* Fully saturated */
  732. X    for (i=STARTCOLOR; i<lowrange + STARTCOLOR; i++) {
  733. X        hls[1] = 1000L * (i-STARTCOLOR) / lowrange;
  734. X        hls2rgb(hls, rgb);
  735. X        Colors[i].red = rgb[0];
  736. X        Colors[i].green = rgb[1];
  737. X        Colors[i].blue = rgb[2];
  738. X    }
  739. X    colgap = rgb_max / numcolors;
  740. X    if (numwheels == 0)
  741. X        XQueryColors(dpy, def_cmap, Colors, numcolors);
  742. X    else if (numwheels == 1) {
  743. X        colgap = 2*rgb_max/(numcolors - color_offset);
  744. X        for (i=mincolindex; i<(numcolors/2); i++) {
  745. X            Colors[i].blue = 0;
  746. X            Colors[i].green=((i+color_offset)*colgap);
  747. X            Colors[i].red=((i+color_offset)*colgap);
  748. X        }
  749. X        for (i=(numcolors/2); i<(numcolors); i++) {
  750. X            Colors[i].blue = 0;
  751. X            Colors[i].green=(((numcolors-i)+color_offset)*colgap);
  752. X            Colors[i].red=(((numcolors-i)+color_offset)*colgap);
  753. X        }
  754. X    }
  755. X    else if (numwheels == 2) {
  756. X            hls[0] = 800;    /* Hue in mid range */
  757. X            hls[2] = 1000;    /* Fully saturated */
  758. X            for (i=STARTCOLOR; i<lowrange + STARTCOLOR; i++) {
  759. X            hls[1] = 1000L * (i-STARTCOLOR) / lowrange;
  760. X            hls2rgb(hls, rgb);
  761. X            Colors[i].red = rgb[0];
  762. X            Colors[i].green = rgb[1];
  763. X            Colors[i].blue = rgb[2];
  764. X            }
  765. X        for (i=mincolindex; i<(numcolors/2); i++) {
  766. X            Colors[i].blue = rgb_max;
  767. X            Colors[i].green = 0;
  768. X            Colors[i].red=(i*2*rgb_max/numcolors);
  769. X        }
  770. X        for (i=(numcolors/2); i<numcolors; i++) {
  771. X            Colors[i].blue = rgb_max;
  772. X            Colors[i].green = 0;
  773. X            Colors[i].red=((numcolors - i)*2*rgb_max/numcolors);
  774. X        }
  775. X    }
  776. X    else if (numwheels == 3) {
  777. X            hls[0] = 800;    /* Hue in mid range */
  778. X            hls[2] = 1000;    /* Fully saturated */
  779. X            for (i=STARTCOLOR; i<lowrange + STARTCOLOR; i++) {
  780. X            hls[1] = 1000L * (i-STARTCOLOR) / lowrange;
  781. X            hls2rgb(hls, rgb);
  782. X            Colors[i].red = rgb[0];
  783. X            Colors[i].green = rgb[1];
  784. X            Colors[i].blue = rgb[2];
  785. X            }
  786. X        colgap = 4*rgb_max/numcolors;
  787. X        for (i=mincolindex; i<(numcolors/4); i++) {
  788. X            Colors[i].blue = rgb_max;
  789. X            Colors[i].green = 0;
  790. X            Colors[i].red=(i*colgap);
  791. X        }
  792. X        for (i=(numcolors/4); i<(numcolors/2); i++) {
  793. X            Colors[i].red = rgb_max;
  794. X            Colors[i].green = 0;
  795. X            Colors[i].blue=((numcolors/2) - i) * colgap;
  796. X        }
  797. X        for (i=(numcolors/2); i<(0.75*numcolors); i++) {
  798. X            Colors[i].red = rgb_max;
  799. X            Colors[i].blue=(i * colgap);
  800. X            Colors[i].green = 0;
  801. X        }
  802. X        for (i=(0.75*numcolors); i<numcolors; i++) {
  803. X            Colors[i].blue = rgb_max;
  804. X            Colors[i].green = 0;
  805. X            Colors[i].red=(numcolors-i)*colgap;
  806. X        }
  807. X    }
  808. X    else if (numwheels == 4) {
  809. X            hls[0] = 800;    /* Hue in mid range */
  810. X            hls[2] = 1000;    /* Fully saturated */
  811. X            for (i=STARTCOLOR; i<lowrange + STARTCOLOR; i++) {
  812. X            hls[1] = 1000L * (i-STARTCOLOR) / lowrange;
  813. X            hls2rgb(hls, rgb);
  814. X            Colors[i].red = rgb[0];
  815. X            Colors[i].green = rgb[1];
  816. X            Colors[i].blue = rgb[2];
  817. X            }
  818. X        colgap = numwheels * rgb_max / numcolors;
  819. X        for (i=mincolindex; i<(numcolors/numwheels); i++) {
  820. X            Colors[i].blue = rgb_max;
  821. X            Colors[i].green = 0;
  822. X            Colors[i].red=(i*colgap);
  823. X        }
  824. X        for (i=(numcolors/numwheels); i<(2*numcolors/numwheels); i++) {
  825. X            Colors[i].red = rgb_max;
  826. X            Colors[i].green = 0;
  827. X            Colors[i].blue=((2*numcolors/numwheels) - i) * colgap;
  828. X        }
  829. X        for (i=(2*numcolors/numwheels); i<numcolors; i++) {
  830. X            Colors[i].red = rgb_max;
  831. X            Colors[i].green=(i - (2*numcolors/numwheels)) * colgap;
  832. X            Colors[i].blue = 0;
  833. X        }
  834. X    }
  835. X    else if (numwheels == 5) {
  836. X        hls[1] = 700;    /* Lightness in midrange */
  837. X        hls[2] = 1000;    /* Fully saturated */
  838. X        for (i=mincolindex; i<numcolors; i++) {
  839. X            hls[0] = 3600L * i / numcolors;
  840. X            hls2rgb(hls, rgb);
  841. X            Colors[i].red = rgb[0];
  842. X            Colors[i].green = rgb[1];
  843. X            Colors[i].blue = rgb[2];
  844. X        }
  845. X        for (i=mincolindex; i<numcolors; i+=stripe_interval) {
  846. X            hls[0] = 3600L * i / numcolors;
  847. X            hls2rgb(hls, rgb);
  848. X            Colors[i].red = rgb[0] / 2;
  849. X            Colors[i].green = rgb[1] / 2;
  850. X            Colors[i].blue = rgb[2] / 2;
  851. X        }
  852. X    }
  853. X    else if (numwheels == 6) {
  854. X        hls[0] = 800;    /* Hue in mid range */
  855. X        hls[2] = 1000;    /* Fully saturated */
  856. X        for (i=STARTCOLOR; i<lowrange + STARTCOLOR; i++) {
  857. X        hls[1] = 1000L * (i-STARTCOLOR) / lowrange;
  858. X        hls2rgb(hls, rgb);
  859. X        Colors[i].red = rgb[0];
  860. X        Colors[i].green = rgb[1];
  861. X        Colors[i].blue = rgb[2];
  862. X        }
  863. X        step = numfreecols / 3;
  864. X        leg = step+mincolindex;
  865. X        for (i = mincolindex; i < leg; ++i)
  866. X        {
  867. X        Colors[i].pixel = i;
  868. X        Colors[i].red = fabs(65535 - (double)i / step * 65535.0);
  869. X        Colors[i].blue = (double)i / step * 65535.0;
  870. X        Colors[i].green = 0;
  871. X        Colors[i].flags = DoRed | DoGreen | DoBlue;
  872. X        }
  873. X        for (j = 0, i = leg, leg += step; i < leg; ++i, ++j)
  874. X        {
  875. X        Colors[i].pixel = i;
  876. X        Colors[i].red = (double)j / step * 65535.0;
  877. X        Colors[i].blue = 65535;
  878. X        Colors[i].green = Colors[i].red;
  879. X        Colors[i].flags = DoRed | DoGreen | DoBlue;
  880. X        }
  881. X        for (j = 0, i = leg, leg += step; i < leg; ++i, ++j)
  882. X        {
  883. X        Colors[i].pixel = i;
  884. X        Colors[i].red = 65535;
  885. X        Colors[i].blue = fabs(65535 - (double)j / step * 65535.0);
  886. X        Colors[i].green = Colors[i].blue;
  887. X        Colors[i].flags = DoRed | DoGreen | DoBlue;
  888. X        }
  889. X    }
  890. X    else if (numwheels == MAXWHEELS) {    /* rainbow palette */
  891. X        hls[1] = 500;    /* Lightness in midrange */
  892. X        hls[2] = 1000;    /* Fully saturated */
  893. X        for (i=mincolindex; i<numcolors; i++) {
  894. X            hls[0] = 3600L * i / numcolors;
  895. X            hls2rgb(hls, rgb);
  896. X            Colors[i].red = rgb[0];
  897. X            Colors[i].green = rgb[1];
  898. X            Colors[i].blue = rgb[2];
  899. X        }
  900. X    }
  901. X    XStoreColors(dpy, cmap, Colors, numcolors);
  902. X}
  903. X
  904. Xparseargs(ac, av)
  905. Xint ac;
  906. Xchar **av;
  907. X{
  908. X    static int c;
  909. X    static int i;
  910. X    int bindex=0, mapindex=0, findex;
  911. X    char *ch;
  912. X    extern int optind;
  913. X    extern char *optarg;
  914. X    extern double atof();
  915. X
  916. X    map = Maps[0];
  917. X    deriv = Derivs[0];
  918. X
  919. X   while ((c=getopt(ac,av,"BLpuvc:m:C:W:H:M:O:S:a:b:D:F:f:o:w:h:r:s:x:"))!=EOF){
  920. X        switch (c) {
  921. X        case 'B':    NoShowButtons=1; break;
  922. X        case 'C':    mincolindex=atoi(optarg); break;
  923. X        case 'D':    dwell=atoi(optarg); break;
  924. X#ifdef MAPS
  925. X        case 'F':    funcmaxindex = strlen(optarg);
  926. X                if (funcmaxindex > FUNCMAXINDEX)
  927. X                    usage();
  928. X                ch = optarg;
  929. X                Force++;
  930. X                for (findex=0;findex<funcmaxindex;findex++) {
  931. X                    Forcing[findex] = (int)(*ch++ - '0');;
  932. X                    if (Forcing[findex] >= NUMMAPS)
  933. X                        usage();
  934. X                }
  935. X                break;
  936. X#endif
  937. X        case 'H':    height=atoi(optarg); break;
  938. X        case 'L':    useprod=0; break;
  939. X        case 'M':    minlyap=ABS(atof(optarg)); break;
  940. X        case 'O':    color_offset=atoi(optarg); break;
  941. X        case 'S':    settle=atoi(optarg); break;
  942. X        case 'W':    width=atoi(optarg); break;
  943. X        case 'a':    min_a=atof(optarg); aflag++; break;
  944. X        case 'b':    min_b=atof(optarg); bflag++; break;
  945. X        case 'c':    numwheels=atoi(optarg); break;
  946. X        case 'f':    maxindex = strlen(optarg);
  947. X                if (maxindex > MAXINDEX)
  948. X                    usage();
  949. X                ch = optarg;
  950. X                force++;
  951. X                while (bindex < maxindex) {
  952. X                    if (*ch == 'a')
  953. X                        forcing[bindex++] = 0;
  954. X                    else if (*ch == 'b')
  955. X                        forcing[bindex++] = 1;
  956. X                    else
  957. X                        usage();
  958. X                    ch++;
  959. X                }
  960. X                break;
  961. X        case 'h':    b_range=atof(optarg); hflag++; break;
  962. X        case 'm':    mapindex=atoi(optarg); 
  963. X                if ((mapindex >= NUMMAPS) || (mapindex < 0))
  964. X                    usage();
  965. X                map = Maps[mapindex];
  966. X                deriv = Derivs[mapindex];
  967. X                if (!aflag)
  968. X                    min_a = amins[mapindex];
  969. X                if (!wflag)
  970. X                    a_range = aranges[mapindex];
  971. X                if (!bflag)
  972. X                    min_b = bmins[mapindex];
  973. X                if (!hflag)
  974. X                    b_range = branges[mapindex];
  975. X                if (!Force)
  976. X                    for (i=0;i<FUNCMAXINDEX;i++)
  977. X                        Forcing[i] = mapindex;
  978. X                break;
  979. X        case 'o':    savefile++; outname=optarg; break;
  980. X        case 'p':    negative--; break;
  981. X        case 'r':    rgb_max=atoi(optarg); break;
  982. X        case 's':    spinlength=atoi(optarg); break;
  983. X        case 'u':    usage(); break;
  984. X        case 'v':    show=1; break;
  985. X        case 'w':    a_range=atof(optarg); wflag++; break;
  986. X        case 'x':    start_x=atof(optarg); break;
  987. X        case '?':    usage(); break;
  988. X        }
  989. X    }
  990. X    max_a = min_a + a_range;
  991. X    max_b = min_b + b_range;
  992. X    o_min_a = orig_min_a = min_a; o_min_b = orig_min_b = min_b;
  993. X    o_max_a = orig_max_a = max_a; o_max_b = orig_max_b = max_b;
  994. X    if (Force)
  995. X        if (maxindex == funcmaxindex)
  996. X            for (findex=0;findex<funcmaxindex;findex++)
  997. X            check_params(Forcing[findex],forcing[findex]);
  998. X        else
  999. X            fprintf(stderr, "Warning! Unable to check parameters\n");
  1000. X    else
  1001. X        check_params(mapindex,2);
  1002. X}
  1003. X
  1004. Xcheck_params(mapnum, parnum)
  1005. Xint mapnum;
  1006. Xint parnum;
  1007. X{
  1008. X
  1009. X    if (parnum != 1) {
  1010. X        if ((max_a > pmaxs[mapnum]) || (min_a < pmins[mapnum])) {
  1011. X        fprintf(stderr, "Warning! Parameter 'a' out of range.\n");
  1012. X        fprintf(stderr, "You have requested a range of (%f,%f).\n",
  1013. X            min_a,max_a);
  1014. X        fprintf(stderr, "Valid range is (%f,%f).\n",
  1015. X            pmins[mapnum],pmaxs[mapnum]);
  1016. X        }
  1017. X    }
  1018. X    if (parnum != 0) {
  1019. X        if ((max_b > pmaxs[mapnum]) || (min_b < pmins[mapnum])) {
  1020. X        fprintf(stderr, "Warning! Parameter 'b' out of range.\n");
  1021. X        fprintf(stderr, "You have requested a range of (%f,%f).\n",
  1022. X            min_b,max_b);
  1023. X        fprintf(stderr, "Valid range is (%f,%f).\n",
  1024. X            pmins[mapnum],pmaxs[mapnum]);
  1025. X        }
  1026. X    }
  1027. X}
  1028. X
  1029. Xusage()
  1030. X{
  1031. X    fprintf(stderr,"lyap [-BLs][-W#][-H#][-a#][-b#][-w#][-h#][-x xstart]\n");
  1032. X    fprintf(stderr,"\t[-M#][-S#][-D#][-f string][-r#][-O#][-C#][-c#][-m#]\n");
  1033. X#ifdef MAPS
  1034. X    fprintf(stderr,"\t[-F string]\n");
  1035. X#endif
  1036. X    fprintf(stderr,"\tWhere: -C# specifies the minimum color index\n");
  1037. X    fprintf(stderr,"\t       -r# specifies the maxzimum rgb value\n");
  1038. X    fprintf(stderr,"\t       -u displays this message\n");
  1039. X    fprintf(stderr,"\t       -a# specifies the minimum horizontal parameter\n");
  1040. X    fprintf(stderr,"\t       -b# specifies the minimum vertical parameter\n");
  1041. X    fprintf(stderr,"\t       -w# specifies the horizontal parameter range\n");
  1042. X    fprintf(stderr,"\t       -h# specifies the vertical parameter range\n");
  1043. X    fprintf(stderr,"\t       -D# specifies the dwell\n");
  1044. X    fprintf(stderr,"\t       -S# specifies the settle\n");
  1045. X    fprintf(stderr,"\t       -H# specifies the initial window height\n");
  1046. X    fprintf(stderr,"\t       -W# specifies the initial window width\n");
  1047. X    fprintf(stderr,"\t       -O# specifies the color offset\n");
  1048. X    fprintf(stderr,"\t       -c# specifies the desired color wheel\n");
  1049. X    fprintf(stderr,"\t       -m# specifies the desired map (0-4)\n");
  1050. X    fprintf(stderr,"\t       -f aabbb specifies a forcing function of 00111\n");
  1051. X#ifdef MAPS
  1052. X    fprintf(stderr,"\t       -F 00111 specifies the function forcing function\n");
  1053. X#endif
  1054. X    fprintf(stderr,"\t       -L indicates use log(x)+log(y) rather than log(xy)\n");
  1055. X    fprintf(stderr,"\tDuring display :\n");
  1056. X    fprintf(stderr,"\t     Use the mouse to zoom in on an area\n");
  1057. X    fprintf(stderr,"\t     b or B toggles button display on/off\n");
  1058. X    fprintf(stderr,"\t     e or E recalculates color indices\n");
  1059. X    fprintf(stderr,"\t     f or F saves exponents to a file\n");
  1060. X    fprintf(stderr,"\t     KJmn increase/decrease minimum negative exponent\n");
  1061. X    fprintf(stderr,"\t     r or R redraws\n");
  1062. X    fprintf(stderr,"\t     s or S spins the colorwheel\n");
  1063. X    fprintf(stderr,"\t     w or W changes the color wheel\n");
  1064. X    fprintf(stderr,"\t     x or X clears the window\n");
  1065. X    fprintf(stderr,"\t     q or Q exits\n");
  1066. X    exit(1);
  1067. X}
  1068. X
  1069. Xvoid
  1070. Xstart_iterate(w, cv, call_data)
  1071. XWidget w, cv;
  1072. XXmAnyCallbackStruct *call_data;
  1073. X{
  1074. X    if(work_proc_id)
  1075. X        XtRemoveWorkProc(work_proc_id);
  1076. X    /*
  1077. X     * Register complyap() as a WorkProc.
  1078. X     */
  1079. X    work_proc_id = XtAddWorkProc(complyap, cv);
  1080. X}
  1081. X
  1082. Xvoid 
  1083. Xstop_iterate(w, cv, call_data)
  1084. XWidget                w, cv;
  1085. XXmAnyCallbackStruct  *call_data;
  1086. X{
  1087. X    FlushBuffer();
  1088. X    if(work_proc_id)
  1089. X        XtRemoveWorkProc(work_proc_id);
  1090. X    work_proc_id = (XtWorkProcId) NULL; 
  1091. X}
  1092. X
  1093. Xvoid
  1094. XSpin(w, call_value)
  1095. XWidget w;
  1096. XXmAnyCallbackStruct *call_value;
  1097. X{
  1098. X    static int i, j;
  1099. X    long tmpxcolor;
  1100. X
  1101. X    if (displayplanes > 1) {
  1102. X        stop_iterate(w,canvas,NULL);
  1103. X        for (j=0;j<spinlength;j++) {
  1104. X            tmpxcolor = Colors[mincolindex].pixel;
  1105. X            for (i=mincolindex;i<numcolors-1;i++)
  1106. X                Colors[i].pixel = Colors[i+1].pixel;
  1107. X            Colors[numcolors-1].pixel = tmpxcolor;
  1108. X            XStoreColors(dpy, cmap, Colors, numcolors);
  1109. X        }
  1110. X        for (j=0;j<spinlength;j++) {
  1111. X            tmpxcolor = Colors[numcolors-1].pixel;
  1112. X            for (i=numcolors-1;i>mincolindex;i--)
  1113. X                Colors[i].pixel = Colors[i-1].pixel;
  1114. X            Colors[mincolindex].pixel = tmpxcolor;
  1115. X            XStoreColors(dpy, cmap, Colors, numcolors);
  1116. X        }
  1117. X        start_iterate(w,canvas,NULL);
  1118. X    }
  1119. X}
  1120. X
  1121. Xvoid
  1122. Xquit(w, call_value)
  1123. XWidget w;
  1124. XXmAnyCallbackStruct *call_value;
  1125. X{
  1126. X    Clear();
  1127. X    exit(0);
  1128. X}
  1129. X
  1130. XXtEventHandler
  1131. XGetkey(w, client_data, event)
  1132. XWidget w;
  1133. Xcaddr_t client_data;
  1134. XXKeyEvent *event;
  1135. X{
  1136. X    Arg wargs[1];
  1137. X    unsigned char key;
  1138. X        XKeyEvent *keyevent = (XKeyEvent *)event;
  1139. X    static int i;
  1140. X
  1141. X        if (XLookupString(keyevent, (char *)&key, sizeof(key), (KeySym *)0,
  1142. X            (XComposeStatus *) 0) > 0)
  1143. X                switch (key) {
  1144. X    case '<': dwell /= 2; if (dwell < 1) dwell = 1; break;
  1145. X    case '>': dwell *= 2; break;
  1146. X    case '[': settle /= 2; if (settle < 1) settle = 1; break;
  1147. X    case ']': settle *= 2; break;
  1148. X    case 'b':
  1149. X    case 'B': NoShowButtons = (!NoShowButtons);
  1150. X           if (NoShowButtons) {
  1151. X            for (i=0;i<4;i++)
  1152. X                XtUnrealizeWidget(button[i]);
  1153. X            XtSetArg(wargs[0], XmNbottomPosition, &bottom);
  1154. X            XtGetValues(canvas, wargs, 1);
  1155. X            XtSetArg(wargs[0], XmNbottomPosition, 99);
  1156. X            XtSetValues(canvas, wargs, 1);
  1157. X           }
  1158. X           else {
  1159. X            XtSetArg(wargs[0], XmNbottomPosition, bottom);
  1160. X            XtSetValues(canvas, wargs, 1);
  1161. X            for (i=0;i<4;i++) {
  1162. X                XtManageChild(button[i]);
  1163. X                XtRealizeWidget(button[i]);
  1164. X            }
  1165. X           }
  1166. X           break;
  1167. X    case 'd':
  1168. X    case 'D': FlushBuffer(); break;
  1169. X    case 'e':
  1170. X    case 'E': recalc(); break;
  1171. X    case 'f':
  1172. X    case 'F': save_to_file(); break;
  1173. X    case 'i': if (stripe_interval > 0) {
  1174. X            stripe_interval--;
  1175. X              if (displayplanes > 1) {
  1176. X                  init_color(); 
  1177. X                  XSetWindowColormap(dpy, XtWindow(toplevel), cmap);
  1178. X              }
  1179. X          }
  1180. X          break;
  1181. X    case 'I': stripe_interval++;
  1182. X          if (displayplanes > 1) {
  1183. X              init_color(); 
  1184. X              XSetWindowColormap(dpy, XtWindow(toplevel), cmap);
  1185. X          }
  1186. X          break;
  1187. X    case 'k':
  1188. X    case 'K': if (minlyap > 0.05)
  1189. X            minlyap -= 0.05;
  1190. X           break;
  1191. X    case 'j':
  1192. X    case 'J': minlyap += 0.05; 
  1193. X           break;
  1194. X    case 'm': if (minlyap > 0.005)
  1195. X            minlyap -= 0.005;
  1196. X           break;
  1197. X    case 'n': minlyap += 0.005;
  1198. X           break;
  1199. X    case 'p':
  1200. X    case 'P': negative = (!negative); 
  1201. X          FlushBuffer(); redraw(exponents, expind, 1); break;
  1202. X    case 'r': FlushBuffer(); redraw(exponents, expind, 1); break;
  1203. X    case 'R': FlushBuffer(); Redraw(); break;
  1204. X    case 's':
  1205. X           spinlength=spinlength/2;
  1206. X    case 'S': if (displayplanes > 1) 
  1207. X            Spin(canvas,NULL); 
  1208. X           spinlength=spinlength*2; break;
  1209. X    case 'u': go_back(); break;
  1210. X    case 'U': go_init(); break;
  1211. X    case 'v':
  1212. X    case 'V': print_values(); break;
  1213. X    case 'W': if (numwheels < MAXWHEELS)
  1214. X            numwheels++;
  1215. X           else
  1216. X            numwheels = 0;
  1217. X           if (displayplanes > 1) {
  1218. X               init_color(); 
  1219. X               XSetWindowColormap(dpy, XtWindow(toplevel), cmap);
  1220. X           }
  1221. X           break;
  1222. X    case 'w': if (numwheels > 0)
  1223. X            numwheels--;
  1224. X           else
  1225. X            numwheels = MAXWHEELS;
  1226. X           if (displayplanes > 1) {
  1227. X               init_color(); 
  1228. X               XSetWindowColormap(dpy, XtWindow(toplevel), cmap);
  1229. X           }
  1230. X           break;
  1231. X    case 'x':
  1232. X    case 'X': Clear(); break;
  1233. X    case 'q':
  1234. X    case 'Q': exit(0); break;
  1235. X    case '?':
  1236. X    case 'h':
  1237. X    case 'H': print_help(); break;
  1238. X    default:  break;
  1239. X    }
  1240. X}
  1241. X
  1242. X/* Here's where we index into a color map. After the Lyapunov exponent is
  1243. X * calculated, it is used to determine what color to use for that point.
  1244. X * I suppose there are a lot of ways to do this. I used the following :
  1245. X * if it's non-negative then there's a reserved area at the lower range
  1246. X * of the color map that i index into. The ratio of some "minimum exponent
  1247. X * value" and the calculated value is used as a ratio of how high to index
  1248. X * into this reserved range. Usually these colors are dark red (see init_color).
  1249. X * If the exponent is negative, the same ratio (expo/minlyap) is used to index
  1250. X * into the remaining portion of the colormap (which is usually some light
  1251. X * shades of color or a rainbow wheel). The coloring scheme can actually make
  1252. X * a great deal of difference in the quality of the picture. Different colormaps
  1253. X * bring out different details of the dynamics while different indexing
  1254. X * algorithms also greatly effect what details are seen. Play around with this.
  1255. X */
  1256. XBoolean
  1257. Xsendpoint(expo)
  1258. Xdouble expo;
  1259. X{
  1260. X    static int i;
  1261. X    static double f, tmpexpo;
  1262. X    extern double exp();
  1263. X
  1264. X    point.x++;
  1265. X    tmpexpo = (negative) ? expo : -1.0 * expo;
  1266. X    if (tmpexpo >= 0) {
  1267. X        if (displayplanes >1) {
  1268. X            f = tmpexpo / minlyap;
  1269. X            i = (int)(f * (double)lowrange);
  1270. X            if (mincolindex)
  1271. X                i = (i % lowrange) + STARTCOLOR;
  1272. X        }
  1273. X        else
  1274. X            i = 0;
  1275. X    }
  1276. X    else {
  1277. X        if (displayplanes >1) {
  1278. X            f = -1.0 * tmpexpo / minlyap;
  1279. X            i = (int)(f * (double)numfreecols);
  1280. X            i = (i % numfreecols) + mincolindex;
  1281. X        }
  1282. X        else
  1283. X            i = 1;
  1284. X    }
  1285. X      BufferPoint(dpy, XtWindow(canvas), i, point.x, point.y);
  1286. X    if (save)
  1287. X        exponents[expind++] = expo;
  1288. X    if (point.x >= width) {
  1289. X        point.y++;
  1290. X        point.x = 0;
  1291. X        if (save) {
  1292. X            b += b_inc;
  1293. X            a = min_a;
  1294. X        }
  1295. X        if (point.y >= height)
  1296. X            return FALSE;
  1297. X        else
  1298. X            return TRUE;
  1299. X    }
  1300. X    return TRUE;
  1301. X}
  1302. X
  1303. Xvoid 
  1304. Xredisplay (w, data, call_data)
  1305. XWidget          w;
  1306. Xstruct image_data     *data;
  1307. XXmDrawingAreaCallbackStruct    *call_data;
  1308. X{
  1309. X    XExposeEvent  *event = (XExposeEvent *) call_data->event;
  1310. X    /*
  1311. X     * Extract the exposed area from the event and copy
  1312. X     * from the saved pixmap to the window.
  1313. X     */
  1314. X    XCopyArea(XtDisplay(w), pixmap, XtWindow(w), Data_GC[0], 
  1315. X           event->x, event->y, event->width, event->height, 
  1316. X           event->x, event->y);
  1317. X}
  1318. X
  1319. Xvoid
  1320. Xresize(w, data, call_data)
  1321. XWidget w;
  1322. Xstruct image_data_t *data;
  1323. XXmDrawingAreaCallbackStruct    *call_data;
  1324. X{
  1325. X    int n;
  1326. X    Arg wargs[32];
  1327. X
  1328. X    n = 0;
  1329. X    XtSetArg(wargs[n], XtNwidth, &width); ++n;
  1330. X    XtSetArg(wargs[n], XtNheight, &height); ++n;
  1331. X    XtGetValues(w, wargs, n);
  1332. X    if (XtIsRealized(w))
  1333. X        XClearArea(XtDisplay(w), XtWindow(w), 0, 0, 0, 0, TRUE);
  1334. X    if (pixmap)
  1335. X        XFreePixmap(XtDisplay(w), pixmap);
  1336. X    pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy), 
  1337. X            width, height, DefaultDepthOfScreen(screen));
  1338. X    Clear();
  1339. X    init_data();
  1340. X    Redraw();
  1341. X}
  1342. X
  1343. Xredraw(exparray, index, cont)
  1344. Xdouble *exparray;
  1345. Xint index, cont;
  1346. X{
  1347. X    static int i;
  1348. X    static int x_sav, y_sav;
  1349. X    extern Boolean sendpoint();
  1350. X
  1351. X    x_sav = point.x;
  1352. X    y_sav = point.y;
  1353. X
  1354. X    point.x = -1;
  1355. X    point.y = 0;
  1356. X
  1357. X    save=0;
  1358. X    for (i=0;i<index;i++)
  1359. X        sendpoint(exparray[i]);
  1360. X    save=1;
  1361. X    
  1362. X    if (cont) {
  1363. X        point.x = x_sav;
  1364. X        point.y = y_sav;
  1365. X    }
  1366. X    else {
  1367. X        a = point.x * a_inc + min_a;
  1368. X        b = point.y * b_inc + min_b;
  1369. X    }
  1370. X}
  1371. X
  1372. XRedraw() {
  1373. X
  1374. X    FlushBuffer();
  1375. X        point.x = -1;
  1376. X        point.y = 0;
  1377. X        a = min_a;
  1378. X        b = min_b;
  1379. X    expind = 0;
  1380. X    if(!work_proc_id)
  1381. X        work_proc_id = XtAddWorkProc(complyap, canvas);
  1382. X}
  1383. X
  1384. X/* Store color pics in PPM format and monochrome in PGM */
  1385. Xsave_to_file() {
  1386. X
  1387. X    FILE *outfile;
  1388. X    unsigned char c;
  1389. X    XImage *ximage;
  1390. X    static int i,j;
  1391. X    struct {
  1392. X        unsigned char red;
  1393. X        unsigned char green;
  1394. X        unsigned char blue;
  1395. X    } colormap[MAXCOLOR];
  1396. X
  1397. X    outfile = fopen(outname,"w");
  1398. X    if(!outfile) {
  1399. X        perror(outname);
  1400. X        exit(-1);
  1401. X    }
  1402. X
  1403. X    ximage=XGetImage(dpy, pixmap, 0, 0, width, height, AllPlanes, XYPixmap);
  1404. X
  1405. X    if (displayplanes > 1) {
  1406. X        for (i=0;i<MAXCOLOR;i++) {
  1407. X            colormap[i].red=(unsigned char)(Colors[i].red >> 8);
  1408. X            colormap[i].green=(unsigned char)(Colors[i].green >> 8);
  1409. X            colormap[i].blue =(unsigned char)(Colors[i].blue >> 8);
  1410. X        }
  1411. X        fprintf(outfile,"P%d %d %d\n",6,width,height);
  1412. X    }
  1413. X    else
  1414. X        fprintf(outfile,"P%d %d %d\n",5,width,height);
  1415. X    fprintf(outfile,"# settle=%d  dwell=%d start_x=%f\n",settle,dwell,
  1416. X                start_x);
  1417. X    fprintf(outfile,"# min_a=%f  a_rng=%f  max_a=%f\n",min_a,a_range,max_a);
  1418. X    fprintf(outfile,"# min_b=%f  b_rng=%f  max_b=%f\n",min_b,b_range,max_b);
  1419. X     if (force) {
  1420. X         fprintf(outfile,"# periodic forcing=");
  1421. X         for (i=0;i<maxindex;i++) {
  1422. X             fprintf(outfile,"%d",forcing[i]);
  1423. X         }
  1424. X         fprintf(outfile,"\n");
  1425. X     }
  1426. X     else
  1427. X         fprintf(outfile,"# periodic forcing=01\n");
  1428. X     if (Force) {
  1429. X         fprintf(outfile,"# function forcing=");
  1430. X         for (i=0;i<funcmaxindex;i++) {
  1431. X             fprintf(outfile,"%d",Forcing[i]);
  1432. X         }
  1433. X         fprintf(outfile,"\n");
  1434. X     }
  1435. X    fprintf(outfile,"%d\n",numcolors-1);
  1436. X
  1437. X    for (j=0;j<height;j++)
  1438. X        for (i=0;i<width;i++) {
  1439. X        c = (unsigned char)XGetPixel(ximage,i,j);
  1440. X        if (displayplanes > 1)
  1441. X            fwrite((char *)&colormap[c],sizeof colormap[0],1,outfile);
  1442. X        else
  1443. X            fwrite((char *)&c,sizeof c,1,outfile);
  1444. X        }
  1445. X    fclose(outfile);
  1446. X}
  1447. X
  1448. Xrecalc() {
  1449. X    static int i, index, x, y;
  1450. X    static double minexp, maxexp;
  1451. X    
  1452. X    minexp = maxexp = 0.0;
  1453. X    x = y = 0;
  1454. X    for (i=0;i<expind;i++) {
  1455. X        if (exponents[i] < minexp)
  1456. X            minexp = exponents[i];
  1457. X        if (exponents[i] > maxexp)
  1458. X            maxexp = exponents[i];
  1459. X    }
  1460. X    for (i=0;i<expind;i++) {
  1461. X        if (exponents[i] < 0.0)
  1462. X            index = exponents[i]*numfreecols/minexp+mincolindex;
  1463. X        else if (exponents[i] > maxexp)
  1464. X            index = exponents[i]*mincolindex/maxexp;
  1465. X        else
  1466. X            index = 0;
  1467. X          BufferPoint(dpy, XtWindow(canvas), index, x, y);
  1468. X        if (++x > width) {
  1469. X            if (++y > height)
  1470. X                break;
  1471. X            x = 0;
  1472. X        }
  1473. X    }
  1474. X    FlushBuffer();
  1475. X}
  1476. X
  1477. XClear() {
  1478. X         XClearArea(dpy, XtWindow(canvas), 0, 0, 0, 0, TRUE);
  1479. X    XCopyArea(dpy, XtWindow(canvas), pixmap, Data_GC[0], 
  1480. X                0, 0, width, height, 0, 0);
  1481. X    InitBuffer();
  1482. X}
  1483. X
  1484. Xvoid
  1485. Xshow_defaults() {
  1486. X
  1487. X    printf("Width=%d  Height=%d  numcolors=%d  settle=%d  dwell=%d\n",
  1488. X        width,height,numcolors,settle,dwell);
  1489. X    printf("min_a=%f  a_range=%f  max_a=%f\n", min_a,a_range,max_a);
  1490. X    printf("min_b=%f  b_range=%f  max_b=%f\n", min_b,b_range,max_b);
  1491. X    exit(0);
  1492. X}
  1493. X
  1494. Xvoid
  1495. XCreateXorGC(w)
  1496. XWidget w;
  1497. X{
  1498. X    XGCValues values;
  1499. X    Arg wargs[2];
  1500. X
  1501. X    XtSetArg(wargs[0], XtNforeground, &values.foreground);
  1502. X    XtSetArg(wargs[1], XtNbackground, &values.background);
  1503. X    XtGetValues,(w, wargs, 2);
  1504. X    values.foreground = values.foreground ^ values.background;
  1505. X    values.line_style = LineSolid;
  1506. X    values.function = GXxor;
  1507. X    RubberGC = XCreateGC(dpy, DefaultRootWindow(dpy),
  1508. X          GCForeground | GCBackground | GCFunction | GCLineStyle, &values);
  1509. X}
  1510. X
  1511. Xvoid StartRubberBand(w, data, event)
  1512. XWidget w;
  1513. Ximage_data_t *data;
  1514. XXEvent *event;
  1515. X{
  1516. X    XPoint corners[5];
  1517. X
  1518. X    nostart = 0;
  1519. X    data->rubber_band.last_x = data->rubber_band.start_x = event->xbutton.x;
  1520. X    data->rubber_band.last_y = data->rubber_band.start_y = event->xbutton.y;
  1521. X    SetupCorners(corners, data);
  1522. X    XDrawLines(XtDisplay(w), XtWindow(w), RubberGC,
  1523. X        corners, sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
  1524. X}
  1525. X
  1526. XSetupCorners(corners, data)
  1527. XXPoint *corners;
  1528. Ximage_data_t *data;
  1529. X{
  1530. X    corners[0].x = data->rubber_band.start_x;
  1531. X    corners[0].y = data->rubber_band.start_y;
  1532. X    corners[1].x = data->rubber_band.start_x;
  1533. X    corners[1].y = data->rubber_band.last_y;
  1534. X    corners[2].x = data->rubber_band.last_x;
  1535. X    corners[2].y = data->rubber_band.last_y;
  1536. X    corners[3].x = data->rubber_band.last_x;
  1537. X    corners[3].y = data->rubber_band.start_y;
  1538. X    corners[4] = corners[0];
  1539. X}
  1540. X
  1541. Xvoid TrackRubberBand(w, data, event)
  1542. XWidget w;
  1543. Ximage_data_t *data;
  1544. XXEvent *event;
  1545. X{
  1546. X    XPoint corners[5];
  1547. X    int xdiff, ydiff, diff;
  1548. X
  1549. X    if (nostart)
  1550. X        return;
  1551. X    SetupCorners(corners, data);
  1552. X    XDrawLines(XtDisplay(w), XtWindow(w), RubberGC,
  1553. X        corners, sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
  1554. X    ydiff = event->xbutton.y - data->rubber_band.start_y;
  1555. X    xdiff = event->xbutton.x - data->rubber_band.start_x;
  1556. X    data->rubber_band.last_x = data->rubber_band.start_x + xdiff;
  1557. X    data->rubber_band.last_y = data->rubber_band.start_y + ydiff;
  1558. X    if (data->rubber_band.last_y < data->rubber_band.start_y ||
  1559. X        data->rubber_band.last_x < data->rubber_band.start_x)
  1560. X    {
  1561. X        data->rubber_band.last_y = data->rubber_band.start_y;
  1562. X        data->rubber_band.last_x = data->rubber_band.start_x;
  1563. X    }
  1564. X    SetupCorners(corners, data);
  1565. X    XDrawLines(XtDisplay(w), XtWindow(w), RubberGC,
  1566. X        corners, sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
  1567. X}
  1568. X
  1569. Xvoid EndRubberBand(w, data, event)
  1570. XWidget w;
  1571. Ximage_data_t *data;
  1572. XXEvent *event;
  1573. X{
  1574. X    XPoint corners[5];
  1575. X    XPoint top, bot;
  1576. X    double delta, diff;
  1577. X
  1578. X    nostart = 1;
  1579. X    SetupCorners(corners, data);
  1580. X    XDrawLines(XtDisplay(w), XtWindow(w), RubberGC,
  1581. X        corners, sizeof(corners) / sizeof(corners[0]), CoordModeOrigin);
  1582. X    if (data->rubber_band.start_x >= data->rubber_band.last_x ||
  1583. X        data->rubber_band.start_y >= data->rubber_band.last_y)
  1584. X        return;
  1585. X    top.x = data->rubber_band.start_x;
  1586. X    bot.x = data->rubber_band.last_x;
  1587. X    top.y = data->rubber_band.start_y;
  1588. X    bot.y = data->rubber_band.last_y;
  1589. X    diff = data->q_max - data->q_min;
  1590. X    delta = (double)top.y / (double)height;
  1591. X    data->q_min += diff * delta;
  1592. X    delta = (double)(height - bot.y) / (double)height;
  1593. X    data->q_max -= diff * delta;
  1594. X    diff = data->p_max - data->p_min;
  1595. X    delta = (double)top.x / (double)width;
  1596. X    data->p_min += diff * delta;
  1597. X    delta = (double)(width - bot.x) / (double)width;
  1598. X    data->p_max -= diff * delta;
  1599. X    printf("q_min=%2.12f q_max=%2.12f\np_min=%2.12f p_max=%2.12f\n\n",
  1600. X        data->q_min, data->q_max, data->p_min, data->p_max);
  1601. X    fflush(stdout);
  1602. X    set_new_params(w, data);
  1603. X}
  1604. X
  1605. Xset_new_params(w, data)
  1606. XWidget w;
  1607. Ximage_data_t *data;
  1608. X{
  1609. X    double *tmpexponents;
  1610. X
  1611. X    a_range = data->p_max - data->p_min;
  1612. X    b_range = data->q_max - data->q_min;
  1613. X    o_min_a = min_a;
  1614. X    o_min_b = min_b;
  1615. X    min_a = data->p_min;
  1616. X    min_b = data->q_min;
  1617. X        a_inc = a_range / (double)width;
  1618. X        b_inc = b_range / (double)height;
  1619. X        point.x = -1;
  1620. X        point.y = 0;
  1621. X        a = min_a;
  1622. X        b = min_b;
  1623. X    o_max_a = max_a;
  1624. X    o_max_b = max_b;
  1625. X        max_a = data->p_max;
  1626. X        max_b = data->q_max;
  1627. X    if (first) {
  1628. X        i_expind = o_expind = expind;
  1629. X        memcpy(i_exponents, exponents, sizeof(double) * i_expind);
  1630. X        memcpy(o_exponents, exponents, sizeof(double) * i_expind);
  1631. X        first = 0;
  1632. X    }
  1633. X    o_expind = expind;
  1634. X    tmpexponents = o_exponents;
  1635. X    o_exponents = exponents;
  1636. X    exponents = tmpexponents;
  1637. X    expind = 0;
  1638. X    Clear();
  1639. X    if(!work_proc_id)
  1640. X        work_proc_id = XtAddWorkProc(complyap, canvas);
  1641. X}
  1642. X
  1643. Xgo_back() {
  1644. X    double *tmpexponents;
  1645. X    static int i;
  1646. X    
  1647. X    rubber_data.p_min = min_a = o_min_a;
  1648. X    rubber_data.q_min = min_b = o_min_b;
  1649. X    rubber_data.p_max = max_a = o_max_a;
  1650. X    rubber_data.q_max = max_b = o_max_b;
  1651. X    o_min_a = orig_min_a;
  1652. X    o_min_b = orig_min_b;
  1653. X    o_max_a = orig_max_a;
  1654. X    o_max_b = orig_max_b;
  1655. X    a_range = max_a - min_a;
  1656. X    b_range = max_b - min_b;
  1657. X        a_inc = a_range / (double)width;
  1658. X        b_inc = b_range / (double)height;
  1659. X        point.x = -1;
  1660. X        point.y = 0;
  1661. X        a = min_a;
  1662. X        b = min_b;
  1663. X    if (!first) {
  1664. X        expind = o_expind;
  1665. X        o_expind = i_expind;
  1666. X        tmpexponents = o_exponents;
  1667. X        o_exponents = exponents;
  1668. X        exponents = tmpexponents;
  1669. X        memcpy(o_exponents, i_exponents, sizeof(double) * i_expind);
  1670. X    }
  1671. X    Clear();
  1672. X    redraw(exponents, expind, 0);
  1673. X    if(!work_proc_id)
  1674. X        work_proc_id = XtAddWorkProc(complyap, canvas);
  1675. X}
  1676. X
  1677. Xgo_init() {
  1678. X    static double *tmpexponents;
  1679. X    static int i;
  1680. X    
  1681. X    rubber_data.p_min = min_a = orig_min_a;
  1682. X    rubber_data.q_min = min_b = orig_min_b;
  1683. X    rubber_data.p_max = max_a = orig_max_a;
  1684. X    rubber_data.q_max = max_b = orig_max_b;
  1685. X    o_min_a = orig_min_a;
  1686. X    o_min_b = orig_min_b;
  1687. X    o_max_a = orig_max_a;
  1688. X    o_max_b = orig_max_b;
  1689. X    a_range = max_a - min_a;
  1690. X    b_range = max_b - min_b;
  1691. X        a_inc = a_range / (double)width;
  1692. X        b_inc = b_range / (double)height;
  1693. X        point.x = -1;
  1694. X        point.y = 0;
  1695. X        a = min_a;
  1696. X        b = min_b;
  1697. X    o_expind = i_expind;
  1698. X    expind = i_expind;
  1699. X    memcpy(o_exponents, i_exponents, sizeof(double) * i_expind);
  1700. X    memcpy(exponents, i_exponents, sizeof(double) * i_expind);
  1701. X    Clear();
  1702. X    redraw(exponents, expind, 0);
  1703. X    first = 1;
  1704. X    if(!work_proc_id)
  1705. X        work_proc_id = XtAddWorkProc(complyap, canvas);
  1706. X}
  1707. X
  1708. Xvoid
  1709. XInitBuffer()
  1710. X{
  1711. X    int i;
  1712. X
  1713. X    for (i = 0 ; i < MAXCOLOR; ++i)
  1714. X        Points.npoints[i] = 0;
  1715. X}
  1716. X
  1717. Xvoid
  1718. XBufferPoint(display, window, color, x, y)
  1719. XDisplay *display;
  1720. XWindow window;
  1721. Xint color;
  1722. Xint x, y;
  1723. X{
  1724. X    if (Points.npoints[color] == MAXPOINTS)
  1725. X    {
  1726. X        if (XtIsRealized(canvas))
  1727. X            XDrawPoints(display, window, Data_GC[color],
  1728. X                Points.data[color], Points.npoints[color],
  1729. X                CoordModeOrigin);
  1730. X        XDrawPoints(display, pixmap, Data_GC[color],
  1731. X            Points.data[color], Points.npoints[color],
  1732. X            CoordModeOrigin);
  1733. X        Points.npoints[color] = 0;
  1734. X    }
  1735. X    Points.data[color][Points.npoints[color]].x = x;
  1736. X    Points.data[color][Points.npoints[color]].y = y;
  1737. X    ++Points.npoints[color];
  1738. X}
  1739. X
  1740. Xvoid
  1741. XFlushBuffer()
  1742. X{
  1743. X    int color;
  1744. X
  1745. X    for (color = 0; color < MAXCOLOR; ++color)
  1746. X        if (Points.npoints[color])
  1747. X        {
  1748. X            if (XtIsRealized(canvas))
  1749. X            XDrawPoints(dpy, XtWindow(canvas), Data_GC[color],
  1750. X                Points.data[color], Points.npoints[color],
  1751. X                CoordModeOrigin);
  1752. X            XDrawPoints(dpy, pixmap, Data_GC[color],
  1753. X                Points.data[color], Points.npoints[color],
  1754. X                CoordModeOrigin);
  1755. X            Points.npoints[color] = 0;
  1756. X        }
  1757. X}
  1758. X
  1759. Xprint_help() {
  1760. X
  1761. X    printf("During run-time, interactive control can be exerted via : \n");
  1762. X    printf("Mouse buttons allow rubber-banding of a zoom box\n");
  1763. X    printf("< halves the 'dwell', > doubles the 'dwell'\n");
  1764. X    printf("[ halves the 'settle', ] doubles the 'settle'\n");
  1765. X    printf("b or B toggles button display on/off\n");
  1766. X    printf("d or D flushes the drawing buffer\n");
  1767. X    printf("e or E recalculates color indices\n");
  1768. X    printf("f or F saves exponents to a file\n");
  1769. X    printf("h or H or ? displays this message\n");
  1770. X    printf("i decrements, I increments the stripe interval\n");
  1771. X    printf("KJmn increase/decrease minimum negative exponent\n");
  1772. X    printf("p or P reverses the colormap for negative/positive exponents\n");
  1773. X    printf("r redraws without recalculating\n");
  1774. X    printf("R redraws, recalculating with new dwell and settle values\n");
  1775. X    printf("s or S spins the colorwheel\n");
  1776. X    printf("u pops back up to the last zoom\n");
  1777. X    printf("U pops back up to the first picture\n");
  1778. X    printf("v or V displays the values of various settings\n");
  1779. X    printf("w decrements, W increments the color wheel index\n");
  1780. X    printf("x or X clears the window\n");
  1781. X    printf("q or Q exits\n");
  1782. X}
  1783. X
  1784. Xprint_values() {
  1785. X    static int i;
  1786. X
  1787. X    printf("\nminlyap=%f\n",minlyap);
  1788. X    printf("width=%d height=%d\n",width,height);
  1789. X    printf("settle=%d  dwell=%d start_x=%f\n",settle,dwell, start_x);
  1790. X    printf("min_a=%f  a_rng=%f  max_a=%f\n",min_a,a_range,max_a);
  1791. X    printf("min_b=%f  b_rng=%f  max_b=%f\n",min_b,b_range,max_b);
  1792. X    if (force) {
  1793. X    printf("periodic forcing=");
  1794. X     for (i=0;i<maxindex;i++)
  1795. X         printf("%d",forcing[i]);
  1796. X     printf("\n");
  1797. X    }
  1798. X    else
  1799. X     printf("periodic forcing=01\n");
  1800. X    if (Force) {
  1801. X     printf("function forcing=");
  1802. X     for (i=0;i<funcmaxindex;i++) {
  1803. X         printf("%d",Forcing[i]);
  1804. X     }
  1805. X     printf("\n");
  1806. X    }
  1807. X    printf("numcolors=%d\n",numcolors-1);
  1808. X}
  1809. END_OF_FILE
  1810. if test 41792 -ne `wc -c <'lyap.c'`; then
  1811.     echo shar: \"'lyap.c'\" unpacked with wrong size!
  1812. fi
  1813. # end of 'lyap.c'
  1814. fi
  1815. if test ! -d 'params' ; then
  1816.     echo shar: Creating directory \"'params'\"
  1817.     mkdir 'params'
  1818. fi
  1819. if test -f 'patchlevel.h' -a "${1}" != "-c" ; then 
  1820.   echo shar: Will not clobber existing file \"'patchlevel.h'\"
  1821. else
  1822. echo shar: Extracting \"'patchlevel.h'\" \(123 characters\)
  1823. sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
  1824. X
  1825. X#ifndef PATCHLEVEL_H
  1826. X#define PATCHLEVEL_H
  1827. X
  1828. X#define LYAP_PATCHLEVEL 2
  1829. X
  1830. X#define LYAP_VERSION "#(@) lyap 2.1 1/11/92"
  1831. X#endif
  1832. END_OF_FILE
  1833. if test 123 -ne `wc -c <'patchlevel.h'`; then
  1834.     echo shar: \"'patchlevel.h'\" unpacked with wrong size!
  1835. fi
  1836. # end of 'patchlevel.h'
  1837. fi
  1838. echo shar: End of archive 1 \(of 2\).
  1839. cp /dev/null ark1isdone
  1840. MISSING=""
  1841. for I in 1 2 ; do
  1842.     if test ! -f ark${I}isdone ; then
  1843.     MISSING="${MISSING} ${I}"
  1844.     fi
  1845. done
  1846. if test "${MISSING}" = "" ; then
  1847.     echo You have unpacked both archives.
  1848.     rm -f ark[1-9]isdone
  1849. else
  1850.     echo You still need to unpack the following archives:
  1851.     echo "        " ${MISSING}
  1852. fi
  1853. ##  End of shell archive.
  1854. exit 0
  1855. -- 
  1856. Molecular Simulations, Inc.             mail: dcmartin@msi.com
  1857. 796 N. Pastoria Avenue                  uucp: uunet!dcmartin
  1858. Sunnyvale, California 94086             at&t: 408/522-9236
  1859.