Math-VecStat-0.08/0040755000076400010400000000000007650352450013317 5ustar guestunknownMath-VecStat-0.08/VecStat.pm0100644000076400010400000002130607650352422015224 0ustar guestunknown
require Exporter;
package Math::VecStat;
@Math::VecStat::ISA=qw(Exporter);
@EXPORT_OK=qw(max min maxabs minabs sum average
vecprod ordered convolute
sumbyelement diffbyelement
allequal median);
$Math::VecStat::VERSION = '0.08';
use strict;
sub max {
my $v=ref($_[0]) ? $_[0] : \@_;
my $i=$#{$v};
my $j=$i;
my $m=$v->[$i];
while (--$i >= 0) { if ($v->[$i] > $m) { $m=$v->[$i]; $j=$i; }}
return wantarray ? ($m,$j): $m;
}
sub min {
my $v=ref($_[0]) ? $_[0] : \@_;
my $i=$#{$v};
my $j=$i;
my $m=$v->[$i];
while (--$i >= 0) { if ($v->[$i] < $m) { $m=$v->[$i]; $j=$i; }}
return wantarray ? ($m,$j): $m;
}
sub maxabs {
my $v=ref($_[0]) ? $_[0] : \@_;
my $i=$#{$v};
my $j=$i;
my $m=abs($v->[$i]);
while (--$i >= 0) { if (abs($v->[$i]) > $m) { $m=abs($v->[$i]); $j=$i}}
return (wantarray ? ($m,$j) : $m);
}
sub minabs {
my $v=ref($_[0]) ? $_[0] : \@_;
my $i=$#{$v};
my $j=$i;
my $m=abs($v->[$i]);
while (--$i >= 0) { if (abs($v->[$i]) < $m) { $m=abs($v->[$i]); $j=$i}}
return (wantarray ? ($m,$j) : $m);
}
sub sum {
my $v=ref($_[0]) ? $_[0] : \@_;
my $s=0;
foreach(@{$v}) { $s+=$_; }
return $s;
}
# spinellia@acm.org, handle the empty array case
sub average {
my $v=ref($_[0]) ? $_[0] : \@_;
return undef unless $#{$v} >= 0;
return $#{$v}==-1 ? 0 : sum($v)/(1+$#{$v});
}
sub vecprod {
my $c = shift;
my $v=ref($_[0]) ? $_[0] : \@_;
return undef unless $#{$v} >= 0;
my @result = map( $_ * $c, @{$v} );
return \@result;
}
sub ordered
{
my $v=ref($_[0]) ? $_[0] : \@_;
if( scalar( @{$v} ) < 2 ){ return 1; }
for(my $i=0; $i<$#{$v}; $i++ ){
return 0 if $v->[$i] > $v->[$i+1];
}
return 1;
}
sub allequal
{
my($v,$u) = @_;
return undef unless (defined($v) and defined($u)); # this is controversial
return undef unless ($#{$v} == $#{$u});
my $i= @{$v};
while (--$i >= 0) { return 0 unless( $v->[$i] == $u->[$i]); }
return 1;
}
sub sumbyelement
{
my($v,$u) = @_;
return undef unless ($#{$v} == $#{$u});
my @summed;
my $i= @{$v};
while (--$i >= 0) { $summed[$i] = $v->[$i] + $u->[$i]; }
return \@summed;
}
sub diffbyelement
{
my($v,$u) = @_;
return undef unless ($#{$v} == $#{$u});
my @summed;
my $i= @{$v};
while (--$i >= 0) { $summed[$i] = $v->[$i] - $u->[$i]; }
return \@summed;
}
sub convolute
{
my($v,$u) = @_;
return undef unless ($#{$v} == $#{$u});
my @conv;
my $i= @{$v};
while (--$i >= 0) { $conv[$i] = $v->[$i]*$u->[$i]; }
return \@conv;
}
sub _justToAvoidWarnings
{
my $a = $Math::VecStat::VERSION;
}
sub median
{
my $v=ref($_[0]) ? $_[0] : \@_;
my $n = scalar @{$v};
# generate a list of [value,index] pairs
my @tras = map( [$v->[$_],$_], 0..$#{$v} );
# sort by ascending value, then by original position
# suggested by david@jamesgang.com
my @sorted = sort { ($a->[0] <=> $b->[0])
or ($a->[1] <=> $b->[1]) } @tras;
# find the middle ordinal
my $med = int( $n / 2 );
# when there are several identical median values
# we arbitrarily (but consistently) choose the first one
# in the original array
while( ($med >= 1) && ($sorted[$med]->[0] == $sorted[$med-1]->[0]) ){
$med--;
}
return $sorted[$med];
}
1;
__END__
# $Id: VecStat.pm,v 1.5 1997/02/26 17:20:37 willijar Exp $
=head1 NAME
Math::VecStat - Some basic numeric stats on vectors
=head1 SYNOPSIS
use Math::VecStat qw(max min maxabs minabs sum average);
$max=max(@vector);
$max=max(\@vector);
($max,$imax)=max(@vector);
($max,$imax)=max(\@vector);
$min=min(@vector);
$min=min(\@vector);
($max,$imin)=min(@vector);
($max,$imin)=min(\@vector);
$max=maxabs(@vector);
$max=maxabs(\@vector);
($max,$imax)=maxabs(@vector);
($max,$imax)=maxabs(\@vector);
$min=minabs(@vector);
$min=minabs(\@vector);
($max,$imin)=minabs(@vector);
($max,$imin)=minabs(\@vector);
$sum=sum($v1,$v2,...);
$sum=sum(@vector);
$sum=sum(\@vector);
$average=average($v1,$v2,...);
$av=average(@vector);
$av=average(\@vector);
$ref=vecprod($scalar,\@vector);
$ok=ordered(@vector);
$ok=ordered(\@vector);
$ref=sumbyelement(\@vector1,\@vector2);
$ref=diffbyelement(\@vector1,\@vector2);
$ok=allequal(\@vector1,\@vector2);
$ref=convolute(\@vector1,\@vector2);
=head1 DESCRIPTION
This package provides some basic statistics on numerical
vectors. All the subroutines can take
a reference to the vector to be operated
on. In some cases a copy of the vector is acceptable,
but is not recommended for efficiency.
=over 5
=item max(@vector), max(\@vector)
return the maximum value of given values or vector. In an array
context returns the value and the index in the array where it
occurs.
=item min(@vector), min(\@vector)
return the minimum value of given values or vector, In an array
context returns the value and the index in the array where it
occurs.
=item maxabs(@vector), maxabs(\@vector)
return the maximum value of absolute of the given values or vector. In
an array context returns the value and the index in the array where it
occurs.
=item minabs(@vector), minabs(\@vector)
return the minimum value of the absolute of the given values or
vector. In an array context returns the value and the index in the
array where it occurs.
=item sum($v1,$v2,...), sum(@vector), sum(\@vector)
return the sum of the given values or vector
=item average($v1,$v2,..), average(@vector), average(\@vector)
return the average of the given values or vector
=item vecprod($a,$v1,$v2,..), vecprod($a,@vector), vecprod( $a, \@vector )
return a vector built by multiplying the scalar $a by each element of the
@vector.
=item ordered($v1,$v2,..), ordered(@vector), ordered(\@vector)
return nonzero iff the vector is nondecreasing with respect to its index.
To be used like
if( ordered( $lowBound, $value, $highBound ) ){
instead of the (slightly) more clumsy
if( ($lowBound <= $value) && ($value <= $highBound) ) {
=item sumbyelement( \@array1, \@array2 ), diffbyelement(\@array1,\@array2)
return the element-by-element sum or difference of two
identically-sized vectors. Given
$s = sumbyelement( [10,20,30], [1,2,3] );
$d = diffbyelement( [10,20,30], [1,2,3] );
C<$s> will be C<[11,22,33]>, C<$d> will be C<[9,18,27]>.
=item allequal( \@array1, \@array2 )
returns true if and only if the two arrays are numerically identical.
=item convolute( \@array1, \@array2 )
return a reference to an array containing the element-by-element
product of the two input arrays. I.e.,
$r = convolute( [1,2,3], [-1,2,1] );
returns a reference to
[-1,4,3]
=item median
evaluates the median, i.e. an element which separates the population
in two halves. It returns a reference to a list whose first element
is the median value and the second element is the index of the
median element in the original vector.
$a = Math::VecStat::median( [9,8,7,6,5,4,3,2,1] );
returns the list reference
[ 5, 4 ]
i.e. the median value is 5 and it is found at position 4 of the
original array.
If there are several elements of the array
having the median value, e.g. [1,3,3,3,5]. In this case
we choose always the first element in the original vector
which is a median. In the example, we return [3,1].
=head1 HISTORY
$Log: VecStat.pm,v $
Revision 1.9 2003/04/20 00:49:00 spinellia@acm.org
Perl 5.8 broke test 36, exposing inconsistency in C. Fixed, thanks to david@jamesgang.com.
Revision 1.8 2001/01/26 11:10:00 spinellia@acm.org
Added function median.
Fixed test, thanks to Andreas Marcel Riechert
Revision 1.7 2000/10/24 15:28:00 spinellia@acm.org
Added functions allequal diffbyelement
Created a reasonable test suite.
Revision 1.6 2000/06/29 16:06:37 spinellia@acm.org
Added functions vecprod, convolute, sumbyelement
Revision 1.5 1997/02/26 17:20:37 willijar
Added line before pod header so pod2man installs man page correctly
Revision 1.4 1996/02/20 07:53:10 willijar
Added ability to return index in array contex to max and min
functions. Added minabs and maxabs functions.
Thanks to Mark Borges for these suggestions.
Revision 1.3 1996/01/06 11:03:30 willijar
Fixed stupid bug that crept into looping in min and max functions
Revision 1.2 1995/12/26 09:56:38 willijar
Oops - removed xy data functions.
Revision 1.1 1995/12/26 09:39:07 willijar
Initial revision
=head1 BUGS
Let me know. I welcome any appropriate additions for this package.
=head1 AUTHORS
John A.R. Williams
Andrea Spinelli
=cut
Math-VecStat-0.08/README0100644000076400010400000000123107175340566014200 0ustar guestunknownPerl Module Math::VecStat - 0.05
Some basic statistics on vectors (min,max,average,....).
Copyright (c) 1995,1996,1997 John A.R. Williams
Copyright (c) 2000 Andrea Spinelli
All rights reserved.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
To install, unzip and untar the archive. In the directory created type
perl Makefile.PL
make install
To execute tests:
perl Makefile.PL
make test
Documentation is in the module file and will be added onto
perllocal.pod as usual.
You may contact Andrea Spinelli, who is currently maintaining
the archive, at spinellia@acm.org
Math-VecStat-0.08/Makefile.PL0100644000076400010400000000050507650350430015262 0ustar guestunknownuse ExtUtils::MakeMaker;
use Config;
$Version = '0.08';
WriteMakefile(
'NAME' => 'Math::VecStat',
'LINKTYPE' => '$(INST_PM)',,
'VERSION' => $Version,
'dist' => { SUFFIX => 'gz', COMPRESS => 'gzip -f' },
'clean' => {'FILES' => '*~'},
);
Math-VecStat-0.08/t/0040755000076400010400000000000007650352450013562 5ustar guestunknownMath-VecStat-0.08/t/VecStat.t0100644000076400010400000000703707650352040015317 0ustar guestunknown
print "1..40\n";
$main::testct = 1;
use Math::VecStat qw(min max ordered allequal
minabs maxabs
sumbyelement diffbyelement
convolute vecprod
average median
);
# require 'VecStat.pm';
# function t moved here to stop complaints
# thanks to Andreas Marcel Riechert
sub t()
{
printf "%sok %d\n", ($main::ok?'':'not '), $main::testct++;
}
##################################
# min (1-5)
##################################
# basic test
$main::ok = (Math::VecStat::min( 1, 2, 3 ) == 1 );
t();
# negative values
$main::ok = (Math::VecStat::min( 1, 2, -3 ) == -3 );
t();
# empty arg list
$main::ok = not defined(Math::VecStat::min());
t();
# empty array
$main::ok = not defined(Math::VecStat::min([]));
t();
# floats
$main::ok = (abs(Math::VecStat::min( 1.1, 0.5, 3.2 ) - 0.5) < 1e-6 );
t();
##################################
# max (6-10)
##################################
# basic test
$main::ok = (Math::VecStat::max( 1, 2, 3 ) == 3 );
t();
# negative values
$main::ok = (Math::VecStat::max( 1, 2, -3 ) == 2 );
t();
# empty arg list
$main::ok = not defined(Math::VecStat::max());
t();
# empty array
$main::ok = not defined(Math::VecStat::max([]));
t();
# floats
$main::ok = (abs(Math::VecStat::max( 1.1, 0.5, 3.2 ) - 3.2) < 1e-6 );
t();
##################################
# ordered (11-15)
##################################
# basic test
$main::ok = ordered(1,2,3);
t();
$main::ok = ordered(1,1,1);
t();
$main::ok = not ordered(1,2,0);
t();
$main::ok = ordered( -3.1, -1.9, 0 );
t();
$main::ok = not ordered( -3.1, -1.9, -5.0 );
t();
##################################
# allequal (16-20)
##################################
$main::ok = allequal( [1,2,3,4,5], [1,2,3,4,5] );
t();
$main::ok = allequal( [], [] );
t();
$main::ok = not allequal( [1,2,3,4,5], [1,2,3,4,6] );
t();
$main::ok = not allequal( [7,2,3,4], [1,2,3,4] );
t();
$main::ok = not allequal( [1,2,3], [1,2,3,4] );
t();
##################################
# {sum,diff}byelement (21-25)
##################################
$main::ok = allequal( sumbyelement( [10,20,30], [1,2,3] ), [11,22,33] );
t();
$main::ok = allequal( diffbyelement( [10,20,30], [1,2,3] ), [9,18,27] );
t();
$main::ok = allequal( sumbyelement( [], [] ), [] );
t();
$main::ok = (maxabs( diffbyelement( [1.03,1.97,3.01],[1,2,3] ) ) < 0.1 );
t();
$main::ok = (minabs( diffbyelement( [1.03,1.97,3.01],[1,2,3] ) ) > 1e-3 );
t();
##################################
# convolute (26-30)
##################################
$main::ok = allequal( convolute( [1,2,3], [-1,2,1] ), [-1,4,3]);
t();
# pro domo sua
$main::ok = not allequal( [], [1] );
t();
$main::ok = not allequal( [2], [] );
t();
$main::ok = allequal( convolute( [], [] ), []);
t();
$main::ok = (maxabs( diffbyelement( convolute( [1.1,2.2,3.3], [2.0,3.0,4.0] ),
[2.2,6.6,13.2] ) ) < 1e-6);
t();
##################################
# average (31-35)
##################################
$main::ok = ( abs( average( 10.1, 4.9, -0.1) - 5.0) < 0.1 );
t();
$main::ok = not defined( average([]) );
t();
$main::ok = ( abs( average( [10.1, 4.9, -0.1] ) - 5.0) < 0.1 );
t();
$main::ok = average( 2.78 ) == 2.78;
t();
$main::ok = average( 0.0 ) == 0.0;
t();
my $a = median( [1,1,2,3,4,3,2,3,4,5] );
$main::ok = ($a->[0] == 3) && ($a->[1] == 3);
t();
$a = median( [1,1,2,4,3,3,2,3,4,5] );
$main::ok = ($a->[0] == 3) && ($a->[1] == 4);
t();
$a = median( [1,3,3,3,5] );
$main::ok = ($a->[0] == 3) && ($a->[1] == 1);
t();
$a = median( [1,2,2,3] );
$main::ok = ($a->[0] == 2) && ($a->[1] == 1);
t();
$a = median( [4,4,4,4] );
$main::ok = ($a->[0] == 4) && ($a->[1] == 0);
t();
Math-VecStat-0.08/MANIFEST0100644000076400010400000000006307175310706014444 0ustar guestunknownMANIFEST
Makefile.PL
VecStat.pm
README
t/VecStat.t