Opened 14 years ago

Closed 12 years ago

## #192 closed enhancement (fixed)

# kNNI and WeNNI has hard coded small numbers, change to something standardized.

Reported by: | Jari Häkkinen | Owned by: | Jari Häkkinen |
---|---|---|---|

Priority: | minor | Milestone: | yat 0.5 |

Component: | utility | Version: | trunk |

Keywords: | Cc: |

### Description

source:trunk/yat/utility/kNNI.cc at approximately line 73:

double d=(distance[*k].second ? distance[*k].second : 1e-10);

and source:trunk/yat/utility/WeNNI.cc at approximately line 66:

double d=(distance[*k].second ? distance[*k].second : 1e-10);

### Change History (6)

### comment:1 Changed 14 years ago by

Milestone: | 0.3 (Public release) → later |
---|

### comment:2 Changed 13 years ago by

### comment:3 Changed 13 years ago by

Well, if we look at how d in WeNNi for example

... // Avoid division with zero (perfect match vectors) double d=(distance[*k].second ? distance[*k].second : 1e-10); new_value+=(weight_(distance[*k].first,j) * data_(distance[*k].first,j)/d); norm+=weight_(distance[*k].first,j)/d; } // No impute if no contributions from neighbours. if (norm){ imputed_data_raw_(i,j) = new_value/norm; new_value+=(weight_(distance[*k].first,j) * data_(distance[*k].first,j)/d); norm+=weight_(distance[*k].first,j)/d; ...

we see that d is set to a small number to avoid division by zero. So we want `d`

to be small but not too small because then "`new_value/norm`

" will result in *Inf divided by Inf* or worse if only one of `norm`

and `new_value`

becomes `Inf`

. How can we avoid that? std::numeric_limits<double>::epsilon() does not really do the work here. Because epsilon is defined as the difference between `1.0`

and next represented number. In other words, what epsilon is the smallest number you can add to `1.0`

without getting back `1.0`

. I can't see the connection to when you wanna divide by a small number and avoid hitting the ceiling. I'm not an expert in floating point representation, but the latter must depend on your range in exponent wehereas the epsilon tells you about precision in the Mantissa (?).

### comment:4 Changed 12 years ago by

Milestone: | yat 0.x+ → yat 0.5 |
---|---|

Status: | new → assigned |

### comment:5 Changed 12 years ago by

Reading through http://www.bnikolic.co.uk/blog/cpp-rr-epsilon.html I think we should use Markus suggestion of std::numeric_limits<double>::epsilon(). The number is small enough to not matter too much but large enough to avoid infinities.

### comment:6 Changed 12 years ago by

Resolution: | → fixed |
---|---|

Status: | assigned → closed |

**Note:**See TracTickets for help on using tickets.

`std::numeric_limits<double>::epsilon()`

should perhaps be used?