<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
I'm trying to use Statistics::Basic to calculate basic statistics
like correlations. These functions return objects which are supposed
to magically become numbers as needed, <a
href="https://metacpan.org/pod/distribution/Statistics-Basic/lib/Statistics/Basic.pod">https://metacpan.org/pod/distribution/Statistics-Basic/lib/Statistics/Basic.pod</a>:<br>
<blockquote type="cite">These actually return objects, not numbers.
The objects will interpolate as nicely formated numbers (using
Number::Format). Or the actual number will be returned when the
object is used as a number.</blockquote>
<br>
But I have a situation where the magic fails. When one (or both)
vector has no variance, the correlation should be zero but the value
of the object is neither defined, nor undefined, it's uninitialized.
<br>
<br>
The code is below, here's the output that's driving me crazy. The
0.00 is correct, but the warnings are annoying:<br>
<br>
$ ./corr.pl<br>
1,0.426<br>
Use of uninitialized value in printf at ./corr.pl line 20.<br>
2,0.000<br>
Use of uninitialized value in addition (+) at ./corr.pl line 25.<br>
3,0.000<br>
<br>
Surely there's a way to force an object to be reduced into a scalar
float (as opposed to just hiding the warnings)?<br>
<br>
I've tried the following: <br>
<ul>
<li>using scalar() (does nothing); <br>
</li>
<li>adding 0 and 0.0 (just moves where the same error is
reported); <br>
</li>
<li>dereferencing the object and trying to force a scalar with
scalar references: "${ $corr }" and "${ $correlation( \@v1, \@v2
) }" (these are all: Not a SCALAR reference);</li>
<li>checking if $corr is defined (it is, it's a defined object);
and <br>
</li>
<li>adding ' || 0' to the end of the definition (does nothing). </li>
</ul>
I can solve the issue with this:<br>
<br>
$corr = ( defined correlation( \@v1, \@v2 ) ? correlation( \@v1,
\@v2 ) : 0 );<br>
<br>
but then I'm forced to compute the correlation twice, which seems
like a pretty poor solution. <br>
<br>
You might argue that corr = cov / ( sd1 sd2 ) and therefore that
corr is undefined when sd1 or sd2 are zero, but in this case cov = 0
(by definition) and it's really unhelpful to me for this function to
return an non-value, particularly because this issue would only
arise occasionally leading to potentially difficult bugs.<br>
<br>
What I need is a way to force the object to collapse into a scalar
value and assign that value to a variable. Any thoughts?<br>
<br>
-Alan<br>
<br>
<br>
#!/usr/bin/perl<br>
<br>
use strict;<br>
use warnings;<br>
<br>
use Data::Dumper;<br>
use Statistics::Basic qw(:all);<br>
<br>
my @v1 = ( 1, 2, 2, 3 );<br>
my @v2 = ( 1, 0, 2, 2 );<br>
<br>
# good data; everything's ok<br>
my $corr = correlation( \@v1, \@v2 );<br>
printf "%d,%.3f\n", 1, $corr;<br>
<br>
# correlation is zero because v2 has no variance<br>
# Use of uninitialized value in printf at ./corr.pl line 20.<br>
@v2 = ( 1, 1, 1, 1 );<br>
$corr = correlation( \@v1, \@v2 );<br>
printf "%d,%.3f\n", 2, $corr;<br>
#print Dumper( $corr ), "\n";<br>
<br>
# v2 still has no variance<br>
# Use of uninitialized value in addition (+) at ./corr.pl line 25.<br>
$corr = 0 + scalar( correlation( \@v1, \@v2 ) );<br>
printf "%d,%.3f\n", 3, $corr;<br>
#print Dumper( $corr ), "\n";<br>
<br>
<pre class="moz-signature" cols="72">--
Alan D. Mead, Ph.D.
President, Talent Algorithms Inc.
science + technology = better workers
<a class="moz-txt-link-freetext" href="http://www.alanmead.org">http://www.alanmead.org</a>
Acton's dictate: Power tends to corrupt, and absolute power corrupts
absolutely. Great men are almost always bad men, even when they exercise
influence and not authority.
</pre>
</body>
</html>