使用Perl打印2500 x 2500维矩阵

时间:2013-11-14 14:18:40

标签: perl

我是Perl的新手。最近我写了一个代码来计算两个结构之间原子之间的相关系数。这是我的计划的简要总结。

for($i=1;$i<=2500;$i++)
{
    for($j=1;$j<=2500;$j++)
    {
         calculate the correlation (Cij);
         print $Cij;
    }
}

该程序在一列中连续打印所有相关性。但是我需要以矩阵的形式打印相关性,比如......

         Atom1    Atom2   Atom3    Atom4
Atom1     0.5     -0.1     0.6      0.8
Atom2     0.1      0.2     0.3     -0.5
Atom3    -0.8      0.9     1.0      0.0
Atom4     0.3      1.0     0.8     -0.8

我不知道,怎么做。请帮我解决一下,或建议我怎么做!

2 个答案:

答案 0 :(得分:0)

免责声明:伪代码,您可能需要自己处理特殊情况,尤其是标题。

for($i=1;$i<=2500;$i++)
{
print "\n";  # linebreak here.
    for($j=1;$j<=2500;$j++)
    {
        calculate the correlation (Cij);
        printf "\t%4f",$Cij;  # print a tab followed by your float giving it 4
                              # spaces of room. But no linebreak here.
    }
}

这当然是一个非常粗糙,快速和肮脏的解决方案。但是如果将输出保存为.csv文件,大多数可以编辑的电子表格程序(OpenOfice)应该能够轻松地将其读入正确的表格。如果您选择的电子表格查看器无法将标签理解为分隔符,则可以轻松添加;或者/或者它可以用于printf字符串的任何东西。

答案 1 :(得分:0)

你遇到的简单问题。完成打印行后,需要打印NL。然而,虽然我引起了你的注意,但我会喋喋不休。

您应该使用references将数据存储在矩阵中。这样,您存储数据的方式与数据的概念相符:

my @atoms;       # Storing the data in here
my $i = 300;
my $j = 400;

my $value = ...; # Calculating what the value should be at column 300, row 400.

# Any one of these will work. Pick one:

my $atoms[$i][$j] = $value;    # Looks just like a matrix!
my $atoms[$i]->[$j] = $value;  # Reminds you this isn't really a matrix.
my ${$atoms[$1]}[$j] = $value; # Now this just looks ridiculous, but is technically correct.

我的偏好是第二种方式。这只是一个轻微的提醒,这实际上不是一个矩阵。相反,它是我的行数组,每个指向另一个包含该特定行的数据的数组。语法仍然很干净,虽然不像第一种方式那么干净。

现在,让我们回到你的问题:

my @atoms;  # I'll store the calculated values here

....

my $atoms[$i]->[$j] = ... # calculated value for row $i column $j

....

# And not to print out my matrix

for my $i (0..$#atoms) {
    for my $j (0..$#{ $atoms[$i] } ) {
       printf "%4.2f  ", $atoms[$i]->[$j];  # Notice no "\n".
    }
    print "\n";    # Print the NL once you finish a row
}

注意我使用for my $i (0..$#atoms)。这种语法比不鼓励的C风格三部分for更清晰。 (Python没有它,我不知道它将在Perl 6中得到支持)。这很容易理解:我正在通过我的数组递增。我还使用$#atom这是我的@atoms数组的长度 - 或我的矩阵中的行数。这样,当我的矩阵大小改变时,我不必编辑我的程序。

[$j]有点过时了。 $atom[$i]是对包含行$i的列数据的数组的引用,并不直接表示一行数据。 (这就是我喜欢$atoms[$i]->[$j]而不是$atoms[$i][$j]的原因。它给了我这个微妙的提醒。)为了获得包含行$i的列数据的实际数组,我需要取消引用它。因此,实际列值存储在数组数组$i中的行@{$atoms[$i]}中。

要获取数组中的最后一个条目,请将@ sigil替换为$#,以便将我的最后一个索引替换为 数组是$#{ $atoms[$i] }

哦,另一件事是因为这不是一个真正的矩阵:每一行可能有不同数量的条目。你不能用真正的矩阵。这使得在Perl中使用数组数组更加强大,而且更加危险。如果需要一致的列数,则必须手动检查。真正的矩阵将根据最大$j值自动创建所需的列。