Not evently-spaced grids/ranges

I need to generate a vector between 0 and 10 such that points are concetrated around 5. Something like:

[0.0 2.0 3.5 4.5 5 5.5 6.5 8.0 10.0] 

Is there any built-in function or package to do something like this?

How about [p for p in sort(2*randn(100).+5) if 0<=p<=10]. Adjust 2 as needed.

4 Likes

Let’s generalize that grid:

function expanding_grid(mid, left, right, step, α)
    v = Vector{typeof(mid + α*step)}()
    # left half
    let s = step, a = mid - s
        while a ≥ left
            push!(v, a)
            s += α
            a -= s
        end
    end
    reverse!(v)
    push!(v, mid)
    let s = step, a = mid + s
        while a ≤ right
            push!(v, a)
            s += α
            a += s
        end
    end
    v
end
julia> expanding_grid(5, 0, 10, 0.5, 0.5)
9-element Array{Float64,1}:
  0.0
  2.0
  3.5
  4.5
  5.0
  5.5
  6.5
  8.0
 10.0
3 Likes

Thanks. I know how to write a function that generates that grid vector too. One could also think of using a logarithmic scale or even the normal distribution. My question is whether there is something built-in that can be used.

Not that we know of, apparently.

This is something rather specialized, so while it is possible that some library would do something similar, I consider it unlikely. Maybe someone will point out something though.

But I am not sure why it is such an important consideration, and why you were expecting a “built-in” function (of which Julia has precious few — everything is gradually being moved into packages) for this.

1 Like

Thank you.

The reason I’m asking is because I rather use something in a package/built-in than do it myself. The reason is that code from packages/built-in is reviewed by other people so it’s less likely to contain errors.

Not necessarily a good assumption. Write tests to make sure the code is correct; don’t assume that other people will do that for you.

3 Likes

I concur with @rdeits: test coverage is the best signal of code quality. Also, many Julia projects are single-person with occasional other contributors. Only major packages, Base and the standard libraries get a more thorough review for the whole codebase.

But for this specific function, you provided a test case already, so you are all set — just check that in your tests.

2 Likes

Any pointers on how to test code systematically and efficiently?

Maybe the nodes from a guassian quadrature? These start from -1 to 1 centered around 0, but you can scale and shift them.

julia> using FastGaussQuadrature

julia> nodes, weights = gausslegendre( 10 )
([-0.973907, -0.865063, -0.67941, -0.433395, -0.148874, 0.148874, 0.433395, 0.67941, 0.865063, 0.973907], [0.0666713, 0.149451, 0.219086, 0.269267, 0.295524, 0.295524, 0.269267, 0.219086, 0.149451, 0.0666713])

julia> nodes5 = 5nodes .+ 5
10-element Array{Float64,1}:
 0.13046735741414128
 0.6746831665550772 
 1.6029521585048778 
 2.8330230293537637 
 4.255628305091844  
 5.744371694908156  
 7.166976970646236  
 8.397047841495123  
 9.325316833444923  
 9.86953264258586  
1 Like

https://docs.julialang.org/en/v1/stdlib/Test/

1 Like

Oops, that was actually concentrated at the edges. Use guasshermite instead.

julia> nodes, weights = gausshermite( 10 )
([-3.43616, -2.53273, -1.75668, -1.03661, -0.342901, 0.342901, 1.03661, 1.75668, 2.53273, 3.43616], [7.64043e-6, 0.00134365, 0.0338744, 0.240139, 0.610863, 0.610863, 0.240139, 0.0338744, 0.00134365, 7.64043e-6])

julia> nodes10 = (nodes .- minimum(nodes)) ./ (maximum(nodes)/(10/2))
10-element Array{Float64,1}:
  0.0               
  1.3145890707624264
  2.4438266847577346
  3.491614046470373 
  4.501039801469247 
  5.498960198530754 
  6.508385953529628 
  7.556173315242267 
  8.685410929237573 
 10.0