分形/數學/導數
外觀
< 分形
- 變數 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)

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)

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
| 次數 | 函式 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;
示例值
它可用於
- 曼德勃羅集邊界 = DEM/M
是關於 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
它可以用於:
- 計算 茱莉亞集的外部距離 (DEM/J)
- 檢測曼德布羅特集分量的內部點[9]
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;
}
- 茱莉亞集邊界 = DEM/J
邏輯斯諦對映
[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

// 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]- 向量場梯度
- 牛頓法和遞推關係
- eDEM = 集外部的距離估計方法
- iDEM = 集內部的 DEM
- 週期點的穩定性(乘子)
- 尋找臨界點
- 斜率 - 將二維影像轉換為三維的演算法
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 範數是:[14]
並將 p 設定為 -2。
- 自動微分[15]
- 畫素 = (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
- ↑ mathoverflow 問題 : whats-a-natural-candidate-for-an-analytic-function-that-interpolates-the-tower/43003
- ↑ Faa di Bruno 和迭代函式的導數,釋出於 2017 年 5 月 20 日,作者 DCHOYLE
- ↑ fractalforums.org : 關於曼德博集導數的一些問題
- ↑ A Cheritat wiki : 曼德博集 - 跟蹤導數
- ↑ fractalforums.org: 週期檢測
- ↑ 維基百科上的微分符號
- ↑ fractalforums.org : 關於曼德博集導數的一些問題
- ↑ fractalforums.org : 所有周期瓣作為點吸引子
- ↑ A Cheritat wiki : 曼德博集 - 內部檢測方法
- ↑ Fractalforums.org : 邏輯斯蒂對映的外部距離估計
- ↑ Arnaud Cheritat 的 跟蹤導數
- ↑ 求曲線的法線方程,作者 Krista King Math
- ↑ 維基百科上的點斜式或點梯度式直線方程
- ↑ fractalforums.org : m-brot 距離估計與 Claude 的假 DE
- ↑ 維基百科上的自動微分
- ↑ fractalforums.org: 超級分形指數對映變換