1

I have an interval, say (0, 9) and I have to generate points between them such that they are denser at the both the boundaries. I know the number of points, say n_x. alpha decides the "denseness" of the system such that points are evenly spaced if alpha = 1.

The cross product of n_x and n_y is supposed to look like this:

[enter image description here

So far the closest I've been to this is by using np.geomspace, but it's only dense near the left-hand side of the domain,

In [55]: np.geomspace(1,10,15) - 1
Out[55]: 
array([0.        , 0.17876863, 0.38949549, 0.63789371, 0.93069773,
       1.27584593, 1.6826958 , 2.16227766, 2.72759372, 3.39397056,
       4.17947468, 5.1054023 , 6.19685673, 7.48342898, 9.        ])

I also tried dividing the domain into two parts, (0,4), (5,10) but that did not help either (since geomspace gives more points only at the LHS of the domain).

In [29]: np.geomspace(5,10, 15)
Out[29]: 
array([ 5.        ,  5.25378319,  5.52044757,  5.80064693,  6.09506827,
        6.40443345,  6.72950096,  7.07106781,  7.42997145,  7.80709182,
        8.20335356,  8.61972821,  9.05723664,  9.51695153, 10.        ])

Apart from that, I am a bit confused about which mathematical function can I use to generate such an array.

Jarwin
  • 1,045
  • 1
  • 9
  • 30

1 Answers1

2

You can use cumulative beta functions and map to your range.

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import beta

def denseboundspace(size=30, start=0, end=9, alpha=.5):
    x = np.linspace(0, 1, size)
    return start + beta.cdf(x, 2.-alpha, 2.-alpha) * (end-start)

n_x = denseboundspace()
#[0.         0.09681662 0.27092155 0.49228501 0.74944966 1.03538131
# 1.34503326 1.67445822 2.02038968 2.38001283 2.75082572 3.13054817
# 3.51705806 3.9083439  4.30246751 4.69753249 5.0916561  5.48294194
# 5.86945183 6.24917428 6.61998717 6.97961032 7.32554178 7.65496674
# 7.96461869 8.25055034 8.50771499 8.72907845 8.90318338 9.        ]

plt.vlines(n_x, 0,2);

beta(1.5, 1.5)

n_x = denseboundspace(size=13, start=1.2, end=7.8, alpha=1.0)
#[1.2  1.75 2.3  2.85 3.4  3.95 4.5  5.05 5.6  6.15 6.7  7.25 7.8 ]

plt.vlines(n_x, 0,2);

beta(1,1)

The spread is continuously controlled by the alpha parameter.

alpha0to1

Michael Szczesny
  • 4,911
  • 5
  • 15
  • 32
  • With beta function, is it possible for the denseness to be a bit more spread out? – Jarwin Sep 06 '21 at 08:47
  • 1
    You can control the spread with the `alpha` parameter. `alpha=1.0` is evenly spaced (maximum spread), `alpha=0.0` is most dense at the bounds. Between `[-∞,2.0)` the spread is continuous. If you want larger gaps you can reduce the `size` parameter. I added a visualization for the `alpha` parameter. – Michael Szczesny Sep 06 '21 at 09:50