How do I set a parameter based on individual values in an existing array? Should I use a for loop or something else?

1 view (last 30 days)
Steven D on 3 Jul 2022
Commented: Steven D on 4 Jul 2022
I need to have 'maxDistLine' be different for different 'L' values (i.e., if L<300, then maxDistLine should be 70, or else if L is between 300 and 1000 maxDistLine should be 50, else maxDistLine should be 20. I've tried using a 'for loop', 'while', and 'if/else' statements and nothing seems to work. Please see attached section of code. Thanks in advance for any help you could offer!
Section of Code:
classdef TripletGraph2
properties
C; %triplet center points
T; %triplet endpoints
Cgraph %The undirected graph of the center points
ArcPoints %2x4xN list of arc points CenterA-EndpointA-EndpointB-CenterB
end
methods
function obj=TripletGraph2(fpep)
% maxDistLine=20;
maxLineLength=1800;
CTDist=35;
% maxDistLineDiff=7;
l2norm=@(z,varargin) vecnorm(z,2,varargin{:});
C=fpep(:,7:8); %Central points
T=reshape( fpep(:,1:6) ,[],2,3); %Triplet end-points Nx2x3
T=(T-C)./l2norm(T-C,2)*CTDist + C; %Normalize center to endpoint distances
DT=delaunayTriangulation(C); %Delaunay triangulation of centers
E=edges(DT); %Edge list
C1=C(E(:,1),:); %Center points listed for all DT edges
C2=C(E(:,2),:);
L=l2norm(C1-C2,2); %Center-to_center lengths for DT edges
if L<500
maxDistLine=21;
maxDistLineDiff=7;
elseif (500<L)&(L<1000)
maxDistLine=18;
maxDistLineDiff=7;
else
maxDistLine=15;
maxDistLineDiff=7;
end

the cyclist on 3 Jul 2022
My best guess here is that L is a vector, and you are expecting the if-else logic to work on the entire vector simultaneously. That's not how it works. For example
if L < 500
will only be true if all elements are less than 500. (The code won't check each element one-by-one.) This is described in the documentation for if, elseif, else.
So, you could loop over the elements, or you could vectorize explicitly, such as
maxDistLine = 21*(L<500) + 10*((L>=500)&(L<1000)) + 15*(L>1000)
Steven D on 3 Jul 2022
Edited: Steven D on 3 Jul 2022
Thanks for your input! However, I tried running your suggestion but was given the following error:
Unable to perform assignment because the size of the left side is 1-by-2772 and the size of the right side is 1-by-2688.
Error in TripletGraph2 (line 103)
EID2(:,:,j)=I;
Error in combined_foam_code2all (line 158)
obj=TripletGraph2(fpep);
Attached is the whole code (TripletGraph2) for all to view.

dpb on 3 Jul 2022
The above if...elseif...else...end construct works; there are other ways -- one way w/ MATLAB is
fnDL=@(L)interp1([500-eps(500),1000-eps(1000),realmax],L,'next','extrap');
using 1D lookup with builtin interp1. The eps() fixes up so the <= condition is met for the breakpoints.
An alternate that's a little more computationally efficient is a recast of the IF construct into a one-liner...
fnDL=@(L)21-3*(L>=500)-3*(L>=1000);
There are any number of ways to rewrite the above as well.
And, of course, the SWITCH construct could be used as well.
I'm sure others will think of many other similar implementations.
Steven D on 4 Jul 2022
Thanks again for your response. Where would you set up return values elsewhere--in the attached code (i.e., 'combined_foam_code2all.m')? If so, where would you put it? Is there a better way to close the polygonal cells (in the images above), then the current approach?

R2022a

Community Treasure Hunt

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

Start Hunting!