跳轉到內容

分形/數學/導數

來自華夏公益教科書,開放世界開放書籍


  • 變數 z
  • 常數引數 c
  • 函式 f
  • 導數 d
  • 迭代次數 p
  • wrt = 關於

符號型別[6]

  • 萊布尼茨符號
  • 尤拉符號
  • 牛頓符號(點符號)
  • 拉格朗日符號(撇號符號)


非正式描述

[編輯 | 編輯原始碼]
The derivative gives you what is called the gradient. For 2D, consider the terrain as a contour map. The gradient tells you the rate of change in x and y directions. The slope is the magnitude of the gradient, and the contours are closer together for higher slope. For 3D the gradient is the rate of change in x, y and z, and the slope is still the magnitude of the gradient. Technically, slope is only 1D, and the gradient also tells you the direction of the slope. When we talk about derivative giving you the slope we are being casual. ( xenodreambuie )[7]

迭代函式的導數

[編輯 | 編輯原始碼]
  "the derivative basically as it's calculated for anlytical DE using the implementation of the chain rule for the derivative of f(g(x)) where f(x) is say g(x)^p+c and the value of g(x) is current z. So f'(g(x)) is p*z^(p-1)  and g'(x) is the derivative from the previous iteration,  so on each iteration the new derivative is:  dz = dz*p*z^(p-1)  and new z = z^p+c as normal" FractalDave[8]


對於Julia 集

// initial values:
c is const 
z =  z0 ( z is a variable, read initial value from the pixel)
dz = 1


// Recurrence steps: 
dz = f'(z)*dz   // calculating dz and multiply the previous d
z = f(z)       // forward iteration

對於Mandelbrot 集

// initial values:
z = critical point ( critical pointis  0 for multibrot sets, z is variable)
c = ( c is a variable, read initial value from the pixel)
dc = 0


// Recurrence steps: 
dc = f'(z)*dc  + 1 // calculating dc and multiply the previous dc
z = f(z)       // forward iteration



可以使用 Maxima CAS 計算

display2d:false;
f:1/(z^3+d*z);
dz : diff(f,z,1); // first derivative of f wrt variable z 
dc :  diff(f,c,1); // first derivative of f wrt parameter c



有理函式

[編輯 | 編輯原始碼]
 
 

關於 z


// function 
f(z)= 1/(z^3 + c*z )

// first derivativwe wrt z
d = f'(z) = -(3z^2 +c)/(z^3 + cz)^2

// iteration:
z_(n+1) = f(z_n)


// initial values:
z = z
d = 1

// Recurrence steps:
d = - d*(3z^2 +c)/(z^3 + cz)^2
z = 1/(z^3 + c*z) 


Julia 集 f(z)=1 over az5+z3+bz
display2d:false;
f: 1/(a*z^5+ z^3 + b*z);
dz: diff(f,z,1);



純文字

  dz = -(5*a*z^4+3*z^2+b)/(a*z^5+z^3+b*z)^2


示例

  • 1/((0.15*I+0.15)*z^5+(3*I-3)*z + z^3)


Buschmann 的 5 次

[編輯 | 編輯原始碼]
Julia 集透過距離估計繪製,迭代形式為 ,以黑白顯示
f(z):=z^5/(4*z+2)-z^2+c+1

(%i4) diff(f(z), z,1);

(%o4) (5*z^4)/(4*z+2)-(4*z^5)/(4*z+2)^2-2*z




多項式

[編輯 | 編輯原始碼]
關於 z 的一階導數
次數 函式 f(z) 關於 z 的導數
2
3
4
d

C 程式碼用於製作多重分形集的外部 DEM/M 影像:Mandelbrot 集,其中 q 是單臨界單項式的階數

#include <complex.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <omp.h> //OpenM

/*
fork of 
mandelbrot-book how to write a book about the Mandelbrot set by Claude Heiland-Alle
https://code.mathr.co.uk/mandelbrot-book/blob/HEAD:/book/

https://stackoverflow.com/questions/77135883/why-do-my-functions-not-work-in-parallel


gcc s.c -lm -Wall -fopenmp

./a.out >ed.ppm   // P6 = binary Portable PixMap see en wikipedia: Netpbm#File_formats


*/

const double pi = 3.141592653589793;

/*
 int q = 5 ;
complex double f(complex double z, int q){ return cpow(z,q) + c;}
complex double d(complex double z, int q) {return q*cpow(z, q-1); }

*/
complex double f(complex double z, complex double c){ return z*z*z*z*z + c;}
complex double d(complex double z) {return 5*z*z*z*z; }




double cnorm(double _Complex z) // https://stackoverflow.com/questions/6363247/what-is-a-complex-data-type-and-an-imaginary-data-type-in-c
{
  return creal(z) * creal(z) + cimag(z) * cimag(z);
}

void hsv2rgb(double h, double s, double v, int *red, int *grn, int *blu) {
  double i, f, p, q, t, r, g, b;
  int ii;
  if (s == 0.0) { r = g = b = v; } else {
    h = 6 * (h - floor(h));
    ii = i = floor(h);
    f = h - i;
    p = v * (1 - s);
    q = v * (1 - (s * f));
    t = v * (1 - (s * (1 - f)));
    switch(ii) {
      case 0: r = v; g = t; b = p; break;
      case 1: r = q; g = v; b = p; break;
      case 2: r = p; g = v; b = t; break;
      case 3: r = p; g = q; b = v; break;
      case 4: r = t; g = p; b = v; break;
      default:r = v; g = p; b = q; break;
    }
  }
  *red = fmin(fmax(255 * r + 0.5, 0), 255);
  *grn = fmin(fmax(255 * g + 0.5, 0), 255);
  *blu = fmin(fmax(255 * b + 0.5, 0), 255);
}

int main()
{
  const int aa = 4;
  const int w = 800 * aa;
  const int h = 800 * aa;
  const int n = 1024;
  const double r = 2;
  const double px = r / (h/2);
  const double r2 = 25 * 25;
  unsigned char *img = malloc(3 * w * h);

  #pragma omp parallel for schedule(dynamic)
  for (int j = 0; j < h; ++j)
  {
    double _Complex c;
    double _Complex z;
    double _Complex dc;
    double y = (h/2 - (j + 0.5)) / (h/2) * r;
    for (int i = 0; i < w; ++i)
    {
      double x =  (i + 0.5 - w/2) / (h/2) * r; // for q=2 add -0.5
      c = x + I * y;
      //double _Complex 
      dc = 0; // first derivative of zn with respect to c
      //double _Complex z = 0;
      z = 0;
      int k;
      for (k = 0; k < n; ++k)
      { 
      // 
        dc = d(z)*dc +1;
        z = f(z,c);
        
        if (cnorm(z) > r2)
          break;
      }
      
      // color
      double hue = 0, sat = 0, val = 1; // interior color = white
      
      if (k < n) 
      { // exterior and boundary color
        double _Complex de = 2 * z * log(cabs(z)) / dc;
        hue = fmod(1 + carg(de) / (2 * pi), 1); // ? slope of de
        sat = 0.25;
        val = tanh(cabs(de) / px / aa);
      }
      
      // hsv to rgb conversion
      int red, grn, blu;
      hsv2rgb(hue, sat, val, &red, &grn, &blu);
      // save rgb color to array
      img[3*(j * w + i)+0] = red;
      img[3*(j * w + i)+1] = grn;
      img[3*(j * w + i)+2] = blu;
    }
  }
  
  //
  printf("P6\n%d %d\n255\n", w, h);
  fwrite(img, 3 * w * h, 1, stdout);
  free(img);
  
  
  return 0;
}

C 程式碼用於製作 的外部 DEM/J 影像,其中 q 是單臨界單項式的階數

#include <complex.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <omp.h> //OpenM

/*
fork of 
mandelbrot-book how to write a book about the Mandelbrot set by Claude Heiland-Alle
https://code.mathr.co.uk/mandelbrot-book/blob/HEAD:/book/

https://stackoverflow.com/questions/77135883/why-do-my-functions-not-work-in-parallel


gcc j.c -lm -Wall -fopenmp

./a.out >ed.ppm   // P6 = binary Portable PixMap see en.wikipedia:  Netpbm#File_formats


*/



complex double examples [6] = {0, 0, I, -0.0649150006787816892861875745218343125883 +0.76821968591243610206311097043854440463 *I, -0.239026451915233+0.415516996006582*I, 0};

const double pi = 3.141592653589793;
int q = 4 ; // degree of multibrot set

/*
 
complex double f(complex double z, int q){ return cpow(z,q) + c;}
complex double d(complex double z, int q) {return q*cpow(z, q-1); }

*/
complex double f(complex double z, complex double c){ return z*z*z*z + c;} // multibrot z^q + c
complex double d(complex double z) {return 4*z*z*z; } // q*z^{q-1}




double cnorm(double _Complex z) // https://stackoverflow.com/questions/6363247/what-is-a-complex-data-type-and-an-imaginary-data-type-in-c
{
  return creal(z) * creal(z) + cimag(z) * cimag(z);
}

void hsv2rgb(double h, double s, double v, int *red, int *grn, int *blu) {
  double i, f, p, q, t, r, g, b;
  int ii;
  if (s == 0.0) { r = g = b = v; } else {
    h = 6 * (h - floor(h));
    ii = i = floor(h);
    f = h - i;
    p = v * (1 - s);
    q = v * (1 - (s * f));
    t = v * (1 - (s * (1 - f)));
    switch(ii) {
      case 0: r = v; g = t; b = p; break;
      case 1: r = q; g = v; b = p; break;
      case 2: r = p; g = v; b = t; break;
      case 3: r = p; g = q; b = v; break;
      case 4: r = t; g = p; b = v; break;
      default:r = v; g = p; b = q; break;
    }
  }
  *red = fmin(fmax(255 * r + 0.5, 0), 255);
  *grn = fmin(fmax(255 * g + 0.5, 0), 255);
  *blu = fmin(fmax(255 * b + 0.5, 0), 255);
}

int main()
{
  const int aa = 4;
  const int w = 800 * aa;
  const int h = 800 * aa;
  const int n = 1024;
  const double r = 2;
  const double px = r / (h/2);
  const double r2 = 25 * 25;
  unsigned char *img = malloc(3 * w * h);
  
  double _Complex c = examples[q];

  #pragma omp parallel for schedule(dynamic)
  for (int j = 0; j < h; ++j)
  {
    
        
    double y = (h/2 - (j + 0.5)) / (h/2) * r;
    for (int i = 0; i < w; ++i)
    {
      double x =  (i + 0.5 - w/2) / (h/2) * r; // for q=2 add -0.5
      double _Complex z = x + I * y;
      double _Complex dz = 1.0; // first derivative of zn with respect to z
      
      
      int k;
      for (k = 0; k < n; ++k)
      { 
        // 
        dz = d(z)*dz ;
        z = f(z,c);
        
        if (cnorm(z) > r2)
          break;
      }
      
      // color
      double hue = 0, sat = 0, val = 1; // interior color = white
      
      if (k < n) 
      { // exterior and boundary color
        double _Complex de = 2 * z * log(cabs(z)) / dz;
        hue = fmod(1 + carg(de) / (2 * pi), 1); // ? slope of de
        sat = 0.25;
        val = tanh(cabs(de) / px / aa);
      }
      
      // hsv to rgb conversion
      int red, grn, blu;
      hsv2rgb(hue, sat, val, &red, &grn, &blu);
      // save rgb color to array
      img[3*(j * w + i)+0] = red;
      img[3*(j * w + i)+1] = grn;
      img[3*(j * w + i)+2] = blu;
    }
  }
  
  //
  printf("P6\n%d %d\n255\n", w, h);
  fwrite(img, 3 * w * h, 1, stdout);
  free(img);
  
  
  return 0;
}


復二次多項式

[edit | edit source]
z^2+c
[edit | edit source]
對 c 的一階導數
[edit | edit source]

在引數平面上

  • 是一個變數
  • 是一個常數

導數 可以透過 迭代 來找到,從以下開始

然後(在計算下一個 z 之前計算導數,因為它使用 z 的先前值)


這可以透過使用導數的 鏈式法則 來驗證。


  • Maxima CAS 函式


dcfn(p, z, c) :=
  if p=0 then 1
  else 2*fn(p-1,z,c)*dcfn(p-1, z, c)+1;

示例值


它可用於

關於 z 的一階導數
[編輯 | 編輯原始碼]

是關於 z 的 一階導數

導數 可以透過 迭代 來找到,從以下開始

然後 



描述 任意名稱 公式 初始條件 遞迴步驟 常用名稱
迭代復二次多項式 z 或 f
關於 z 的一階導數 f' 的 dz,d(來自導數)或 p(來自素數)


遞迴關係的推導


以下是導數的應用:

"As we iterate z, we can look at the derivatives of P at z. In our case it is quite simple: P′(z)=2z. Multiplying all these numbers along an orbit yields the derivative at z of the composition Pn. This multiplication can be carried on iteratively as we iterate z " A Cheritat
 der = 1
 z = c # note that we start with c instead of 0, to avoid multiplying the derivative by 0
 for n in range(0,N):
   new_z = z*z+c
   new_der = der*2*z
   z = new_z
   der = new_der


它可以用於:

unsigned char ComputeColorOfDEMJ(complex double z){
	


	int nMax = IterMax_DEM;
	complex double dz = 1.0; //  is first derivative with respect to z.
	double distance;
	double cabsz;
	
	int n;

	for (n=0; n < nMax; n++){ //forward iteration

		if (cabs2(z)> ER2 || cabs(dz)> 1e60) break; // big values
  			
		dz = derivative_wrt_z(z) * dz; 
		z  = f(z); /* forward iteration : complex quadratic polynomial */ 
	}
  
	if (n==nMax) return iColorOfInterior; // not escaping
	
	
	// escaping and boundary
	cabsz = cabs(z);
	distance = 2.0 * cabsz* log(cabsz)/ cabs(dz);
	double g = tanh(distance / PixelWidth);
  
	return 255*g; // iColorOfExterior;
}
邏輯斯諦對映
[edit | edit source]

邏輯斯諦對映[10]

復三次多項式

[edit | edit source]

關於 z

(%i2) display2d:false;

(%o2) false
(%i3) f(z):= z^3 + c;

(%o3) f(z):=z^3+c
(%i4) diff(f(z), z,1);

(%o4) 3*z^2
(%i5) diff(f(z), c,1);

(%o5) 1


對於f(z) = z^3 +z*(0.1008317508132964*i + 1.004954206930806)的茱莉亞集



// function 
f(z)= z^3 + c*z 

// first derivativwe wrt z
d = f'(z) = 3*z^2 + c

// iteration:
z_(n+1) = f(z_n)


// initial values:
z = z
d = 1

// Recurrence steps:
d = (3*z^2 + c)*d
z = z^3 + c*z 


四次方程

[edit | edit source]
(%i1) display2d:false;

(%o1) false

(%o4) f(z):=z^4+c
(%i5) diff(f(z), z,1);

(%o5) 4*z^3

常見問題解答

[edit | edit source]
  • 為什麼新的d必須在新的z計算之前計算?[11]


應用

[edit | edit source]


Keep track of derivatives of Z+z  wrt. Z1+z1  (where Z0+z0  is at the critical point, usually 0 ). When the absolute value of the derivative drops below a threshold such as 0.001, classify it as interior and stop iterating.
Keep track of derivatives of Z+z  wrt. pixel coordinates k . As Z  is constant for the whole image, you just need dzdk . An easy way to do this is with dual numbers for automatic numeric differentiation. Set up the pixel coordinates as dual numbers with dual part 1+0i , then transform them to the complex C+c plane of the fractal iterations. At the end you plug the complex derivative into the (directional) distance estimate formula, it is already prescaled by the pixel spacing (this also helps to avoid overflow during iteration). (	Claude Heiland-Allen)

尋找曲線法線和切線的方程

[edit | edit source]

根據 Krista King Math 的說法,要找到在給定點處曲線法線的方程:[12]

  • 對原始曲線求導,並在給定點處計算其值。這是切線斜率,稱為 m。
  • 找到 m 的負倒數。這是法線斜率,我們將其稱為 n。所以 n = −1/m。
  • 將 n 和給定點代入直線方程的點斜式公式[13] 中,(y−y1)=n(x−x1)
  • 透過解出 y 來簡化方程

內部距離估計

[edit | edit source]

內部距離估計 由下式給出:

其中

週期 = 週期軌道的長度

是要估計的來自 引數平面 的點

復二次多項式

-次迭代的

是構成周期軌道(極限環) 個點中的任意一個

 處計算 的 4 個 導數

First partial derivative with respect to z


必須透過應用鏈式法則遞迴計算

起點:

第一次迭代:

第二次迭代:

第 p 次迭代的一般規則:

關於 c 的一階偏導數


必須透過應用鏈式法則遞迴計算

起點:

第一次迭代:

第二次迭代:

對p次迭代的一般規則:

關於z的二階偏導數


必須與:

  • 一起計算
  • 透過應用鏈式法則遞迴

起點:

第一次迭代:

第二次迭代:

p 迭代的一般規則:

二階混合偏導數

如何計算導數?

[編輯 | 編輯原始碼]

梯度的 p 範數

[編輯 | 編輯原始碼]

梯度的 p 範數是:[14]



並將 p 設定為 -2。

Claude 關於畫素座標的導數

[編輯 | 編輯原始碼]
  • 畫素 = (x + i y);x 在 [0..w) 中,y 在 [0..h) 中(如果使用抖動,則可能是分數)
  • C = r exp(i pi (Pixel - (w + i h) /2) / w) + C0
  • dc/dpixel = r i pi / w exp(i pi (Pixel - (w + i h) /2) / w)
  • 對於 z <- z^2 + c
    • dz/dpixel <- 2 z dz/dpixel + dc/dpixel
    • 螢幕空間中的距離估計:de = |z| log |z| / |dz/dpixel|

這裡

  • 畫素大小 = |dc/dpixel|(只需除以 dc/dpixel 即可得到 dz/dpixel / dc/dpixel = dz/dc 等)
  • dy = (2 * circle_period * Math.PI) / image_size;
  • dx = dy * height_ratio;
  • height_ratio 通常為 1。它只是用來在一個方向上拉伸影像。


關於畫素的導數不太可能溢位,並自動給出螢幕空間 de。[16]

另外,現在我再次檢查了 e^(x*dx) 項,實際上是 e^(x*dx + offset)。我不知道這是否會改變很多事情。

 C value = (e^(x*dx + offset)) * (cos(y * dy) + sin(y* dy)i) + C0

參考文獻

[編輯 | 編輯原始碼]
  1. mathoverflow 問題 : whats-a-natural-candidate-for-an-analytic-function-that-interpolates-the-tower/43003
  2. Faa di Bruno 和迭代函式的導數,釋出於 2017 年 5 月 20 日,作者 DCHOYLE
  3. fractalforums.org : 關於曼德博集導數的一些問題
  4. A Cheritat wiki : 曼德博集 - 跟蹤導數
  5. fractalforums.org: 週期檢測
  6. 維基百科上的微分符號
  7. fractalforums.org : 關於曼德博集導數的一些問題
  8. fractalforums.org : 所有周期瓣作為點吸引子
  9. A Cheritat wiki  : 曼德博集 - 內部檢測方法
  10. Fractalforums.org : 邏輯斯蒂對映的外部距離估計
  11. Arnaud Cheritat 的 跟蹤導數
  12. 求曲線的法線方程,作者 Krista King Math
  13. 維基百科上的點斜式或點梯度式直線方程
  14. fractalforums.org : m-brot 距離估計與 Claude 的假 DE
  15. 維基百科上的自動微分
  16. fractalforums.org: 超級分形指數對映變換
華夏公益教科書