diff --git a/Utilities/Generic/MATLAB/Functions/diagCorr.m b/Utilities/Generic/MATLAB/Functions/diagCorr.m new file mode 100644 index 0000000000000000000000000000000000000000..bcb22005e08bdc9c46242c9aa6f533a979aa2bf9 --- /dev/null +++ b/Utilities/Generic/MATLAB/Functions/diagCorr.m @@ -0,0 +1,81 @@ +%% Calculate a "diagonality" measure/metric +% -------------------------------------------------- +% Author: Achilles Kappis +% e-mail: axilleaz@protonmail.com +% +% Date: 17/02/2025 (DD/MM/YYYY) +% +% Copyright: MIT +% -------------------------------------------------- +% Functionality: Calculate a "diagonality" measure. This provides a notion +% "how diagonal" a matrix is. In practice this is the +% correlation coefficient of a matrix to a diagonal matrix. +% -------------------------------------------------- +% Input +% +% mat [numeric]: The matrices to be "checked" for "diagonality". This can +% be either a 2D array (matrix) or a 3D array (stacked +% matrices), in which case the first two dimensions will be +% treated as matrices of which the "diagonality" will be +% checked. The matrices must be square. +% +% -------------------------------------------------- +% Output +% +% diagonality [numeric]: This is the diagonality correlation coefficient +% for each of the arrays provided. This will be +% either a scalar, if M is 2D, or a vector if M is +% 3D, with each element corresponing to the +% diagonality metric for each matrix. +% +% -------------------------------------------------- +% Notes +% +% - The metric is calculated as provided in the Mathematics StackExchange +% at https://math.stackexchange.com/a/1393907. +% +% -------------------------------------------------- +function [diagonality] = diagCorr(mat) + % ==================================================== + % Check for number of arguments + % ==================================================== + narginchk(1, 1); + nargoutchk(0, 1); + + % ==================================================== + % Validate input arguments + % ==================================================== + % Validate mandatory arguments + validateattributes(mat, "numeric", {'3d', 'square', 'nonempty'}, mfilename, "Matrices to be checked for diagonality", 1); + + + % ==================================================== + % Calculate auxiliary vectors + % ==================================================== + elemSum = ones(1, size(mat, 1)); + r = 1:length(elemSum); + r2 = r.^2; + + + % ==================================================== + % Calculate correlation coefficient to diagonal matrix + % ==================================================== + % Go through the matrices + for idx = size(mat, 3):-1:1 + % Get the matrix at the current index + tmpMat = mat(:, :, idx); + + % Calculate auxiliary values + n = sum(tmpMat, "all"); + sumRow = r * tmpMat * elemSum'; + sumCol = elemSum * tmpMat * r'; + sumRow2 = r2 * tmpMat * elemSum'; + sumCol2 = elemSum * tmpMat * r2'; + sumRowCol = r * tmpMat * r'; + + diagonality(idx) = (n * sumRowCol - sumRow * sumCol)/(sqrt(n * sumRow2 - (sumRow^2)) * sqrt(n * sumCol2 - (sumCol^2))); + end + + % Get rid of possible imaginary residuals + diagonality = real(diagonality); +end \ No newline at end of file