我试图创建一个通用的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万个矩阵的数量级)。如果以前有类似的问题,我深表歉意,但我已尽力将论坛范围扩大到类似的问题。
一种普遍接受的机制是提供一个匿名上下文参数,该参数通过以下方式传递:
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这样的体面类型系统来说是不匹配的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句