我正在尝试将在FORTRAN 77中声明和初始化的三维数组编码为C#中的等效数组。
在做了一些研究之后,我发现FORTRAN 77遵循列主要方法。我仍然无法想象如何表示在C#中用FORTRAN 77初始化的三维数组。这是FORTRAN 77代码,它声明并初始化一个三维数组:
real*4 temperature_factors(2,6,9)/
c .000,.054, .055,.070, .071,.085, .086,.105, .106,.200,
c -1.0,-1.0,
c -1.0,-1.0, -1.0,-1.0, .125,.164, .165,.204, .205,.404,
c .405,.604,
c 0.0,12.0, 12.1,35.4, 35.5,55.4, 55.5,150.4, 150.5,250.4,
c 250.5,500.4,
c 0.0,54.0, 55.0,154.0, 155.0,254.0, 255.0,354.0, 355.0,424.0,
c 425.0,604.0,
c 0.0,4.4, 4.5,9.4, 9.5,12.4, 12.5,15.4, 15.5,30.4,
c 30.5,50.4,
c .000,.035, .036,.75, .76,.185, -1., -1., -1., -1.,
c -1., -1.,
c -1., -1., -1., -1., -1., -1.,.186,.304, .305,.604,
c .605,1.004,
c -1.0,10.0, -1.0,-1.0, -1.0,-1.0, -1.0,-1.0, -1.,-1.0,
c -1.0,10.0,
c .000,.053, .054,.100, .101,.360, .361,.649, .650,1.249,
c 1.250,2.049/
我最初尝试在C#中表示上述内容:
double[, ,] temperature_factors = new double[2, 6, 9]
{
{
{0.000, 0.054, 0.055, 0.070, 0.071, 0.085, 0.086, 0.105, 0.106,},
{0.200, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 0.125, 0.164},
{0.165, 0.204, 0.205, 0.404, 0.405, 0.604, 0.0, 12.0, 12.1},
{35.4, 35.5, 55.4, 55.5, 150.4, 150.5, 250.4, 250.5, 500.4},
{0.0, 54.0, 55.0, 154.0, 155.0, 254.0, 255.0, 354.0, 355.0},
{424.0, 425.0, 604.0, 0.0, 4.4, 4.5, 9.4, 9.5, 12.4}
},
{
{12.5, 15.4, 15.5, 30.4, 30.5, 50.4, 0.000, 0.035, 0.036},
{0.75, 0.76, 0.185, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0},
{-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 0.186, 0.304, 0.305},
{0.604, 0.605, 1.004, -1.0, 10.0, -1.0, -1.0, -1.0, -1.0},
{-1.0, -1.0, -1.0, -1.0, -1.0, 10.0, 0.000, 0.053, 0.054},
{0.100, 0.101, 0.360, 0.361, 0.649, 0.650, 1.249, 1.250, 2.049}
}
};
但显然这不正确。任何人都可以帮我初始化用FORTRAN 77编写的3维数组到C#中的等价数据。
谢谢。
答案 0 :(得分:0)
Fortran数组是列专用的,因此Fortran代码中的文字值按A
的顺序填充到A(1,1,1), A(2,1,1), A(1,2,1), A(2,2,1), ..., A(1,6,9), A(2,6,9)
(其中A
表示temperature_factors
)。另一方面,C#数组是行主要的(根据这个page和一个迷你测试(请参见本答案的底部)),所以我认为我们需要切换索引的顺序来利用直接的文字值序列。具体来说,我们首先从文字值创建一个1D(临时)数组
double[] arr1 = new double[ 9 * 6 * 2 ]
{
.000,.054, .055,.070, .071,.085, .086,.105, .106,.200, -1.0,-1.0,
-1.0,-1.0, -1.0,-1.0, .125,.164, .165,.204, .205,.404, .405,.604,
0.0,12.0, 12.1,35.4, 35.5,55.4, 55.5,150.4, 150.5,250.4, 250.5,500.4,
0.0,54.0, 55.0,154.0, 155.0,254.0, 255.0,354.0, 355.0,424.0, 425.0,604.0,
0.0,4.4, 4.5,9.4, 9.5,12.4, 12.5,15.4, 15.5,30.4, 30.5,50.4,
.000,.035, .036,.75, .76,.185, -1.0,-1.0, -1.0,-1.0, -1.0,-1.0,
-1.0,-1.0, -1.0,-1.0, -1.0,-1.0, .186,.304, .305,.604, .605,1.004,
-1.0,10.0, -1.0,-1.0, -1.0,-1.0, -1.0,-1.0, -1.0,-1.0, -1.0,10.0,
.000,.053, .054,.100, .101,.360, .361,.649, .650,1.249, 1.250,2.049
};
然后通过循环逐个复制元素(最右边的索引k
应该运行得最快):
double [,,] arr3 = new double[ 9, 6, 2 ];
int ind = 0;
for (int i = 0; i < 9; i++)
for (int j = 0; j < 6; j++)
for (int k = 0; k < 2; k++) {
arr3[ i, j, k ] = arr1[ ind ];
ind++;
}
或等效地,直接复制一块内存(根据此page)
Buffer.BlockCopy( arr1, 0, arr3, 0, arr1.Length * sizeof(double) );
我们可以通过打印arr3
的几个元素来检查结果:
// using static System.Console;
WriteLine( arr3[ 0, 0, 0 ] );
WriteLine( arr3[ 0, 0, 1 ] );
WriteLine( arr3[ 0, 1, 0 ] );
WriteLine( arr3[ 0, 1, 1 ] );
WriteLine( "..." );
WriteLine( arr3[ 8, 4, 0 ] );
WriteLine( arr3[ 8, 4, 1 ] );
WriteLine( arr3[ 8, 5, 0 ] );
WriteLine( arr3[ 8, 5, 1 ] );
给出了
0 // A(1,1,1) in Fortran
0.054 // A(2,1,1)
0.055 // A(1,2,1)
0.07 // A(2,2,1)
...
0.65 // A(1,5,9)
1.249 // A(2,5,9)
1.25 // A(1,6,9)
2.049 // A(2,6,9)
要使用与Fortran相同的索引顺序,它也可能有用 创建另一个反转索引顺序的3D数组,例如:
double [,,] arr3_alt = new double[ 2, 6, 9 ];
for (int i = 0; i < 2; i++)
for (int j = 0; j < 6; j++)
for (int k = 0; k < 9; k++) {
arr3_alt[ i, j, k ] = arr3[ k, j, i ];
}
WriteLine( arr3_alt[ 0, 0, 0 ] );
WriteLine( arr3_alt[ 1, 0, 0 ] );
WriteLine( arr3_alt[ 0, 1, 0 ] );
WriteLine( arr3_alt[ 1, 1, 0 ] );
WriteLine( "..." );
WriteLine( arr3_alt[ 0, 4, 8 ] );
WriteLine( arr3_alt[ 1, 4, 8 ] );
WriteLine( arr3_alt[ 0, 5, 8 ] );
WriteLine( arr3_alt[ 1, 5, 8 ] );
这是一个迷你测试,我试图检查对齐 内存中的数组元素:
int[,] A = new int[2,3] { {1,2,3}, {4,5,6} };
int[] B = new int[6];
Buffer.BlockCopy( A, 0, B, 0, sizeof(int) * 6 ); // A=src, B=dest, 0=offset, count=in-bytes
WriteLine( "B[0] = " + B[0] + " A[0,0] = " + A[0,0] );
WriteLine( "B[1] = " + B[1] + " A[0,1] = " + A[0,1] );
WriteLine( "B[2] = " + B[2] + " A[0,2] = " + A[0,2] );
WriteLine( "B[3] = " + B[3] + " A[1,0] = " + A[1,0] );
WriteLine( "B[4] = " + B[4] + " A[1,1] = " + A[1,1] );
WriteLine( "B[5] = " + B[5] + " A[1,2] = " + A[1,2] );
给出了
B[0] = 1 A[0,0] = 1
B[1] = 2 A[0,1] = 2
B[2] = 3 A[0,2] = 3
B[3] = 4 A[1,0] = 4
B[4] = 5 A[1,1] = 5
B[5] = 6 A[1,2] = 6