1package Statistics::Descriptive::Sparse; 2$Statistics::Descriptive::Sparse::VERSION = '3.0800'; 3use strict; 4use warnings; 5 6use vars qw(%fields); 7use Carp qw/ carp /; 8require Statistics::Descriptive; 9use Statistics::Descriptive::Smoother (); 10 11## no critic (ProhibitExplicitReturnUndef) 12 13sub _make_accessors 14{ 15 my ( $pkg, $methods ) = @_; 16 17 ## no critic 18 no strict 'refs'; 19 ## use critic 20 foreach my $method (@$methods) 21 { 22 *{ $pkg . "::" . $method } = do 23 { 24 my $m = $method; 25 sub { 26 my $self = shift; 27 28 if (@_) 29 { 30 $self->{$m} = shift; 31 } 32 return $self->{$m}; 33 }; 34 }; 35 } 36 37 return; 38} 39 40sub _make_private_accessors 41{ 42 my ( $pkg, $methods ) = @_; 43 44 ## no critic 45 no strict 'refs'; 46 ## use critic 47 foreach my $method (@$methods) 48 { 49 *{ $pkg . "::_" . $method } = do 50 { 51 my $m = $method; 52 sub { 53 my $self = shift; 54 55 if (@_) 56 { 57 $self->{$m} = shift; 58 } 59 return $self->{$m}; 60 }; 61 }; 62 } 63 64 return; 65} 66 67##Define the fields to be used as methods 68%fields = ( 69 count => 0, 70 mean => undef, 71 sum => undef, 72 sumsq => undef, 73 min => undef, 74 max => undef, 75 mindex => undef, 76 maxdex => undef, 77 sample_range => undef, 78 variance => undef, 79); 80 81__PACKAGE__->_make_accessors( [ grep { $_ ne "variance" } keys(%fields) ] ); 82__PACKAGE__->_make_accessors( ["_permitted"] ); 83__PACKAGE__->_make_private_accessors( ["variance"] ); 84 85sub new 86{ 87 my $proto = shift; 88 my $class = ref($proto) || $proto; 89 my $self = { %fields, }; 90 bless( $self, $class ); 91 $self->_permitted( \%fields ); 92 return $self; 93} 94 95sub _is_permitted 96{ 97 my $self = shift; 98 my $key = shift; 99 100 return exists( $self->_permitted()->{$key} ); 101} 102 103sub add_data 104{ 105 my $self = shift; ##Myself 106 my $oldmean; 107 my ( $min, $mindex, $max, $maxdex, $sum, $sumsq, $count ); 108 my $aref; 109 110 if ( ref $_[0] eq 'ARRAY' ) 111 { 112 $aref = $_[0]; 113 } 114 else 115 { 116 $aref = \@_; 117 } 118 119 ##If we were given no data, we do nothing. 120 return 1 if ( !@{$aref} ); 121 122 ##Take care of appending to an existing data set 123 124 if ( !defined( $min = $self->min() ) ) 125 { 126 $min = $aref->[ $mindex = 0 ]; 127 } 128 else 129 { 130 $mindex = $self->mindex(); 131 } 132 133 if ( !defined( $max = $self->max() ) ) 134 { 135 $max = $aref->[ $maxdex = 0 ]; 136 } 137 else 138 { 139 $maxdex = $self->maxdex(); 140 } 141 142 $sum = $self->sum(); 143 $sumsq = $self->sumsq(); 144 $count = $self->count(); 145 146 ##Calculate new mean, sumsq, min and max; 147 foreach ( @{$aref} ) 148 { 149 $sum += $_; 150 $sumsq += $_**2; 151 ++$count; 152 if ( $_ >= $max ) 153 { 154 $max = $_; 155 $maxdex = $count - 1; 156 } 157 if ( $_ <= $min ) 158 { 159 $min = $_; 160 $mindex = $count - 1; 161 } 162 } 163 164 $self->min($min); 165 $self->mindex($mindex); 166 $self->max($max); 167 $self->maxdex($maxdex); 168 $self->sample_range( $max - $min ); 169 $self->sum($sum); 170 $self->sumsq($sumsq); 171 $self->mean( $sum / $count ); 172 $self->count($count); 173 ##indicator the value is not cached. Variance isn't commonly enough 174 ##used to recompute every single data add. 175 $self->_variance(undef); 176 return 1; 177} 178 179sub standard_deviation 180{ 181 my $self = shift; ##Myself 182 return undef if ( !$self->count() ); 183 return sqrt( $self->variance() ); 184} 185 186##Return variance; if needed, compute and cache it. 187sub variance 188{ 189 my $self = shift; ##Myself 190 191 my $count = $self->count(); 192 193 return undef if !$count; 194 195 return 0 if $count == 1; 196 197 if ( !defined( $self->_variance() ) ) 198 { 199 my $variance = ( $self->sumsq() - $count * $self->mean()**2 ); 200 201 # Sometimes due to rounding errors we get a number below 0. 202 # This makes sure this is handled as gracefully as possible. 203 # 204 # See: 205 # 206 # https://rt.cpan.org/Public/Bug/Display.html?id=46026 207 208 $variance = $variance < 0 ? 0 : $variance / ( $count - 1 ); 209 210 $self->_variance($variance); 211 212 # Return now to avoid re-entering this sub 213 # (and therefore save time when many objects are used). 214 return $variance; 215 } 216 217 return $self->_variance(); 218} 219 220##Clear a stat. More efficient than destroying an object and calling 221##new. 222sub clear 223{ 224 my $self = shift; ##Myself 225 my $key; 226 227 return if ( !$self->count() ); 228 while ( my ( $field, $value ) = each %fields ) 229 { # could use a slice assignment here 230 $self->{$field} = $value; 231 } 232} 233 2341; 235 236__END__ 237 238=pod 239 240=encoding UTF-8 241 242=head1 NAME 243 244Statistics::Descriptive - Module of basic descriptive statistical functions. 245 246=head1 VERSION 247 248version 3.0800 249 250=head1 SYNOPSIS 251 252 use Statistics::Descriptive; 253 my $stat = Statistics::Descriptive::Full->new(); 254 $stat->add_data(1,2,3,4); 255 my $mean = $stat->mean(); 256 my $var = $stat->variance(); 257 my $tm = $stat->trimmed_mean(.25); 258 $Statistics::Descriptive::Tolerance = 1e-10; 259 260=head1 DESCRIPTION 261 262This module provides basic functions used in descriptive statistics. 263It has an object oriented design and supports two different types of 264data storage and calculation objects: sparse and full. With the sparse 265method, none of the data is stored and only a few statistical measures 266are available. Using the full method, the entire data set is retained 267and additional functions are available. 268 269Whenever a division by zero may occur, the denominator is checked to be 270greater than the value C<$Statistics::Descriptive::Tolerance>, which 271defaults to 0.0. You may want to change this value to some small 272positive value such as 1e-24 in order to obtain error messages in case 273of very small denominators. 274 275Many of the methods (both Sparse and Full) cache values so that subsequent 276calls with the same arguments are faster. 277 278=head1 METHODS 279 280=head2 Sparse Methods 281 282=over 5 283 284=item $stat = Statistics::Descriptive::Sparse->new(); 285 286Create a new sparse statistics object. 287 288=item $stat->clear(); 289 290Effectively the same as 291 292 my $class = ref($stat); 293 undef $stat; 294 $stat = new $class; 295 296except more efficient. 297 298=item $stat->add_data(1,2,3); 299 300Adds data to the statistics variable. The cached statistical values are 301updated automatically. 302 303=item $stat->count(); 304 305Returns the number of data items. 306 307=item $stat->mean(); 308 309Returns the mean of the data. 310 311=item $stat->sum(); 312 313Returns the sum of the data. 314 315=item $stat->variance(); 316 317Returns the variance of the data. Division by n-1 is used. 318 319=item $stat->standard_deviation(); 320 321Returns the standard deviation of the data. Division by n-1 is used. 322 323=item $stat->min(); 324 325Returns the minimum value of the data set. 326 327=item $stat->mindex(); 328 329Returns the index of the minimum value of the data set. 330 331=item $stat->max(); 332 333Returns the maximum value of the data set. 334 335=item $stat->maxdex(); 336 337Returns the index of the maximum value of the data set. 338 339=item $stat->sample_range(); 340 341Returns the sample range (max - min) of the data set. 342 343=back 344 345=head2 Full Methods 346 347Similar to the Sparse Methods above, any Full Method that is called caches 348the current result so that it doesn't have to be recalculated. In some 349cases, several values can be cached at the same time. 350 351=over 5 352 353=item $stat = Statistics::Descriptive::Full->new(); 354 355Create a new statistics object that inherits from 356Statistics::Descriptive::Sparse so that it contains all the methods 357described above. 358 359=item $stat->add_data(1,2,4,5); 360 361Adds data to the statistics variable. All of the sparse statistical 362values are updated and cached. Cached values from Full methods are 363deleted since they are no longer valid. 364 365I<Note: Calling add_data with an empty array will delete all of your 366Full method cached values! Cached values for the sparse methods are 367not changed> 368 369=item $stat->add_data_with_samples([{1 => 10}, {2 => 20}, {3 => 30},]); 370 371Add data to the statistics variable and set the number of samples each value 372has been built with. The data is the key of each element of the input array 373ref, while the value is the number of samples: [{data1 => smaples1}, {data2 => 374samples2}, ...]. 375 376B<NOTE:> The number of samples is only used by the smoothing function and is 377ignored otherwise. It is not equivalent to repeat count. In order to repeat 378a certain datum more than one time call add_data() like this: 379 380 my $value = 5; 381 my $repeat_count = 10; 382 $stat->add_data( 383 [ ($value) x $repeat_count ] 384 ); 385 386=item $stat->get_data(); 387 388Returns a copy of the data array. 389 390=item $stat->get_data_without_outliers(); 391 392Returns a copy of the data array without outliers. The number minimum of 393samples to apply the outlier filtering is C<$Statistics::Descriptive::Min_samples_number>, 3944 by default. 395 396A function to detect outliers need to be defined (see C<set_outlier_filter>), 397otherwise the function will return an undef value. 398 399The filtering will act only on the most extreme value of the data set 400(i.e.: value with the highest absolute standard deviation from the mean). 401 402If there is the need to remove more than one outlier, the filtering 403need to be re-run for the next most extreme value with the initial outlier removed. 404 405This is not always needed since the test (for example Grubb's test) usually can only detect 406the most exreme value. If there is more than one extreme case in a set, 407then the standard deviation will be high enough to make neither case an outlier. 408 409=item $stat->set_outlier_filter($code_ref); 410 411Set the function to filter out the outlier. 412 413C<$code_ref> is the reference to the subroutine implementing the filtering 414function. 415 416Returns C<undef> for invalid values of C<$code_ref> (i.e.: not defined or not a 417code reference), C<1> otherwise. 418 419=over 4 420 421=item 422 423Example #1: Undefined code reference 424 425 my $stat = Statistics::Descriptive::Full->new(); 426 $stat->add_data(1, 2, 3, 4, 5); 427 428 print $stat->set_outlier_filter(); # => undef 429 430=item 431 432Example #2: Valid code reference 433 434 sub outlier_filter { return $_[1] > 1; } 435 436 my $stat = Statistics::Descriptive::Full->new(); 437 $stat->add_data( 1, 1, 1, 100, 1, ); 438 439 print $stat->set_outlier_filter( \&outlier_filter ); # => 1 440 my @filtered_data = $stat->get_data_without_outliers(); 441 # @filtered_data is (1, 1, 1, 1) 442 443In this example the series is really simple and the outlier filter function as well. 444For more complex series the outlier filter function might be more complex 445(see Grubbs' test for outliers). 446 447The outlier filter function will receive as first parameter the Statistics::Descriptive::Full object, 448as second the value of the candidate outlier. Having the object in the function 449might be useful for complex filters where statistics property are needed (again see Grubbs' test for outlier). 450 451=back 452 453=item $stat->set_smoother({ method => 'exponential', coeff => 0, }); 454 455Set the method used to smooth the data and the smoothing coefficient. 456See C<Statistics::Smoother> for more details. 457 458=item $stat->get_smoothed_data(); 459 460Returns a copy of the smoothed data array. 461 462The smoothing method and coefficient need to be defined (see C<set_smoother>), 463otherwise the function will return an undef value. 464 465=item $stat->sort_data(); 466 467Sort the stored data and update the mindex and maxdex methods. This 468method uses perl's internal sort. 469 470=item $stat->presorted(1); 471 472=item $stat->presorted(); 473 474If called with a non-zero argument, this method sets a flag that says 475the data is already sorted and need not be sorted again. Since some of 476the methods in this class require sorted data, this saves some time. 477If you supply sorted data to the object, call this method to prevent 478the data from being sorted again. The flag is cleared whenever add_data 479is called. Calling the method without an argument returns the value of 480the flag. 481 482=item $stat->skewness(); 483 484Returns the skewness of the data. 485A value of zero is no skew, negative is a left skewed tail, 486positive is a right skewed tail. 487This is consistent with Excel. 488 489=item $stat->kurtosis(); 490 491Returns the kurtosis of the data. 492Positive is peaked, negative is flattened. 493 494=item $x = $stat->percentile(25); 495 496=item ($x, $index) = $stat->percentile(25); 497 498Sorts the data and returns the value that corresponds to the 499percentile as defined in RFC2330: 500 501=over 4 502 503=item 504 505For example, given the 6 measurements: 506 507-2, 7, 7, 4, 18, -5 508 509Then F(-8) = 0, F(-5) = 1/6, F(-5.0001) = 0, F(-4.999) = 1/6, F(7) = 5105/6, F(18) = 1, F(239) = 1. 511 512Note that we can recover the different measured values and how many 513times each occurred from F(x) -- no information regarding the range 514in values is lost. Summarizing measurements using histograms, on the 515other hand, in general loses information about the different values 516observed, so the EDF is preferred. 517 518Using either the EDF or a histogram, however, we do lose information 519regarding the order in which the values were observed. Whether this 520loss is potentially significant will depend on the metric being 521measured. 522 523We will use the term "percentile" to refer to the smallest value of x 524for which F(x) >= a given percentage. So the 50th percentile of the 525example above is 4, since F(4) = 3/6 = 50%; the 25th percentile is 526-2, since F(-5) = 1/6 < 25%, and F(-2) = 2/6 >= 25%; the 100th 527percentile is 18; and the 0th percentile is -infinity, as is the 15th 528percentile, which for ease of handling and backward compatibility is returned 529as undef() by the function. 530 531Care must be taken when using percentiles to summarize a sample, 532because they can lend an unwarranted appearance of more precision 533than is really available. Any such summary must include the sample 534size N, because any percentile difference finer than 1/N is below the 535resolution of the sample. 536 537=back 538 539(Taken from: 540I<RFC2330 - Framework for IP Performance Metrics>, 541Section 11.3. Defining Statistical Distributions. 542RFC2330 is available from: 543L<http://www.ietf.org/rfc/rfc2330.txt> .) 544 545If the percentile method is called in a list context then it will 546also return the index of the percentile. 547 548=item $x = $stat->quantile($Type); 549 550Sorts the data and returns estimates of underlying distribution quantiles based on one 551or two order statistics from the supplied elements. 552 553This method use the same algorithm as Excel and R language (quantile B<type 7>). 554 555The generic function quantile produces sample quantiles corresponding to the given probabilities. 556 557B<$Type> is an integer value between 0 to 4 : 558 559 0 => zero quartile (Q0) : minimal value 560 1 => first quartile (Q1) : lower quartile = lowest cut off (25%) of data = 25th percentile 561 2 => second quartile (Q2) : median = it cuts data set in half = 50th percentile 562 3 => third quartile (Q3) : upper quartile = highest cut off (25%) of data, or lowest 75% = 75th percentile 563 4 => fourth quartile (Q4) : maximal value 564 565Example : 566 567 my @data = (1..10); 568 my $stat = Statistics::Descriptive::Full->new(); 569 $stat->add_data(@data); 570 print $stat->quantile(0); # => 1 571 print $stat->quantile(1); # => 3.25 572 print $stat->quantile(2); # => 5.5 573 print $stat->quantile(3); # => 7.75 574 print $stat->quantile(4); # => 10 575 576=item $stat->median(); 577 578Sorts the data and returns the median value of the data. 579 580=item $stat->harmonic_mean(); 581 582Returns the harmonic mean of the data. Since the mean is undefined 583if any of the data are zero or if the sum of the reciprocals is zero, 584it will return undef for both of those cases. 585 586=item $stat->geometric_mean(); 587 588Returns the geometric mean of the data. 589 590=item my $mode = $stat->mode(); 591 592Returns the mode of the data. The mode is the most commonly occurring datum. 593See L<http://en.wikipedia.org/wiki/Mode_%28statistics%29> . If all values 594occur only once, then mode() will return undef. 595 596=item $stat->sumsq() 597 598The sum of squares. 599 600=item $stat->trimmed_mean(ltrim[,utrim]); 601 602C<trimmed_mean(ltrim)> returns the mean with a fraction C<ltrim> 603of entries at each end dropped. C<trimmed_mean(ltrim,utrim)> 604returns the mean after a fraction C<ltrim> has been removed from the 605lower end of the data and a fraction C<utrim> has been removed from the 606upper end of the data. This method sorts the data before beginning 607to analyze it. 608 609All calls to trimmed_mean() are cached so that they don't have to be 610calculated a second time. 611 612=item $stat->frequency_distribution_ref($partitions); 613 614=item $stat->frequency_distribution_ref(\@bins); 615 616=item $stat->frequency_distribution_ref(); 617 618C<frequency_distribution_ref($partitions)> slices the data into 619C<$partition> sets (where $partition is greater than 1) and counts the 620number of items that fall into each partition. It returns a reference to 621a hash where the keys are the numerical values of the 622partitions used. The minimum value of the data set is not a key and the 623maximum value of the data set is always a key. The number of entries 624for a particular partition key are the number of items which are 625greater than the previous partition key and less then or equal to the 626current partition key. As an example, 627 628 $stat->add_data(1,1.5,2,2.5,3,3.5,4); 629 $f = $stat->frequency_distribution_ref(2); 630 for (sort {$a <=> $b} keys %$f) { 631 print "key = $_, count = $f->{$_}\n"; 632 } 633 634prints 635 636 key = 2.5, count = 4 637 key = 4, count = 3 638 639since there are four items less than or equal to 2.5, and 3 items 640greater than 2.5 and less than 4. 641 642C<frequency_distribution_refs(\@bins)> provides the bins that are to be used 643for the distribution. This allows for non-uniform distributions as 644well as trimmed or sample distributions to be found. C<@bins> must 645be monotonic and contain at least one element. Note that unless the 646set of bins contains the range that the total counts returned will 647be less than the sample size. 648 649Calling C<frequency_distribution_ref()> with no arguments returns the last 650distribution calculated, if such exists. 651 652=item my %hash = $stat->frequency_distribution($partitions); 653 654=item my %hash = $stat->frequency_distribution(\@bins); 655 656=item my %hash = $stat->frequency_distribution(); 657 658Same as C<frequency_distribution_ref()> except that returns the hash clobbered 659into the return list. Kept for compatibility reasons with previous 660versions of Statistics::Descriptive and using it is discouraged. 661 662=item $stat->least_squares_fit(); 663 664=item $stat->least_squares_fit(@x); 665 666C<least_squares_fit()> performs a least squares fit on the data, 667assuming a domain of C<@x> or a default of 1..$stat->count(). It 668returns an array of four elements C<($q, $m, $r, $rms)> where 669 670=over 4 671 672=item C<$q and $m> 673 674satisfy the equation C($y = $m*$x + $q). 675 676=item C<$r> 677 678is the Pearson linear correlation cofficient. 679 680=item C<$rms> 681 682is the root-mean-square error. 683 684=back 685 686If case of error or division by zero, the empty list is returned. 687 688The array that is returned can be "coerced" into a hash structure 689by doing the following: 690 691 my %hash = (); 692 @hash{'q', 'm', 'r', 'err'} = $stat->least_squares_fit(); 693 694Because calling C<least_squares_fit()> with no arguments defaults 695to using the current range, there is no caching of the results. 696 697=back 698 699=head1 REPORTING ERRORS 700 701I read my email frequently, but since adopting this module I've added 2 702children and 1 dog to my family, so please be patient about my response 703times. When reporting errors, please include the following to help 704me out: 705 706=over 4 707 708=item * 709 710Your version of perl. This can be obtained by typing perl C<-v> at 711the command line. 712 713=item * 714 715Which version of Statistics::Descriptive you're using. As you can 716see below, I do make mistakes. Unfortunately for me, right now 717there are thousands of CD's with the version of this module with 718the bugs in it. Fortunately for you, I'm a very patient module 719maintainer. 720 721=item * 722 723Details about what the error is. Try to narrow down the scope 724of the problem and send me code that I can run to verify and 725track it down. 726 727=back 728 729=head1 AUTHOR 730 731Current maintainer: 732 733Shlomi Fish, L<http://www.shlomifish.org/> , C<shlomif@cpan.org> 734 735Previously: 736 737Colin Kuskie 738 739My email address can be found at http://www.perl.com under Who's Who 740or at: https://metacpan.org/author/COLINK . 741 742=head1 CONTRIBUTORS 743 744Fabio Ponciroli & Adzuna Ltd. team (outliers handling) 745 746=head1 REFERENCES 747 748RFC2330, Framework for IP Performance Metrics 749 750The Art of Computer Programming, Volume 2, Donald Knuth. 751 752Handbook of Mathematica Functions, Milton Abramowitz and Irene Stegun. 753 754Probability and Statistics for Engineering and the Sciences, Jay Devore. 755 756=head1 COPYRIGHT 757 758Copyright (c) 1997,1998 Colin Kuskie. All rights reserved. This 759program is free software; you can redistribute it and/or modify it 760under the same terms as Perl itself. 761 762Copyright (c) 1998 Andrea Spinelli. All rights reserved. This program 763is free software; you can redistribute it and/or modify it under the 764same terms as Perl itself. 765 766Copyright (c) 1994,1995 Jason Kastner. All rights 767reserved. This program is free software; you can redistribute it 768and/or modify it under the same terms as Perl itself. 769 770=head1 LICENSE 771 772This program is free software; you can redistribute it and/or modify it 773under the same terms as Perl itself. 774 775=for :stopwords cpan testmatrix url bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan 776 777=head1 SUPPORT 778 779=head2 Websites 780 781The following websites have more information about this module, and may be of help to you. As always, 782in addition to those websites please use your favorite search engine to discover more resources. 783 784=over 4 785 786=item * 787 788MetaCPAN 789 790A modern, open-source CPAN search engine, useful to view POD in HTML format. 791 792L<https://metacpan.org/release/Statistics-Descriptive> 793 794=item * 795 796RT: CPAN's Bug Tracker 797 798The RT ( Request Tracker ) website is the default bug/issue tracking system for CPAN. 799 800L<https://rt.cpan.org/Public/Dist/Display.html?Name=Statistics-Descriptive> 801 802=item * 803 804CPANTS 805 806The CPANTS is a website that analyzes the Kwalitee ( code metrics ) of a distribution. 807 808L<http://cpants.cpanauthors.org/dist/Statistics-Descriptive> 809 810=item * 811 812CPAN Testers 813 814The CPAN Testers is a network of smoke testers who run automated tests on uploaded CPAN distributions. 815 816L<http://www.cpantesters.org/distro/S/Statistics-Descriptive> 817 818=item * 819 820CPAN Testers Matrix 821 822The CPAN Testers Matrix is a website that provides a visual overview of the test results for a distribution on various Perls/platforms. 823 824L<http://matrix.cpantesters.org/?dist=Statistics-Descriptive> 825 826=item * 827 828CPAN Testers Dependencies 829 830The CPAN Testers Dependencies is a website that shows a chart of the test results of all dependencies for a distribution. 831 832L<http://deps.cpantesters.org/?module=Statistics::Descriptive> 833 834=back 835 836=head2 Bugs / Feature Requests 837 838Please report any bugs or feature requests by email to C<bug-statistics-descriptive at rt.cpan.org>, or through 839the web interface at L<https://rt.cpan.org/Public/Bug/Report.html?Queue=Statistics-Descriptive>. You will be automatically notified of any 840progress on the request by the system. 841 842=head2 Source Code 843 844The code is open to the world, and available for you to hack on. Please feel free to browse it and play 845with it, or whatever. If you want to contribute patches, please send me a diff or prod me to pull 846from your repository :) 847 848L<https://github.com/shlomif/perl-Statistics-Descriptive> 849 850 git clone git://github.com/shlomif/perl-Statistics-Descriptive.git 851 852=head1 AUTHOR 853 854Shlomi Fish <shlomif@cpan.org> 855 856=head1 BUGS 857 858Please report any bugs or feature requests on the bugtracker website 859L<https://github.com/shlomif/perl-Statistics-Descriptive/issues> 860 861When submitting a bug or request, please include a test-file or a 862patch to an existing test-file that illustrates the bug or desired 863feature. 864 865=head1 COPYRIGHT AND LICENSE 866 867This software is copyright (c) 1997 by Jason Kastner, Andrea Spinelli, Colin Kuskie, and others. 868 869This is free software; you can redistribute it and/or modify it under 870the same terms as the Perl 5 programming language system itself. 871 872=cut 873