User:Kghose/ikeda code
Appearance
I used the following code on a linux box to generate the Ikeda map attractor plots and animations.
Movie Script
[edit]Use the following script to create the animation and plots. It requires ImageMagick and mencoder from mplayer.
#Notes: #For hint about depth 8 see http://lists.mplayerhq.hu/pipermail/mencoder-users/2006-August/003817.html #For hint about adding text using ImageMagick see http://www-128.ibm.com/developerworks/library/l-graf/?ca=dnt-428 #For bash scripting see http://linuxgazette.net/issue18/bash.html #For mencoder options see http://www.mplayerhq.hu/DOCS/HTML/en/menc-feat-enc-images.html #run calculations ./ikeda #annotate and convert to depth 8 for img in `ls ikeda0*.png` do theend=${img#*0} caption="u = 0.${theend%.png}" echo $caption convert -font helvetica -fill black -pointsize 12 -draw "text 10,20 \"$caption\"" $img -depth 8 $img done #Now run mencoder on the depth 8 files mencoder mf://ikeda0*.png -mf w=400:h=400 -ovc lavc -lavcopts vcodec=xvid -of avi -o ikeda_map.avi
Makefile
[edit]Compile the c++ code with the following makefile:
CC=g++ CFLAGS= -c -Wall -O4 -DNO_FREETYPE LDFLAGS= -lfreetype -lm -lpng -lpngwriter -lz -DNO_FREETYPE -O4 EXECUTABLE = ikeda all: $(HEADERS) $(SOURCES) $(EXECUTABLE) ikeda: main.cpp $(CC) $(LDFLAGS) main.cpp pngwriter.o -oikeda clean: rm -f *.o ikeda
C++ Code
[edit]The c++ program requires pngwriter, libpng and zlib.
#include <stdlib.h> #include <iostream> #include <pngwriter.h> using namespace std; //N is the number of trajectory points //X,Y are arrays (pre assigned) of length N that contain the trajectory //bb_XXXX contains the bounding box of the plot struct IkedaTrajectory { int N; double *X, *Y, bb_xmin, bb_xmax, bb_ymin, bb_ymax ; }; //a convenience structure for the plot bounding box struct Scale { double bb_xmin, bb_xmax, bb_ymin, bb_ymax ; }; //convenience structure to carry the simulation params struct Params { double u; int N, // simulation steps N_start_points, //points in trajectory Nx, Ny, //size of image last_N_points; //for attractor plot, how many points from a trajectory do we plot }; struct ImageData { char filename[80]; int *X, *Y; }; //u is the Ikeda parameter //x,y is the initial point //it is the ikeda trajectory structure we return our answer in //remember to initialise it void ikeda_trajectory(double u, double x, double y, IkedaTrajectory &it) { it.X[0] = x ; it.Y[0] = y ; double t, x1 = x, y1 = y; for(int n = 1 ; n < it.N ; n++) { /* if( it.bb_xmin > x1 ) it.bb_xmin = x1 ; if( it.bb_xmax < x1 ) it.bb_xmax = x1 ; if( it.bb_ymin > y1 ) it.bb_ymin = y1 ; if( it.bb_ymax < y1 ) it.bb_ymax = y1 ; */ t = 0.4 - 6.0/(1.0 + x1*x1 + y1*y1); it.X[n] = 1.0 + u*(x1*cos(t) - y1*sin(t)) ; it.Y[n] = u*(x1*sin(t) + y1*cos(t)) ; x1 = it.X[n]; y1 = it.Y[n]; } } //scale the plot data to the canvas //Pre allocate X and Y void scale_plot(IkedaTrajectory &it, Scale &sc, int Nx, int Ny, int *X, int *Y) { double scaleX, translateX, scaleY, translateY ; scaleX = (double)Nx / (sc.bb_xmax - sc.bb_xmin) ; translateX = sc.bb_xmin ; scaleY = (double)Ny / (sc.bb_ymax - sc.bb_ymin) ; translateY = sc.bb_ymin ; for(int n = 0 ; n < it.N ; n++) { X[n] = (int)( (it.X[n] - translateX) * scaleX ); Y[n] = (int)( (it.Y[n] - translateY) * scaleY ); } } void save_plot(Params p, IkedaTrajectory &it, Scale &it_scale, ImageData &imagedata) { pngwriter png(p.Nx, p.Ny, 1.0, imagedata.filename); double r, b, x, y ; cout << "Computing u = " << p.u << flush ; for(int n = 0 ; n < p.N_start_points ; n++) { r = rand()/((double)RAND_MAX + 1); b = rand()/((double)RAND_MAX + 1); x = ( r - 0.5 ) * 20.0; y = ( r - 0.5 ) * 20.0; ikeda_trajectory(p.u, x, y, it) ; scale_plot(it, it_scale, p.Nx, p.Ny, imagedata.X, imagedata.Y) ; for(int m = it.N - p.last_N_points ; m < it.N ; m++) { png.filledcircle_blend( imagedata.X[m], imagedata.Y[m], 2.0, 0.6, r, 0.5, b); png.plot( imagedata.X[m], imagedata.Y[m], r, 0.5, b ); } } cout << " --- Saving " << flush ; //png.setcompressionlevel(1); //messing with this does not speed up the process png.close(); cout << " --- Done ! " << endl ; } int main(int argc, char *argv[]) { Params p ; ImageData imagedata ; p.N = 500 ; p.N_start_points = 20000 ; p.Nx = 400 ; p.Ny = 400 ; p.last_N_points = 20 ; IkedaTrajectory it ; Scale it_scale ; it_scale.bb_xmax = 5; it_scale.bb_ymax = 4.5; it_scale.bb_xmin = -1; it_scale.bb_ymin = -1.5; it.N = p.N ; it.X = new double [it.N]; it.Y = new double [it.N]; imagedata.X = new int [it.N]; imagedata.Y = new int [it.N]; for(double u = 0.0 ; u < 1.0 ; u += 0.001) { p.u = u; sprintf(imagedata.filename, "ikeda%04d.png", (int)(p.u * 1000 +.5)); save_plot(p, it, it_scale, imagedata); } delete[] it.X ; delete[] it.Y ; delete[] imagedata.X ; delete[] imagedata.Y ; return EXIT_SUCCESS; }