-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathhenon.c
131 lines (110 loc) · 4.47 KB
/
henon.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* NAME
* henon - plot the phase space of the Henon system
* NOTES
* None.
* MISCELLANY
* The method for choosing the viewable region may seem
* counter-intuitive at first, but it has some nice properties. In
* particular, selecting the exact (x, y) coordinates for the
* upper-left corner and only selecting the lower right y coordinate
* forces both the x and y scales to be identical since all scales
* are uniquely determined by these values along with the plot
* width and height. If you then change the width or height of the
* plot, the relative scales will still match up. The options for
* making a box work similarly.
* BUGS
* No sanity checks are performed to make sure that any of the
* options make sense.
* AUTHOR
* Copyright (c) 1997, Gary William Flake.
*
* Permission granted for any use according to the standard GNU
* ``copyleft'' agreement provided that the author's comments are
* neither modified nor removed. No warranty is given or implied.
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "misc.h"
int width = 480, height = 480, skip = 100, points = 1000, invert = 0;
int box = 0, swap = 1, data = 0, delay = 1, mag = 1;
double A = 1.29, B = 0.3;
double ulx = -1.75, uly = 1.75, lly = -1.75, bulx, buly, blly;
char *term = NULL;
char help_string[] = "\
The phase space of the Henon system, which is described by the equation \
x(t+1) = A - x(t)^2 + B * x(t - 1), is plotted according to the \
specified parameters. \
";
OPTION options[] = {
{ "-width", OPT_INT, &width, "Width of the plot in pixels." },
{ "-height", OPT_INT, &height, "Height of the plot in pixels." },
{ "-skip", OPT_INT, &skip, "Number of initial points to skip." },
{ "-swap", OPT_SWITCH, &swap, "Swap the x and y axis?" },
{ "-points", OPT_INT, &points, "Number of points to plot." },
{ "-delay", OPT_INT, &delay, "Time steps to delay for." },
{ "-A", OPT_DOUBLE, &A, "Value of the A parameter." },
{ "-B", OPT_DOUBLE, &B, "Value of the B parameter." },
{ "-ulx", OPT_DOUBLE, &ulx, "Upper-left corner x-coordinate." },
{ "-uly", OPT_DOUBLE, &uly, "Upper-left corner y-coordinate." },
{ "-lly", OPT_DOUBLE, &lly, "Lower-left corner y-coordinate." },
{ "-box", OPT_INT, &box, "Line width for a box." },
{ "-bulx", OPT_DOUBLE, &bulx, "Box's upper-left x-coordinate." },
{ "-buly", OPT_DOUBLE, &buly, "Box's upper-left y-coordinate." },
{ "-blly", OPT_DOUBLE, &blly, "Box's lower-left y-coordinate." },
{ "-data", OPT_SWITCH, &data, "Don't plot, but print points." },
{ "-inv", OPT_SWITCH, &invert, "Invert all colors?" },
{ "-mag", OPT_INT, &mag, "Magnification factor." },
{ "-term", OPT_STRING, &term, "How to plot points." },
{ NULL, OPT_NULL, NULL, NULL }
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
int main(int argc, char **argv)
{
extern int plot_mag;
extern int plot_inverse;
int i, h;
double x, t, y, a, b, lrx, blrx;
double *hold;
get_options(argc, argv, options, help_string);
/* Calculate the area covered by a single pixel. */
lrx = ulx + ((uly - lly) / (height - 1)) * (width - 1);
if(!data) {
plot_mag = mag;
plot_inverse = invert;
plot_init(width, height, 2, term);
plot_set_range(ulx, lrx, lly, uly);
plot_set_all(0);
}
/* Use random initial conditions. */
x = random_range(-0.1, 0.1);
y = random_range(-0.1, 0.1);
/* Get space to hold delayed values. */
hold = xmalloc(sizeof(double) * delay); h = 0;
/* For each point to plot ... */
for(i = 0; i < points + skip + delay; i++) {
/* Hold old values. */
hold[h] = x; h++; h %= delay;
/* Calculate the next iterate. */
t = A - x*x + B * y; y = x; x = t;
/* Swap axes, if appropriate. */
a = swap ? hold[h] : x; b = swap ? x : hold[h];
/* Plot or display a point. */
if(i >= skip + delay) {
/* Only show points that are within the asked for region. */
if(a > ulx && a < lrx && b > lly && b < uly) {
if(data) printf("%f\t%f\n", a, b);
else plot_point(a, b, 1);
}
}
}
/* Show the box, if appropriate. */
plot_inverse = 0;
if(!data && box > 0) {
blrx = bulx + ((buly - blly) / (height - 1)) * (width - 1);
plot_box(bulx, buly, blrx, blly, box);
}
if(!data) plot_finish();
exit(0);
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */