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 = n*sum_x_sq[i] - sum_x[i]**2
dy = n*sum_y_sq[j] - sum_y[j]**2

corr[i][j] = ( n

*sum_xy[i][j] - sum_x[i]*

unless dxdy==0.0

*sum_y[j] ) /*

Math.sqrt(dxdy)Math.sqrt(dx

unless dx

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