From 65f953774109b3c57b339be3d2ba766c7712c4ca Mon Sep 17 00:00:00 2001 From: eminSerin Date: Thu, 5 Sep 2024 20:19:13 +0200 Subject: [PATCH] - Bump version. - Update CHANGELOG --- .gitignore | 7 +- CHANGELOG.txt | 17 +++- TangentSpace.m | 194 ----------------------------------------- is_positive_definite.m | 20 ----- src/.DS_Store | Bin 14340 -> 0 bytes test/.DS_Store | Bin 10244 -> 0 bytes 6 files changed, 18 insertions(+), 220 deletions(-) delete mode 100644 TangentSpace.m delete mode 100644 is_positive_definite.m delete mode 100644 src/.DS_Store delete mode 100644 test/.DS_Store diff --git a/.gitignore b/.gitignore index 817ce6a..607e757 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ # Operating system files -*.DS_Store +.DS_Store Thumbs.db .AppleDouble .LSOverride @@ -12,7 +12,4 @@ workspaces.mat src/ext/BrainNetViewer_20181219/tmp.edge src/ext/BrainNetViewer_20181219/tmp.node *.asv -src/.DS_Store -test/.DS_Store -src/.DS_Store - +develop/* diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 940ab52..25f73a6 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,4 +1,19 @@ -## [v1.0.0-beta.10] - +## [v1.0.0-beta.13] - 05.09.2024 +- Fix random seed error in newer versions of MATLAB. + +## [v1.0.0-beta.12-hotfix] - 21.04.2024 +- Add function to check if given matrix symmetric with tolerance. +- Fix minor bug in NBSPredict_predict. + +## [v1.0.0-beta.12] - 03.04.2024 +- Reintroduced LOOCV for classification problems (no LOOCV for regression yet). +- Fix minor bugs in GUI. + +## [v1.0.0-beta.11] - 21.08.2023 +- Fix minor bugs in novel data prediction function. +- Fix minor bugs in saving results. + +## [v1.0.0-beta.10] - 19.06.2023 - Refactor CPM functions. - CPM can now provide predicted and true labels, so that user can compute further performance metrics. - Prediction performance of combined network (positive and negative) is now provided. diff --git a/TangentSpace.m b/TangentSpace.m deleted file mode 100644 index 904fed8..0000000 --- a/TangentSpace.m +++ /dev/null @@ -1,194 +0,0 @@ -classdef TangentSpace < handle - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % TangentSpace Transforms positive definite covariance matrices - % into tangent space. Transforming covariance matrices - % (or positive definite correlation matrices) into tangent space - % has been shown to provide significantly higher - % prediction performance (Dadi et al., 2019; Pervaiz et al., 2020). - % - % - % - % Example: - % vectorizer = TangentSpace; - % edgeMatrix = vectorizer.transform(data); - % - % References: - % Dadi, Kamalaker, et al. "Benchmarking functional connectome-based - % predictive models for resting-state fMRI." - % NeuroImage 192 (2019): 115-134. - % Pervaiz, Usama, et al. "Optimising network modelling - % methods for fMRI." Neuroimage 211 (2020): 116604. - % - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - properties (Access = private) - dims % dimensions of the data - whitening % whitening matrix - ref_matrix % reference matrix - end - - properties (Access = public) - ref - end - - methods (Access = private) - function [] = check_positive_definite(~, X) - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % Checks whether input matrices are positive definite. - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - x_dim = size(X); - n_dims = numel(x_dim); - assert(ismember(n_dims, [2,3], 'Input matrix must be 2D or 3D!')); - if numel(x_dim) == 3 - for s = 1: x_dim(3) - assert(is_positive_definite(X(:,:,s)),... - 'Input matrix is not positive definite!') - end - elseif numel(x_dim) == 2 - assert(is_positive_definite(X),... - 'Input matrix is not positive definite!') - end - end - - function [] = map_shrinkage(obj, X) - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % Applies shrinkage each covariance matrix in X dataset. - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - switch obj.ref - case 'euclidian' - % Takes euclidian mean of input matrix. - obj.ref_matrix = squeeze(mean(X, 3)); - case 'log_euclidian' - % Computes log euclidian mean of input matrix. - obj.ref_matrix = exp(mean(log(X), 3)); - end - end - - function symMat = form_symmetric_matrix(~, X, func) - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % Constructs a symmetric matrix from a given X matrix - % using eigenvalues and eigenvectors computed from the input - % matrix. While constructing, it also applies a custom - % function to eigenvalues to transform the matrix space. - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - if nargin < 2 - func = @(x) 1./x; - end - - % Eigendecomposition - [EV,DV] = eig(X); - DV = func(DV); % transform eigenvalues using given function. - DV(isinf(DV)) = 0; - - % form matrix again. - symMat = EV*DV*EV'; - end - end - - methods - function obj = TangentSpace(varargin) - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % Initializes class. - % - % Args: - % ref: Method to compute mean reference matrix - % (default = 'euclidian'). - % - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % Default parameters. - defaultVals.ref = 'euclidian'; - refOptions = {'euclidian', 'log_euclidian'}; - - % Input Parser - validationRef = @(x) any(validatestring(x,refOptions)); - p = inputParser(); p.PartialMatching = 0; % deactivate partial matching. - addParameter(p,'ref',defaultVals.ref,validationRef); - - % Parse inputs and store into the object. - parse(p,varargin{:}); - obj.ref = p.Results.ref; - obj.dims = []; - end - - function obj = fit(obj,X) - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % Fits the tangent space transformer to the given X matrix. - % - % Args: - % X: 3D (nodes x nodes x subject) input matrix. - % - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - obj.check_positive_definite(X); - obj.ref_matrix = map_shrinkage(X); % compute reference matrix. - obj.whitening = form_symmetric_matrix(obj, X); - end - - function trans_mat = transform(obj,X) - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % Projects the input covariance matrices into tangent space - % using computed reference mean matrix. - % - % Args: - % X: 3D (nodes x nodes x subject) or 2D (nodes x nodes) - % input matrix. - % - % Output: - % trans_mat: Transformed matrix. - % - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - obj.check_positive_definite(X); - x_dim = size(X); - n_dims = numel(x_dim); - assert(ismember(n_dims, [2,3], 'Input matrix must be 2D or 3D!')); - if n_dims == 3 - nSub = x_dim(3); - trans_mat = zeros(x_dim); - elseif n_dims == 2 - nSub = 1; - trans_mat = zeros([1; x_dim(:)]'); - end - - for s = 1: nSub - trans_mat(s,:,:) = obj.form_symmetric_matrix(... - obj.whitening * X(s,:,:) * obj.whitening, log); - end - trans_mat = squeeze(trans_mat); - end - - function untrans_mat = inverse_transform(obj, X) - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - % Inverse transform from tangent space to covariance matrix - % (Riemannian space). - % - % Args: - % X: Tangent transformed input matrix. - % - % Output: - % untrans_mat: Inverse transformed, covariance matrices. - % - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - sqrt_whitening = obj.form_symmetric_matrix(obj.refMat, sqrt); - x_dim = size(X); - n_dims = numel(x_dim); - assert(ismember(n_dims, [2,3], 'Input matrix must be 2D or 3D!')); - if n_dims == 3 - nSub = x_dim(3); - untrans_mat = zeros(x_dim); - elseif n_dims == 2 - nSub = 1; - untrans_mat = zeros([1; x_dim(:)]'); - end - - for s = 1: nSub - untrans_mat(:,:,1) =... - sqrt_whitening * obj.form_symmetric_matrix(X(:,:,s), exp) *... - sqrt_whitening; - end - untrans_mat = squeeze(untrans_mat); - end - - end -end - - - diff --git a/is_positive_definite.m b/is_positive_definite.m deleted file mode 100644 index 1b30c8d..0000000 --- a/is_positive_definite.m +++ /dev/null @@ -1,20 +0,0 @@ -function [isPosDef] = is_positive_definite(X) -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% is_positive_definite Checks if given matrix is positive definite. -% -% Arguments: -% X = 2D (nodes x nodes) matrix. -% -% Output: -% isPosDef = Whether given matrices are positive definite. -% -% Emin Serin - 28.02.2022 -% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -try chol(X) - isPosDef = 1; -catch - isPosDef = 0; -end -end - diff --git a/src/.DS_Store b/src/.DS_Store deleted file mode 100644 index f26257b10dcbe6775a8f478b623f2ecc7acc329a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14340 zcmeHNU2Ggz6+UO|#4|WfCc*h*S+d1-6;dbhu7B3s{B&bGX-(SN&Bn2vrfl|SY7d>A zad&3dX+t8H2Pl+6f8c?i77!G*eMouWC%hn_MWTp8RiXk7NPyb%f`pKGC=U?My?1s! zGaK7U5Q$J`q`7zQz31H7^PTV9nR9ml00%3@I6yZ5$aJz=T}8zw0Aj569BiDO4M!98 zAf3DEq-zyGpPh+k3RY>hLH1%D5_K~DW;&Z-8Y%&On)3obxN;L{Z~~nCoIRU2tUT`v zix7bjfe?WZfe?WZfy+gJJ$vbpTSXm~Ap#)+Ap&&-*!mEolhtXro)W?vTs?%;gFKVFvf zbDyjyLqD6JHFVqQ?tTNMrsfqZTjUnGRlYYfW6fopoKvv}bLD$j>#$`R`Py|Ze?-^j zvTFN~WjZY6k(I2v>Ey|HGT9YNq!OpPVkZYu zJzcT>o}N>u6nTBe&RvJH_ZubC`ZWE1I?!EApiQ*v<)d`vv&oqD?rTiG85}QJ!^18< z@(&(g(cXUV%ljH-ip$FQ_D{rG=KCE1A4#Bt74QxF?Oxw-nQQKoo)q~c9_KzukbnBf zKbP+lZj0X+hZxSh-|K_X(Pz(p^PQJGV++^^$9$N>JWVI&3t-&>C5i+G%7l3V>;UTj zBrPxM0qLdiZ&6xWTmCmOq10j`(aVBjAjR>I(`9d}`wH+6SmpOb#}^2LfP~j4eXm~_ z_~@UwPa32aytBBJ-%s7lPl0&?9$P~mv!KXVu`JlU*2s4biyAQf9t6gfXFO}#GTI)G zzEWG|ep6fJ2zI&cV(Z*k&Y7vNbN~IC$L`}UdcCQBim)VeaFPcYT~mN7h&@#NkDn%}WrUtcMN_5521q;PF(FR@iti5AdEiEwJ$`SzvuO`F%aJhwS%_ zdp-N?o8Oy$>MicsfXsp)7nAXM4VlyY_X+r@9qxib$iNsa#Ttb-TaF#b(u<0>y#q@A z0Ov0)UjMbZ8cffkIW$@#Y?{r4>3}ACq+X)twdX;CXb=|*{gv}z32gkVh(1TyEFtaX z2uaqWe@Tr6#$1|)k3U3 zGpp7|KX}v4-F>(09lGs~v2$&!*Qm-mrG28R+j`#6#^>~+Gc%R53z}Kf&FQ1GKVmxi zeY#dw)?$}(*vyr*bLxhTn>N2M5(!GzW|^$y^#>}t^Pt)x%ia!>q4dgXQ5iRK zdCd@ANhKw#2bGDcuvm1iQ})QpBz;>_B4cdPmyQg|>d)klup8fzvz^gd&7^xX(}uT1 zB2%n?U$Lka$%0KAHmZ@4$U#|sT|R2h z8;@WXk7FJSsACyztY8&S<0tVE{1iTkU&gQCGx$|JgWty=<4^D<`~|*>zrxq>Jidi* z<2(4SgpwpRNgJe%QcUWUb_hEp@$wBYCEB%8VwTk+#;&^G-$+vzi;L*~1Gn{DleqZZ zDi#TA*S)uW{RcX>Zcp^@y0y+1L9ZI4yiDcf^ii67lLtwVSR!PU=s2-gJF!^gs4XnY z00zqDkl8X}Z>+k}68_vSZM94SbJp2*<2JgbZv6%?C0XGo|-;Yru z;a1#+H)9v}VG>h#3sG_y58&-Mf*-~Vj^hMQ;uI0Gh#KC97Cu0vbcmLxaULJWkK?2G z7=8{P$0s;Fzb1%Pr`zo{qKO)xr`n~PH-9+TdhC&1Z}S|pKDv-AG>-c6f^W>T$z8ob z4&ZKp2OfYd-}gTN`6p^iWq4O(dpk8SKp9@5pJ)14zP;_*?0W!8KRwGa;&ytG|NKnq z@A6+<9FJ=LIUY6G p=Xe8L$Sr6r%`T~)7d2hcan(Nrr2U&P|F3OGh50{Y;q{pR{|Ab_fIt8M diff --git a/test/.DS_Store b/test/.DS_Store deleted file mode 100644 index a218275b7d20074f1f55ae5d7bc285de3a4d23b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10244 zcmeGhTWlOx^_;aE&#mKl;yAXG#q~B@myo!L?Z$T8kYv4f9wupQdF|NFYcsnuwnv$r z+0M+an}!q@@sJwYs(^$*YDGcf10*OPi1LY=O5~?4l~q7hc}UO?_y7qZ1qrpBd++Ra zAGQ<&6>YV%ntSd&_nb3x&pnTOW&r@>IlT`c0sso#9IBhCS>xjK{I0q}0cICLBz^!F zY|y|56Y^EmHAGDVH4W4>P}4w712qkN7&JgRn_o(!gtfM&ftm(t8YpUj$A<{r9L55; zBB2N!)QA#*U_GJ5MSZFR1WzP@u>h_}C|F6RtR666#h}DM$xibTPEIfuz!eE4JD_9- z44#ZZg@WSg#1|3dfH4VcZA}9;4ODAj7opmyX1AznH_GaF1Cj#22oB**nqPtpcqgVN zdvl)e5??)>p*frQHYj7G{3Azrs*m z{au?H6h^-$wIl-U9l4{4bYkdcX2YVv@L)UvE*M|CsdLjeVzs{8Q?!Lq0 zmorx%yY|`ZkAG7v6EKKn&@9Kr_FEfOf|@LSJI!q;L#S0`$lHmUT{c$o>V@O^-ah2&Kj;qa9(p= z&0aL(S1(#x%CIKvxa0dyX3k7IwtTB*A%upLuE7OFkN!<6Fd92m=dzbH&p2aaffp!Rf5(}<7jJT}+K^{w9R0tR zkzFcX#|mH0hTb8caBa)67m1JSb`!-MgJM&b$EJ#?@gtfqjT&XNAJ?c*w#YK0f!5zu zDy-BfXzuMs`(MOjt1G&ixX@V!j^iE=@w_kY;Y`Ga&Z z6YdIkE6RC}A9W3CC7SIH?_sK@OnbCaDdGXPpQ#?3zC!t2vi7qBimJ02k!>Vuhz%?1 zDK?vzDM=zf&5kHrv4_o3w9e2nJ&7I(k1FafluP{Cr!~)?$Qm|1p0Dm$S2#S+@gur! z=(LEAw)UoQOZb$cob#46*O*wQQ$_(hp(tYK2+!pl(@ozgPA2%IYT9{|4l|S`<(Wo_ z#)3R2))S2d*-7O!)eh)^BXAtfL7Loh8NLEf!PD>@d=GvMKZT#eEqE1PhhM@Q@D}_5 z{sMo8f5E%(9s)ATdYiEccVZOp!*1-uhwu;{#v?e2r}1H&z)76JOPE9rQ@DhWpo>1{ z@H&18zl=}f4g5MjhtK1;@dbPle}*sPO?(Ak#n$9{gzOHgP-d}V8SNO1TGU0lmUI**??`QZP>Lw+OAT`hFzx+l8(f&Rfm zv7+5bODh;xsnH5MEwgU1ufk_44NQ6u>zpA&HXdEiiPQ#evdSu_?uxKZ^)51XIlQl% zhMUODY(?u|I_~P?5J{U#jNI_v12ufg*3k zKD2^IWpakfW?o8r)SiJjB&e)#X{^&+nsECdQ?XC~B$=iAw6(~eyfX=+fPTKDfaY&` z2Une>i8K;Cw*LSBcOa=oQqw?910PilVEtHPEKYA{r3E+PysQ)$0Eb>XYur Hvi|=!s+G