有人可以用更好的逻辑编写这段代码吗?

发布于 2024-12-07 09:41:36 字数 1129 浏览 0 评论 0原文

我被这个问题困扰了2天。有人可以帮我理清逻辑吗?

我正在研究 C++ 程序以获得良好的算法。我现在正在研究 Danielson-Lanczos 算法来计算序列的 FFT。

查看

mmax=2;
while (n>mmax) {
    istep = mmax<<1;
    theta = -(2*M_PI/mmax);
    wtemp = sin(0.5*theta);
    wpr = -2.0*wtemp*wtemp;
    wpi = sin(theta);
    wr = 1.0;
    wi = 0.0;

    for (m=1; m < mmax; m += 2) {
        for (i=m; i <= n; i += istep) {
            j=i+mmax;
            tempr = wr*data[j-1] - wi*data[j];
            tempi = wr * data[j] + wi*data[j-1];

            data[j-1] = data[i-1] - tempr;
            data[j] = data[i] - tempi;
            data[i-1] += tempr;
            data[i] += tempi;
        }
        wtemp=wr;
        wr += wr*wpr - wi*wpi;
        wi += wi*wpr + wtemp*wpi;
    }
    mmax=istep;
}

来源:http://www.eetimes.com/design/signal-processing-dsp/4017495/A-Simple-and-Efficient-FFT-Implementation-in-C--Part-I

有没有什么方法可以逻辑地编写代码,使整个 for-loop 部分减少到只有 4 行代码(甚至更好)?

I am stuck with this problem for 2 days. Can someone help me with the logic ?

I am working on C++ programs for good algorithms. I am now working on the Danielson-Lanczos Algorithm to compute the FFT of a sequence.

Looking at

mmax=2;
while (n>mmax) {
    istep = mmax<<1;
    theta = -(2*M_PI/mmax);
    wtemp = sin(0.5*theta);
    wpr = -2.0*wtemp*wtemp;
    wpi = sin(theta);
    wr = 1.0;
    wi = 0.0;

    for (m=1; m < mmax; m += 2) {
        for (i=m; i <= n; i += istep) {
            j=i+mmax;
            tempr = wr*data[j-1] - wi*data[j];
            tempi = wr * data[j] + wi*data[j-1];

            data[j-1] = data[i-1] - tempr;
            data[j] = data[i] - tempi;
            data[i-1] += tempr;
            data[i] += tempi;
        }
        wtemp=wr;
        wr += wr*wpr - wi*wpi;
        wi += wi*wpr + wtemp*wpi;
    }
    mmax=istep;
}

Source: http://www.eetimes.com/design/signal-processing-dsp/4017495/A-Simple-and-Efficient-FFT-Implementation-in-C--Part-I

Is there any way to logically write a code such that the whole for-loop portion is reduced to just 4 lines of code (or even better)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

祁梦 2024-12-14 09:41:36

更好的缩进会有很长的路要走。我为你解决了这个问题。此外,这似乎要求变量具有更好的局部性。我不清楚变量名称,但这可能是因为我不知道该算法所属的域。

一般来说,如果您想让复杂的代码更容易理解,请识别子算法并将它们放入自己的(内联)函数中。 (将代码片段放入函数中可以有效地给它一个名称,并使变量进出代码的传递更加明显。通常,这使代码更容易理解。)
不过,我不确定这对于这段代码是否必要。

然而,仅仅压缩代码并不会使其更具可读性。相反,它只会使其更加浓缩。

Better indentation would go a long way. I fixed that for you. Also, this seems to beg for better locality of the variables. The variable names are not clear to me, but that might be because I don't know the domain this algorithm belongs to.

Generally, if you want to make complex code easier to understand, identify sub-algorithms and put them into their own (inlined) functions. (Putting a code snippet into a function effectively gives it a name, and makes the passing of variables into and out of the code more obvious. Often, that makes code easier to digest.)
I'm not sure this is necessary for this piece of code, though.

Merely condensing code, however, will not make it more readable. Instead, it will just make it more condensed.

猫九 2024-12-14 09:41:36

不要压缩您的代码。请?请问漂亮吗?上面有一颗樱桃吗?

除非你能创建一个更好的算法,否则压缩现有的代码只会让它看起来像是直接从地狱之门出来的东西。没有人能够理解它。 将无法理解它,即使是几天后。

即使编译器也可能对所有分支感到困惑而无法正确优化它。

如果您正在尝试提高性能,请考虑以下事项:

  1. 过早的优化是万恶之源。

  2. 首先研究你的算法,然后研究你的代码。

  3. 行数可能与生成的可执行代码的大小完全没有关系。

  4. 编译器不喜欢纠缠的代码路径和复杂的表达式。真的...

  5. 除非代码真的对性能至关重要,否则可读性胜过一切

  6. 如果它对性能至关重要,则首先进行分析,然后开始优化。

Do not compress your code. Please? Pretty please? With a cherry on top?

Unless you can create a better algorithm, compressing an existing piece of code will only make it look like something straight out of the gates of Hell itself. No one would be able to understand it. You would not be able to understand it, even a few days later.

Even the compiler might get too confused by all the branches to properly optimize it.

If you are trying to improve performance, consider the following:

  1. Premature optimization is the source of all evils.

  2. Work on your algorithms first, then on your code.

  3. The line count may have absolutely no relation to the size of the produced executable code.

  4. Compilers do not like entangled code paths and complex expressions. Really...

  5. Unless the code is really performance critical, readability trumps everything else.

  6. If it is performance critical, profile first, then start optimizing.

月亮是我掰弯的 2024-12-14 09:41:36

您可以使用复数类来反映所涉及的数学。

代码的很大一部分是由两个复杂的乘法组成的。

您可以将代码重写为:

unsigned long mmax=2;
while (n>mmax)
{
    unsigned long istep = mmax<<1;
    const complex wp = coef( mmax );
    complex w( 1. , 0. );
    for (unsigned long m=1; m < mmax; m += 2)
    {
        for (unsigned long i=m; i <= n; i += istep)
        {
            j=i+mmax;
            complex temp = w * complex( data[j-1] , data[j] );
            complexref( data[j-1] , data[j] ) = complex( data[i-1] , data[i] ) - temp ;
            complexref( data[i-1] , data[i] ) += temp ;
        }
        w += w * wp ;
    }
    mmax=istep;
}

使用:

struct complex
{
    double r , i ;
    complex( double r , double i ) : r( r ) , i( i ) {}

    inline complex & operator+=( complex const& ref )
    {
        r += ref.r ;
        i += ref.i ;
        return *this ;
    }
};

struct complexref
{
    double & r , & i ;
    complexref( double & r , double & i ) : r( r ) , i( i ) {}

    inline complexref & operator=( complex const& ref )
    {
        r = ref.r ;
        i = ref.i ;
        return *this ;
    }

    inline complexref & operator+=( complex const& ref )
    {
        r += ref.r ;
        i += ref.i ;
        return *this ;
    }
}    ;

inline complex operator*( complex const& w , complex const& b )
{
    return complex(
        w.r * b.r - w.i * b.i ,
        w.r * b.i + w.i * b.r
    );
}

inline complex operator-( complex const& w , complex const& b )
{
    return complex( w.r - b.r , w.i - b.i );
}
inline complex coef( unsigned long mmax )
{
    double theta = -(2*M_PI/mmax);
    double wtemp = sin(0.5*theta);
    return complex( -2.0*wtemp*wtemp , sin(theta) );
}

You could use a complex number class to reflect the math involved.

A good part of the code is made of two complex multiplications.

You can rewrite your code as :

unsigned long mmax=2;
while (n>mmax)
{
    unsigned long istep = mmax<<1;
    const complex wp = coef( mmax );
    complex w( 1. , 0. );
    for (unsigned long m=1; m < mmax; m += 2)
    {
        for (unsigned long i=m; i <= n; i += istep)
        {
            j=i+mmax;
            complex temp = w * complex( data[j-1] , data[j] );
            complexref( data[j-1] , data[j] ) = complex( data[i-1] , data[i] ) - temp ;
            complexref( data[i-1] , data[i] ) += temp ;
        }
        w += w * wp ;
    }
    mmax=istep;
}

With :

struct complex
{
    double r , i ;
    complex( double r , double i ) : r( r ) , i( i ) {}

    inline complex & operator+=( complex const& ref )
    {
        r += ref.r ;
        i += ref.i ;
        return *this ;
    }
};

struct complexref
{
    double & r , & i ;
    complexref( double & r , double & i ) : r( r ) , i( i ) {}

    inline complexref & operator=( complex const& ref )
    {
        r = ref.r ;
        i = ref.i ;
        return *this ;
    }

    inline complexref & operator+=( complex const& ref )
    {
        r += ref.r ;
        i += ref.i ;
        return *this ;
    }
}    ;

inline complex operator*( complex const& w , complex const& b )
{
    return complex(
        w.r * b.r - w.i * b.i ,
        w.r * b.i + w.i * b.r
    );
}

inline complex operator-( complex const& w , complex const& b )
{
    return complex( w.r - b.r , w.i - b.i );
}
inline complex coef( unsigned long mmax )
{
    double theta = -(2*M_PI/mmax);
    double wtemp = sin(0.5*theta);
    return complex( -2.0*wtemp*wtemp , sin(theta) );
}
你与昨日 2024-12-14 09:41:36
  1. 我不相信你能够让它变得更短。
  2. 如果这段代码变得更短,我猜它会显着降低可读性。
  3. 由于逻辑相对清晰,行数并不重要 - 除非您计划在 codegolf.stackexchange.com 上使用它,否则您应该相信您的编译器会帮助您(因为它会)
  4. 这让我印象深刻作为过早的优化。
  1. I don't believe you would be able to make it substantially shorter.
  2. If this code were made much shorter, I would guess that it would significantly diminish readability.
  3. Since the logic is relatively clear, number of lines does not matter — unless you're planning on using this on codegolf.stackexchange.com, this is a place where you should trust your compiler to help you (because it will)
  4. This strikes me as premature optimization.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文