⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mandel.cpp

📁 复数运算库
💻 CPP
字号:
#define WANT_MATH#define WANT_STREAM#include "include.h"#include "array1.h"#include "cx.h"//  Consider the sequence of complex numbers//     z[0] =0; z[n+1] = z[n] ** 2 + c//  where ** denotes exponentiation (i.e. square in this case).////  The Mandelbrot set, M, is the set of values of c for which this sequence//  remains bounded as n tends to infinity.////  This program calculates the set, Z, of values of c for which z[n] = 0//  for some n > 0.////  Of course, Z is a subset of M. It follows from Montel's theorem in//  complex analysis that the boundary of M is contained in the closure//  of Z.////  So if we calculate the points of Z we get an outline of M.////  We can search for the values of Z using contour integration. Think of//  z[n] as function of c and contour integrate d[n] = z[n]' / z[n]//  around a square. Here ' denotes derivative wrt c.//  If there are any zeros of z[n] in the square then the imaginary part of//  integral will have a positive value depending on the number of zeros;//  otherwise it will be zero.////  The program uses gaussian integration to evaluate the integral numerically.//  It uses an iterative scheme to work through values of n and a recursive//  scheme to search for the zeros.////  Start with a square covering the area we are interested in.//  If the contour integration program finds it contains a zero divide//  the square into 4 squares by dividing the horizontal and vertical//  sides in half. Search each of these squares for zeros. Continue the//  process until the zeros have been located with the desired accuracy.#ifdef use_namespaceusing namespace RBD_COMMON;             // needed for VC++using namespace RBD_COMPLEX;#endifclass SearchClass{   int maxit;                    // maximum number of iterations   Real limit;                   // minimum for deciding a point is a "zero"   const array1<Real>& gauss;    // integration points   const array1<Real>& weight;   // integration weights   int gs;                       // number of integration points   int g4;                       // gs * 4   array1<CX> C;                 // for integrating around square   array1<CX> W;   array1<CX> Z;   array1<CX> D;   array1<bool> skip;public:   SearchClass(int mi, Real li, const array1<Real>& g, const array1<Real>& w);   void IntegrationPoints(CX centre, Real delta);   int IntegrateSquare(Real delta);   int Search(CX centre, Real delta, int depth);};void GaussianIntegration(array1<Real>& G, array1<Real>& W);int main(){   int n = 16;                  // order of integration (16, 8, 4 or 2)   CX centre(0,0);              // centre of square to be examined   Real delta = 2.0;            // distance of side of square from centre   int depth = 9;               // number of binary divisions of side of square   int maxit = 1000;            // maximum number of iterations//   int n = 16;//   CX centre(-0.74916,0.06648);//   Real delta = 0.00004;//   int depth = 8;//   int maxit = 10000;   array1<Real> G(n);           // these will contain the gaussian integration   array1<Real> W(n);           // parameters - n will set the number of values.   GaussianIntegration(G, W);   // get Gaussian integration parameters and load                                // them into G and W.   SearchClass sc(maxit, 0.2, G, W); // a class that organises the search   int s = sc.Search(centre, delta, depth); // search our initial square   cout << "Number of points = " << s << endl;   return 0;}SearchClass::SearchClass(int mi, Real li, const array1<Real>& g,   const array1<Real>& w)      : maxit(mi), limit(li), gauss(g), weight(w){   gs = gauss.size(); g4 = 4 * gs;   C.resize(g4); W.resize(g4); Z.resize(g4); D.resize(g4); skip.resize(g4);}// Setup the integration points and their weights for the square defined// by centre and deltavoid SearchClass::IntegrationPoints(CX centre, Real delta){   int i; int j = 0;   Imag i_delta = _I_ * delta; CX mid = centre + delta;   for (i = 0; i < gs; i++)      { W(j) = weight(i) * i_delta;   C(j) = mid + gauss(i) * i_delta; ++j; }   mid = centre + i_delta;   for (i = 0; i < gs; i++)      { W(j) = - weight(i) * delta;   C(j) = mid - gauss(i) * delta;   ++j; }   mid = centre - delta;   for (i = 0; i < gs; i++)      { W(j) = - weight(i) * i_delta; C(j) = mid - gauss(i) * i_delta; ++j; }   mid = centre - i_delta;   for (i = 0; i < gs; i++)      { W(j) = weight(i) * delta;     C(j) = mid + gauss(i) * delta;   ++j; }}// do the integration around the square for each nint SearchClass::IntegrateSquare(Real delta){   Z = CX(0.0); D = CX(0.0); skip = false;    // set all elements of an array   for (int n = 1; n <= maxit; n++)   {      Real sum = 0.0; bool converge = true;      CX* z = Z.data(); CX* d = D.data(); CX* c = C.data(); CX* w = W.data();      bool* s = skip.data();      for (int j = 0; j < g4; j++)      {         if (!*s)         {            CX z_next = square(*z) + *c;  *z = z_next;            if (z_next == 0) return n;  // we have hit an exact zero            *d *= 2.0;            CX e = (1.0 - *d * *c) / z_next;            *d += e;                    // the new value of d            sum += imag(*w * e);        // integration of imaginary part                                        // we need do only e since we have                                        // already shown that the integral of                                        // the previous d is zero            Real nz = norm1(z_next);            if (nz < 4 || delta * ( 1.0 + norm1(*d) ) > 0.0001 * nz)               converge = false;            else *s = true;             // this term can't contribute                                        // significantly in the future         }         ++z; ++d; ++c; ++w; ++s;      }      if (sum / pi_times_2 > limit) return n;  // have found a zero      if (converge) return 0;           // no term can contribute in the future   }   return -1;                           // exit on iteration limit                                        // usually means that our square                                        // is completely in the interior}// the recursive searchint SearchClass::Search(CX centre, Real delta, int depth){   IntegrationPoints(centre, delta); int n = IntegrateSquare(delta);   if (n > 0)   {      if (depth > 0)      {         Real d2 = delta / 2.0; Imag d2i = d2 * _I_; int k = 0;         k += Search(centre-d2-d2i, d2, depth-1);         k += Search(centre-d2+d2i, d2, depth-1);         k += Search(centre+d2-d2i, d2, depth-1);         k += Search(centre+d2+d2i, d2, depth-1);         return k;      }      else      {         // print coordinates of centre of square and iteration number         cout << setw(20) << setprecision(15) << centre.real() << " "              << setw(20) << setprecision(15) << centre.imag() << " "              << setw(10) << n << endl;         return 1;      }   }   else return 0;}// load the integration parameters into G and Wvoid GaussianIntegration(array1<Real>& G, array1<Real>& W){   switch (G.size())   {   case 16:      G(8)  = 0.095012509837637;  G(7) = -G(8);      G(9)  = 0.281603550779259;  G(6) = -G(9);      G(10) = 0.458016777657227;  G(5) = -G(10);      G(11) = 0.617876244402644;  G(4) = -G(11);      G(12) = 0.755404408355003;  G(3) = -G(12);      G(13) = 0.865631202387832;  G(2) = -G(13);      G(14) = 0.944575023073233;  G(1) = -G(14);      G(15) = 0.989400934991650;  G(0) = -G(15);      W(8)  = 0.189450610455068;  W(7) = W(8);      W(9)  = 0.182603415044924;  W(6) = W(9);      W(10) = 0.169156519395003;  W(5) = W(10);      W(11) = 0.149595988816577;  W(4) = W(11);      W(12) = 0.124628971255534;  W(3) = W(12);      W(13) = 0.095158511682493;  W(2) = W(13);      W(14) = 0.062253523938648;  W(1) = W(14);      W(15) = 0.027152459411754;  W(0) = W(15);      break;   case 8:      G(4) = 0.183434642495650;  G(3) = -G(4);      G(5) = 0.525532409916329;  G(2) = -G(5);      G(6) = 0.796666477413627;  G(1) = -G(6);      G(7) = 0.960289856497536;  G(0) = -G(7);      W(4) = 0.362683783378362;  W(3) = W(4);      W(5) = 0.313706645877887;  W(2) = W(5);      W(6) = 0.222381034453374;  W(1) = W(6);      W(7) = 0.101228536290376;  W(0) = W(7);      break;   case 4:      G(2) = 0.339981043584856;  G(1) = -G(2);      G(3) = 0.861136311594053;  G(0) = -G(3);      W(2) = 0.652145154862546;  W(1) = W(2);      W(3) = 0.347854845137454;  W(0) = W(3);      break;   case 2:      G(1) = 0.577350269189626;  G(0) = -G(1);      W(1) = 1.0; W(0) = 1.0;      break;   default: cout << "invalid parameter" << endl; exit(1);   }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -