NaN from dear euclid

May 13, 2007 at 1:53pm

NaN from dear euclid

I’ve got a Euclidean distance method which looks right to me, but it’s giving me NaNs here and there…

public double euclideanDistance(double[] origin, double[] point)
{
double distance = 0;
double sum = 0;
for(int i=0;i < point.length;i++)
{
double diff = Math.abs(origin[i] – point[i]);
double pow = (double)Math.pow(diff, 2);
sum += pow;
}
distance = (double)Math.sqrt(sum);
post(“origin tension: ” +origin[0] +”, point tension: ” +point[0] +”, distance: ” +distance);
return distance;
}

I check that the double[]s are the same length *before* calling.

I’m wondering whether this is a precision or rounding problem with double…??? (As in, perhaps I need the mythical bigDecimal)
I’ve never used BigDecimal, so if somebody can clue me in, I’d appreciate it.

Or maybe I’m just doing something goofy that I’m not seeing?

J.

#31889
May 13, 2007 at 2:13pm

ugh…

So, I tried using BigDecimal with MathContext HALF_UP, and the line where the BigDecimal shows up gives a NumberFormatException: Infinite or NaN. Fair enough. It certainly seems to indicate that I’ve found the problem, but how do I track down the source? I just thought BigDecimal would deal with it…

J.

#104072
May 13, 2007 at 2:47pm

okay… sorry for the spam.

It’s not the euclideanDistance method. I was sending poor euclid a NaN somehow… tracking it down now. Not sure why it didn’t get detected earlier.

Apologies.

J.

#104073
May 13, 2007 at 6:05pm

On 13 mai 07, at 16:47, jbmaxwell wrote:

> okay… sorry for the spam.
>
> It’s not the euclideanDistance method. I was sending poor euclid a
> NaN somehow… tracking it down now. Not sure why it didn’t get
> detected earlier.

By the way, why do you use Math.abs? I’m quite sure your for loop can
be more efficient (no memory allocation either):

for(int i=0;i < point.length;i++)
{
sum += (double)Math.pow(origin[i] – point[i], 2);
}

Cheers,
ej

#104074
May 13, 2007 at 6:44pm

Quote: Emmanuel Jourdan wrote on Sun, 13 May 2007 19:05
—————————————————-
> On 13 mai 07, at 16:47, jbmaxwell wrote:
>
> > okay… sorry for the spam.
> >
> > It’s not the euclideanDistance method. I was sending poor euclid a
> > NaN somehow… tracking it down now. Not sure why it didn’t get
> > detected earlier.
>
> By the way, why do you use Math.abs? I’m quite sure your for loop can
> be more efficient (no memory allocation either):
>
> for(int i=0;i < point.length;i++)
> {
> sum += (double)Math.pow(origin[i] – point[i], 2);
> }
>
> Cheers,
> ej
>

oops! Yeah, the Math.abs() wasn’t in there originally, but I was freaking out thinking maybe a sqrt() on a negative value was causing my NaN… I’ll rip that out again.

thanks!

J.

#104075
May 13, 2007 at 6:51pm

Actually, ej, this brings up a general efficiency question I’ve had. Is it actually more efficient to roll multiple lines into one, like you did with my code? I’ve never really been sure about that. I mean, it looks more “compact” on the page, but does it matter once the class is compiled?

thanks,

J.

#104076
May 13, 2007 at 7:16pm

#104077
May 15, 2007 at 7:21pm

#104078
May 16, 2007 at 6:19am

>
> ps. I would use a*a instead of Math.pow(a,2) :)
>

Right, got it. Good point! Not much need to load up a whole new class for a^2. I guess pow() is handy when it’s a^25 or something.

cheers,

J.

#104079
May 16, 2007 at 5:02pm

> Right, got it. Good point! Not much need to load up a whole new class for a^2. I guess pow() is handy when it’s a^25 or something.

Yes. Or even better, when the exponent value is also a variable. :)

#104080

You must be logged in to reply to this topic.