Setting floating point variable as infinite

Discussion in 'C++' started by Rui Maciel, Mar 23, 2012.

  1. Rui Maciel

    Rui Maciel Guest

    Consider a data set whose elements can be mapped to a particular floating
    point number. In order to determine the smallest floating point number
    computed from each element from the set, is it a good idea to initialize a
    temporary float as infinite, compare the temporary float with the value
    mapped from each data element and then update the temporary if the mapped
    value is smaller?

    More importantly, is there a better way to do this?


    Thanks in advance,
    Rui Maciel
     
    Rui Maciel, Mar 23, 2012
    #1
    1. Advertisements

  2. Rui Maciel

    Marc Guest

    It's a very common way to do it.
    You can use the first element of your data set to initialize the minimum
    and only start the loop from the second element. In some cases that can
    be inconvenient to do.
     
    Marc, Mar 23, 2012
    #2
    1. Advertisements

  3. Specifically, it fails in the case that the data set length is zero.

    -- glen
     
    glen herrmannsfeldt, Mar 23, 2012
    #3
  4. Rui Maciel

    gwowen Guest

    It only fails if you think you know what the right answer for the
    minimum value of an empty set is.
     
    gwowen, Mar 23, 2012
    #4
  5. I assume you mean "whose elements can be mapped to floating point
    numbers (each element to its own particular FP number)".
    The usual way to find the minimum is to initialize the value from the
    first element, and then start comparing from the second element. An
    empty set is a special case for which the calculation of the "minimum"
    should just throw an exception. A set of one element is also a special
    case: there is no need to compare anything. Two elements *could* be
    made into a special case by use of std::min.

    As for infinity (unrelated to searching through a set of numbers), there
    is 'std::numeric_limits<double>::infinity()', which you could call if
    'std::numeric_limits<double>::has_infinity' is 'true'.

    V
     
    Victor Bazarov, Mar 23, 2012
    #5
  6. Rui Maciel

    Rui Maciel Guest

    Conversely, initializing a FP value as infinity may also bring unwanted
    consequences. After all, if the data set length is zero then the minimum
    value is set as infinity.


    Rui Maciel
     
    Rui Maciel, Mar 23, 2012
    #6
  7. Rui Maciel

    Rui Maciel Guest

    I was hoping to use a single loop. Relying on a separate initialization
    block feels a bit like a crude-ish hack.

    Yes, I was using that, and according to the standard
    std::numeric_limits<T>::has_infinity is true for T = float and double, so no
    test is necessary. The only problem I have with it is that it doesn't feel
    quite right to handle infinity values like this. At least I never saw this
    being done anywhere else.


    Rui Maciel
     
    Rui Maciel, Mar 23, 2012
    #7
  8. Are you concerned with less typing, and not with implementing it
    correctly *logically*? Do you consider "a single loop" better or more
    efficient in some way?
    "Crude-ish"? Really? <shrug> Using an infinity value in that manner is
    crudish, IMNSHO. It suggests that (a) infinity is not a valid value for
    any set element to be associated with (which might be true in your
    model, but doesn't necessarily sound right in all cases), and (b) that
    the maximum value from the elements of an empty set is infinity, which
    is a number (if you divide by it, you get 0). I'd probably use NaN for
    that, although by definition of "seeking a maximum associated floating
    point number" should *not* be allowed for an empty set, such search
    shouldn't return a value.
    <another shrug> I have. But it's still not right. You can use any
    other designated value that can never be found in your set. And if you
    don't have any identifiable value to use, don't. Use *logic*.
    Essentially you're trying to have a mapping of yourtype values to
    double/float values without

    std::map<double, yourtype const*> yourmap;

    .. And you're trying to figure out a hack to get
    (*yourmap.rbegin()).first without checking whether the 'yourmap' is
    empty or not. <third shrug>

    V
     
    Victor Bazarov, Mar 23, 2012
    #8
  9. Rui Maciel

    Rui Maciel Guest

    You either failed to understand what I wrote or you are intentionally trying
    to misrepresenting what I said. No one claimed that it is better to use
    code which is logically incorrect if it provides a way to save on typing. I
    don't know where you came up with that nonsense.

    What happened to logical correctness? And do you also believe that, if the
    objective was to get the largest non-negative number, initializing it to
    zero or even any negative number would also be crudish?

    Zero is also not valid in a considerable number of cases, and yet variables
    are still set by default as zero.

    As a side note, and nit-picking a bit, this isn't true. Infinity isn't a
    number, and k/infinity is meaningless. The k/infinity = 0 is only valid
    because it was a specific indeterminate form which is often defined as
    lim{x->infinity} k/x.

    Similarly, division by zero has also been defined as k/0 = infinity, but
    this doesn't mean it's a good idea to hold this as true. For a start, this
    would mean that infinity*0 = k.

    Why is it "not right"? Is there actually a valid technical reason behind
    your assertion?

    Again, you either failed to understand what I wrote or you are intentionally
    trying to misrepresent what I said. No one claimed that the set in question
    could be empty, and somehow you felt the need to attribute that claim, which
    you invented, to someone else.

    So, to avoid any more misconceptions or any attempts to misrepresent
    anything, here is a clear description of this case.

    - there is a non-empty set of data.
    - there is a set of operators which map each element of that set to a
    floating point number.
    - the objective is to evaluate which is the minimum value of the codomain of
    a particular operator.

    I suggested the following approach:

    <pseudo-ish code>

    float minimum = std::numeric_limits<float>::infinity();
    for(auto element: element_list)
    {
    if( operator(element) < minimum)
    minimum = operator(element);
    }

    </pseudo-ish code>

    Then, I asked if it was a good idea to do this. In other words, if there
    was any reason that would made it a bad idea. Until now, no reason has been
    given.

    I also asked if there was a better way to get the minimum value.

    Simple as that.


    Rui Maciel
     
    Rui Maciel, Mar 23, 2012
    #9
  10. (snip, I wrote)
    The Fortran MINVAL intrinsic function returns the minimum value of
    the elements of an array. As Fortran (now) allows arrays dimensioned
    zero, it has to allow for that case.

    For arrays with no elements, it returns the largest representable
    value, which I believe even for IEEE implementations is not
    the IEEE Infinity value. Most likely, the value returned by
    the HUGE intrinsic function.

    -- glen
     
    glen herrmannsfeldt, Mar 23, 2012
    #10
  11. Failed? Maybe. Intentionally? You know what, if you're having a bad
    day, why are you trying to blame me for that? Snap at somebody who
    actually gives a damn.
    Why would a solution that works be a bad idea? Since you didn't state
    the complexity of your 'operator', we could presume that it's expensive.
    Then the only concern is efficiency.

    The pseudo code has two inefficiencies. First, it initializes 'minimum'
    to some value, and immediately overrides it with the
    'operator(element#0)'. Second inefficiency is that it evaluates the
    'operator' for each element twice.

    Simple as that.
    Don't evaluate twice and initialize from the first element, and skip the
    first element while doing the loop.
    If you need algorithm advice, consider asking in 'comp.programming'.

    V
     
    Victor Bazarov, Mar 23, 2012
    #11
  12. Rui Maciel

    Miles Bader Guest

    Wait, what?

    It still works fine if some set element has a value of infinity...
    (if that's the _only_ set element, then infinity is indeed the minimum;
    if there is some smaller element, then the smaller element will win)

    -Miles
     
    Miles Bader, Mar 24, 2012
    #12
  13. Yes, but if infinity is allowed to be associated, and there are no
    elements in the set?

    V
     
    Victor Bazarov, Mar 24, 2012
    #13
  14. Rui Maciel

    Rui Maciel Guest

    <pseudo-ish code>

    float minimum = std::numeric_limits<float>::infinity();
    for(auto element: element_list)
    {
    if( operator(element) < minimum)
    minimum = operator(element);
    }

    if(minimum == std::numeric_limits<float>::infinity() )
    {
    throw something;
    }

    </pseudo-ish code>


    Rui Maciel
     
    Rui Maciel, Mar 24, 2012
    #14
  15. Rui Maciel

    Rui Maciel Guest

    If you express disdain towards others you shouldn't be surprized that people
    don't react kindly to that.


    The complexity of any hypothetical operator is irrelevant to this
    discussion. If you read the thread, or even just the subject, you will
    realize that the issue under discussion refers to the use of infinite values
    in a particular floating point operation.

    I believe we can agree that discussing the perceived efficiency of a pseudo-
    code snippet is silly, particularly when the perceived inefficiency boils
    down to a single floating point assignment executed only once at the start
    of a iteration through an undetermined number of elements in a set.

    I was aware of that when I wrote the pseudo-code, but, again, it is pseudo-
    code and nothing more than that, and has nothing to do with the topic of
    this discussion, which is the reliance of infinite values in floating point
    operations.

    Too bad it doesn't have anything to do with the topic being discussed.


    Rui Maciel
     
    Rui Maciel, Mar 24, 2012
    #15
  16. On 03/23/12 15:32, Victor Bazarov wrote:

    Leaving aside any matter about correctness, logic, and so on in case the
    set has zero elements...


    I usually use std::numeric_limits<double>::max() in such cases.
    Anything wrong with this?
    Any unobvious disadvantage or potential trouble?

    bye & Thanks
    av.
     
    Andrea Venturoli, Mar 24, 2012
    #16
  17. Rui Maciel

    Miles Bader Guest

    With some algorithms (calling the min function), it doesn't matter,
    and it's fine to just return infinity for either case.

    If it's desirable to distinguish the "empty container" case, then just
    test for it first -- it's usually cheap and straight-forward to test a
    container for emptiness -- and handle empty containers that way.
    Note you'd have to do the _same thing_ for the method you advocated.

    -miles
     
    Miles Bader, Mar 24, 2012
    #17
  18. If you aren't going to use that value in such a way that can cause
    overflow or underflow after you've obtained it, there is no harm. Any
    designated value, be it the infinity or the max, should be OK as long as
    you watch what you do with it afterwards, IME.

    V
     
    Victor Bazarov, Mar 24, 2012
    #18
  19. Rui Maciel

    Rui Maciel Guest

    Considering that the values being compared aren't stored and, instead, are
    calculated by an operator which is called for this specific purpose, doesn't
    std::min_element require more than n calls to that operator, n being
    container::size() ?

    Another inconvenience is that std::min_element only returns an iterator
    pointing to the element which relates to the smallest value. If the
    objective is to determine that particular value then using std::min_element
    requires an extra call to that operator.

    Meanwhile, the method which has been presented and relies on
    std::numeric_limits<float>::infinity() only requires n calls to the
    operator, and in the end the smallest value is already provided.


    Rui Maciel
     
    Rui Maciel, Mar 25, 2012
    #19
  20. Rui Maciel

    Rui Maciel Guest

    At this moment I can't say, but I suspect that it will be expensive. The
    operator which maps each element to a float is defined through a strategy
    pattern, and currently I don't have any way to know which strategies will be
    implemented.


    Rui Maciel
     
    Rui Maciel, Mar 25, 2012
    #20
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.