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)
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

Answers (2)

the cyclist
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)
  1 Comment
Steven D
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.

Sign in to comment.


dpb
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.
  8 Comments
dpb
dpb on 4 Jul 2022
That just replaces a loop and the IF construct to produce the requested distance value in the code you posted...but your function doesn't return anything it calculates for anything else to be done with it, so it doesn't matter at all what it does until you decide what it is you want/need elsewhere and set up the return values to return the needed-elsewhere variables you're calculating.
Steven D
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?

Sign in to comment.

Products


Release

R2022a

Community Treasure Hunt

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

Start Hunting!