Fortrans等效于C ++的语法

时间:2017-06-08 04:11:27

标签: c++ optimization fortran benchmarking linear-programming

我正在处理一个文件。内容格式如下:

name   - problem name (A string value)
m      - number or rows (int value)
n      - number of columns (int value)
Ap     - pointers to the begining of storage of column (size n+1)(an array of size (n+1) )
Ai     - row indices for each non zero entry (input, nnz A)
Ax     - non zero entries (input, nnz A)
b      - right hand side (input, size m)(an double array of size m )
c      - objective vector (minimize, size n) (an double array of size n) )
z0     - initial fixed value for objective (double value)
lobnd  - lower bounds on variables (size n) (an double array of size n )
upbnd  - upper bounds on variables (size n) (an double array of size n )

在fortran中读取此文件的语法如下:

Ap (j) = location of start of column j
Ai (Ap (j)) through Ai (Ap (j+1)-1) are the row indices in column j
Ax (Ap (j)) through Ax (Ap (j+1)-1) are the numerical values in column j

      read(file,'(a8)') name
      read(file,*) m,n
      read(file,*) (ia(i),i=1,n+1)
      read(file,*) (ja(i),i=1,ia(n+1)-1)
      read(file,*) (a(i),i=1,ia(n+1)-1)
      read(file,*) (b(i),i=1,m)
      read(file,*) (c(i),i=1,n)
      read(file,*) z0
      read(file,*) (lobnd(i),i=1,n)
      read(file,*) (upbnd(i),i=1,n)

我想知道C ++中的相应语法。有谁知道如何将此程序从fortran转换为C ++? Here is an example of an file .

根据上述文件中的文件格式说明

name   = 'BLEND'
m      = 74  
n      = 114
upbnd  = I can see the n or 114 double values at the end of the file
lobnd  = I can see the n or 114 double values before the values of upbnd  
z0     = here I can see 0. is the value of z0
c      = I can see n or 114 values before z0 in the file and understand this
b      = I understand the right hand side and I can see the m or 74 values
Ai     - I understand row indices for each non zero entry (input, nnz A)
Ax     - non zero entries (input, nnz A)

Now I can not understand the following values in the file:
Ap     = I can not understand what do these (n+1) or 115 integers mean

我想了解文件中的这个Ap值。 提前谢谢。

1 个答案:

答案 0 :(得分:3)

read(file,'(a8)') name大致翻译为scanf("%8s", name);

read(file,*) m,n大致相当于file >> m >> n;

read(file,*) (ia(i),i=1,n+1)这样的线条无疑是最棘手的。第一个逗号后面的部分是“隐含的DO循环”。它基本上意味着这大致相当于以下顺序:

for (int i=1; i<n+1; i++)
    file >> ia[i];

我相信其余的只是上面显示的一个或另一个的重复。

另外还有一点要记住:Fortran按列主要顺序存储数组。 C和C ++以行主顺序存储数组。这意味着当您在C或C ++中遍历数组时,通常需要逐行遍历它。除其他外,这将优化缓存使用,因为每一行都是连续存储在内存中。

Fortran是专栏专业。这意味着每列在内存中是连续的,并且遍历数组的自然方式是一次一列。由于每列在内存中是连续的,因此(当然)优化了缓存使用。

Ap中的值包含每列开头的位置。即Ap(1)是第一列中第一项的索引。 Ap(2)是第二列中第一项的索引,依此类推。如果您需要读取N th 列,Ap(N)将告诉您主阵列中您开始读取的位置以获取该列的数据。由于Ap(N + 1)是列N + 1的开头,因此N列中的最后一项是Ap(N + 1)-1。

因此,我们假设您将主数据数组读入平坦(1D)数组,我们只需调用data。要阅读data中的N th 列,您可以使用Ap。例如,要打印出N th 列,我们可以编写如下代码:

void print_column(int n) {
    for (int i=Ap[n]; i<Ap[n+1]; i++)
        std::cout << data[i] << '\t';
}

这使您可以避免必须处理动态分配2D数组,而只使用单个new / malloc / vector来保存数据,同时使用第二个保存每列开头的索引。在C ++中,创建一个2D矩阵类非常容易,该类重载operator()以对存储在vector中的数据进行2D寻址。您可以使用Ap提供的额外级别的间接,或者您可以使用乘法来到达正确的位置。在当前处理器上,乘法可能比内存引用快,但在较旧的处理器上,相对于内存访问,乘法通常要慢得多。