Here is an example used for computing correlations.
It’s almost a direct translation of several hundred
lines of Fortran 77.
If you can bare to look, please help, even it is simply
to say “yo bonehead, why didn’t you just require ‘some_library’?”
Thanks,
Bil
cat << EOF > correlation_test.rb
require ‘test/unit’
require ‘correlation’
class TestCorrelation < Test::Unit::TestCase
def test_1x1_perfectly_correlated
x = [ [0,1] ]
y = [ [0,1] ]
c, c2 = correlation(x,y)
assert_equal( [ [ 1.0 ] ], c )
assert_equal( [ [ 1.0 ] ], c2 )
end
def test_1x1_perfectly_anti_correlated
x = [ [0,1] ]
y = [ [1,0] ]
c, c2 = correlation(x,y)
assert_equal( [ [ -1.0 ] ], c )
assert_equal( [ [ 1.0 ] ], c2 )
end
def test_1x1_perfectly_uncorrelated
x = [ [0,1] ]
y = [ [0,0] ]
c, c2 = correlation(x,y)
assert_equal( [ [ 0.0 ] ], c )
assert_equal( [ [ 0.0 ] ], c2 )
end
def test_2x1_perfectly_correlated
x = [ [0,1], [0,1] ]
y = [ [0,1] ]
c, c2 = correlation(x,y)
assert_equal( [ [ 1.0 ], [ 1.0 ] ], c )
assert_equal( [ [ 0.5 ], [ 0.5 ] ], c2 )
end
def test_2x1_perfectly_correlated_and_uncorrelated
x = [ [0,1], [0,0] ]
y = [ [0,1] ]
c, c2 = correlation(x,y)
assert_equal( [ [ 1.0 ], [ 0.0 ] ], c )
assert_equal( [ [ 1.0 ], [ 0.0 ] ], c2 )
end
def test_1x2_perfectly_anti_correlated
x = [ [0,1] ]
y = [ [1,0], [1,0] ]
c, c2 = correlation(x,y)
assert_equal( [ [ -1.0, -1.0 ] ], c )
assert_equal( [ [ 1.0, 1.0 ] ], c2 )
end
def test_1x2_perfectly_correlated_and_uncorrelated
x = [ [0,1] ]
y = [ [0,1], [0,0] ]
c, c2 = correlation(x,y)
assert_equal( [ [ 1.0, 0.0 ] ], c )
assert_equal( [ [ 1.0, 0.0 ] ], c2 )
end
end
EOF
cat << EOF > correlation.rb
Returns an array with correlation and y-normalized correlation^2
Assumes two nested arrays of variables and samples. For example,
here’s a case with 3 samples of 3 input variables and 2 output
variables:
x = [ [a1,a2,a3], [b1,b2,b3], [c1,c2,c3] ]
y = [ [r1,r2,r3], [s1,s2,s3] ]
def correlation(x,y)
fail ‘size arrays unequal’ if x.first.size != y.first.size # lame
n = x.first.size
sum_x = Array.new(x.size){0.0}
sum_x_sq = Array.new(x.size){0.0}
for i in 0…x.size-1
sum_x[i] = x[i].inject(0) { |sum, e| sum + e }
sum_x_sq[i] = x[i].inject(0) { |sum, e| sum + e**2 }
end
sum_y = Array.new(y.size){0.0}
sum_y_sq = Array.new(y.size){0.0}
for i in 0…y.size-1
sum_y[i] = y[i].inject(0) { |sum, e| sum + e }
sum_y_sq[i] = y[i].inject(0) { |sum, e| sum + e**2 }
end
sum_xy = Array.new(x.size){ Array.new(y.size){0.0} }
for k in 0…n-1
for i in 0…x.size-1
for j in 0…y.size-1
sum_xy[i][j] += x[i][k]*y[j][k]
end
end
end
corr = Array.new(x.size){ Array.new(y.size){0.0} }
for i in 0…x.size-1
for j in 0…y.size-1
dx = nsum_x_sq[i] - sum_x[i]**2
dy = nsum_y_sq[j] - sum_y[j]**2
corr[i][j] = ( nsum_xy[i][j] - sum_x[i]sum_y[j] ) /
Math.sqrt(dxdy)
unless dxdy==0.0
end
end
sum_corr_sq_y = Array.new(y.size){0.0}
for j in 0…y.size-1
for i in 0…x.size-1
sum_corr_sq_y[j] += corr[i][j]**2
end
end
corr_sq = Array.new(x.size){ Array.new(y.size){0.0} }
for i in 0…x.size-1
for j in 0…y.size-1
corr_sq[i][j] = corr[i][j]**2/sum_corr_sq_y[j]
unless sum_corr_sq_y[j]==0.0
end
end
[corr, corr_sq]
end
EOF