1
\$\begingroup\$

I am attempting to implement a GetNeighborhood function in order to get a specific region from inputCells by sizeInput and centralLocation parameters in 3D cells structure.

The experimental implementation

The experimental implementation of GetNeighborhood function is as below.

function [output] = GetNeighborhood(inputCells, sizeInput, centralLocation)
 % Get neighborhood of fixed size and centered at centralLocation
 output = cell( sizeInput ,sizeInput ,sizeInput );
 X = centralLocation(1);
 Y = centralLocation(2);
 Z = centralLocation(3);
 for x = -sizeInput:sizeInput
 for y = -sizeInput:sizeInput
 for z = -sizeInput:sizeInput
 if X + x < 1
 xLocation = 1;
 elseif X + x > size(inputCells, 1)
 xLocation = size(inputCells, 1);
 else
 xLocation = X + x;
 end
 
 if Y + y < 1
 yLocation = 1;
 elseif Y + y > size(inputCells, 2)
 yLocation = size(inputCells, 2);
 else
 yLocation = Y + y;
 end
 
 if Z + z < 1
 zLocation = 1;
 elseif Z + z > size(inputCells, 3)
 zLocation = size(inputCells, 3);
 else
 zLocation = Z + z;
 end
 
 output{sizeInput + x + 1, sizeInput + y + 1, sizeInput + z + 1} = ...
 inputCells{xLocation, yLocation, zLocation};
 end
 end
 end
end

Test cases

For testing purpose, a simple test script is created as below.

clear all;
clc;
close all;
set(groot,'defaultFigureVisible','on');
%% Create test cells
testCellsSize = 10;
test = cell(testCellsSize, testCellsSize, testCellsSize);
for x = 1:size(test, 1)
 for y = 1:size(test, 2)
 for z = 1:size(test, 3)
 test{x, y, z} = [x * 100 + y * 10 + z];
 end
 end
end
%% Specify test parameters
NeighborhoodDist = 1;
centralLocation = [5 2 2];
%% Perform test
result = GetNeighborhood(test, NeighborhoodDist, centralLocation);
result

The output of the above testing code:


 ×ばつ3 cell array
result(:,:,1) = 
 {[411]} {[421]} {[431]}
 {[511]} {[521]} {[531]}
 {[611]} {[621]} {[631]}
result(:,:,2) = 
 {[412]} {[422]} {[432]}
 {[512]} {[522]} {[532]}
 {[612]} {[622]} {[632]}
result(:,:,3) = 
 {[413]} {[423]} {[433]}
 {[513]} {[523]} {[533]}
 {[613]} {[623]} {[633]}

If there is any possible improvement about potential drawback or unnecessary overhead, please let me know.

asked Apr 20, 2021 at 23:58
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I think the biggest gain in efficiency you can get is to not use a cell array. Each element of a cell array is an array. Each array has a header data structure that takes up 104 bytes (if I remember that number correctly). Storing only one number in an array means that there is a memory overhead of 104/(104+8)=92%. Access is also slower because of the double indirection. To store individual numbers you should always use a numeric array.

This code:

if X + x < 1
 xLocation = 1;
elseif X + x > size(inputCells, 1)
 xLocation = size(inputCells, 1);
else
 xLocation = X + x;
end

has quite some redundancy. Every time you write the same expression twice, you should think about storing the result of the expression. Even if the computation is trivial and likely not to slow down your code, duplicated code still leads to maintenance issues. You could do instead:

xLocation = X + x;
maxLocation = size(inputCells, 1);
if xLocation < 1
 xLocation = 1;
elseif xLocation > maxLocation
 xLocation = maxLocation
end

This can be further simplified using max and min:

xLocation = X + x;
xLocation = max(xLocation, 1);
xLocation = min(xLocation, size(inputCells, 1));

You could maybe even simplify this to a single line of code, though that doesn’t improve readability:

xLocation = min(max(X + x, 1), size(inputCells, 1));

Furthermore, this code is repeated three times, so you should make it into a function you can call three times.

Once your input and output are numeric arrays, you can likely vectorize the operation, removing the loops and further simplifying the code.

clear all is not recommended. clear by itself clears the workspace, deleting all defined variables. Adding the all argument causes it to additionally remove from memory all parsed and pre-compiled functions, meaning that the next time you call those functions they’ll take longer to run. clear all is hardly ever needed, and should not be a part of your normal workflow.

answered Apr 23, 2021 at 1:22
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.