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?

Hi –

On Wed, 22 Jul 2009, Ã„lphÃ¤ BlÃ¼Ã« wrote:

def product

@arr.inject {|a,b| a * b }

end

product, sum = 0.0, 0.0

arr.each do |a|

sum += a

product += a*a

end

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

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©

=> 38.7148740874228

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.

Hi –

On Wed, 22 Jul 2009, Ã„lphÃ¤ BlÃ¼Ã« wrote:

of complex issues all day long and so my mind is mush at this point. I

don’t quite follow…

The method is calculating “product” as the sum of the squares (which I

don’t actually think is the product, is it?). The class’s product

method is calculating the product of all the elements of the array. So

they’re different.

[1,2,3].inject {|a,b| a * b } # 6

total = 0.0

[1,2,3].each {|a| total += a * a }

total # 14.0

David

Hi –

On Wed, 22 Jul 2009, Ã„lphÃ¤ BlÃ¼Ã« wrote:

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.

OK, then the product method in the class is wrong. “Product” doesn’t

sound like the right name for a sum-of-the-squares calculation. But

anyway –

def whatever_you_call_it #

@arr.inject(0) {|acc,x| acc + x * x }

end

David

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©

=> 38.7148740874228 (correct)

So, compared to the class now, versus the method I created, do you see

any anomolies that would change this behavior?

Thanks so much David - that’s perfect…

Works great now as a class…

Hi –

On Wed, 22 Jul 2009, Ã„lphÃ¤ BlÃ¼Ã« wrote:

def sum

@arr.inject {|a,b| a + b }

end

@arr.inject(0.0) {|a,b| a + b }

which will give you a float error (which corresponds to what you have

in the method version).

So, compared to the class now, versus the method I created, do you see

any anomolies that would change this behavior?

See above

David