O
Oscar Stiffelman
I have a vector of numeric points specified as 2 cols in a text file.
I want to break the points into windows and compute averages for each
window.
And (this is important), I am looking for a compact perlish way to do
it, ideally using the more "functional programming" parts of the
language, as opposed to the direct, nested for loops.
I am new to Perl, so I would appreciate feedback on the approach I
have taken below.
#!/usr/bin/perl
$w = shift; # this is the block size
die "must specify window size" if !$w;
@x = sort {@$a[0] <=> @$b[0]} map {[split]} <>;
print "@$_\n" for map {
($s0,$s1)=(0,0);
for(@$_) {
$s0 += @$_[0];
$s1 += @$_[1]
};
[$s0/$w, $s1/$w]
} map {
[@x[$_*$w .. ($_+1)*$w-1]]
} (0..$#x/$w);
# In pseudocode, this is what it does:
for(i = 0; i < n; i+= width) {
(x,y) = (0,0);
for(int j = 0; j < width; j++) {
x += vec[i+j][0];
y += vec[i+j][1];
}
push results, [x/width, y/width];
}
Can anyone suggest an even more compact or idiomatically-correct way
to do this?
P.S.,
I am evaluating using Perl to do some of the data manipulation and
analysis that I currently perform in Mathematica. In Mathematica,
lisp-ish mapping of anonymous functions is really common (and
convenient), so I am trying to decide if similar transformations can
be expressed compactly in perl.
I want to break the points into windows and compute averages for each
window.
And (this is important), I am looking for a compact perlish way to do
it, ideally using the more "functional programming" parts of the
language, as opposed to the direct, nested for loops.
I am new to Perl, so I would appreciate feedback on the approach I
have taken below.
#!/usr/bin/perl
$w = shift; # this is the block size
die "must specify window size" if !$w;
@x = sort {@$a[0] <=> @$b[0]} map {[split]} <>;
print "@$_\n" for map {
($s0,$s1)=(0,0);
for(@$_) {
$s0 += @$_[0];
$s1 += @$_[1]
};
[$s0/$w, $s1/$w]
} map {
[@x[$_*$w .. ($_+1)*$w-1]]
} (0..$#x/$w);
# In pseudocode, this is what it does:
for(i = 0; i < n; i+= width) {
(x,y) = (0,0);
for(int j = 0; j < width; j++) {
x += vec[i+j][0];
y += vec[i+j][1];
}
push results, [x/width, y/width];
}
Can anyone suggest an even more compact or idiomatically-correct way
to do this?
P.S.,
I am evaluating using Perl to do some of the data manipulation and
analysis that I currently perform in Mathematica. In Mathematica,
lisp-ish mapping of anonymous functions is really common (and
convenient), so I am trying to decide if similar transformations can
be expressed compactly in perl.