データの整理をしていたら22年前に書いたtoy programが出てきた。どうやらカオス・フラクタルの本を読んで組んでみたらしいが、もちろん、そのままではコンパイル出来ず、ビルドできるようにしてみた。今見ると、根本的に書き直した方が良いだろうと思うが、肝心の書籍が見当たらない。
でもって、面白いから Ubuntu Linux 22.04LTS ,openindiana, FreeBSD13.2R , NetBSD 9.3 で無事コンパイルできるようにしてみた。C++ コンパイラと Gnuplot が入っていれば基本的にOK。

複素数の平面転写によるバイオモルフ
$ make or gmake
で実行ファイル作成
Makefile の CC は g++ or c++ を指定
$ ./rec_complex
で、dat ファイル作成
gnuplotで
gnuplot> plot "dat"
で、バイオモルフ表示
Makefile
---
#コンパイラは、C++を使う
CC = g++
CFLAGS = -Wall -c -g -o
LDFRAGS = -g -lm
#実行プログラム
TARGET = rec_complex
#ソースファイル
SRC1 = main.C
SRC2 = complex.C
#object Files
OBJ1 = $(SRC1:.c=.o)
OBJ2 = $(SRC2:.c=.o)
#依存関係
LINK = ${OBJ1} ${OBJ2}
#拡張子ルール
.c.o:
@echo $< compile..
@${CC} $< ${CFLAGS} $@
@echo source compile done!
#object file のリンクと実行ファイルの作成
${TARGET}:${LINK}
@echo $^ Link..
@${CC} $^ -o $@ ${LDFRAGS}
@echo object link done!
#オブジェクトファイルのクリア
clean:
rm -f *.o
---
main.C
---
/* 複素数の反復写像図の生成 *
* バイオモルフを作るため Conversion TEST B を使用 *
* f(x) = z^2 * z + z^5 として超越関数成分を持つ *
* 多項式を使用 *
* 2001.4.28 2023.10.14 debianan */
#include <stdio.h>
#include "global.h"
int main(int argc,char **argv){
int value;
value = RecImage_Complex();
return(value);
}
---
global.h
---
/* global.h *
* 定数と関数参照のみ *
* *
* 2001.4.28 2023.10.14 debianan */
extern int RecImage_Complex(void);
#define TRUE 1
#define FAULSE 0
#define LIMIT_A 50 // 敷居値 A
#define LIMIT_B 5000 // 敷居値 B
---
complex.C
---
/* 複素数の反復写像図の生成 *
* バイオモルフを作るため Conversion TEST B を使用 *
* f(x) = z^2 * z + z^5 として超越関数成分を持つ *
* 多項式を使用 *
* rz,iz は、それぞれ複素数の実部と虚部 *
* i は反復カウンタ u_complex,z_complex = 複素数 *
* 2001.4.28 2023.10.14 debianan */
#include <complex>
#include <stdio.h>
#include <math.h>
#include "global.h"
int RecImage_Complex(void);
std::complex<double> gen_data(std::complex<double> seed);
int ConvergenceTest_A(std::complex<double> z);
int ConvergenceTest_B(std::complex<double> z);
void PrintDot(double x,double y,FILE *fp);
/* 反復写像の生成と出力 *
* 2001.4.28 2023.10.14 debianan *
* */
int RecImage_Complex(void){
int real_count, // 実数でのループカウンタ
imag_count, // 複素数でのループカウンタ
i, // 中間値のループカウンタ
value, // 戻り値
result;// 検査結果
double rrz,iiz; // 各々のピクセル単位
double rz,iz; // 複素数計算の中間値
std::complex<double> u_complex, // 複素数
z_complex; // 複素数
FILE *fp;
fp = fopen("dat","w");
for(rrz = -4;rrz <= 4;rrz += 0.08){
for(iiz = -4;iiz <= 4;iiz += 0.08){
z_complex = std::complex<double>(rrz,iiz);
u_complex = std::complex<double>(rrz,iiz);
for(i = 1;i <= 30;i++){
z_complex = gen_data(z_complex) + u_complex;
rz = std::real(z_complex);
iz = std::imag(z_complex);
if (sqrt(pow(rz,2) + pow(iz,2)) > 100){
break;
}
}
result = ConvergenceTest_A(z_complex);
if(result){
PrintDot(rrz,iiz,fp);
}
result = ConvergenceTest_B(z_complex);
if(result){
if(fabs(rz) < 100 || fabs(iz) < 100){
PrintDot(rrz,iiz,fp);
}
}
}
}
fclose(fp);
value = TRUE;
return(value);
}
/* 複素数データの生成 *
* f(x) = z^z + z^5 *
* 2001.4.28 2023.10.14 debianan */
std::complex<double> gen_data(std::complex<double> seed){
std::complex<double> value;
value = pow(seed,seed) + pow(seed,5);
return(value);
}
/* 有界テストA *
* √[Re(Zn)]^2+[Im(Zn)]^2 < t(敷居値) *
* 2001.4.28 2023.10.14 debianan */
int ConvergenceTest_A(std::complex<double> z){
double re,im,temp;
int value = 0;
re = std::real(z);
im = std::imag(z);
temp = sqrt(pow(re,2) + pow(im,2));
if(temp < LIMIT_A && abs(z) < LIMIT_A){
value = TRUE;
// printf("有界テストAを通ったよ! %f %f\n",re,im);
}else{
value = FAULSE;
// printf("有界テストA失敗だよ! %f %f\n",re,im);
}
return(value);
}
/* 有界テストB *
* 有界性の評価を高速にするため平方と開平 *
* の計算を省く *
* abs[Re(Zn)] < t /\ abs[Im(zn)] < t *
* 2001.4.28 2023.10.14 debianan */
int ConvergenceTest_B(std::complex<double> z){
int value = 0;
double re;
double im;
re = std::real(z);
im = std::imag(z);
if( fabs(re) < LIMIT_B && fabs(im) < LIMIT_B){
value = TRUE;
// printf("有界テストB通ったよ! %d %f %f\n",value,re,im);
}else{
value = FAULSE;
// printf("有界テストB失敗だよ! %d %f %f\n",value,re,im);
}
return(value);
}
/* データファイルの作成 *
* y 虚軸 x 実数軸 *
* 2001.4.28 2023.10.14 debianan */
void PrintDot(double x,double y,FILE *fp){
fprintf(fp,"%f %f\n",x,y);
return;
}
---
で、これが合っているかどうかも今となっては判らない。間違い等、指摘あったら下さいな^^;