User:Kghose/ikeda code

I used the following code on a linux box to generate the Ikeda map attractor plots and animations.

Movie Script
Use the following script to create the animation and plots. It requires ImageMagick and mencoder from mplayer.


 * 1) Notes:
 * 2) For hint about depth 8 see http://lists.mplayerhq.hu/pipermail/mencoder-users/2006-August/003817.html
 * 3) For hint about adding text using ImageMagick see http://www-128.ibm.com/developerworks/library/l-graf/?ca=dnt-428
 * 4) For bash scripting see http://linuxgazette.net/issue18/bash.html
 * 5) For mencoder options see http://www.mplayerhq.hu/DOCS/HTML/en/menc-feat-enc-images.html

./ikeda
 * 1) run calculations

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
 * 1) annotate and convert to depth 8

mencoder mf://ikeda0*.png -mf w=400:h=400 -ovc lavc -lavcopts vcodec=xvid -of avi -o ikeda_map.avi
 * 1) Now run mencoder on the depth 8 files

Makefile
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
The c++ program requires pngwriter, libpng and zlib.


 * 1) include 
 * 2) include
 * 3) include 

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; }