Difference between both adjacent and non-adjacent values using multiple indexes

13 views (last 30 days)
I wish to calculate the difference between pairs of values (which may or may not be adjacent), using two indexes to specify between which pairs the calculation is made.
pos = [2 4 5 11 1 5 8 11 12 20] %values
type = [1 2 1 2 1 1 2 1 2 3] %index 1
category = [1 1 1 1 2 2 2 2 2 2] %index 2
Any valid pair is one comprising values of the same type (index 1) and same category (index 2) read sequentially in ascending order. Using the above data as an example:
When category = 1
The difference(s) between type 1 positions = 3 (5-2).
The difference(s) between type 2 positions = 7 (11-4).
When category = 2
There are no cross-category calculations.
The difference(s) between type 1 positions = 4 (5-1), 6 (11-5).
The difference(s) between type 2 positions = 4 (12-8).
The final output for this would be a matrix containing this information (labels added for clarity only):
Type 1 Type 2 Type 3
3 7 0
4 4 0
6 0 0
i.e. all differences for each type. The output does not need to separate by category (index 2), but the calculations must be made using it.
Is there a concise and/or fast method to achieve this?
  2 Comments
dpb
dpb on 23 Aug 2015
Can't decipher the rules, sorry. I don't understand how you get the result for any of the above; how do you get the (5-2)=3 from the first, exactly, for example?
Anna
Anna on 23 Aug 2015
Sorry for the lack of clarity. 5-2 is arrived at because these are the first values in 'pos' with a 'type' = 1. In other words, they are the same type - they are also part of the same category, so they meet the criteria as a valid pair.

Sign in to comment.

Answers (1)

the cyclist
the cyclist on 23 Aug 2015
The following code does not create exactly the output that you specified, but it provides one important part of the algorithm you want.
pos = [2 4 5 11 1 5 8 11 12 20]; %values
type = [1 2 1 2 1 1 2 1 2 3]; %index 1
category = [1 1 1 1 2 2 2 2 2 2]; %index 2
[uniqueType, ~,idxBackFromUniqueTypeToAll] = unique(type);
[uniqueCategory,~,idxBackFromUniqueCategoryToAll] = unique(category);
numberTypes = numel(uniqueType);
numberCategories = numel(uniqueCategory);
posDiffCategoryType = cell(numberCategories,numberTypes);
for nc = 1:numberCategories
for nt=1:numberTypes
idxThisCategoryType = (nt==idxBackFromUniqueTypeToAll) & (nc==idxBackFromUniqueCategoryToAll);
posThisCategoryType = pos(idxThisCategoryType);
posDiffCategoryType{nc,nt} = diff(posThisCategoryType);
end
end
Notice that the output is a cell array. Each cell in the array corresponds to a category/type combination. The contents of this cell will be
  • A scalar value, if there is exactly one pos-difference in that category/type (e.g. cat 1 type 1)
  • A vector of values, if there is more than one pos-difference in that category/type (e.g. cat 2 type 1)
  • An empty vector, if the category/type combination occurs, but has only 1 pos values, and therefore cannot generate a diff (e.g. cat 1 type 3)
  • Nothing (i.e. an empty cell), if the category/type combination does not occur (e.g. cat 2 type 3)
I like this output format, because I think it captures all information compactly. You might even be able to work with this directly for your next step.
If you really need the output in the format you specify, you may be able to figure out how to take the next step of extracting the info you need from the cell array.

Products

Community Treasure Hunt

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

Start Hunting!