跳转到内容

分形/数学/导数

来自维基教科书,开放世界开放书籍


  • 变量 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: 超级分形指数映射变换
华夏公益教科书