如何将这些Fortran语句转换为C#?

时间:2018-07-03 13:44:16

标签: c# fortran

我的任务是将多个Fortran文件转换为C#。我别无选择,在这种情况下无法使用Dot网络驱动程序读取Fortran。我是C#的业余爱好者,并且在1983年将Fortran用作我的唯一一次。

我有几个条款似乎无法弄清楚如何在C#中关联-请问有人会指出我正确的方向吗?

我在Fortran中有很多实例,其中使用ALLOCATABLE命令分配了数组。我不知道如何在C#中执行类似操作,稍后在代码中,我也需要引用此分配作为检查。

我有一个Type声明:

TYPE Cell
  DOUBLE PRECISION, POINTER :: column(:)
END TYPE Cell

如何将此声明转换为C#?

我使用上述声明进行分配:

TYPE(Cell), POINTER           :: PMAT(:)
TYPE(Cell), POINTER           :: PMATD(:) 
TYPE(Cell), POINTER           :: NMATD(:)     

如何在C#中声明这些变量?

2 个答案:

答案 0 :(得分:2)

从发布的内容来看,我看不出有什么理由为什么不能用您最喜欢的C#方法来替换那些Fortran声明来定义锯齿状数组,即每行包含一个数组具有不同数量的元素(在这种情况下,当然是两倍)。

首先,声明

TYPE(Cell), POINTER           :: PMAT(:)

不声明指向type(cell)的事物的指针的数组,而是声明指向type(cell)的事物的数组的指针;即有一个指针,其指针是一个数组。在Fortran中,指针大约有两个用途:

  1. 它们可以在执行期间用于动态分配内存;这几乎与将变量声明为allocatable相同。
  2. 它们可用于提供对同一变量的多个引用,对于数组,可用于引用同一数组的不同切片。如果您可以找到具有属性target的相同类型的变量,那么您就会知道这就是代码中正在发生的事情。如果不能,那么pointer的使用几乎可以肯定只是实现动态内存管理的一种方式。

类型定义

TYPE Cell
  DOUBLE PRECISION, POINTER :: column(:)
END TYPE Cell

声明cell是一个双精度数组,在执行过程中将建立几个。然后出现

TYPE(Cell), POINTER           :: PMAT(:)

它声明PMAT将是cell的数组,而波什,您自己是一个锯齿状的双精度数组。这是用于声明锯齿状数组的常见Fortran习惯用法。像所有正确思考的语言一样,它确实将锯齿状数组视为可憎的东西,因此您必须跳过箍以实现它们。

我不是C#程序员,但我怀疑所有这些声明都可以按照以下方式在C#中实现:

double[][] pmat = new double[3][];
...
pmat[0] = new double[5];
pmat[1] = new double[4];
pmat[2] = new double[2];

答案 1 :(得分:1)

也不是C#程序员,但是为了获得一些经验,我尝试通过查看教程页面来创建最少的示例。第一个代码是@HPM在回答中提到的锯齿状数组:

using static System.Console;

class Program {

    static void Main() {

        double[][] pmat;            // reference to a jagged array
        pmat = new double[ 2 ][ ];  // creates a jagged array of size 2

        pmat[ 0 ] = new double[ 3 ];
        pmat[ 1 ] = new double[ 4 ];

        pmat[ 0 ][ 1 ] = 777.0;
        pmat[ 1 ][ 2 ] = 888.0;

        foreach( var x in pmat[ 0 ] ) WriteLine( x );  // prints 0 777 0
        foreach( var x in pmat[ 1 ] ) WriteLine( x );  // prints 0 0 888 0
    }
}

第二个代码是使用struct,它是一个值类型,可能类似于Fortran中的type。因此,OP代码的字面翻译可能看起来像

using static System.Console;

public struct Cell
{
    public double[] column;    // reference to a double array
}

class Program {

    static void Main() {

        Cell[] pmat;  // reference to a Cell array

        pmat = new Cell[ 2 ];  // allocates an array of Cell objects

        pmat[ 0 ].column = new double[ 3 ];
        pmat[ 1 ].column = new double[ 4 ];

        pmat[ 0 ].column[ 1 ] = 777.0;
        pmat[ 1 ].column[ 2 ] = 888.0;

        foreach( var x in pmat[ 0 ].column ) WriteLine( x );  // 0 777 0
        foreach( var x in pmat[ 1 ].column ) WriteLine( x );  // 0 0 888 0
    }
}

第三个代码是使用class(一种引用类型)。因此,它的数组类似于Fortran中的指针数组(但不是数组指针,如另一个答案所述)。

using static System.Console;

public class Cell
{
    public double[] column;
}

class Program {

    static void Main() {

        Cell[] pmat;

        pmat = new Cell[ 2 ];  // allocates an array of references (to Cell objects)

        pmat[ 0 ] = new Cell();  // allocates a new object
        pmat[ 1 ] = pmat[ 0 ];   // can point to an existing object

        pmat[ 0 ].column = new double[ 3 ];

        pmat[ 0 ].column[ 1 ] = 777.0;
        pmat[ 1 ].column[ 2 ] = 888.0;  // modifies pmat[0] in practice

        foreach( var x in pmat[ 0 ].column ) WriteLine( x );  // 0 777 888
        foreach( var x in pmat[ 1 ].column ) WriteLine( x );  // 0 777 888
    }
}

但是对于锯齿状的数组(在这种情况下),同样的事情似乎也是可能的:

double[][] pmat;
pmat = new double[ 2 ][ ];

pmat[ 0 ] = new double[ 3 ];
pmat[ 1 ] = pmat[ 0 ];

pmat[ 0 ][ 1 ] = 777.0;
pmat[ 1 ][ 2 ] = 888.0;

foreach( var x in pmat[ 0 ] ) WriteLine( x );  // 0 777 888
foreach( var x in pmat[ 1 ] ) WriteLine( x );  // 0 777 888