2012-07-15 92 views
2

在GSL中,一个实数n * m矩阵M在内部表示为大小为n*m的数组。要访问M的(i,j)元素,内部GSL必须访问数组的位置,其中涉及整数乘法和加法。GSL vs数值食谱。处理矩阵的最佳方法

在C的Numerical Recipes中,他们推荐了另一种方法来声明n指针数组,每个指针指向一个数组m。然后访问(i,j)元素,一个放入M[i-1][j-1]。他们声称这更有效,因为它避免了整数倍增。缺点是必须分别初始化每个指针。

我想知道,每种方法的优缺点是什么?

+0

请注意,习惯于0索引。这是最好的。 0是第一个元素。 – 2012-07-15 04:21:18

+1

@JoshPetitt NR书使用1索引。以便代码与Fortran版本相同。在Fortran中编写了大量的数字代码。 – 2012-07-15 05:38:53

+1

@马丁,你是对的。 Fortran中编写了许多数字代码。 Fortran具有列主要的顺序,并且通常Fortran对2D矩阵计算更快。 C不是Fortran。这个问题是用C标记的。在写C时,我会使用C约定。尤其是如果我关心的是尽可能快地用C来做事情。 – 2012-07-15 16:45:43

回答

2

在C:

#define n 2 
#define m 3 

int M[n*m]; 

在C矩阵相同

int M[n][m]; 

被说成是存储在行优先顺序

http://en.wikipedia.org/wiki/Row-major_order

在C中,

M[1][2] 

相同

*(M + 1*m + 2) // if M is define as M[n][m] 

您可以定义中号正指针数组,但你还是必须把数据的地方,最好的地方可能是一个二维数组。我会建议:

int M[n][m]; 

int* Mrows[n] = {M[0], M[1]}; 

然后,你可以做一个直接偏移到行到达你想要的行。然后:

Mrows[1][2] 

是一样的程序员

*((*(Mrows + 1)) + 2) 

它更多的工作,大概只有值得的,如果你想要去的真快。在这种情况下,您可能希望查看更多优化,例如特定的机器指令。此外,根据您的算法,您可能只能使用+操作(如果您正在遍历矩阵)