我正在尝试创建一个通用的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)
在程序的其他地方,我将lattice
和site
结构定义为
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万个矩阵的数量级)。如果以前有类似的问题,我深表歉意,但我已尽力将论坛范围扩大到类似的问题。
答案 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这样的体面类型系统不匹配。