如何在不带参数的情况下将大数据集传递给函数

时间:2020-04-08 17:04:03

标签: c function-pointers lattice lanczos

我正在尝试创建一个通用的Lanczos算法,该算法接受一个运算符(函数指针)并在C中从该运算符中打印出一定数量的特征值。我正在使用GNU科学库来处理矢量和矩阵。具体地说,所讨论的运算符采用一些输入向量,并通过引用输出一个向量。因此,我希望Lanczos方法的函数原型至少看起来像这样,

void Lanczos( void (*operator) (gsl_vector_complex *,gsl_vector_complex *) , int k    );

其中k是我要打印的特征值的数量。问题是我立即对寻找本征值感兴趣的操作员感兴趣,因为他们需要使用我在先前模拟中生成的大量外部数据。具体来说,我感兴趣的运算符可以原型化为

void WDoperator(gsl_vector_complex * input, gsl_vector_complex * output, lattice * L)

在程序的其他地方,我将latticesite结构定义为

typedef struct lattice{
  site * R[10*10*10*10];
}lattice;
typedef struct site{
  gsl_matrix_complex * link[4];
}site;

但是,当然,它的编写方式无法将看起来像我的WDoperator的函数指针传递到Lanczos中。解决这个问题的想法是只拥有一个全局lattice指针来保存我的模拟结果,而不是将其作为参数传递给WDoperator。但是,在研究stackoverflow时,似乎普遍的共识是不使用全局变量,尤其是不使用全局指针。因此,有没有我没有想到的更好的方法呢?有没有一种方法可以“抑制”函数的参数,使其适合我的Lanczos例程将接受的函数指针?如果要使用全局指针,是否有使用它们的最佳实践,这样我就不会创建内存泄漏的怪物了?特别是考虑要存储在网格中的数据的大小(目前有40,000个矩阵,但是一旦我能正常工作,我想将其按比例放大,以便达到20万个矩阵的数量级)。如果以前有类似的问题,我深表歉意,但我已尽力将论坛范围扩大到类似的问题。

2 个答案:

答案 0 :(得分:0)

是否可以“抑制”函数的参数,使其适合Lanczos例程将接受的函数指针?

您可以当您不想使用lattice * L的附加参数时,请使用条件编译语句并为宏常量赋予不同的值:

#define CD 1

void WDoperator(gsl_vector_complex * input, gsl_vector_complex * output
#if CD 1
, lattice * L
#endif
);

void Lanczos( void (*operator) (int *,double *) 
#if CD 1
, lattice* L
#endif 
) int k);

在两个函数的定义以及每个使用lattice指针的函数中的算法上,都必须对参数列表应用相同的内容。

抱歉,如果这不是您想要的,但我认为它可以为您提供帮助。

答案 1 :(得分:0)

一种普遍接受的机制是提供通过以下方式传递的匿名上下文参数:

void Lanczos( void (*operator) (gsl_vector_complex *,gsl_vector_complex *) , int k, void *ctx)
void WDoperator(gsl_vector_complex * input, gsl_vector_complex * output, void * ctx) {
   Lattice *L = ctx;

...

如果您想更严格地进行错误检查,可以提出类似以下内容:

struct L_ctx {
    int type;
    void *arg;
};
enum {
    L_NoType,
    L_Lattice,
    L_ComplexLattice,
    ...
};

然后检查是否传入了适当的类型。较少出现错误,但是与像Golang这样的体面类型系统不匹配。