I need help transforming data

1 view (last 30 days)
Michael J
Michael J on 13 Dec 2014
Commented: Star Strider on 16 Dec 2014
Hello,
I have multiple sets of nx3 matrices, where n is varying between the matrices and the matrices consist of coordinate points. I am trying to transform the data to get a matrix where the first column of my nx3 matrices (the x-coordinates) are the row indices, the 2nd column of the nx3 matrices (y-coordinates) are the column indices, and the 3rd column of the nx3 matrices (z-coordinates) are the values of the new matrix where the value matches with it's corresponding x and y indices (so the z-coordinate corresponds with its appropriate x and y coordinates). This is all to use the functions surf(Z) and surface(Z) in order to try and recreate an object in MATLAB. So far, I have the code
function Z = GetZmatrix(concatenatedmatrix)
Z=zeros(size(concatenatedmatrix,1)); %create matrix of zeroes
x = (1:size(concatenatedmatrix,1));
y = (1:size(concatenatedmatrix,2));
sorted = ceil(sortrows(concatenatedmatrix)) %sorts and gets rid of decimals
for i = sorted(:,1).'
for j = 1:size(concatenatedmatrix,1)
for l = sorted(:,2).'
for k = 1:size(concatenatedmatrix,2)
if i == j
if l == k
Z(k,j) = Z(k,j) + sorted(i,3);
end
end
end
end
end
end
However, this is not giving me the output I want for my test matrix. I created the matrix
in hopes of getting
However my code gave me
Can anyone help me understand why my code is giving the wrong output and maybe help me get what I'm trying to get? And I'm fairly new to MATLAB, so forgive my code if it is ugly or sloppy. Thanks! Michael
  4 Comments
Michael J
Michael J on 16 Dec 2014
I am trying to get some sort of mathematical formula for the object (and the process for other future objects) so that I can make inferences on it as certain parameters are advised or become interesting.
Star Strider
Star Strider on 16 Dec 2014
Is the ‘object’ you’re referring to ‘A’ or ‘B’?
The only process I see maps the third column of ‘A’ by the column and row indices (respectively) given in its first two columns. So long as that remains unique, you simply have a discrete mapping.

Sign in to comment.

Accepted Answer

Star Strider
Star Strider on 13 Dec 2014
Edited: Star Strider on 13 Dec 2014
Alternatively, a very simple implementation with one loop is:
A = [1 2 4; 5 6 4; 3 2 1; 1 1 1; 2 3 4; 4 1 5];
B = zeros(6);
for k1 = 1:size(A,1)
B(A(k1,2),A(k1,1)) = A(k1,3);
end
  6 Comments
Guillaume
Guillaume on 16 Dec 2014
I am chilled. I'm just pointing a slightly more efficient way (in my opinion) to write the loop (saves on a indexing operation).
Note that I did it as a comment to your answer, so Michael would still accept your answer if he wanted to go with the loop.
Star Strider
Star Strider on 16 Dec 2014
It seems indexing operations aren’t what Michael J wants anyway.
He’s looking for a mathematical relation that defines the indexing operation.
I don’t see it, and a linear regression (of columns 1:2 against column 3) is a poor fit. (We don’t have the data that created the ‘A’ matrix.) Until we learn more, I doubt any answer (thus far) is what he’s looking for.

Sign in to comment.

More Answers (1)

Guillaume
Guillaume on 13 Dec 2014
accumarray is what you want:
A = [1 2 4
5 6 4
3 2 1
1 1 1
2 3 4
4 1 5]
B = accumarray(A(:, [1 2]), A(:, 3))'
Note if you have identical x and y, the default behaviour of accumarray is to sum the z. You could use @min or @max or whatever you want if that were to happen and the sum doesn't suit you:
B = accumarray(A(:, [1 2]), A(:, 3), [], @min)'
  2 Comments
Michael J
Michael J on 16 Dec 2014
This works for my test matrix A that I made up, but when I try to use it on the matrix of coordinate points, I get the error "First input SUBS must contain positive integer subscripts". I'm not sure how to fix this issue as I used the ceil function to make it so that my data is all positive integers and my coordinate points exist in the first octant. When I look at the data, the smallest point is (17, 12, 60). Do you know how to get around this error? Thanks for you help!
Guillaume
Guillaume on 16 Dec 2014
Edited: Guillaume on 16 Dec 2014
What does
[r, c] = find(A(:, [1 2]) < 1 | mod(A(:, [1 2]), 1));
return?
If you get this error it's either because because some coordinates are not integer or are less than 1. Either way, you'll get the same error with Star Strider's answer.
You'll also get the same issue of creating a matrix big enough to hold all your points. The answer is also to create a sparse matrix, which accumarray allows you to do:
B = accumarray(A(:, [1 2]), A(:, 3), [], [], [], true);
Note that accumarray is probably faster than a handwritten loop.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!