convert a range vector of bin centers to bin edges. Bin Centers and edges are non-uniform

22 vues (au cours des 30 derniers jours)
tsan toso le 22 Oct 2013
Commenté : Peter Kövesdi le 10 Avr 2024
Is there a trivial way of converting a vector that contain bin centers to bin edges. The caveat here is that they are unequal. Does matlab provide a trivial way to do it?
Thanks
2 commentairesAfficher AucuneMasquer Aucune
dpb le 22 Oct 2013
Wouldn't that just be
[-inf midpoint-between-points inf]
?
Peter Kövesdi le 9 Avr 2024
Déplacé(e) : Voss le 9 Avr 2024
I have exactly the same question: I have bin centers and want to have edges, that way, that the centers stay centered between the resulting edges.
So, is there any solution?

Connectez-vous pour commenter.

Réponses (5)

Image Analyst le 22 Oct 2013
Where do you want the edges? Exactly half-way between the centers? If so you simply use conv():
% Make up some non-uniformly spaced bin centers.
binCenters = unique(sort(randi(99, 1,10)))
% Get edges half way in between.
binEdges = conv(binCenters, [0.5, 0.5], 'valid')
% Define end points outside of bin centers.
binEdges = [0 binEdges inf]
0 commentairesAfficher -2 commentaires plus anciensMasquer -2 commentaires plus anciens

Connectez-vous pour commenter.

W. Owen Brimijoin le 22 Oct 2013
If we assume the simplest case, that the edges should be precisely between the centres (i.e., not geometric, or logarithmic, etc), and that the first and last edge should be -inf and +inf, respectively, then this is a simple solution:
%example of random bin centres:
centers = cumsum(randi(10,20,1))
%create equidistant edges:
edges = [-inf;centers(:)+[diff(centers(:))/2;inf]];
0 commentairesAfficher -2 commentaires plus anciensMasquer -2 commentaires plus anciens

Connectez-vous pour commenter.

tsan toso le 23 Oct 2013
Hi all
Thanks for the all the feedback.
I am working with centers that are not evenly spaced.
Correct me if I am wrong the formulas provided would on occasion not give me edges that are equidistant from the left and right of center bin. That is to say the bins would no longer be the center of the edges anymore.
Would there be way such that the edges are identified such that the centers would always be the center of each and every edge?
Thanks
3 commentairesAfficher 1 commentaire plus ancienMasquer 1 commentaire plus ancien
Image Analyst le 23 Oct 2013
I agree with Owen. The formula make the edges exactly half way between the original centers, but the distance from the new edges to the original centers will be different on each side of the original center, unless you have uniformly spaced centers.
tsan toso le 23 Oct 2013
Thanks Owen and Image.
Bummer. I was just trying to use the kmeans function to bin my 1d data, but it returns the centers instead and I need it in edges. Dividing the distance between centres seem to inaccurately define the edge between clusters.
Guess have to work with what I have.
Cheers

Connectez-vous pour commenter.

Peter Kövesdi le 9 Avr 2024
Ok, I come up with this solution:
binedges = zeros(size(binmids));
binedges(1)=2*binmids(1);
for i=2:length(binmids)
binedges(i) = 2*binmids(i)-binedges(i-1);
end
But maybe, there's a more Matlab way of doing it?
0 commentairesAfficher -2 commentaires plus anciensMasquer -2 commentaires plus anciens

Connectez-vous pour commenter.

Steven Lord le 9 Avr 2024
If you know one of the edges of the region you're trying to bin, either the left-most or right-most edge, you can do this. Let's say you had bin centers at 1, 3.5, 7, and 11.5.
c = [1; 3.5; 7; 11.5];
Since we know these are the bin centers, the distances from each center to both edges of the bin are the same. So bin 1 is the interval [1-d1, 1+d1] for some distance d1. Let's ignore which edge is contained in each bin. Similarly bin 2 is [3.5-d2, 3.5+d2], etc. Because bin 1 ends at the start of bin 2, we have 1+d1 = 3.5-d2 or d1+d2 = 3.5-1. We can do the same for bins 2 and 3 and bins 3 and 4. This gives us a coefficient matrix and a right-hand side.
M = [1 1 0 0; 0 1 1 0; 0 0 1 1]
M = 3x4
1 1 0 0 0 1 1 0 0 0 1 1
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
R = diff(c)
R = 3x1
2.5000 3.5000 4.5000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
With one more piece of information (either the left edge of the interval being binned or the right edge) we can fix either d1 or d4. Let's say we know d1 is 1 (the leftmost bin starts at 0.)
d1 = 1;
Md1 = [1 0 0 0; M];
Rd1 = [d1; R];
d = Md1\Rd1
d = 4x1
1.0000 1.5000 2.0000 2.5000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
This puts the bin edges at 0 (c(1)-d(1)), 2 (c(1)+d(1) or c(2)-d(2)), 5 (c(2)+d(2) or c(3)-d(3)), 9 (c(3)+d(3) or c(4)-d(4)), and 14 (c(4)+d(4)).
edges = [c-d; c(end)+d(end)]
edges = 5x1
0 2 5 9 14
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
edges = [c(1)-d(1); c+d]
edges = 5x1
0 2 5 9 14
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Are these bins centered at the values in c?
centers = [c, edges(1:end-1)+diff(edges)/2]
centers = 4x2
1.0000 1.0000 3.5000 3.5000 7.0000 7.0000 11.5000 11.5000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
xline(edges)
hold on
plot(c, 1, 'x')
xlim([-1 15])
xticks(edges)
Sure looks like it.
The same holds if you know d4. [I'm not going to plot this; note that the plot above doesn't depend on d1, just the result d, and the backslash call below gives the same d vector as the backslash call above.]
d4 = 2.5;
Md4 = [M; 0 0 0 1];
Rd4 = [R; d4];
d = Md4\Rd4
d = 4x1
1.0000 1.5000 2.0000 2.5000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
Generalizing the creation of M to any number of bins is easy with two calls to diag.
What if we'd chosen a different d1 or d4 value?
d1 = 0.5;
Rd1 = [d1; R];
d = Md1\Rd1;
edges = [c-d; c(end)+d(end)]
edges = 5x1
0.5000 1.5000 5.5000 8.5000 14.5000
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
figure
xline(edges)
hold on
plot(c, 1, 'x')
xlim([-1 15])
xticks(edges)
Those x markers do appear to be centered between the edges. But again, you do need one of the bin widths (easiest to write is either the first or last) which is equivalent to knowing one of the edges of one of the bins. Otherwise how would I distinguish the d1 = 1 case from the d1 = 0.5 case? The two plots are different.
1 commentaireAfficher -1 commentaires plus anciensMasquer -1 commentaires plus anciens
Peter Kövesdi le 10 Avr 2024
Thank you very much for this more Matlab-like solution!
> (the leftmost bin starts at 0.)
Sorry, in my solution I assumed that silently in Line 2.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Object Analysis dans Help Center et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by