In question "Dictionary based non-local mean implementation in Matlab", the Manhattan distance between two three-dimensional structures can be calculated by ManhattanDistance
function. In this post, besides Manhattan distance, the functions for calculating Euclidean distance, squared Euclidean distance and maximum distance are presented here.
In mathematical form, Euclidean distance of two three-dimensional inputs X1 and X2 with size N1 x N2 x N3 is defined as
$$ \begin{split} D_{Euclidean}(X_{1}, X_{2}) & = \left\|X_{1} - X_{2}\right\|_{2} \\ & = \sqrt{\sum_{k_{1} = 1}^{N_{1}} \sum_{k_{2} = 1}^{N_{2}} \sum_{k_{3} = 1}^{N_{3}} {( X_{1}(k_{1}, k_{2}, k_{3}) - X_{2}(k_{1}, k_{2}, k_{3}) )}^{2}} \end{split} $$
Squared Euclidean distance of two three-dimensional inputs X1 and X2 with size N1 x N2 x N3 is defined as
$$ \begin{split} D_{Euclidean}^{2}(X_{1}, X_{2}) & = \left\|X_{1} - X_{2}\right\|_{2}^{2} \\ & = \sum_{k_{1} = 1}^{N_{1}} \sum_{k_{2} = 1}^{N_{2}} \sum_{k_{3} = 1}^{N_{3}} {( X_{1}(k_{1}, k_{2}, k_{3}) - X_{2}(k_{1}, k_{2}, k_{3}) )}^{2} \end{split} $$
Maximum distance of two three-dimensional inputs X1 and X2 with size N1 x N2 x N3 is defined as
$$ \begin{split} D_{Maximum}(X_{1}, X_{2}) & = \left\|X_{1} - X_{2}\right\|_{\infty} \\ & = \max_{k_{1}, k_{2}, k_{3}} {( X_{1}(k_{1}, k_{2}, k_{3}) - X_{2}(k_{1}, k_{2}, k_{3}) )} \end{split} $$
The experimental implementation
EuclideanDistance
function: for calculating Euclidean distance between two inputsfunction [output] = EuclideanDistance(X1, X2) %EUCLIDEANDISTANCE Calculate Euclidean distance between two inputs if size(X1)~=size(X2) fprintf("Sizes of inputs are not equal!\n"); return; end output = sqrt(SquaredEuclideanDistance(X1, X2)); end
SquaredEuclideanDistance
function: for calculating squared Euclidean distance between two inputsfunction [output] = SquaredEuclideanDistance(X1, X2) %SQUAREDEUCLIDEANDISTANCE Calculate squared Euclidean distance between two inputs if size(X1)~=size(X2) fprintf("Sizes of inputs are not equal!\n"); return; end output = sum((X1 - X2).^2, 'all'); end
MaximumDistance
function: for calculating maximum distance between two inputsfunction [output] = MaximumDistance(X1, X2) %MAXIMUMDISTANCE Calculate maximum distance between two inputs if size(X1)~=size(X2) fprintf("Sizes of inputs are not equal!\n"); return; end output = max(X1 - X2, [], 'all'); end
Test case
%% Three-dimensional test case
fprintf("Three-dimensional test case\n");
SizeNum = 8;
A = ones(SizeNum, SizeNum, SizeNum) .* 0.2;
B = ones(SizeNum, SizeNum, SizeNum) .* 0.1;
ED = EuclideanDistance(A, B)
MD = MaximumDistance(A, B)
SED = SquaredEuclideanDistance(A, B)
%% Four-dimensional test case
fprintf("Four-dimensional test case\n");
SizeNum = 8;
A = ones(SizeNum, SizeNum, SizeNum, SizeNum) .* 0.2;
B = ones(SizeNum, SizeNum, SizeNum, SizeNum) .* 0.1;
ED = EuclideanDistance(A, B)
MD = MaximumDistance(A, B)
SED = SquaredEuclideanDistance(A, B)
%% Five-dimensional test case
fprintf("Five-dimensional test case\n");
SizeNum = 8;
A = ones(SizeNum, SizeNum, SizeNum, SizeNum, SizeNum) .* 0.2;
B = ones(SizeNum, SizeNum, SizeNum, SizeNum, SizeNum) .* 0.1;
ED = EuclideanDistance(A, B)
MD = MaximumDistance(A, B)
SED = SquaredEuclideanDistance(A, B)
%% Six-dimensional test case
fprintf("Six-dimensional test case\n");
SizeNum = 8;
A = ones(SizeNum, SizeNum, SizeNum, SizeNum, SizeNum, SizeNum) .* 0.2;
B = ones(SizeNum, SizeNum, SizeNum, SizeNum, SizeNum, SizeNum) .* 0.1;
ED = EuclideanDistance(A, B)
MD = MaximumDistance(A, B)
SED = SquaredEuclideanDistance(A, B)
The output result of testing code above:
Three-dimensional test case
ED =
2.2627
MD =
0.1000
SED =
5.1200
Four-dimensional test case
ED =
6.4000
MD =
0.1000
SED =
40.9600
Five-dimensional test case
ED =
18.1019
MD =
0.1000
SED =
327.6800
Six-dimensional test case
ED =
51.2000
MD =
0.1000
SED =
2.6214e+03
All suggestions are welcome.
1 Answer 1
Your test cases don’t test the error condition handling:
if size(X1)~=size(X2)
fprintf("Sizes of inputs are not equal!\n");
return;
end
In the case of two inputs with different dimensionality, you will see an error message saying you’re comparing vectors of different length. This is because size
will return, say a 1x2 matrix and a 1x3 matrix, and you cannot compare those with ~=
, that operator requires equal-size arrays.
In case of two inputs with the same number of dimensions but different sizes, you will see your message printed to screen, and then an error that the output argument was not assigned a value. This is because you return without assigning to output
.
If there is an error condition, you should use error
to flag it. You can’t produce an output value and have calling code continue to process normally. Throw an error and either have the calling code handle it or the program stop altogether.
The proper way to test for equal input sizes is as follows:
if ~isequal(size(X1), size(X2))
error('Sizes of inputs are not equal!')
end
isequal
will return false if the two arrays are of different size or do not have equal values.
You could also use assert
, or the new input parameter specification system.