Forums > Java

NaN from dear euclid


jbm
May 13, 2007 | 1:53 pm

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.



jbm
May 13, 2007 | 2:13 pm

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.



jbm
May 13, 2007 | 2:47 pm

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.


May 13, 2007 | 6:05 pm

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



jbm
May 13, 2007 | 6:44 pm

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.



jbm
May 13, 2007 | 6:51 pm

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.


May 13, 2007 | 7:16 pm


May 15, 2007 | 7:21 pm



jbm
May 16, 2007 | 6:19 am

>
> 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.


May 16, 2007 | 5:02 pm

> 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. :)


Viewing 10 posts - 1 through 10 (of 10 total)