C 언어로 된 Logistic map의 1 차원 분기도 계산 프로그램

10219 단어 C

소개



이산 매핑의 1 차원 분기 다이어그램은 간단한 프로그램으로 구현할 수 있습니다.
지금까지는 필요에 따라 옛 프로그램을 참조했지만, 파일을 찾는 것이 번거롭기 때문에 Qiita에 남기기로 했다.
필요에 따라 적절하게 수정합니다.

현재, 범용성이 낮은 쓰기 방법이 되어 있어, 그다지 재미있지 않기 때문에, 이후의 수정으로 검토해 나간다.

Logistic map



Logistic map은 대표적인 비선형 역학 시스템이며 다음 방정식으로 정의됩니다.

$$
x_{n+1} = rx_n(1-x_n)
$$

역학계의 해궤도 $\{x_0, x_1, x_2,\ldots\}$ 는 어느 파라미터를 경계에 혼돈적으로 행동한다.

C 언어로 된 코드



여기에서는 C 언어로 구현했지만, 어느 언어로 쓰더라도 프로그램의 큰 틀은 변하지 않는다.
#include<stdio.h>                                                                                                                                         
#include<stdlib.h>
#include<math.h>

// Definition of Logistic map
double logistic_map(double x, double r){
  return (r*x*(1.0-x));
}

int main (void){
  double range[2] = {2.4, 4.0};       // Parameter domain
  double r = range[0], x0 = 0.5;      // Initial parameter and state
  int resolution = 2000, maps= 2000;  // Resolution of diagram, count of maps

  double step = (range[1]-range[0])/(double)resolution;

  FILE *fp;
  fp = fopen("out.bf1", "w");         // Output filename

  // Print initial value, parameter, and environment information                                                                                                
  char header[256];
  sprintf(header,
          "# Logistic map bifurcation diagram\n"
          "# x0 = %lf, range = [%lf %lf], resolution = %d, maps = %d\n",
          x0, range[0], range[1], resolution, maps);
  fprintf(fp, "%s", header);
  fprintf(stdout, "%s", header);

  // Main loop                                                                                                                                            
  for(int ri = 0; ri <= resolution; ri++){
    fprintf(fp, "%lf %lf\n", r, x0);

    for(int mi = 1; mi <= maps; mi++){
      x0 = logistic_map(x0, r);

      // if x0 got divergent                                                                                                                              
      if (isinf(x0)){
        fprintf(stderr, "Got divergent at ri = %d, mi = %d\n", ri, mi);
        fclose(fp);
        return -1;
      }
      // else print                                                                                                                                       
      fprintf(fp, "%lf %lf\n", r, x0);
      fprintf(stdout, "\t[%04d/%04d] [%04d/%04d] %+.5lf %+.5lf\r",
              ri, resolution, mi, maps, r, x0);
    }
    // iterate paramter                                                                                                                                   
    r += step;
    fprintf(fp, "\n");
  }

  fprintf(stdout, "\n");
  fclose(fp);
  return 0;
}


Gnuplot의 그림



위 프로그램 out.bf1에 의해 출력 된 결과는 다음과 같습니다.
plot의 이로하 다른 기사에 맡기기로 한다.

좋은 웹페이지 즐겨찾기