Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sample equidistant points from a numeric vector

I have a numeric vector:

vec = c(1464.556644,552.6007169,155.4249747,1855.360016,1315.874155,2047.980206,2361.475519,4130.530507,1609.572131,4298.980363,697.6034771,312.080866,2790.738644,1116.406288,989.6391649,2683.393338,3032.080837,2462.137352,2964.362507,1182.894473,1268.968128,4495.503015,576.1063996,232.4996213,1355.256694,1336.607876,2506.458008,1242.918255,3645.587384)

and I'd like to sample n=5 points from it that are as equidistant from each other as possible. In other words I'd like to get the points from vec that are closest to these points:

seq(min(vec),max(vec),(max(vec)-min(vec))/(n-1))

What's the fastest way to achieve this?

like image 261
user1701545 Avatar asked Apr 18 '14 00:04

user1701545


People also ask

How do you calculate equidistant points?

The distance between any two given points can be calculated with the help of the distance formula: d = √[(x2−x1)2+(y2−y1)2] √ [ ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 ] ; here [x1 x 1 and y1 y 1 )] are the coordinates of one point and [x2 x 2 and y2 y 2 ] are the coordinates of the other point.

What are equidistant points?

Two objects are equidistant from a point if the distance between each object and that point are the same.


2 Answers

I upvoted thelatemail, that would also have been my quick and dirty solution had he not posted so quickly :-)

I think a more robust approach is to solve an integer programming. It will for example prevent the possibility of selecting a same point more than once.

n <- 5
N <- length(vec)
ideal <- seq(min(vec),max(vec),(max(vec)-min(vec))/(n-1))

library(lpSolve)
cost.mat  <- outer(ideal, vec, function(x, y) abs(x-y))
row.signs <- rep("==", n)
row.rhs   <- rep(1, n)
col.signs <- rep("<=", N)
col.rhs   <- rep(1, N)
sol <- lp.transport(cost.mat, "min", row.signs, row.rhs,
                                     col.signs, col.rhs)$solution

final <- vec[apply(sol, 1, which.max)]

This will definitely be slower but it is the only "optimal and 100% reliable" way in my opinion.

like image 182
flodel Avatar answered Nov 15 '22 00:11

flodel


An attempt:

ideal <- seq(min(vec),max(vec),(max(vec)-min(vec))/(n-1))
result <- sapply(ideal, function(x) vec[which.min(abs(vec-x))] )

Compare:

cbind(result,ideal)

       result    ideal
[1,]  155.425  155.425
[2,] 1242.918 1240.444
[3,] 2361.476 2325.464
[4,] 3645.587 3410.484
[5,] 4495.503 4495.503
like image 22
thelatemail Avatar answered Nov 14 '22 23:11

thelatemail