Need help with equation and plotting
in
Programming Questions
•
3 years ago
Hey,
I'm learning about strange attractors and the book I'm reading has QBasic examples of graphing 2D functions. I'm trying to convert one of the examples to Processing, but I keep stumbling over myself. Maybe I am missing boundary checks?
Any help would be greatly appreciated!
Thanks.
[EDIT] Modified some of the code, but still doesnt work.
I'm learning about strange attractors and the book I'm reading has QBasic examples of graphing 2D functions. I'm trying to convert one of the examples to Processing, but I keep stumbling over myself. Maybe I am missing boundary checks?
Any help would be greatly appreciated!
Thanks.
- ///
int prev = 5;
int nmax = 11000;
int omax = 2;
int d = 2;
float xmin;
float xmax;
float ymin;
float ymax;
float xp, yp;
float x, y;
float x2,y2;
int n;
int nl;
float lsum;
float l;
float xh,xl,yh,yl;
float xe,ye;
float []coeffs;
PFont font;
void setup() {
size(500,500);
background(255);
font = loadFont("MonotypeSorts-9.vlw");
textFont(font, 9);
setparm();
}
void draw() {
fill(255);
stroke(255);
rect(width/2, 0, width, 20);
fill(0);
text("L: "+l, width-100, 15);
iterate();
display();
test();
}
void setparm() {
x = 0.5;
y = 0.5;
xe = x + .000001;
ye = y;
coeffs = getCoeff();
lsum = 0;
n = 0;
l =0;
nl = 0;
xmin = 1000000;
xmax = -xmin;
ymin = xmin;
ymax = xmax;
}
float[] getCoeff() {
int o = 2 + int((omax - 1) * random(0,1));
float m = 1;
String code = "";
code += char(59 + 4 * d + o);
for(int i = 1; i <= d;i++){
m = m * (o+i);
}
for(int i = 1; i <= m; i++) {
code += char(65 + int(25 * random(0,1)));
}
println("Reset!");
float []a = new float[(int)m];
for(int i = 0; i < m; i++) {
a[i] = int(code.charAt(i))-77;
a[i] = a[i]/10;
print(a[i]+" ");
}
println();
fill(255);
stroke(255);
rect(0, 0, width/2, 20);
fill(0);
text(code, 5, 16);
return a;
}
void iterate() {
x2 = coeffs[0] + x * (coeffs[1] + coeffs[2] * x + coeffs[3] * y) + y * (coeffs[4] + coeffs[5] * y);
y2 = coeffs[6] + x * (coeffs[7] + coeffs[8] * x + coeffs[9] * y) + y * (coeffs[10] + coeffs[11] * y);
println(++n+" x:"+x+" x2:"+x2+" y:"+y+" y2:"+y2);
}
/*
1700 REM Iterate equations
1720 XNEW = A(1) + X * (A(2) + A(3) * X + A(4) * Y)
1730 XNEW = XNEW + Y * (A(5) + A(6) * Y)
1830 YNEW = A(7) + X * (A(8) + A(9) * X + A(10) * Y)
1930 YNEW = YNEW + Y * (A(11) + A(12) * Y)
2020 N = N + 1
2030 RETURN*/
void display() {
if( !(n < 100) && !(n > 1000) ) {
if( x < xmin ) xmin = x;
if( x > xmax ) xmax = x;
if( y < ymin ) ymin = y;
if( y > ymax ) ymax = y;
}
if( n == 1000 )
resizescreen();
if( n < 1000 || x <= xl || x >= xh || y <= yl || y >= yh ){
}
else {
fill(0);
point(width * (x-xl)/(xh-xl),height*(yh-y)/(yh-yl));
println("x="+(width * (x-xl)/(xh-xl))+" y="+(height*(yh-y)/(yh-yl)));
}
}
/*
2100 REM Display results
2110 IF N < 100 OR N > 1000 THEN GOTO 2200
2120 IF X < XMIN THEN XMIN = X
2130 IF X > XMAX THEN XMAX = X
2140 IF Y < YMIN THEN YMIN = Y
2150 IF Y > YMAX THEN YMAX = Y
2200 IF N = 1000 THEN GOSUB 3100 'Resize the screen
2210 XS(P%) = X
2220 P% = (P% + 1) MOD 500
2230 I% = (P% + 500 - PREV%) MOD 500
2240 IF D% = 1 THEN XP = XS(I%): YP = XNEW ELSE XP = X: YP = Y
2250 IF N < 1000 OR XP <= XL OR XP >= XH OR YP <= YL OR YP >= YH THEN GOTO 2320
2300 PSET (WW * (XP - XL) / (XH - XL), WH * (YH - YP) / (YH - YL))
2310 IF SND% = 1 THEN GOSUB 3500 'Produce sound
2320 RETURN
*/
void resizescreen() {
if( xmax - xmin < .000001 ) {
xmin -= .0000005;
xmax += .0000005;
}
if( ymax - ymin < .000001 ) {
ymin -= .0000005;
ymax += .0000005;
}
float mx = .1 * (xmax - xmin);
float my = .1 * (ymax - ymin);
xl = xmin - mx;
xh = xmax + mx;
yl = ymin - my;
yh = ymax + my;
}
/*3100 REM Resize the screen
3110 IF D% = 1 THEN YMIN = XMIN: YMAX = XMAX
3120 IF XMAX - XMIN < .000001 THEN XMIN = XMIN - .0000005: XMAX = XMAX + .0000005
3130 IF YMAX - YMIN < .000001 THEN YMIN = YMIN - .0000005: YMAX = YMAX + .0000005
3160 MX = .1 * (XMAX - XMIN): MY = .1 * (YMAX - YMIN)
3170 XL = XMIN - MX: XH = XMAX + MX: YL = YMIN - MY: YH = YMAX + MY
3180 WW = WINDOW(2): WH = WINDOW(3): BUTTON CLOSE 0: CLS
3460 RETURN*/
void test() {
if( abs(x2) + abs(y2) > 1000000 ) {
setparm();
}
else {
calc();
if( (n >= nmax) ) {
println("!st");
setparm();
}
if(n > 100 && l < .005) {
println("2nd");
setparm();
}
if((abs(x2-x) + abs(y2-y)) < .000001) {
println("3rd");
setparm();
}
x = x2;
y = y2;
}
}
/*
2400 REM Test results
2410 IF ABS(XNEW) + ABS(YNEW) > 1000000! THEN T% = 2 'Unbounded
2430 GOSUB 2900 'Calculate Lyapunov exponent
2460 IF N >= NMAX THEN T% = 2 'Strange attractor found
2470 IF ABS(XNEW - X) + ABS(YNEW - Y) < .000001 THEN T% = 2
2480 IF N > 100 AND L < .005 THEN T% = 2 'Limit cycle
2490 Q$ = INKEY$: IF LEN(Q$) THEN GOSUB 3600 'Respond to user command
2500 IF MENU(0) = 2 AND MENU(1) = 1 THEN Q$ = "S": GOSUB 3600
2510 X = XNEW 'Update value of X
2520 Y = YNEW
2550 RETURN
*/
void calc() {
float xsave = x2;
float ysave = y2;
x = xe;
y = ye;
n--;
iterate();
float dlx = x2 - xsave;
float dly = y2 - ysave;
float dl2 = dlx*dlx + dly * dly;
if( (int)dl2 > 0 ) {
println("tab");
float df = 1000000000000L * dl2;
float rs = 1 / sqrt(df);
xe = xsave + rs * (x2 - xsave);
ye = ysave + rs * (y2 - ysave);
x2 = xsave;
y2 = ysave;
if( df > 0 ) {
lsum = lsum + log(df);
nl++;
}
l = .721347 * lsum / nl;
}
}/*
2900 REM Calculate Lyapunov exponent
2910 XSAVE = XNEW: YSAVE = YNEW: X = XE: Y = YE: N = N - 1
2930 GOSUB 1700 'Reiterate equations
2940 DLX = XNEW - XSAVE: DLY = YNEW - YSAVE
2960 DL2 = DLX * DLX + DLY * DLY
2970 IF CSNG(DL2) <= 0 THEN GOTO 3070 'Don't divide by zero
2980 DF = 1000000000000# * DL2
2990 RS = 1 / SQR(DF)
3000 XE = XSAVE + RS * (XNEW - XSAVE): YE = YSAVE + RS * (YNEW - YSAVE)
3020 XNEW = XSAVE: YNEW = YSAVE
3030 IF DF > 0 THEN LSUM = LSUM + LOG(DF): NL = NL + 1
3040 L = .721347 * LSUM / NL
3070 RETURN*/
[EDIT] Modified some of the code, but still doesnt work.
1
