Does there exist any alternative of `logspace` in Julia (v1.3.1)?
Asked Answered
I

3

7

Background and Existing Solutions

I am porting some Python code into Julia (v1.3.1), and I have run into an issue with trying to reproduce the code into as easily readable code in Julia.

In Python (using numpy), we have created a 101-element logarithmically spaced sequence from 0.001 to 1000:

>>> X = numpy.logspace( -3, 3, 101 )
array([1.00000000e-03, 1.14815362e-03, 1.31825674e-03, ..., 1.00000000e+03])

Implementing this in Julia with PyCall would of course work like this:

julia> using PyCall
julia> numpy = pyimport("numpy")
julia> X_python = numpy.logspace( -3, 3, 101 )
101-element Array{Float64,1}:
    0.001                
    0.0011481536214968829
    0.0013182567385564075 
    ⋮       
 1000.0                  

But I want to implement this in pure Julia for my current project. Not finding the same function from the Julia documentation, after some searching I came across an older documentation entry for logspace here. I then came across this Github pull request for deprecating logspace into its definition, so currently it seems that this is the way to create the logarithmically spaced sequence:

julia> X_julia  = 10 .^ range( -3, 3, length = 101 )
101-element Array{Float64,1}:
    0.001                
    0.0011481536214968829
    0.0013182567385564075
    ⋮                    
 1000.0        

TL;DR / The Actual Question

julia> LinRange(1e-3, 1e3, 101)
101-element LinRange{Float64}:
 0.001,10.001,20.001,…,1000.0

Since there currently exists a simple and easy-to-read function, LinRange, for creating linear sequences (as seen above), does there exist a similar function, something like LogRange, for logarithmic sequences?

I am going for simplicity and improved readability in this project, so while broadcasting a range into the exponent of 10 works from the mathematical point of view, something like LogRange(1e-3, 1e3, 101) would be easier for a beginner or part-time programmer to understand.


EDIT: When the limits of the sequence are integer exponents of 10, the code is fairly clear, but when the limits are floats, the difference in readability between LogRange() and 10 .^ () becomes more apparent:

julia> 10 .^ range( log10(1.56e-2), log10(3.62e4), length = 101 )
julia> LogRange( 1.56e-2, 3.62e4, 101 )
Idio answered 30/1, 2020 at 11:29 Comment(2)
The answer is probably “No”. 😀 That PR has plenty of discussion, but I suppose you could open an issue asking for LogRange back.Honeywell
@Honeywell Yeah I'm trying to avoid having to take on that work on the odd chance that what I need would actually already exist (still) 😄Idio
K
1

You can just use range

For Log-spaced values ∈ [1.0e-10, 1.0e10]:

10 .^ range(-10, stop=10, length=101)
Kapp answered 14/2, 2022 at 18:53 Comment(0)
B
5

Can't you just define your own function logrange, like this:

logrange(x1, x2, n) = (10^y for y in range(log10(x1), log10(x2), length=n))

?

This returns a generator, so it will not allocate an array, and should be easy to understand and use for other users.

Breaker answered 30/1, 2020 at 13:51 Comment(4)
In principle, yes, and it fits the purpose for what I am doing now. I am just interested in finding out if LogSpace / LogRangestill exists as part of some package so that I won't have to define the function for every document I am working for or need to upkeep it myself. 🙂Idio
it would probably be better to make a LogRange struct that computes the elements lazily, but that's not really the biggest problem.Mauri
But this solution does calculate lazily, and it's much simpler than implementing a type with iteration.Breaker
What this generator doesn't do is allow random access, nor hit the ends exactly (e.g. first(logrange(0.01, 1, 3)) != 0.01). These are corrected in github.com/JuliaLang/julia/pull/39071Aboard
K
1

You can just use range

For Log-spaced values ∈ [1.0e-10, 1.0e10]:

10 .^ range(-10, stop=10, length=101)
Kapp answered 14/2, 2022 at 18:53 Comment(0)
A
1

Julia 1.11 has a new logrange function which, like range(start, stop; length) and LinRange(start, stop, length), takes the first and last elements. On earlier versions of Julia, it's available from the package Compat.jl:

julia> using Compat

julia> logrange(1/4, 16, length=5)
5-element Compat.LogRange{Float64, Base.TwicePrecision{Float64}}:
  0.25
  0.7071067811865476
  2.0
  5.656854249492381
 16.0

This is similar to numpy.geomspace, rather than numpy.logspace which takes powers of base 10.

Aboard answered 24/2, 2024 at 17:20 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.