繁体   English   中英

如何使我的 function 工作于 C 中的任意维度

[英]How to make my function work for arbitrary dimensionality in C

我有一个数学 function 想在 1d、2d 和 3d 空间中使用。 我编写了适用于 3-d 案例的代码,并且我可以轻松地为其他案例修改它,但是我想知道是否有一种方法可以编写它以便它适用于任意维度。 基本上每个维度都有另一个嵌套循环,我不知道如何制作多个嵌套循环而不实际将它们写在代码中。

void gen_kernel_Gk(double *Gk, double L, double b, int np, int Z, int m)
{
    // Generates Kernel Function G in k-space
    // Gk is the array of the function values, it has Z * m number of values
    // L is cuttoff distance
    // b is monomer size
    // np is the degree of polymerization
    // Z is the number of modes
    // m is the dimensionality of the real space

    int i, j, k, l, index, Zhalf;
    double pref, kvec[m], k2;

    pref = pow( 2 * PI / (double)L, 2) * pow( b, 2) * (double)np / 6.0;

    Zhalf = Z / 2;

    for( i = 0; i < Z; ++i)
    {
        if( i < Zhalf)
        {
            kvec[0] = (double) pow( i, 2);
        }
        else
        {
            kvec[0] = (double) pow ( Z - i ,2);
        }

        for( j = 0; j < Z; ++j)
        {
            if( i < Zhalf)
            {
                kvec[1] = (double) pow( j, 2);
            }
            else
            {
                kvec[1] = (double) pow ( Z - j ,2);
            }

            for( k = 0 ; k < Z ; ++k)
            {
                if( k < Zhalf)
                {
                    kvec[2] = (double) pow( k, 2);
                }
                else
                {
                    kvec[2] = (double) pow ( Z - k ,2);
                }

                for( k2 = 0, l = 0; l < m; ++l)
                {
                    k2 += kvec[l];
                }

                index = i * pow( Z, 2) + j * Z + k;
                Gk[index] = 2.0 * ( exp( -k2) + k2 - 1.0) / pow( k2, 2);
            } 
        }
    }
    return;
}

如果您想要任意数量的嵌套for循环,您可以使用 go 来获得使用递归的解决方案。

具体怎么做取决于你的具体任务。 下面的示例并非完全基于您的代码,但它是一个更通用的代码示例来展示原理。 希望您能看到这个想法并将其应用于您的特定任务。

基本思想是递归 function 需要 arguments 来描述诸如维数和每个维的大小(在数组中)和当前级别/索引等内容。 要解决特定任务,您可能需要添加额外的 arguments。

喜欢:

#include <stdio.h>
#include <assert.h>

void opr(const unsigned dimensions, const unsigned * dimsize, 
         unsigned curdim, unsigned * curindex)
{
  assert(curdim < dimensions);
  for (unsigned u = 0; u < dimsize[curdim]; ++u)
  {
    // Save the current index
    curindex[curdim] = u;

    // Check if the last dimension has been reached
    if (curdim == (dimensions - 1))
    {
      // yes, last dimension has been reached - now do the operation you want...
      // Here the code just do a simple print
      printf("Handle array element at ");
      for (unsigned t = 0; t < dimensions; ++t)
      {
        printf("[%u]", curindex[t]);
      }
      printf("\n");
    }
    else
    {
      // no, last dimension has NOT been reached
      // so do a recursive call for the next dimension
      opr(dimensions, dimsize, curdim + 1, curindex);
                    // notice: ^^^^^^^^^^ increase current dimension 
    }
  }
}

int main(void)
{
  unsigned dimsizeA[] = {2, 3};  // [2][3]
  unsigned dimensionsA = sizeof dimsizeA / sizeof dimsizeA[0];
  unsigned curindexA[] = {0, 0};
  opr(dimensionsA, dimsizeA, 0, curindexA);

  printf("-----------------------------------\n");

  unsigned dimsizeB[] = {2, 3, 3, 2};  // [2][3][3][2]
  unsigned dimensionsB = sizeof dimsizeB / sizeof dimsizeB[0];
  unsigned curindexB[] = {0, 0, 0, 0};
  opr(dimensionsB, dimsizeB, 0, curindexB);

  return 0;
}

Output:

Handle array element at [0][0]
Handle array element at [0][1]
Handle array element at [0][2]
Handle array element at [1][0]
Handle array element at [1][1]
Handle array element at [1][2]
-----------------------------------
Handle array element at [0][0][0][0]
Handle array element at [0][0][0][1]
Handle array element at [0][0][1][0]
Handle array element at [0][0][1][1]
Handle array element at [0][0][2][0]
Handle array element at [0][0][2][1]
Handle array element at [0][1][0][0]
Handle array element at [0][1][0][1]
Handle array element at [0][1][1][0]
Handle array element at [0][1][1][1]
Handle array element at [0][1][2][0]
Handle array element at [0][1][2][1]
Handle array element at [0][2][0][0]
Handle array element at [0][2][0][1]
Handle array element at [0][2][1][0]
Handle array element at [0][2][1][1]
Handle array element at [0][2][2][0]
Handle array element at [0][2][2][1]
Handle array element at [1][0][0][0]
Handle array element at [1][0][0][1]
Handle array element at [1][0][1][0]
Handle array element at [1][0][1][1]
Handle array element at [1][0][2][0]
Handle array element at [1][0][2][1]
Handle array element at [1][1][0][0]
Handle array element at [1][1][0][1]
Handle array element at [1][1][1][0]
Handle array element at [1][1][1][1]
Handle array element at [1][1][2][0]
Handle array element at [1][1][2][1]
Handle array element at [1][2][0][0]
Handle array element at [1][2][0][1]
Handle array element at [1][2][1][0]
Handle array element at [1][2][1][1]
Handle array element at [1][2][2][0]
Handle array element at [1][2][2][1]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM