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.
1 Answer 1
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.