50 views (last 30 days)

Dear MATLAB Community,

I was wondering if you were able to help me with the following problem. I am trying to find the following coordinates (from Columns 2-4 in CourseMeshNodeLocs) in FibreOrientationPositionElement (Columns 8-10). Columns 2-4 wont exactly match Columns 8-10, hence some of of the logic functions I have learnt over the past few weeks will not help me.

I want to find a row in FibreOrientationPositionElement (Columns 8-10) that closly represents a row in CourseMeshNodeLocs (Columns 2-4), either through averaging or finding the closest one. Once the closest co-ordinates can be found, I then want to output columns 2-7 in FibreOrientationPositionElement for each row in CourseMeshNodeLocs.

What would be the best way of doing this? I had an idea regarding if and for loops defining a range which the co-ordinates need to be in, but I believe there may be another simpler way, which I can learn for the future.

Attached are some files and a code.

CoarseMeshNodeLocs = dlmread('CoarseTjointMesh.txt','',9,0); %Fibre Orientation @ Elements. Read text file, first few lines not needed

CoarseMeshNodeLocs(:,[2 3 4]) = CoarseMeshNodeLocs(:,[2 3 4])*10^-3; %Converts mm into m

FibreOrientationPositionElement = dlmread('matrix.txt','',0,0); %Fibre Orientation and Position data at elements

Stephen Cobeldick
on 25 Jan 2020 at 20:14

Edited: Stephen Cobeldick
on 25 Jan 2020 at 22:39

I tried a simple vectorized solution of permute and sum of squares approach, but ran into "out of memory" issues:

>> C = dlmread('CoarseTjointMesh.txt','',9,0); %Fibre Orientation @ Elements. Read text file, first few lines not needed

>> C(:,2:4) = C(:,2:4)*1e-3; % Convert mm into m

>> F = dlmread('matrix.txt','',0,0); %Fibre Orientation and Position data at elements

>> B = 3*8*size(C,1)*size(F,1)

B = 13703964384

>> num2sip(B) % Oops... I don't have 14 GBytes of memory

ans = 13.704 G

However using a cell array worked without error, and is just as simple:

% split into row vectors in cell array:

tmp = num2cell(C(:,2:4),2);

% find indices of closest set of points:

fun = @(v)min(sum((v-F(:,8:10)).^2,2)); % requires >=R2016b

[dst,idx] = cellfun(fun,tmp);

% get output rows selected by those indices:

out = F(idx,2:7);

Note that the subtraction inside the anonymous function requires scalar dimension expansion, which was introduced in R2016b. For earlier versions replace the subtraction with bsxfun.

Stephen Cobeldick
on 26 Jan 2020 at 18:36

@JLV: the calculation is for the (square of the) euclidean distance in 3 dimensions:

The calculation does not involve any "length" from the origin as it directly calculates the distance between any two points (where those points are relative to the origin is irrelevant).

Sign in to comment.

Raunak Gupta
on 22 Jan 2020 at 15:44

Hi,

You may try finding difference between two matrices (here m x 3 matrices as m rows and 3 columns). From that you may try finding the max of the absolute of difference for each rows so it will result into a m x 1 vector. In that the minimum value will define the closest two rows in the two set of columns. You may use something like 10 times(This needs to be tuned according to what is required) of this lowest value and then find corresponding “similar” rows by using ismembertol. You may find below code useful.

% Here since the size is different for FibreOrientationPositionElement

% taking only the Number of elements that are there in CoarseMeshNodeLocs

FibreOrientationPosition_col_8_10 = FibreOrientationPositionElement(1:2393,8:10);

CoarseMeshNodeLocs_col_2_4 = CoarseMeshNodeLocs(:,2:4);

% Absolute difference between two matrices

difference = abs(FibreOrientationPosition_col_8_10 - CoarseMeshNodeLocs_col_2_4);

minimum_tol = min(max(difference,[],2));

% Here the maximum_tol can be tuned

maximum_tol = minimum_tol*10;

% Returns logical array of the similar rows

similarRowsIndex = ismembertol(FibreOrientationPositionElement(:,8:10),CoarseMeshNodeLocs(:,2:4),maximum_tol,'ByRows',true);

% Column 2-7 Values of FibreOrientationPositionElement for similar rows

similarRowsProperties = FibreOrientationPositionElement(similarRowsIndex,2:7);

Hope this helps.

Raunak Gupta
on 26 Jan 2020 at 14:21

Sign in to comment.

Sign in to answer this question.

Opportunities for recent engineering grads.

Apply Today
## 4 Comments

## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/500006-finding-three-columns-in-one-variable-in-another-variable#comment_785417

⋮## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/500006-finding-three-columns-in-one-variable-in-another-variable#comment_785417

## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/500006-finding-three-columns-in-one-variable-in-another-variable#comment_785422

⋮## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/500006-finding-three-columns-in-one-variable-in-another-variable#comment_785422

## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/500006-finding-three-columns-in-one-variable-in-another-variable#comment_786608

⋮## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/500006-finding-three-columns-in-one-variable-in-another-variable#comment_786608

## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/500006-finding-three-columns-in-one-variable-in-another-variable#comment_790107

⋮## Direct link to this comment

https://ww2.mathworks.cn/matlabcentral/answers/500006-finding-three-columns-in-one-variable-in-another-variable#comment_790107

Sign in to comment.