首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将PDL劈成两半

将PDL劈成两半
EN

Stack Overflow用户
提问于 2013-11-21 18:01:24
回答 1查看 149关注 0票数 3

我有一个一维PDL,我想对每一半进行计算;也就是说,将它分开,然后在前半部分进行计算,在下半部分进行相同的计算。

是否有一种更容易/更好/更优雅的方法来简单地将PDL分割成两半,而不是得到元素的数量(用nelem),然后将其除以二,然后执行两片呢?

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-22 14:24:26

是的,只要你不需要直接调用片来得到你想要的东西。您可以使用这样的方法来链接splitdimdog

代码语言:javascript
复制
# Assume we have $data, a piddle
my ($left, $right) = $data->splitdim(0, $data->nelem/2)->dog;

当然,这很容易扩展到两个以上的部门。但是,如果您想将其扩展到更高维的小空间(即存储在一个小空间中的时间序列的集合),那么您就需要更加精细一些。如果您想沿着第一个维度(它的索引为0)分割,您可以这样说:

代码语言:javascript
复制
# Assume we have $data, a piddle
my ($left, $right) = $data->splitdim(0, $data->dim(0)/2)->mv(1, -1)->dog;

splitdim操作将第0维分解为二维,第0维长度为dim(0)/2,第1维为2维(因为我们将其分为两部分)。由于dog在最后一个维度上操作,所以在调用dog之前,我们将第一个维度移到末尾。

然而,即使是单维解决方案,也有一个警告。由于$data->splitdim的工作方式,如果您有奇数的元素,它将截断最后一段数据。在一个有21个元素的凸起点上尝试一下这个操作,你就会明白我的意思:

代码语言:javascript
复制
my $data = sequence(20);
say "data is $data";  # lists 0-19
my ($left, $right) = $data->splitdim(0, $data->nelem/2)->dog;
say "left is $left and right is $right";  # lists 0-9, then 10-19

$data = sequence(21);
say "data is $data";  # lists 0-20, i.e. 21 elements
my ($left, $right) = $data->splitdim(0, $data->nelem/2)->dog;
say "left is $left and right is $right";  # lists 0-9, then 10-19!!

如果您想要避免这种情况,您可以生成您自己的方法,将第一个维度分割成两半,而不需要截断。它可能看起来是这样的:

代码语言:javascript
复制
sub PDL::split_in_half {
    my $self = shift;

    # the int() isn't strictly necessary, but should make things a
    # tad faster
    my $left = $self->slice(':' . int($self->dim(0)/2-1) );
    my $right = $self->slice(int($self->dim(0)/2) . ':');
    return ($left, $right);
}

在这里,我还使用了内置的int,以确保如果.5是奇怪的,我们就没有dim(0)。这有点复杂,但我们把这种复杂性精确地隐藏在一种方法中,这样我们就不需要考虑复杂性了,所以我们可以在它的同时为自己买几个时钟周期。

这样,您就可以轻松地调用该方法:

代码语言:javascript
复制
my ($left, $right) = $data->split_in_half;
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20128532

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档