Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimized get(colorscheme, data) function #91

Closed
stevengj opened this issue Apr 19, 2022 · 1 comment
Closed

optimized get(colorscheme, data) function #91

stevengj opened this issue Apr 19, 2022 · 1 comment

Comments

@stevengj
Copy link

stevengj commented Apr 19, 2022

In the course of this discussion on the fastest way to display large matrices as images, I noticed that the get(colorscheme, data) function is not as fast as it could be, and allocates a lot of large temporary arrays (the same size as the image).

The following function seems to be more than 2x faster, and allocates 5x less memory (it only allocates the output image):

import ColorSchemes: AllowedInput, defaultrange
import ColorVectorSpace, Colors

# faster weighted_color_mean that assumes w ∈ [0,1] and
# exploits ColorVectorSpace operations for RGB and Gray types.
fast_weighted_color_mean(w::Real, c1, c2) = Colors.weighted_color_mean(w, c1, c2)
fast_weighted_color_mean(w::Real, c1::ColorVectorSpace.MathTypes, c2::ColorVectorSpace.MathTypes) = w*c1 + (1-w)*c2

function myget(cscheme::ColorScheme, X::AllowedInput, rangescale::NTuple{2,<:Real}=defaultrange(x))
    rangemin, rangemax = !iszero(rangescale[2] - rangescale[1]) ?
        rangescale : (zero(rangescale[1]), oneunit(rangescale[2]))
    scaleby = (length(cscheme) - 1) / (rangemax - rangemin)
    return map(X) do x
        xclamp = clamp(x, rangemin, rangemax)
        before_fp = (xclamp - rangemin) * scaleby + 1
        before = round(Int, before_fp, RoundDown)
        after =  min(before + 1, length(cscheme))
        cpt = before_fp - before
        #  blend between the two colors adjacent to the point
        @inbounds fast_weighted_color_mean(cpt, cscheme.colors[before], cscheme.colors[after])
    end
end

It adds a dependency on ColorVectorSpace.jl, but that's pretty lightweight (and is pulled in by things like Images.jl anyway).

@cormullion
Copy link
Member

This is great, thanks. There's a bit of "journeyman" code in this package that would benefit from modernization.

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

No branches or pull requests

2 participants