Standard Deviation question regarding EDOM errors

  • Thread starter Älphä Blüë
  • Start date
Ã

Älphä Blüë

Okay,

Take a very close look at the two (one is a class, the other is a
method):

class Stdev
def initialize(arr)
@arr = arr
@size = @arr.to_a.size
end

def sum
@arr.inject {|a,b| a + b }
end

def product
@arr.inject {|a,b| a * b }
end

def calculate
Math.sqrt(((product - (sum * sum)/@size)/(@size-1)))
end

end

def stddev(arr)
size = arr.to_a.size
product, sum = 0.0, 0.0
arr.each do |a|
sum += a
product += a*a
end
std = Math.sqrt(((product - (sum * sum)/size)/(size-1)))
return std
end

Testing with both:

a = [123.369, 68.6179]

Stdev.new(a).calculate
=> Errno::EDOM: Domain error - sqrt

stddev(a)
=> 38.7148740874228

Test a web calculator for the same thing:

http://www.easycalculation.com/statistics/standard-deviation.php

The method will pan out.

So, to save suspense the reason why the class is erroring out is because
the sqrt is being attempted on a negative number. Therefore, in order
to continue to use that I would have to require 'complex' and the return
values from complex return two values in an array.

I'm just curious, why, given both of these being so very similar - the
method passes but the class fails?
 
Ã

Älphä Blüë

The logic in the second snippet is wrong (assuming the logic in the
product method is what you want). Try it with [1,2], for example, and
you'll get 2 for the first one and 5 for the second.


David

Hi David,

Please bear with me as my brain is a bit fried - been working on a lot
of complex issues all day long and so my mind is mush at this point. I
don't quite follow..

The method produces correct standard deviation results everytime..

a = [1,2,3,4,5]
b = [1,2]
c = [123.369, 68.6179]

stddev(a)
=> 1.58113883008419

stddev(b)
=> 0.707106781186548

stddev(c)
=> 38.7148740874228
 
Ã

Älphä Blüë

Hi David,

I think I understand what you are saying..

What I want with..

product += a*a


is .. a[0]*a[0]+a[1]*a[1]+a[2]*a[2]..etc.
 
Ã

Älphä Blüë

Hi David,

Thanks for showing me my error. So, I implemented a change in the class
for testing purposes:

class Stdev
def initialize(arr)
@arr = arr
@size = @arr.to_a.size
end

def sum
@arr.inject {|a,b| a + b }
end


def product
total = 0.0
@arr.each {|a| total += a * a }
total
end

def calculate
Math.sqrt(((product - (sum * sum)/@size)/(@size-1)))
end

end

Running the same test with the same things:

a = [1,2,3,4,5]
b = [1,2]
c = [123.369, 68.6179]

stddev(a)
=> 1.58113883008419 (correct)

stddev(b)
=> 1.0 (NOT expected)

stddev(c)
=> 38.7148740874228 (correct)

So, compared to the class now, versus the method I created, do you see
any anomolies that would change this behavior?
 
Ã

Älphä Blüë

Thanks so much David - that's perfect..

Works great now as a class...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top