Creating an array with values that obey a criteria of smallest distance to the mean

Viewed 90

I am trying to build credible bands in Julia, however, there is a technical procedure that I am not aware of how to do. The code is the following:

#Significance level 95%
alpha_sign=0.05
#Genrate random values
N_1 = 100
Fs_1 = Array{Float64}(undef, length(x), N_1);

x = 0.0:0.01:1.0
for k in 1:100
  f = rand(postΠ)
  Fs_1[:,k] = f.(x)
end

# sup|theta_i(t)-average|


dif_b=Array{Float64}(undef, length(x),N);
for k in 1:100
dif_b[:,k] = Fs_1[:,k]-average_across
end



#Defining a function that allows to compute the n smallest values
using Base.Sort

function smallestn(a, n)
  sort(a; alg=Sort.PartialQuickSort(n))[1:n]
end



#Compute the maximum of the difference across time
sup_b=Array{Float64}(undef, N_1)
for k in 1:100
sup_b[k]=(maximum(abs.(dif_b[:,k] )))
end

#Build a matrix with the smallest distances
N_min=(1-alpha_sign)*N
using Base.Sort
min_sup_b=smallestn(sup_b,95)

To simplify the problem I am creating this example: Imagine I have the matrix down there and I want to create a matrix with the values that are closest to the mean. I am able to compute the distances and store into a vector as displayed in the code above and later get the smallest values but I need to get back to the original matrix to extract those values.


X=[1,2,7,4,5]
av_X=mean(X,dims=1)

Question:

I am able to compute the distances and store them into a vector as displayed in the code above and later get the smallest values but I need to get back to the original matrix to extract those values. How do I do that?

Thanks in advance!

2 Answers
using Statistics

arr = rand(1:20, (4, 4))
colmeans = [mean(col) for col in eachcol(arr)]
deltas = map(cart -> abs(arr[cart] - colmeans[first(Tuple(cart))]) => cart, CartesianIndices(arr))
sorteddeltas = sort(deltas, lt = (x, y) -> first(x) < first(y), dims=1)

sarr = zeros(Int, (4, 4))
for (i, d) in enumerate(sorteddeltas)
    sarr[i] = arr[last(d)]
end

println(arr) # [7 1 2 15; 18 7 14 10; 3 11 10 13; 7 14 20 8]

println(colmeans) # [8.75, 8.25, 11.5, 11.5]

println(sarr) # [7 11 10 13; 7 7 14 10; 3 14 2 8; 18 1 20 15]

println(sarr') # [7 7 3 18; 11 7 14 1; 10 14 2 20; 13 10 8 15]

This should give you a sorted list of pairs of the distances from the mean of each column, with the second part of the pair the Cartesian coordinates of the original matrix.

sarr is the original matrix sorted column-major by closeness to the mean for each column.

I think the function you are looking for is findmin(). It gives both the minimum value and its index.

julia> x = randn(5)
5-element Vector{Float64}:
 -0.025159738348978562
 -0.24720173332739662
 -0.32508319212563325
  0.9470582053428686
  1.1467087893336048

julia> findmin(x)
(-0.32508319212563325, 3)

If you want to do this for every column in a matrix, you can do something like:

julia> X = randn(3, 5)
3×5 Matrix{Float64}:
  1.06405    1.03267    -0.826687   -1.68299   0.00319586
 -0.129021   0.0615327   0.0756477   1.05258   0.525504
  0.569748  -0.0877886  -1.48372     0.823895  0.319364

julia> min_inds = [findmin(X[:, i]) for i = 1:5]
5-element Vector{Tuple{Float64, Int64}}:
 (-0.12902069012799203, 2)
 (-0.08778864856976668, 3)
 (-1.4837211369655696, 3)
 (-1.6829919363620507, 1)
 (0.003195860366775878, 1)
Related