Mandelbrot 的算法在不使用复数的情况下无法给出所需的结果

Posted

技术标签:

【中文标题】Mandelbrot 的算法在不使用复数的情况下无法给出所需的结果【英文标题】:Mandelbrot's algorithm not giving the desired result without using complex numbers 【发布时间】:2020-09-23 07:48:02 【问题描述】:

当我使用以下算法来使用 mandelbrot 算法时,我得到的图像与我想要的图像相似,但它看起来更像是最终图像的轮廓,当我使用复数算法时,它会给出适当的锐度图片

代码是用c++编写的

//pseudocode 
//z=x+yi    //x=0,y=0
//c=x0+y0i  //x=scaled(px),y=scaled(py)
//do
//z2=x2+(2*xy)i-y2
//z=z2+c   //z=x2-y2+x0+(2*xy+y0)i
//x=x2-y2+x0   //y=2*xy+y0
//x2=x*x       //y2=y*y
//if(sqrt(x2+y2)<2 )
// break
//iteration++
//while( iteration<max_iteration)
//code without complex numbers
int mandelbrot::_test_num_iteration( double px, double py ) 
double x0 scale_x( px ) , x 0 ;
double y0 scale_y( py ) , y 0 ;
double x2 0 , y2 0 ;
//z=x+iy        c=x0+iy0
int iteration 0 ;
while (iteration < max_iteration)          //for instance max_iteration=1000
    x2 = x * x;             y2 = y * y;
    x = x2  + x0 - y2;      y = 2 * x * y + y0;
    x2 = (x * x);           y2 = (y * y);
    if (sqrt(( x2 + y2 )) > 2)   
        break;
    iteration++;

return iteration;

 //code with complex numbers
    int mandelbrot::get_iteration( double px, double py) 
    //x+iy=z
    //z2=x2+(2*xyi)-y2
    //c=x0+iy0
    //x0&y0=scaled x and y coordinates
    double x scale_x( px ) ;
    double y scale_y( py ) ;
    complex::complex_numbers z;
    complex::complex_numbers c x,y ;
    int iteration 0 ;
    while (iteration < max_iteration) 
        z = z * z + c;
        if (mod( z ) > 2)   //mod is a function which returns sqrt(x2+y2)
            break;
        iteration++;
    

    return iteration;
    

【问题讨论】:

complex 到底是什么?代码肯定是有区别的,没有看到完整的代码就无法判断到底有什么区别。请发帖minimal reproducible example 他的名字叫 Mandelbrot。 不要比较 sqrt(x2 + y2) &gt; 2,因为 sqrt() 非常慢。您可以将两边平方给您x2 + y2 &gt; 4,以便更快地进行测试。类似的复数使用norm(z) &gt; 4 @idclev463035818 complex 是一个自定义命名空间,我在其中创建了一个名为 complex_numbers 的 c++ 类。它与复杂的头类相同,只是为了执行某些任务而进行了一些优化,并包含一些自定义函数,这些函数正是顾名思义,就像复数模的 mod。我真的很抱歉造成这种混乱。 没有复数(或至少模拟复数的行为 -> i^2 = -1)无法计算 Mandelbrot 【参考方案1】:

问题在于您没有根据旧值计算两个新值。 这里,

x = x2  + x0 - y2;      y = 2 * x * y + y0;

您将新的x 用于新的y。 您需要几个变量来临时存储更新的值。

double new_x = x2 - y2 + x0;      
double new_y = 2 * x * y + y0;
x = new_x;
y = new_y;

【讨论】:

或者只计算 x 之前的 y。 ohkk 非常感谢您指出这一点,我认为我们可以创建一个,而不是创建 2 个变量,然后我们可以继续分 2 个步骤和 1 个临时变量 double new_x = x2 - y2 + x0; y = 2 * x * y + y0; x = new_x;跨度> 【参考方案2】:

此块中有一个错误:

    x2 = x * x;             y2 = y * y;
    x = x2  + x0 - y2;      y = 2 * x * y + y0;

您尝试实现z*z+c。但是,在第二行中,您将“z”的实部更改为实部的平方减去虚部加上常数。此时,z的实部已经更新。接下来更新 y(虚部与更新的实部)。哎呀。

我会逐行检查并检查您对复数运算的实现是否确实完成了他们应该做的事情。如果您不知道如何使用调试器,请使用一些 cout &lt;&lt; 语句。

编辑:删除不正确的sqrt(x2+y2) 评论。

【讨论】:

@molbdnilo 忽略了那条线。感谢您指出。

以上是关于Mandelbrot 的算法在不使用复数的情况下无法给出所需的结果的主要内容,如果未能解决你的问题,请参考以下文章

将颜色层添加到 mandelbrot 集

如何在不混淆字段的情况下声明复数? [复制]

具有一般指数的 OpenGL ES GLSL Mandelbrot

蓝桥杯 算法提高 6-17复数四则运算

算法提高 6-17复数四则运算

实体框架6在不需要时复数表名