1

我正在随机填充一个网格,其中笛卡尔坐标从 0 归一化到 100(100x100x100 网格),其中每个数据点的“强度”从 0 归一化到 256。这是我在 perl 中的代码的摘录:

open(FILE,$file);
while(sysread(FILE,$data,16)) {
    @row=unpack("f>4",$data);   # input file is binary so I had to convert here
    $x=int((($row[0] - $xmin)/($xmax - $xmin)*10) + 0.5); # max and min variables
    $y=int((($row[1] - $ymin)/($ymax - $ymin)*10) + 0.5); # are previously defined
    $z=int((($row[2] - $zmin)/($zmax - $zmin)*10) + 0.5);
    $i=int(($row[3]/62*256) + 0.5);
    $i=255 if ($i>255);

    $out[$x][$y][$z]=$i;   # simply assigns an intensity for each data
                           # point (in random order), only 1 point can be
                           # added to each 1x1x1 cell
}

有些点靠得太近,被放置在同一个 1x1x1 单元格中。发生这种情况时,添加的每个强度都会覆盖前一个强度。如何计算一个单元格中放置多个点的次数?

提前致谢!

4

3 回答 3

1

您可以使用另一个哈希轻松完成此操作,只需将所有键 ( $x, $y, $z) 连接到一个键中,并在插入值时将哈希值设置为true 。

my %visited_points; 

open(FILE,$file);
while(sysread(FILE,$data,16)) {
    @row=unpack("f>4",$data);   # input file is binary so I had to convert here
    $x=int((($row[0] - $xmin)/($xmax - $xmin)*10) + 0.5); # max and min variables
    $y=int((($row[1] - $ymin)/($ymax - $ymin)*10) + 0.5); # are
    $z=int((($row[2] - $zmin)/($zmax - $zmin)*10) + 0.5);
    $i=int(($row[3]/62*256) + 0.5);
    $i=255 if ($i>255);

    my $key = "$x$y$z";
    # check if something already occupies this cell
    if( exists( $visited_points{$key} ) ) {
        # take some other action
    }

    $out[$x][$y][$z]=$i;   # simply assigns an intensity for each data
                           # point (in random order), only 1 point can be
                           # added to each 1x1x1 cell

    # mark that there is something in this cell
    $visited_points{$key} = 1;
}

如果您想计数,您只需增加数值即可。

于 2013-06-20T20:27:00.367 回答
1

为了使它对 hpc(高性能计算)更友好,我发现代替 $key 和 if 循环,简单地输入这样的计数也可以。

open(FILE,$file);
while(sysread(FILE,$data,16)) {
    @row=unpack("f>4",$data);   # input file is binary so I had to convert here
    $x=int((($row[0] - $xmin)/($xmax - $xmin)*10) + 0.5); # max and min variables
    $y=int((($row[1] - $ymin)/($ymax - $ymin)*10) + 0.5); # are previously defined
    $z=int((($row[2] - $zmin)/($zmax - $zmin)*10) + 0.5);
    $i=int(($row[3]/62*256) + 0.5);
    $i=255 if ($i>255);

    $count[$x][$y][$z]+=1;

    $out[$x][$y][$z]=$i;   # simply assigns an intensity for each data
                           # point (in random order), only 1 point can be
                           # added to each 1x1x1 cell
}

然后,如果 $count[$x][$y][$z] 大于 1,则意味着在该 bin 中放置了多个点。如果等于 1,则只放一个点,如果小于 1,则 bin 是空的。

于 2013-06-24T20:09:57.097 回答
0

Hunter 解决方案的另一个版本替换了哈希(使用编码的密钥);带有一个数组(带有一个编码索引)。

优点:可能会略微提高性能。老实说,很有可能,没有足够大的余地,但要确定自己的基准。

缺点:牺牲记忆。如果您的网格填充稀疏(例如 100 万个点中有 1000 个点),您将在散列中存储 1000 个元素,但在数组中存储 1,000,000 个元素。

# my @visited_points;

my $key = $x * 10000 + $y * 100 + $z;

# Mark as visited
$visited_points[$key]++;

# Check if visited:
if (defined $visited_points[$key]) {
    # Bail out?
}

# Check how many times visited?
# Use trinary ?: operator to gracefully convert undef to 0
my $count = $visited_points[$key] ? $visited_points[$key] : 0;
于 2013-06-20T20:59:11.940 回答