# Is there a log scale range function?

Is there a function like `range()` but the steps are multiplicative?
Something like

``````logrange(start,stepmul,length) =  cumprod([start,(ones(length)*stepmul)...])
``````
1 Like

You can use broadcasting to apply a log transform to a range:

``````julia> logrange(start,stepmul,length) = start .* stepmul .^ (0:(length-1))
logrange (generic function with 1 method)

julia> logrange(3, 4, 5)
5-element Vector{Int64}:
3
12
48
192
768
``````
1 Like

Thereās a PR to add it to base Add a lazy `LogRange` function by mcabbott Ā· Pull Request #39071 Ā· JuliaLang/julia Ā· GitHub. It tuns out that getting it perfect is surprisingly difficult.

2 Likes

The tricky thing about a function which takes the ratio (`stepmul` above) is that it will tend to create an expectation that this be interpreted exactly.

Linear ranges like `0:0.1:1` do this, by some serious black magic. It knows you mean `1//10` even though that isnāt precisely represented by any Float64. Doing `cumsum(fill(0.1, 10))` will miss the āobviousā endpoint of `1.0`.

Similar things go wrong for ratio `0.1`:

``````julia> logrange1(100, 0.1, 5)  # from 1st message, with stepmul
6-element Vector{Float64}:
100.0
10.0
1.0
0.1
0.010000000000000002
0.0010000000000000002

julia> logrange2(100, 0.1, 5)  # from 2nd message above
5-element Vector{Float64}:
100.0
10.0
1.0000000000000002
0.10000000000000002
0.010000000000000002

julia> logrange(100, ratio=0.1, length=5)  # lazy PowerRange, somewhere in PR
5-element PowerRange{Float64}:
100.0
10.0
1.0000000000000002
0.10000000000000002
0.010000000000000002
``````

The linked PR avoids this by taking the first & last values. Then thereās no chance that it doesnāt stop where you want, it can simply guarantee to hit `0.01` exactly, without enquiring further. (It tries hard to be accurate in between, but isnāt perfect.)

``````julia> Base.logrange(100, 0.01, length=5)
5-element LogRange{Float64, Base.TwicePrecision{Float64}}:
100.0, 10.0, 1.0, 0.1, 0.01

julia> collect(ans)
5-element Vector{Float64}:
100.0
10.0
1.0
0.1
0.01
``````

And apart from such details, in real use I think itās common to do that, and then decide you want more / less points (on your plot), or a wider / narrower range (to exclude the bad ones). With the ratio specified, you have to experiment a bit. Specifying the ends and length seems to me more often useful.

5 Likes

``````julia> using FlexiMaps