).
=cut
sub obsdev {
return observed(@_) - expected(@_);
}
*observed_deviation = \&obsdev;
=head2 stdev, standard_deviation
$v = $pot->stdev(state => 'x'); # use data already loaded - anonymously; or specify its "label" or "index" - see observed()
$v = $pot->stdev(data => [qw/x z x x p c/], state => 'x');
Returns square-root of the variance.
=cut
sub stdev {
return sqrt(variance(@_));
}
*standard_deviation = \&stdev;
=head2 z_value, zscore, pot_zscore, pzs
$v = $pot->z_value(ccorr => 1, state => 'x'); # use data already loaded - anonymously; or specify its "label" or "index" - see observed()
$v = $pot->z_value(data => $aref, ccorr => 1, state => 'x');
($zvalue, $pvalue) = $pot->z_value(data => $aref, ccorr => 1, tails => 2, state => 'x'); # same but wanting an array, get the p-value too
Returns the zscore from a test of pot deviation, taking the pot expected away from that observed and dividing by the root expected pot variance, by default with a continuity correction to expectation. Called wanting an array, returns the z-value with its I-value for the tails (1 or 2) given.
The data to test can already have been Led, or sent directly as an aref keyed as B.
Other options are B (for the z_value) and B (for the p_value).
=cut
sub z_value {
my $self = shift;
my $args = ref $_[0] ? shift : {@_};
my $ccorr = defined $args->{'ccorr'} ? $args->{'ccorr'} : 1;
my $tails = $args->{'tails'} || 2;
my $precision_s = $args->{'precision_s'};
my $precision_p = $args->{'precision_p'};
my $pvo = defined $args->{'observed'} ? $args->{'observed'} : $self->pvo($args);
my ($zval, $pval) = $zed->zscore(
observed => $pvo,
expected => $self->pve($args),
variance => $self->pvv($args),
ccorr => $ccorr,
tails => $tails,
precision_s => $precision_s,
precision_p => $precision_p,
);
return wantarray ? ($zval, $pval) : $zval;
}
*pzs = \&z_value;
*pot_zscore = \&z_value;
*zscore = \&z_value;
=head2 p_value, test, pot_test, ptt
$p = $pot->p_value(state => 'x'); # using loaded data and default args
$p = $pot->p_value(ccorr => 0|1, tails => 1|2, state => 'x'); # normal-approximation based on loaded data
$p = $pot->p_value(data => $aref, ccorr => 1, tails => 2, state => 'x'); # using given data (by-passing load and read)
Test the currently loaded data for significance of the vale of pot. Returns the zscore from test of pot deviation, or, called wanting an array, the z-value with its I

-value for the tails (1 or 2) given.
=cut
sub p_value {
return (z_value(@_))[1];
}
*test = \&p_value;
*pot_test = \&p_value;
*ptt = \&p_value;
=head2 stats_hash
$href = $pot->stats_hash(values => {observed => 1, expected => 1, variance => 1, z_value => 1, p_value => 1}, prob => .5, ccorr => 1);
Returns a hashref for the counts and stats as specified by hashref in its "values" argument, and with any options for calculating them. See L for details.
=head2 dump
$pot->dump(values => { observed => 1, variance => 1, p_value => 1}, exact => 1, flag => 1, precision_s => 3); # among other options
Print Pot-test results to STDOUT. See L in the Statistics::Sequences manpage for details.
=cut
sub dump {
my $self = shift;
my $args = ref $_[0] ? $_[0] : {@_};
$args->{'stat'} = 'pot';
$args->{'stat'} .= " ($args->{'state'})" if defined $args->{'state'};
$self->SUPER::dump($args);
#No. of bunches of state '$self->{'state'}' = " . $self->{'bunches'}->count() .
# ', with a mean length of '. sprintf('%.2f', $self->{'bunches'}->mean()) .
# ', and a mean spacing of '. sprintf('%.2f', $self->{'spaces'}->mean()) ." between each bunch.\n" if $self->{'bunches'};
# $args->{'title'} .= ' (Calculated with a range of ' . sprintf('%.2f', $self->{'range'}) . " over a scale of $self->{'scale'})";
}
sub _set_terms {
my $self = shift;
my $args = ref $_[0] ? $_[0] : {@_};
my $data = ref $args->{'data'} ? $args->{'data'} : $self->read($args);
my ($m, $n, $r, $scale, $state, $indices, $bunches, $spaces) = ();
$m = scalar(@{$data});
#$m = defined $args->{'trials'} ? $args->{'trials'} : scalar(@{$data});
#if (ref $args->{'indices'}) { # defunct by-pass from having data
# $n = scalar @{$args->{'indices'}};
# $indices = $args->{'indices'};
#}
#else {
$state = defined $args->{'state'} ? $args->{'state'} : croak __PACKAGE__, '::test A state for pot-testing is needed';
($indices, $bunches, $spaces) = _state_indices($data, $state, $m);
$n = scalar(@{$indices});
#}
$scale = (!$args->{'scale'} or $args->{'scale'} < 1) ? 1 : $args->{'scale'}; # assume scale = 1 if not specified or invalid
$r = _range($n, $m, $scale);
return ($m, $n, $r, $scale, $state, $indices, $bunches, $spaces);
}
sub _range { # init range parameter
my ($n, $m, $scale) = @_;
return exp(-$n / $m * $scale);
}
sub _state_indices {# Init an array holding the indices at which the state appears in the given data:
my ($data, $state, $m) = @_;
# Meanwhile, build arrays of bunch and space frequencies, should this be requested:
my ($i, $j, $k, @indices, @bunches, @spaces) = (0, 0, 0);
for ($i = 0; $i < $m; $i++) {
# Allow for matching numerical or string values:
if ($data->[$i] eq $state) {
$k++ if $spaces[$k];
$j++ if ( scalar @indices ) and ( $indices[-1] != ($i - 1) );
$bunches[$j]++;
push @indices, $i;
}
else {
$spaces[$k]++;
}
}
return (\@indices, \@bunches, \@spaces);
}
1;
__END__
=head1 EXAMPLE
Using Pot as a test of bunching of a particular state within a collection of quasi-random events.
use strict;
use Statistics::Sequences::Pot;
my ($i, @data) = ();
# Init random integers ranging from 0 to 15:
for ($i = 0; $i < 960; $i++) { $data[$i] = int(rand(16)); }
# Assess degree of bunching within these data with respect to a randomly selected target state:
my $state = int(rand(16));
my $pot = Statistics::Sequences::Pot->new();
$pot->load(\@data);
my %args = (state => $state, values => {p_value => 1, observed => 1, expected => 1, stdev => 1});
my $statsref = $pot->stats_hash(\%args);
# Access the results of this analysis:
print "The probability of obtaining as much bunching of $state as observed is $statsref->{'p_value'}.\n";
print "The observed value of Pot was $statsref->{'observed'}, with expected value $statsref->{'expected'} ($statsref->{'stdev'}).\n";
# or print the lot, and more, in English:
$pot->dump(%args, precision_s => 3, precision_p => 7,);
=head1 REFERENCES
Schmidt, H. (2000). A proposed measure for psi-induced bunching of randomly spaced events. I, I<64,> 301-316.
=head1 SEE ALSO
L for Schmidt's many papers on the physical conceptualisation and properties of psi.
L : The present module adds data to "Full" objects of this package in order to access descriptives re bunches and spaces.
L : the C method in this module could be informative when working with data of the kind used here.
=head1 BUGS/LIMITATIONS
No computational bugs as yet identfied. Hopefully this will change, given time.
Limitations of the code, perhaps, concern the non-unique storage of data arrays (compared to, say, C, but see C). This would require a unique name for each array of data, and explicit reference to one or another array with each L (when, perhaps, you'd have only one data-set, after all). In any case, the data are accepted as array references.
=head1 REVISION HISTORY
See CHANGES in installation dist for revisions.
=head1 AUTHOR/LICENSE
=over 4
=item Copyright (c) 2006-2013 Roderick Garton
rgarton AT cpan DOT org
This program is free software. It may be used, redistributed and/or modified under the same terms as Perl-5.6.1 (or later) (see L).
=item Disclaimer
To the maximum extent permitted by applicable law, the author of this module disclaims all warranties, either express or implied, including but not limited to implied warranties of merchantability and fitness for a particular purpose, with regard to the software and the accompanying documentation.
=back
=head1 END
This ends documentation of a Perl implementation of Helmut Schmidt's test of pot (potential energy) of occurrence of a state among others in a categorical sequence.
=cut