From: mike@... (Mike Stok) Date: 2003-08-12T20:23:31+09:00 Subject: Re: NaN and Infinity In article <86r83r5v8l.fsf@daemon.argelfraster.org>, Paul J. Sanchez wrote: >>>>>> "ST" == Scott Thompson writes: > > >>> If I do something like > >>> > >>> a = Math::log(-1) > >>> > >>> then a properly takes the value NaN. > >>> > >>> Is there any way to explicitly assign the variable "a" to NaN > >>> (or Inifinity or -Infinity) to begin with? I tried finding > >>> "NaN" as a constant but couldn't locate it. It doesn't appear > >>> to be a constant in Float or Math. > >> I don't understand what you mean by 'assign the variable "a" > >> to NaN'. > >> > >> NaNs and infinite values are best tested for using the nan? and > >> infinite? methods. Note that infinite? returns +1 or -1 for > >> positive and negative infinities and nil for finite numbers: > > ST> In the C library that I am trying to expose to Ruby there is a > ST> constant for a NULL rectangle. You would get a NULL > ST> rectangle, for example, if you asked for the intersection of > ST> two disjoint rectangles. The NULL rectangle is very different > ST> from the "zero rectangle" (a rectangle whose corner is at the > ST> origin and whose height and width are zero). > > ST> The NULL rectangle is implemented as a rectangle whose lower > ST> left corner is at (+Infinity, +Infinity) and whose height and > ST> width are both zero. > > ST> I wanted to make sure that if I exposed that constant to Ruby > ST> that it would behave as expected. As a result, I was trying > ST> to experiment with "irb" and I wanted to create an instance of > ST> my "Point" object whose x and y coordinates were +Infinity. I > ST> was looking to do something like: > > ST> apoint = CGPoint.new(Float::Infinity, Float::Infinity) > > ST> when I couldn't find Infinity I started looking for NaN as > ST> well. I found some sample code on the internet that showed > ST> how to generate a NaN result, but not how to initialize a > ST> float to NaN or +/-Infinity. > > ST> It seems, in some cases, it might be valuable to assign a > ST> float to "a value that is not a legal value" similar to the > ST> way one might assign a pointer to NULL in C, or even a object > ST> reference to nil in Ruby. But that may be just me :-) > >I wanted the same thing for a simple statistics class that used Kalman >filter-style updates instead of the more traditional (and prone to >numerical problems) sum of x, sum of x^2 based calculations. Like >you, I wanted to distinguish between the case where I had no data and >the case where I had zero for mean, variance, min, or max. I did the >following: > >class SimpleStats > attr_reader :n, :mean, :variance, :min, :max > > def initialize > reset > end > > def reset > @n = 0 > @variance = @mean = Math::log(-1) > @min = 1.0 / 0.0 > @max = -@min > end > > def newObs(x) > @max = x if x > @max > @min = x if x < @min > @n += 1 > if (@n > 1) > x -= @mean > @mean += x / @n > @variance = (@n - 2.0) / (@n - 1.0) * @variance + x * x / @n > else > @mean = x > @variance = 0.0 > end > end > > def stdDeviation > Math::sqrt @variance > end >end > > >Note that by initializing min and max to +/- Infinity, respectively, >the update stage for them doesn't need a special case for the first >time. If only the same were true of the mean and variance updates... > >If anyone has any suggestions for tightening this up, by the way, >they'd be appreciated! Does it make sense that s = SimpleStats.new s.max => Infinity nil seems more reasonable for a "no value" result. If you let @variance, @mean, @max and @min start out life as nil then def newObs(x) @max = [@max, x].max @min = [@min, x].min @n += 1 unless @mean # if @mean.nil? @mean, @variance = x, 0.0 else x -= @mean @mean += x / @n @variance = (@n - 2.0) / (@n - 1.0) * @variance + x * x / @n end end might be worth trying; Enumerable#max and Enumerable#min do the "right thing" with nil. Hope this helps, Mike -- mike@stok.co.uk | The "`Stok' disclaimers" apply. http://www.stok.co.uk/~mike/ | GPG PGP Key 1024D/059913DA mike@exegenix.com | Fingerprint 0570 71CD 6790 7C28 3D60 http://www.exegenix.com/ | 75D2 9EC4 C1C0 0599 13DA