Compare two meshes for difference in values

Asked by Bob Nbob

Bob Nbob (view profile)

on 22 Aug 2019
Latest activity Commented on by Bob Nbob

Bob Nbob (view profile)

on 22 Aug 2019
Accepted Answer by Guillaume

Guillaume (view profile)

I feel like I should know how to do this, but apparently I don't have the patience to figure it out today.
I have two 'mesh grids' with assigned values in mx4 and nx4 arrays. I would like to compare the result values, column 4, for points which have the same coordinate values, columns 1:3. I can identify the coordinates of the points which are the same using intersect, but my attempts at getting the difference in result values through logic indexing have been unsuccessful.
data = struct('name',{'Original','Layered'});
[data(1).nums] = randi(100,100,4);
[data(2).nums] = randi(100,200,4);
rs = intersect(data(1).nums(:,1:3),data(2).nums(:,1:3),'rows');
compared = [rs,find(data(1).nums(data(1).nums(:,1:3)==rs,4))-find(data(2).nums(data(2).nums(:,1:3)==rs,4))];
Error: Matrix dimensions must agree.
I don't care that much about fixing this error specifically, if somebody knows a better way to do the comparison, this was just where my train of thought went.

Guillaume (view profile)

on 22 Aug 2019
Edited by Guillaume

Guillaume (view profile)

on 22 Aug 2019

Strange way to fill your structure! Why the []?
[rs, wherein1, wherein2] = intersect(data(1).nums(:, 1:3), data(2).nums(:, 1:3), 'rows');
compared = [rs, data(1).nums(wherein1, 4) - data(2).nums(wherein2, 4)]
Note that this assumes that the coordinate triplets are only common once. If not, intersect is probably not the right function depending on what you want to do.
edit: Another way, which may be better for visualisation is to convert to table and innerjoin them (which is basically an intersect):
original = array2table(randi(100, 100, 4), 'VariableNames', {'X', 'Y', 'Z', 'Values'});
layered = array2table([randi(100, 200, 4); [original{randperm(100, 10), 1:3}, randi(100, 10, 1)]], 'VariableNames', {'X', 'Y', 'Z', 'Values'});
common = innerjoin(original, layered, 'Keys', 1:3);
common.difference = common.(4) - common.(5)

Bob Nbob

Bob Nbob (view profile)

on 22 Aug 2019
Using the [] is a habit from trying to create structure fields in the past. Not really sure if it is necessary, but it seems to work.
Guillaume

Guillaume (view profile)

on 22 Aug 2019
You would use
[s(nonscalarindices).somefield] = something
to assign to multiple elements (at nonscalarindices) of a structure array. somefield must be horizontally concatenable (is that a word?).
eg:
data = struct('name',{'Original','Layered'});
[data.name] = deal('NewNameA', 'NewNameB'); %typically instead of deal you'd use a comma-separated list
would put new values in name (remember that data.name is the same as data(1:end).name)
For assignin to a scalar structure such as data(1), the brackets don't do anything and made me wonder if you meant to do something else.
Bob Nbob

Bob Nbob (view profile)

on 22 Aug 2019
In the past I have used the brackets in a scalar structure because I seemed to have issues creating new fields and assigning values to them. Typically this occurred in a loop with the scalar index being the loop index. Because I was only looking at one index value at a time, the assigned values were usually a single string, or an array of data, depending on the situation.