The only issue in merging these seems to be the use of floor and ceil vs.
ifloor and iceil.  One possiblilty would be to replace those two calls
with oftype(T,
floor(log10(bw)) and oftype(T, ceil(lo/step)-1), respectively.

A perhaps better change would be to create versions of ceil and floor (and
other such functions) which take a type as the first parameter and dispatch
to ceil/floor or iceil/ifloor accordingly.

Cheers,
    Kevin



On Thu, Dec 26, 2013 at 4:47 AM, Michael Fox <415...@gmail.com> wrote:

> It's kind of painful to see codes repeating themselves like this. Here's
> one I just ran across in `statistics.jl`. Is there something about the type
> or dispatch system that encourages or even requires such repetition? Can
> you think of a better idea?
>
> ## nice-valued ranges for histograms
> function histrange{T<:FloatingPoint,N}(v::AbstractArray{T,N}, n::Integer)
>     if length(v) == 0
>         return Range(0.0,1.0,1)
>     end
>     lo, hi = minimum(v), maximum(v)
>     if hi == lo
>         step = 1.0
>     else
>         bw = (hi - lo) / n
>         e = 10.0^floor(log10(bw))
>         r = bw / e
>         if r <= 2
>             step = 2*e
>         elseif r <= 5
>             step = 5*e
>         else
>             step = 10*e
>         end
>     end
>     start = step*(ceil(lo/step)-1)
>     Range(start,step,1+iceil((hi - start)/step))
> end
>
> function histrange{T<:Integer,N}(v::AbstractArray{T,N}, n::Integer)
>     if length(v) == 0
>         return Range(0,1,1)
>     end
>     lo, hi = minimum(v), maximum(v)
>     if hi == lo
>         step = 1
>     else
>         bw = (hi - lo) / n
>         e = 10^max(0,ifloor(log10(bw)))
>         r = bw / e
>         if r <= 1
>             step = e
>         elseif r <= 2
>             step = 2*e
>         elseif r <= 5
>             step = 5*e
>         else
>             step = 10*e
>         end
>     end
>     start = step*(iceil(lo/step)-1)
>     Range(start,step,1+iceil((hi - start)/step))
> end
>
>

Reply via email to