Don't convert vmin, vmax to floats. #6700

Merged
merged 2 commits into from Jul 12, 2016

Conversation

Projects
None yet
6 participants
Contributor

anntzer commented Jul 6, 2016

They may be float128's in which case precision would be lost; this can
result in Normalize returning values (barely) outside of [0, 1].

(The cast to float was introduced in 28e1d2, referring to bug 2997687
on SF; it may be worth checking what it was about.)

See #6698.

mdboom added the needs_review label Jul 6, 2016

Owner

efiring commented Jul 6, 2016

I suspect it would make more sense to just convert the float128 input to float64 at an early stage. The conversion will occur sooner or later anyway; we have no mechanism for maintaining float128 throughout the pipeline, and that level of precision makes no sense for plotting anyway.

Member

WeatherGod commented Jul 6, 2016

Eventually, everything needs to become float-like. The purpose of casting
to float was most likely to avoid integer division. Unfortunately, the
issue tracker is no longer up on sourceforge, so it is going to be hard to
find out what that particular issue was.

On Wed, Jul 6, 2016 at 3:34 PM, Antony Lee notifications@github.com wrote:

They may be float128's in which case precision would be lost; this can
result in Normalize returning values (barely) outside of [0, 1].

(The cast to float was introduced in 28e1d2, referring to bug 2997687
on SF; it may be worth checking what it was about.)

See #6698 #6698.

You can view, comment on, or merge this pull request online at:

#6700
Commit Summary

  • Don't convert vmin, vmax to floats.

File Changes

Patch Links:


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#6700, or mute the thread
https://github.com/notifications/unsubscribe/AARy-KbEYAVFrGM6K78a6IvYiNORYcJIks5qTANWgaJpZM4JGbL8
.

Contributor

anntzer commented Jul 6, 2016 edited

See also #6677 for @efiring's suggestion (which I agree with -- similar bugs with handling float128's probably occur at a bunch of other places). However I'd rather keep this simple solution for now and have a separate discussion for making the switch to float64 (or even float32, which is certainly enough for plotting purposes) everywhere at the same time.

PS: The failure on Travis seems spurious.

Owner

tacaswell commented Jul 7, 2016

There is no float128 on windows?

tacaswell added this to the 2.1 (next point release) milestone Jul 7, 2016

@anntzer anntzer Don't convert vmin, vmax to floats.
They may be float128's in which case precision would be lost; this can
result in `Normalize` returning values (barely) outside of `[0, 1]`.

(The cast to `float` was introduced in 28e1d2, referring to bug 2997687
on SF; it may be worth checking what it was about.)
16f9778
Contributor

anntzer commented Jul 7, 2016

Apparently not... https://mail.scipy.org/pipermail/scipy-dev/2008-March/008562.html
A quick test tells me that longdouble is float64 on Windows. Still, that seems good enough for the tests. Updated.

Owner

tacaswell commented Jul 7, 2016

It looks like the single value branch of the process_value method needs the same sort of logic as the array branch. I think it will currently cast a single float128 to a possibly shorter float leading to the same issue.

Contributor

anntzer commented Jul 7, 2016

Actually both branches probably need it, right?
I think we should cast result to np.promote_types(result.dtype, np.float32) (i.e. at least float32 but not smaller than the actual size).

Owner

tacaswell commented Jul 7, 2016

The array branch only casts to it if it is not a float type, otherwise we just copy.

Contributor

anntzer commented Jul 7, 2016

I see. I guess the whole process_value method could be simplified to

def process_value(value):
    is_scalar = not cbook.iterable(value)
    if is_scalar:
        value = [value]
    dtype = np.min_scalar_type(value)
    dtype = (np.float32 if dtype.itemsize <= 2
             else np.promote_types(dtype, float))
    result = np.ma.array(value, dtype=dtype, copy=True)
    return result, is_scalar

right?

Owner

tacaswell commented Jul 8, 2016

Yes, I think so.

@anntzer anntzer Proper norm'ing of float128 scalars too.
ff78a06
Contributor

anntzer commented Jul 8, 2016

done.

Owner

tacaswell commented Jul 8, 2016

👍 LGTM pending appveyor

Contributor

anntzer commented Jul 9, 2016

Appveyor failure seems spurious?
Also, note that the parent issue (#6698) is milestoned to 2.0 (and this bug was revealed by #6382, which is also in 2.0).

Owner

jenshnielsen commented Jul 11, 2016

Regarding float128 it's not actually 128 bytes but a long double which is padded to 128 bits http://docs.scipy.org/doc/numpy-dev/user/basics.types.html

On Linux and OSX long doubles are normally 80 bits but on windows (MSVC) they are equivalent to doubles. They may have more precision on other less common platforms.

@tacaswell tacaswell merged commit 0346f1a into matplotlib:master Jul 12, 2016

2 of 3 checks passed

continuous-integration/appveyor/pr AppVeyor build failed
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
coverage/coveralls Coverage increased (+0.002%) to 70.275%
Details

tacaswell removed the needs_review label Jul 12, 2016

anntzer deleted the anntzer:dont-cast-normalize-limits-to-float branch Jul 12, 2016

@tacaswell tacaswell added a commit that referenced this pull request Jul 12, 2016

@tacaswell tacaswell Merge pull request #6700 from anntzer/dont-cast-normalize-limits-to-f…
…loat

FIX: Don't convert vmin, vmax to floats in norm

Conflicts:
	lib/matplotlib/colors.py
	   Kept version from master.  Conflicts due to maskedarray
	   name normalization.
c7d7d19
Owner

tacaswell commented Jul 12, 2016

backported to v2.x as c7d7d19

Contributor

anntzer commented Jul 25, 2016

@efiring @WeatherGod @tacaswell
Following the discussion in #6825 I will probably need to revert that PR for a more comprehensive solution instead, which is unlikely to be ready by 2.0 (any timeline btw?). However, we still need a fix for #6698 for 2.0. I think we can probably get away with giving a bit of tolerance to the 0-1 range (i.e. clip values between -1e-8 and 0 to 0 and values between 1 and 1+1e-8 to 1). Thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment