How to from a list produce a list of all distinct difference of elements and find out it comes from efficiently?

2 views (last 30 days)
Let a list be
j = [1 2 3 16 27 39 78 88 98];
How to produce a list of all the distinct differences from one index to the other index, and also know where the difference comes from?
For example,
j(1) - j(2) = -1, j(8) - j(7) = 10, j(9) - j(8) = 10.
So
for i = 1:9
j(i) - j
end
ans =
0 -1 -2 -15 -26 -38 -77 -87 -97
ans =
1 0 -1 -14 -25 -37 -76 -86 -96
ans =
2 1 0 -13 -24 -36 -75 -85 -95
ans =
15 14 13 0 -11 -23 -62 -72 -82
ans =
26 25 24 11 0 -12 -51 -61 -71
ans =
38 37 36 23 12 0 -39 -49 -59
ans =
77 76 75 62 51 39 0 -10 -20
ans =
87 86 85 72 61 49 10 0 -10
ans =
97 96 95 82 71 59 20 10 0
is the list of difference. More compactly,
reshape(bsxfun(@minus, j', j),1,81)
ans =
Columns 1 through 13
0 1 2 15 26 38 77 87 97 -1 0 1 14
Columns 14 through 26
25 37 76 86 96 -2 -1 0 13 24 36 75 85
Columns 27 through 39
95 -15 -14 -13 0 11 23 62 72 82 -26 -25 -24
Columns 40 through 52
-11 0 12 51 61 71 -38 -37 -36 -23 -12 0 39
Columns 53 through 65
49 59 -77 -76 -75 -62 -51 -39 0 10 20 -87 -86
Columns 66 through 78
-85 -72 -61 -49 -10 0 10 -97 -96 -95 -82 -71 -59
Columns 79 through 81
-20 -10 0
If the differences are all distinct (except the trivial same index minus same index, which results in the trivial zero), the "difference" array should be 1 by 81 or by removing zeros: 1 by (9*9 - 9 + 1). However, this is not the usual case as repetitive nonzero elements occur.
sort(reshape(bsxfun(@minus, j', j),1,81))
ans =
Columns 1 through 13
-97 -96 -95 -87 -86 -85 -82 -77 -76 -75 -72 -71 -62
Columns 14 through 26
-61 -59 -51 -49 -39 -38 -37 -36 -26 -25 -24 -23 -20
Columns 27 through 39
-15 -14 -13 -12 -11 -10 -10 -2 -1 -1 0 0 0
Columns 40 through 52
0 0 0 0 0 0 1 1 2 10 10 11 12
Columns 53 through 65
13 14 15 20 23 24 25 26 36 37 38 39 49
Columns 66 through 78
51 59 61 62 71 72 75 76 77 82 85 86 87
Columns 79 through 81
95 96 97
It is not distinct, which can be made distinct by some functions or for loop. But more importantly, by looking at each element, how do we know, for example, where 86 comes from. I want to know as I need to do operation on ,e.g.,86 and two indices that produce this: for example, for each difference, say 86, i do 86*8*2, as j(8)- j(2) = 86. But for 10, I need to do 10*(9*8+8*7) as j(8) - j(7) = 10, j(9) - j(8) = 10 which is not distinct.

Answers (2)

Thorsten
Thorsten on 26 Aug 2016
X = bsxfun(@minus, j', j)
x = 10;
[i j] = ind2sub(size(X), find(X == x));
y = x*(prod(i) + prod(j))

Andrei Bobrov
Andrei Bobrov on 26 Aug 2016
Edited: Andrei Bobrov on 26 Aug 2016
a = [1 2 3 16 27 39 78 88 98];
[ii,jj] = ndgrid(1:numel(a));
t = jj < ii;
d = bsxfun(@minus,a(:),a(:)');
[a1,~,c] = unique(d(t));
p = accumarray(c,jj(t).*ii(t));
out = a1.*p;

Products

Community Treasure Hunt

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

Start Hunting!