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