├── +experimental_scripts ├── +visualization │ ├── visualize_all.m │ ├── visualize_boundpairs.m │ ├── visualize_bundle_capacity.m │ ├── visualize_language_recognition.m │ └── visualize_repetitive_binding.m ├── boundpairs.m ├── bundle_capacity.m ├── language_recognition.m ├── place_recognition.m ├── repetitive_binding.m ├── save_results.m └── visual_place_recognition.m ├── +functions ├── createPR.m ├── get_sLSBH.m └── seqSLAMConv.m ├── +operations ├── bind_vectors.m ├── bundle_vectors.m ├── cdt.m ├── complexSim.m ├── compute_sim.m ├── convert_vectors.m ├── fractional_binding.m ├── generate_vectors.m ├── getNgram.m └── unbind_vectors.m ├── LICENSE ├── README.md ├── demo.m ├── experimental_results ├── boundpairs.mat ├── bundle_capacity.mat ├── language_recognition.mat └── repetitive_binding.mat ├── experiments_main.m └── vsa_env.m /+experimental_scripts/+visualization/visualize_all.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | %% visualization of results 25 | 26 | % setup the saving-paths 27 | if exist('workspace_path') 28 | image_path = [workspace_path '/experimental_results/plots/']; 29 | else 30 | [filepath,~,~] = fileparts(mfilename('fullpath')); 31 | image_path = fullfile(filepath, '../../experimental_results/plots/'); 32 | end 33 | 34 | if ~exist(image_path, 'dir') 35 | mkdir(image_path) 36 | end 37 | 38 | %% check visualtion 39 | % if the script is started stand alone, you have to chose which 40 | % results have to be visualized 41 | 42 | if exist('check_repetitive_binding')==0 43 | check_repetitive_binding= 1; 44 | end 45 | if exist('check_bundle_capacity')==0 46 | check_bundle_capacity= 1; 47 | end 48 | if exist('check_boundpairs')==0 49 | check_boundpairs= 1; 50 | end 51 | if exist('check_langRec')==0 52 | check_langRec= 1; 53 | end 54 | if exist('use_saved_data')==0 55 | use_saved_data= 1; 56 | end 57 | 58 | 59 | % chose vsa to plot 60 | choice_boundpairs={'MAP_B';'MAP_C'; 'MAP_I'; 'HRR'; 'HRR_VTB'; 'MBAT'; 'FHRR'; 'BSC'; 'BSDC_SHIFT'; 'BSDC_SEG'}; % are the VSA of the comparison paper 61 | choice_repBind = {'MAP_C'; 'HRR';'HRR_VTB'}; 62 | choice_cap={'MAP_B';'MAP_C'; 'MAP_I'; 'HRR'; 'FHRR'; 'BSC'; 'BSDC_SHIFT'}; % are the VSA of the comparison paper 63 | choice_lang={'MAP_B';'MAP_C'; 'MAP_I'; 'HRR'; 'HRR_VTB';'MBAT' ; 'FHRR'; 'BSC'; 'BSDC_SHIFT'; 'BSDC_SEG'}; % are the VSA of the comparison paper 64 | 65 | names_mapping_cap = containers.Map(choice_cap,{'MAP-B';'MAP-C'; 'MAP-I'; 'HRR, VTB, MBAT';'FHRR';'BSC';'BSDC-S, BSDC-SEG, BSDC-CDT'}); 66 | names_mapping_boundpairs = containers.Map(choice_boundpairs,{'MAP-B';'MAP-C'; 'MAP-I'; 'HRR'; 'VTB'; 'MBAT';'FHRR';'BSC';'BSDC-S'; 'BSDC-SEG'}); 67 | names_mapping_lang_rec = containers.Map(choice_lang,{'MAP-B';'MAP-C'; 'MAP-I'; 'HRR'; 'VTB'; 'MBAT';'FHRR';'BSC';'BSDC-S'; 'BSDC-SEG'}); 68 | 69 | %% plot results 70 | 71 | 72 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 73 | %% 74 | if check_bundle_capacity 75 | experimental_scripts.visualization.visualize_bundle_capacity 76 | end 77 | 78 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 79 | %% 80 | if check_boundpairs 81 | experimental_scripts.visualization.visualize_boundpairs 82 | end 83 | 84 | 85 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 86 | %% 87 | if check_repetitive_binding 88 | experimental_scripts.visualization.visualize_repetitive_binding 89 | end 90 | 91 | 92 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 93 | %% 94 | if check_langRec 95 | experimental_scripts.visualization.visualize_language_recognition 96 | end 97 | 98 | 99 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 100 | %% 101 | % if check_place_rec 102 | % vis_place_recognition 103 | % end 104 | 105 | 106 | -------------------------------------------------------------------------------- /+experimental_scripts/+visualization/visualize_boundpairs.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | %% visualize bindpairs results 25 | 26 | % load mat file 27 | if use_saved_data, load(fullfile(image_path, '../', 'boundpairs.mat')), end; 28 | 29 | k_curve=5; % plot explicit curve of k nearest neighbors 30 | threshold=0.99; 31 | 32 | 33 | %% plot specific curve of k role filler pairs 34 | 35 | % plot results of capacity 2 experiment 36 | figure() 37 | lines=[]; 38 | cmap=colormap('lines'); 39 | leg={}; 40 | counter=1; 41 | for i=1:size(vsa_dict,1) 42 | switch vsa_dict{i} 43 | case choice_boundpairs 44 | L=shadedErrorBar(dim_range_pairs,results_bindpairs_mean{i}(:,k_curve),results_bindpairs_var{i}(:,k_curve),'lineprops',{'color',cmap(counter,:)}); 45 | lines=[lines; L.mainLine]; 46 | leg={leg{:} strrep(vsa_dict{i},'_',' ')};% ' d=' num2str(vsa_dims(i))]; 47 | hold on; 48 | end 49 | counter=counter+1; 50 | end 51 | title(['Increasing Number of Dimensions with ' num2str(k_range(k_curve)) ' role-filler Pairs and ' num2str(item_memory_size) ' items'],'FontWeight','bold', 'FontSize',14, 'FontName','Times New Roman') 52 | xlabel('Number of dimensions') 53 | ylabel('Probability of correct query answer') 54 | xlim([1 1000]) 55 | legend(lines,strrep(leg,'_',' '),'Location','southeast') 56 | set(gcf,'color','w') 57 | set(gcf, 'Position', [700 700 900 600]) 58 | grid on 59 | if exist('export_fig') 60 | export_fig([image_path 'boundpairs_accuracy_with_' num2str(k_range(k_curve)) '_pairs.pdf'],'-dpdf') 61 | else 62 | saveas(gcf,[image_path 'boundpairs_accuracy_with_' num2str(k_range(k_curve)) '_pairs.png']) 63 | end 64 | 65 | 66 | %% plot 2D results (increasing number of dimensions and number of pairs) 67 | figure() 68 | title('k role-filler paris - probability of correct answers','FontWeight','bold', 'FontSize',16, 'FontName','Times New Roman') 69 | counter=1; 70 | for i=1:size(vsa_dict,1) 71 | switch vsa_dict{i} 72 | case choice_boundpairs 73 | subplot(2,ceil(numel(choice_boundpairs)/2),counter) 74 | counter=counter+1; 75 | imshow(flipdim(results_bindpairs_mean{i},1),[0 1]) 76 | colormap jet; 77 | axis on; 78 | xticks(1:4:numel(k_range)) 79 | xticklabels(strsplit(num2str(k_range(1:4:numel(k_range))))) 80 | xtickangle(90) 81 | yticks(1:5:numel(dim_range_pairs)) 82 | yticklabels(strsplit(num2str(flipdim(dim_range_pairs(1:5:numel(dim_range_pairs)),2)))) 83 | ylabel(['# dimensions']) 84 | xlabel(['# pairs']) 85 | title(names_mapping_boundpairs(vsa_dict{i,1})); 86 | end 87 | end 88 | colorbar('Position', [0.92 0.1 0.01 0.8]) 89 | set(gcf,'color','w') 90 | sgtitle(['Accuracies as Heatmaps'],'FontWeight','bold', 'FontSize',16, 'FontName','Times New Roman') 91 | set(gcf, 'Position', [700 700 900 400]) 92 | if exist('export_fig') 93 | export_fig([image_path 'boundpairs_2D_results.pdf'],'-dpdf') 94 | else 95 | saveas(gcf,[image_path 'boundpairs_2D_results.png']) 96 | end 97 | 98 | 99 | %% plot minimum required number of dimenesion to reach threshold accuracy 100 | 101 | result=zeros([numel(k_range) numel(vsa_dict)]); 102 | figure() 103 | lines=[]; 104 | cmap=colormap('lines'); 105 | marker = '-'; 106 | leg={}; 107 | nn=15; % number of neighbors for computing the minimum requiered number of dimensions to reach 100% accuracy with it 108 | counter=1; 109 | appr_grad_bb=zeros([numel(choice_boundpairs) 1]); 110 | disp('Bound pairs: ') 111 | for i=1:numel(vsa_dict) 112 | for l=1:numel(k_range) 113 | idx=find(results_bindpairs_mean{i}(:,l)>=threshold); 114 | if isempty(idx)==0, result(l,i)=dim_range_pairs(idx(1));, end; 115 | end 116 | 117 | switch vsa_dict{i} 118 | case choice_boundpairs 119 | valid_idx=find(result(:,i)>0); 120 | L_main=plot(k_range(valid_idx),result(valid_idx,i),':','color',cmap(counter,:),'LineWidth',0.5); 121 | hold on 122 | f=fit(k_range(valid_idx)',result(valid_idx,i),'poly1'); 123 | disp([strrep(vsa_dict{i},'_',' ') 9 'Minimum required number of dimension to reach accuracy of ' num2str(threshold) ' is: ' num2str(round(f(nn),-1))]) 124 | min_dim_nn(vsa_dict{i})=f(nn); 125 | appr_grad_bb(counter)=f.p1; 126 | if counter>7, marker = '-.'; end 127 | L=plot(f,marker); 128 | set(L,'color',cmap(counter,:),'LineWidth',2) 129 | lines=[lines; L]; 130 | leg={leg{:} names_mapping_boundpairs(vsa_dict{i,1})}; 131 | counter=counter+1; 132 | end 133 | 134 | 135 | xlabel('number of bundled pairs') 136 | ylabel('number of dimensions') 137 | % ylim([0 max(dim_range_pairs)]) 138 | ylim([0 1200]) 139 | xlim([1 max(k_range)]) 140 | legend(lines,strrep(leg,'_',' '),'Location','southeast') 141 | set(gcf,'color','w') 142 | set(gcf, 'Position', [700 700 900 400]) 143 | title(['Minimum required number of dimensions to reach ' num2str(threshold*100) '% accuracy'],'FontWeight','bold', 'FontSize',16, 'FontName','Times New Roman') 144 | grid on 145 | 146 | 147 | end 148 | if exist('export_fig') 149 | export_fig([image_path 'boundpairs_min_dim_at_thresh_of_' replace(num2str(threshold),'.','_') '.pdf'],'-dpdf') 150 | else 151 | saveas(gcf,[image_path 'boundpairs_min_dim_at_thresh_of_' replace(num2str(threshold),'.','_') '.png']) 152 | end 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /+experimental_scripts/+visualization/visualize_bundle_capacity.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | % visualize results of capacity experiment 25 | % parameter 26 | 27 | k_curve=5; % plot explicit curve of k bundled vectors 28 | threshold=0.99; 29 | plot_analytical_results = 0; 30 | 31 | % load default mat file 32 | if use_saved_data, load(fullfile(image_path, '../', 'bundle_capacity.mat')), end; 33 | 34 | %% plot the dependency of the number of items in the memory and number of dimensions 35 | if numel(item_memory_size)>1 36 | 37 | figure() 38 | cmap=colormap('lines'); 39 | if max(item_memory_size)<10; item_memory_size=item_memory_size(1:3:end); end; 40 | 41 | for r = 1:numel(item_memory_size) 42 | s=subplot(ceil(numel(item_memory_size)/3),3,r); 43 | counter = 1; 44 | marker = '-'; 45 | leg={}; 46 | lines=[]; 47 | for i=1:numel(vsa_dict) 48 | switch vsa_dict{i} 49 | case choice_cap 50 | result = zeros([numel(k_range) 1]); 51 | % average over all iterations (for better statistical 52 | % robustness) 53 | for k=1:numel(k_range) 54 | results = median(results_capacity{i}(:,k,r,:),4); 55 | idx=find(results>=threshold); 56 | if isempty(idx) == 0, result(k)=dim_range_cap(idx(1)); end; 57 | end 58 | valid_idx=find(result(:)>0); 59 | 60 | % plot experimental results 61 | L_main = plot(k_range(valid_idx),result(valid_idx),':','color',cmap(counter,:),'LineWidth',0.5); 62 | hold on 63 | 64 | % fit and plot experimental linear line 65 | f = fit(k_range(valid_idx)',result(valid_idx),'poly1'); % fit results into polynom first order 66 | 67 | L=plot(f, marker); 68 | set(L,'color',cmap(counter,:),'LineWidth',2) 69 | lines=[lines; L]; 70 | leg={leg{:} names_mapping_cap(vsa_dict{i,1})}; 71 | if max(item_memory_size)<10; title(['ratio N/D = ' num2str(item_memory_size(r))]); end; 72 | if max(item_memory_size)>10; title(['item memory size = ' num2str(item_memory_size(r))]); end; 73 | counter=counter+1; 74 | 75 | end 76 | end 77 | xlabel('number of bundled vectors') 78 | ylabel('number of dimensions') 79 | ylim([0 1200]) 80 | xlim([5 max(k_range)]) 81 | legend(lines,strrep(leg,'_','-'),'Location','southeast','FontSize', 4) 82 | set(gcf,'color','w') 83 | % title(['Minimum required number of dimensions to reach ' num2str(threshold*100) '% accuracy'],'FontWeight','bold', 'FontSize',16, 'FontName','Times New Roman') 84 | % set(gcf, 'Position', [700 700 1000 400]) 85 | grid on 86 | 87 | end 88 | 89 | if exist('export_fig') 90 | if min(item_memory_size)<1; export_fig([image_path 'bundle_capacity_memory_ratio.pdf'],'-dpdf'); end; 91 | if min(item_memory_size)>1; export_fig([image_path 'bundle_capacity_memory_size.pdf'],'-dpdf'); end; 92 | else 93 | if min(item_memory_size)<1; saveas(gcf,[image_path 'bundle_capacity_memory_ratio.png']); end; 94 | if min(item_memory_size)>1; saveas(gcf,[image_path 'bundle_capacity_memory_size.png']); end; 95 | end 96 | 97 | %% plot with fixed number of neighbors and different dimensions and item memory sizes 98 | figure() 99 | cmap=colormap('lines'); 100 | fixed_k = 10; 101 | k_idx = find(k_range==fixed_k); 102 | 103 | if min(item_memory_size)<1; is_ratio=1; else; is_ratio=0; end 104 | 105 | counter = 1; 106 | marker = '-'; 107 | leg={}; 108 | lines=[]; 109 | vsa_results = []; 110 | vsas = {}; 111 | for i=1:numel(vsa_dict) 112 | switch vsa_dict{i} 113 | case choice_cap 114 | result = zeros([numel(item_memory_size) size(results_capacity,4)]); 115 | for it=1:size(results_capacity{i},4) 116 | for r = 1:numel(item_memory_size) 117 | results = results_capacity{i}(:,k_idx,r,it); 118 | idx=find(results>=threshold); 119 | if isempty(idx) == 0, result(r,it)=dim_range_cap(idx(1)); end; 120 | end 121 | end 122 | 123 | % average over all dimensions 124 | result = mean(result,2); 125 | valid_idx=find(result(:)>0); 126 | 127 | % write to matrix 128 | vsa_results(:,end+1) = result(valid_idx); 129 | vsas{end+1} = vsa_dict{i}; 130 | 131 | % plot experimental results 132 | L_main = plot(item_memory_size(valid_idx),result(valid_idx),':','color',cmap(counter,:),'LineWidth',0.5); 133 | hold on 134 | 135 | % fit and plot experimental linear line 136 | ft = fittype('a + b*log(x)', 'dependent',{'y'},'independent',{'x'}, 'coefficients',{'a','b'}); 137 | f = fit(item_memory_size(valid_idx)',result(valid_idx),ft); % fit results into polynom first order 138 | 139 | L=plot(f,item_memory_size(valid_idx),result(valid_idx)); 140 | 141 | set(L,'color',cmap(counter,:),'LineWidth',2,'Marker','none') 142 | lines=[lines; L(end)]; 143 | leg={leg{:} names_mapping_cap(vsa_dict{i,1})}; 144 | counter=counter+1; 145 | 146 | end 147 | end 148 | if is_ratio 149 | xlabel('ratio between number of items and number of dimenions [N/D]') 150 | else 151 | xlabel('item memory size') 152 | end 153 | ylabel('number of dimensions') 154 | ylim([0 700]) 155 | legend(lines,strrep(leg,'_','-'),'Location','southeast','FontSize', 4) 156 | set(gcf,'color','w') 157 | set(gca, 'XScale', 'log') 158 | title(['Minimum required number of dimensions to reach ' num2str(threshold*100) '% accuracy with k=' num2str(fixed_k)],'FontWeight','bold', 'FontSize',16, 'FontName','Times New Roman') 159 | set(gcf, 'Position', [700 700 1000 400]) 160 | grid on 161 | 162 | if exist('export_fig') 163 | if min(item_memory_size)<1; export_fig([image_path 'bundle_capacity_memory_ratio_fix_k.pdf'],'-dpdf'); end; 164 | if min(item_memory_size)>1; export_fig([image_path 'bundle_capacity_memory_size_fix_k.pdf'],'-dpdf'); end; 165 | else 166 | if min(item_memory_size)<1; saveas(gcf,[image_path 'bundle_capacity_memory_ratio_fix_k.png']); end; 167 | if min(item_memory_size)>1; saveas(gcf,[image_path 'bundle_capacity_memory_size_fix_k.png']); end; 168 | end 169 | end 170 | 171 | %% plot results of one item memory size 172 | item_size = 1000; 173 | memory_idx = find(item_memory_size==item_size); 174 | % if the searched item memory size is in the results, plot it 175 | if numel(memory_idx)>0 176 | %% plot 2D results (increasing number of dimensions and number of neighbors) 177 | figure() 178 | counter = 1; 179 | arrow_offset = [-0.01 -0.009]; 180 | arrow_length = [0.04 0.06]; 181 | 182 | for i=1:size(vsa_dict,1) 183 | switch vsa_dict{i} 184 | case choice_cap 185 | if numel(size(results_capacity{i}))>3 186 | results_capacity_mean = mean(results_capacity{i},4); 187 | else 188 | results_capacity_mean = results_capacity{i}; 189 | end; 190 | s=subplot(2,ceil(numel(choice_cap)/2),counter); 191 | counter=counter+1; 192 | imshow(flipdim(squeeze(results_capacity_mean(:,:,memory_idx)),1)) 193 | colormap jet; 194 | axis on; 195 | xticks(1:4:numel(k_range)) 196 | xticklabels(strsplit(num2str(k_range(1:4:numel(k_range))))) 197 | xtickangle(90) 198 | yticks(1:5:numel(dim_range_cap)) 199 | yticklabels(strsplit(num2str(flipdim(dim_range_cap(1:5:numel(dim_range_cap)),2)))) 200 | ylabel(['# dimensions']) 201 | xlabel(['# bundled vectors']) 202 | title(names_mapping_cap(vsa_dict{i,1})); 203 | end 204 | end 205 | colorbar('Position', [0.92 0.1 0.01 0.8]) 206 | set(gcf,'color','w') 207 | set(gcf, 'Position', [700 700 900 400]) 208 | sgtitle(['Accuracies as Heatmaps'],'FontWeight','bold', 'FontSize',16, 'FontName','Times New Roman') 209 | if exist('export_fig') 210 | export_fig([image_path 'bundle_capacity_2D_results.pdf'],'-dpdf') 211 | else 212 | saveas(gcf,[image_path 'bundle_capacity_2D_results.png']) 213 | end 214 | 215 | %% plot minimum required number of dimenesion to reach threshold accuracy 216 | 217 | result=zeros([numel(k_range) numel(vsa_dict)]); 218 | result_analytical=zeros([numel(k_range) numel(vsa_dict)]); 219 | figure() 220 | lines=[]; 221 | cmap=colormap('lines'); 222 | marker = '-'; 223 | leg={}; 224 | nn=15; % number of neighbors for computing the minimum requiered number of dimensions to reach specific accuracy 225 | min_dim_nn=containers.Map; 226 | counter=1; 227 | appr_grad_cap=zeros([numel(choice_cap) 1]); 228 | disp('Bundling Capacity: ') 229 | for i=1:numel(vsa_dict) 230 | for k=1:numel(k_range) 231 | % average first and compute dimension second 232 | idx = find(mean(results_capacity{i}(:,k,memory_idx,:),4)>=threshold); 233 | if isempty(idx)==0, result(k,i)=dim_range_cap(idx(1)); end; 234 | end 235 | 236 | switch vsa_dict{i} 237 | case choice_cap 238 | valid_idx = find(result(:,i)>0); 239 | valid_idx_a = find(result_analytical(:,i)>0); 240 | % plot experimental results 241 | L_main = plot(k_range(valid_idx),result(valid_idx,i),':','color',cmap(counter,:),'LineWidth',0.5); 242 | hold on 243 | 244 | % fit and plot experimental linear line 245 | f = fit(k_range(valid_idx)',result(valid_idx,i),'poly1'); % fit results into polynom first order 246 | appr_grad_cap(counter)=f.p1; 247 | disp([strrep(vsa_dict{i},'_',' ') 9 'Minimum required number of dimension to reach accuracy of ' num2str(threshold) ' is: ' num2str(round(f(nn),-1))]) 248 | min_dim_nn(vsa_dict{i})=f(nn); 249 | if counter>7, marker = '-.'; end 250 | L = plot(f, marker); 251 | set(L,'color',cmap(counter,:),'LineWidth',2) 252 | 253 | % fit and plot analytical results 254 | if numel(result_analytical(valid_idx_a,i))>2 && plot_analytical_results==1 255 | f_analyt=fit(k_range(valid_idx_a)',result_analytical(valid_idx_a,i),'poly1'); 256 | L_analyt=plot(f_analyt,'--'); 257 | set(L_analyt,'color',cmap(counter,:),'LineWidth',2) 258 | lines=[lines; L; L_analyt]; 259 | leg={leg{:} vsa_dict{i,1} [vsa_dict{i,1} ' analytical']}; 260 | else 261 | lines=[lines; L]; 262 | leg={leg{:} names_mapping_cap(vsa_dict{i,1})}; 263 | end 264 | 265 | counter=counter+1; 266 | end 267 | 268 | 269 | xlabel('number of bundled vectors') 270 | ylabel('number of dimensions') 271 | % ylim([0 max(dim_range_cap)]) 272 | ylim([0 1200]) 273 | xlim([5 max(k_range)]) 274 | legend(lines,strrep(leg,'_','-'),'Location','southeast') 275 | set(gcf,'color','w') 276 | title(['Minimum required number of dimensions to reach ' num2str(threshold*100) '% accuracy'],'FontWeight','bold', 'FontSize',16, 'FontName','Times New Roman') 277 | set(gcf, 'Position', [700 700 1000 400]) 278 | grid on 279 | 280 | end 281 | if exist('export_fig') 282 | export_fig([image_path 'bundle_capacity_min_dim_at_thresh_of_' replace(num2str(threshold),'.','_') '.pdf'],'-dpdf') 283 | else 284 | saveas(gcf,[image_path 'bundle_capacity_min_dim_at_thresh_of_' replace(num2str(threshold),'.','_') '.png']) 285 | end 286 | end 287 | 288 | 289 | 290 | -------------------------------------------------------------------------------- /+experimental_scripts/+visualization/visualize_language_recognition.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | %% visualize results of language recognition experiment 25 | 26 | % load default mat file 27 | if use_saved_data, load(fullfile(image_path, '../', 'language_recognition.mat')), end; 28 | 29 | %% plot results 30 | 31 | figure() 32 | lines=[]; 33 | cmap=colormap('lines'); 34 | leg={}; 35 | counter=1; 36 | marker = '-'; 37 | for i=1:size(vsa_dict,1) 38 | switch vsa_dict{i} 39 | case choice_lang 40 | if counter>7, marker = '-.'; end 41 | L=plot(dim_range_lang(1:end-1),smooth(results_langRec{i}(1:end-1),3),marker,'color',cmap(counter,:), 'LineWidth',1.2); 42 | lines=[lines; L]; 43 | leg={leg{:} names_mapping_lang_rec(vsa_dict{i,1})}; 44 | hold on; 45 | counter = counter+1; 46 | end 47 | 48 | end 49 | 50 | title(['Accuracy in Language Recognition experiment with increasing number of dimensions'],'FontWeight','bold', 'FontSize',16, 'FontName','Times New Roman'); 51 | xlabel('Number of dimensions') 52 | ylabel('Accuracy') 53 | xlim([1 2116]) 54 | legend(lines,strrep(leg,'_',' '),'Location','southeast') 55 | set(gcf,'color','w') 56 | set(gcf, 'Position', [700 700 900 400]) 57 | grid on 58 | if exist('export_fig') 59 | export_fig([image_path 'language_recognition_acc.pdf'],'-dpdf') 60 | else 61 | saveas(gcf,[image_path 'language_recognition_acc.png']) 62 | end 63 | 64 | -------------------------------------------------------------------------------- /+experimental_scripts/+visualization/visualize_repetitive_binding.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | %% visualize the results of the repetitive binding experiment 25 | 26 | % load mat file 27 | if use_saved_data, load(fullfile(image_path, '../', 'repetitive_binding.mat')), end; 28 | 29 | % plot accuracy at specific dimension 30 | figure() 31 | lines=[]; 32 | plot_dim=16; 33 | counter=1; 34 | cmap=colormap('Lines'); 35 | leg={}; 36 | for i=1:size(vsa_dict,1) 37 | switch vsa_dict{i} 38 | case choice_repBind 39 | L=shadedErrorBar(1:bind_repetitions,results_bind_unbind1_mean{i}(plot_dim,:),results_bind_unbind1_var{i}(plot_dim,:),'lineprops',{'color',cmap(counter,:)}); 40 | lines=[lines; L.mainLine]; 41 | % leg={leg{:} upper(vsa_dict{i,1})};% ' d=' num2str(vsa_dims(i))]; 42 | leg={leg{:} names_mapping_boundpairs(vsa_dict{i,1})}; 43 | counter=counter+1; 44 | hold on; 45 | end 46 | end 47 | title(['Similarity of unbound vector with dimension D= ' num2str(dim_range_bind(plot_dim))],'FontWeight','bold', 'FontSize',14, 'FontName','Times New Roman') 48 | xlabel('number of bind repetitions') 49 | ylabel('normalized similarity to initial vector') 50 | % ylim([-1 1]); 51 | xlim([1 bind_repetitions]); 52 | legend(lines,strrep(leg,'_',' '),'Location','northeast') 53 | set(gcf,'color','w') 54 | grid on 55 | set(gcf, 'Position', [700 700 950 320]) 56 | if exist('export_fig') 57 | export_fig([image_path 'repetitive_binding.pdf'],'-dpdf') 58 | else 59 | saveas(gcf,[image_path 'repetitive_binding.png']) 60 | end 61 | 62 | %% plot 2D 63 | figure() 64 | counter=1; 65 | for i=1:size(vsa_dict,1) 66 | switch vsa_dict{i} 67 | case choice_repBind 68 | subplot(2,ceil(numel(choice_repBind)/2),counter) 69 | counter=counter+1; 70 | imshow(flipdim(results_bind_unbind1_mean{i},1),[0 1]) 71 | colormap jet; 72 | axis on; 73 | xticks(1:4:bind_repetitions) 74 | xticklabels(strsplit(num2str(1:4:bind_repetitions))) 75 | xtickangle(90) 76 | yticks(1:5:numel(dim_range_bind)) 77 | yticklabels(strsplit(num2str(flipdim(dim_range_bind(1:5:numel(dim_range_bind)),2)))) 78 | ylabel(['# dimensions']) 79 | xlabel(['# bind repetitions']) 80 | title(strrep(vsa_dict{i,1},'_',' ')); 81 | end 82 | end 83 | colorbar('Position', [0.92 0.1 0.02 0.8]) 84 | set(gcf,'color','w') 85 | set(gcf, 'Position', [700 700 1400 800]) 86 | sgtitle(['Binding-unbinding properties'],'FontWeight','bold', 'FontSize',16, 'FontName','Times New Roman') 87 | if exist('export_fig') 88 | export_fig([image_path 'bind_unbind_2d.pdf'],'-dpdf') 89 | else 90 | saveas(gcf,[image_path 'bind_unbind_2d.png']) 91 | end 92 | -------------------------------------------------------------------------------- /+experimental_scripts/boundpairs.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | 25 | %% bound pairs and retrive them 26 | % refered to the paper "A comparison of Vector Symbolic Architectures" 27 | % the bound pairs capacity experiment computes the results of bundling 28 | % bound pairs (base for table 2) 29 | % default parameters are used in the original paper 30 | % 31 | % scken, 2020 32 | 33 | 34 | % params 35 | item_memory_size=1000; 36 | k_range=3:2:51; 37 | dim_range_pairs=[2:2:40].^2; 38 | 39 | % init empty result tensor 40 | prob_correct_tensor=zeros([numel(dim_range_pairs),numel(k_range),number_iterations]); 41 | 42 | 43 | for it=1:number_iterations 44 | prob_correct_array = zeros([numel(dim_range_pairs),numel(k_range)]); 45 | 46 | disp(['iteration: ' num2str(it)]) 47 | 48 | % iterate over dimension 49 | parfor d_idx=1:numel(dim_range_pairs) 50 | VSA=vsa_env('vsa',vsa_dict{i,1},'dim',dim_range_pairs(d_idx)); 51 | 52 | % add vectors to container 53 | VSA.add_vector('num',item_memory_size); 54 | 55 | % generate k (complete range) role-filler pairs 56 | item_names=VSA.item_mem{1,2}; 57 | 58 | prob_correct=zeros([1 numel(k_range)]); 59 | 60 | % calculate the complete range of k 61 | for k_idx=1:numel(k_range) 62 | k=k_range(k_idx); 63 | 64 | % sample roles and fillers 65 | pairs_names=datasample(item_names,k*2,'Replace',false); 66 | role_names=pairs_names(1:k,:); 67 | filler_names=pairs_names(k+1:end,:); 68 | filler_idx = find(ismember(item_names,filler_names)); 69 | role_idx = find(ismember(item_names,role_names)); 70 | 71 | role = VSA.item_mem{1,1}(:,role_idx); 72 | filler = VSA.item_mem{1,1}(:,filler_idx); 73 | 74 | % bind to role filler pairs 75 | pairs = VSA.bind(role,filler); 76 | 77 | % one-step bundling: 78 | bundle = VSA.bundle(pairs,[]); 79 | 80 | % unbind all roles and search in item memory 81 | unbound_pairs = VSA.unbind(role,repmat(bundle,[1 k])); 82 | sim = VSA.sim(unbound_pairs, VSA.item_mem{1,1}); 83 | [~, max_idx] = maxk(sim, 1, 2); 84 | item_names = VSA.item_mem{1,2}; % all names of the item memory 85 | unbound_filler_names = item_names(max_idx,:); 86 | 87 | % check if the unbinded filler names are the correct names 88 | num_correct=numel(find(ismember(filler_names,unbound_filler_names))); 89 | prob_correct(k_idx)=num_correct/k; 90 | 91 | end 92 | 93 | prob_correct_array(d_idx,:) = prob_correct; 94 | 95 | end 96 | 97 | % concat each iteration to one tensor 98 | prob_correct_tensor(:,:,it)= prob_correct_array; 99 | 100 | end 101 | 102 | % compute mean and variance 103 | results_bindpairs_mean{i}=[results_bindpairs_mean{i}; mean(prob_correct_tensor,3)]; 104 | results_bindpairs_var{i}=[results_bindpairs_var{i}; var(prob_correct_tensor,1,3)]; 105 | -------------------------------------------------------------------------------- /+experimental_scripts/bundle_capacity.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | 25 | %% bundle capacity experiment 26 | % refered to the paper "A comparison of Vector Symbolic Architectures" 27 | % the bundle capacity experiment provides the data for Figure 2 28 | % default parameters are used in the original paper 29 | % 30 | % scken, 2020 31 | 32 | 33 | % params 34 | k_range = 2:2:51; 35 | dim_range_cap = [2:2:34].^2; 36 | prob_correct_tensor = zeros([numel(dim_range_cap),numel(k_range),numel(item_memory_size),number_iterations]); % init tensor for saving the results 37 | 38 | %% experimental capacity 39 | 40 | 41 | for it=1:number_iterations 42 | prob_correct_memory_size = []; 43 | disp(['iteration: ' num2str(it)]) 44 | 45 | % iterate over dimension - item_mem ratio 46 | for r = 1:numel(item_memory_size) 47 | 48 | prob_correct_array = zeros([numel(dim_range_cap),numel(k_range)]); 49 | 50 | % iterate over dimension 51 | parfor d_idx=1:numel(dim_range_cap) 52 | memory_size = item_memory_size(r); 53 | 54 | % fill data base (item memory) 55 | VSA=vsa_env('vsa',vsa_dict{i,1},'dim',dim_range_cap(d_idx)); 56 | VSA.add_vector('num',memory_size,'return_vector',0); 57 | 58 | prob_correct_answer=zeros([1 numel(k_range)]); 59 | 60 | % calculate the complete range of k 61 | item_names = VSA.item_mem{1,2}; 62 | for k_idx=1:nnz(k_range. % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | 25 | function [acc, VSA] = language_recognition(vsa, dim, num_ngrams) 26 | % perform the language recognition experiment 27 | % 28 | % INPUT: 29 | % VSA: VSA object (vsa_env) 30 | % dim: Dimesnion 31 | % num_ngrams: number of letters in ngram 32 | % OUTPUT: 33 | % acc: accuracy 34 | % VSA: VSA object (vsa_env) 35 | % 36 | % scken, 2020 37 | 38 | 39 | % load data from TUC server 40 | workspace_path = mfilename('fullpath'); 41 | workspace_path = workspace_path(1:find(workspace_path == '/',1,'last')); 42 | 43 | if isdir([workspace_path '../datasets/lang_rec'])==0 44 | mkdir([workspace_path '../datasets']); 45 | websave([workspace_path '../datasets/download'], 'https://tuc.cloud/index.php/s/skMKBzWE6RztDjF/download'); 46 | unzip([workspace_path '../datasets/download'],[workspace_path '../datasets/lang_rec']); 47 | delete([workspace_path '../datasets/download']); 48 | end 49 | 50 | dataset_path_train = [workspace_path '../datasets/lang_rec/N-grams/training']; 51 | dataset_path_test = [workspace_path '../datasets/lang_rec/N-grams/testing']; 52 | 53 | 54 | 55 | files = dir(dataset_path_train); 56 | 57 | VSA = vsa_env('vsa',vsa,'dim',dim, 'max_density', 0.5); 58 | 59 | % create bag of characters 60 | chars_item_memory = VSA.add_vector('num',10000,'add_item',0); 61 | 62 | % create n-grams sequence encodings 63 | seq_item_memory = VSA.add_vector('num',num_ngrams,'add_item',0); 64 | 65 | data_size = 0.1; 66 | 67 | %% training 68 | 69 | vector_buffer = []; 70 | name_buffer = {}; 71 | 72 | fprintf('\n Training... Computation Progress: %3d%%\n',0); 73 | parfor id=3:size(files,1) 74 | file_name = files(id,:); 75 | prog = id/(size(files,1)); 76 | fprintf(1,'\b\b\b\b%3.0f%%',prog*100); 77 | sentences = readtable([dataset_path_train '/' file_name.name '/' file_name.name '.txt'],'Format','%s','ReadVariableNames',0); 78 | 79 | text = [sentences.Var1{1:data_size*size(sentences.Var1,1)}]; 80 | buffer = []; 81 | 82 | for c=num_ngrams+1:numel(text) 83 | ngram = operations.getNgram(VSA, text(c-num_ngrams:c-1), chars_item_memory, seq_item_memory); 84 | % accumulate all vectors without normalization 85 | buffer = VSA.bundle(buffer,ngram,0); 86 | end 87 | 88 | % normalize vector into specific range 89 | language_vector = VSA.bundle(buffer,[]); 90 | 91 | vector_buffer(:,id-2) = language_vector; 92 | name_buffer{id-2,1} = file_name.name(1:3); 93 | end 94 | 95 | VSA.add_vector('vec', vector_buffer, 'name', name_buffer); 96 | 97 | %% testing 98 | 99 | files = dir(dataset_path_test); 100 | correct = 0; 101 | total = 0; 102 | 103 | fprintf('\n Testing... Computation Progress: %3d%%\n',0); 104 | parfor i=3:size(files,1) 105 | file_name = files(i,:); 106 | prog = i/(size(files,1)); 107 | fprintf(1,'\b\b\b\b%3.0f%%',prog*100); 108 | sentences = readtable([dataset_path_test '/' file_name.name '/' file_name.name '.txt'],'Format','%s','ReadVariableNames',0); 109 | 110 | currentLabel = file_name.name; 111 | 112 | % create n-grams language vector 113 | for s=1:floor(size(sentences,1)*data_size) 114 | text = [sentences.Var1{s}]; 115 | char_codes = double(text); 116 | buffer = []; 117 | 118 | % create ngrams 119 | for c=num_ngrams+1:numel(text) 120 | %create ngrams 121 | ngram = operations.getNgram(VSA, text(c-num_ngrams:c-1), chars_item_memory, seq_item_memory); 122 | % accumulate all vectors without normalization 123 | buffer = VSA.bundle(buffer,ngram,0); 124 | end 125 | 126 | % normalize vector into specific range 127 | language_vector = VSA.bundle(buffer,[]); 128 | 129 | [~, lang, ~] = VSA.find_k_nearest(language_vector,1); 130 | 131 | if lang{1} == currentLabel 132 | correct = correct +1; 133 | end 134 | 135 | total = total +1; 136 | end 137 | end 138 | 139 | acc=correct/total; 140 | 141 | fprintf('\n') 142 | 143 | end 144 | 145 | -------------------------------------------------------------------------------- /+experimental_scripts/place_recognition.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | 25 | function [sim_matrix] = place_recognition(VSA, dim, training_values, test_values, seq, permute_degree) 26 | % perform the place recognition experiment 27 | % 28 | % INPUT: 29 | % VSA: VSA object (vsa_env) 30 | % dim: Dimesnion 31 | % training_values: training vectors column wise vectors 32 | % test_values: test vectors column wise vectors 33 | % seq: number of sequences 34 | % OUTPUT: 35 | % sim_matrix: similarit matrix 36 | % 37 | % scken, 2020 38 | 39 | if nargin <=5 40 | permute_degree = 1; 41 | end 42 | 43 | %% preprocessing 44 | 45 | % create sequence vector 46 | d=floor(seq/2); 47 | 48 | timestamps = VSA.add_vector('num',2*d+1,'add_item',0); 49 | 50 | 51 | %% training 52 | num_vecs = size(training_values,2); 53 | training_sequences = training_values; 54 | 55 | for i=d+1:num_vecs-d 56 | 57 | 58 | sequence = VSA.bind(timestamps,training_values(:,(i-d):i+d)); 59 | 60 | training_sequences(:,i) = VSA.bundle(sequence,[]); 61 | % % if sparse VSA, no normalization (no thinning) 62 | % if any(strcmp(VSA.vsa,{'BSDC_SHIFT','BSDC_SEG'})) 63 | % temp = VSA.density; 64 | % VSA.density = 1; % no thinning 65 | % training_sequences(:,i) = VSA.bundle(sequence,[],0); 66 | % VSA.density = temp; 67 | % else 68 | % training_sequences(:,i) = VSA.bundle(sequence,[]); 69 | % end 70 | end 71 | 72 | 73 | %% test 74 | 75 | num_vecs = size(test_values,2); 76 | test_sequences = test_values; 77 | 78 | for i=d+1:num_vecs-d 79 | sequence = VSA.bind(timestamps,test_values(:,(i-d):i+d)); 80 | 81 | test_sequences(:,i) = VSA.bundle(sequence,[]); 82 | % % if sparse VSA, no normalization (no thinning) 83 | % if any(strcmp(VSA.vsa,{'BSDC_SHIFT','BSDC_SEG'})) 84 | % temp = VSA.density; 85 | % VSA.density = 1; % no thinning 86 | % test_sequences(:,i) = VSA.bundle(sequence,[],0); 87 | % VSA.density = temp; 88 | % else 89 | % 90 | % end 91 | end 92 | 93 | %% similarity matrix 94 | 95 | sim_matrix = VSA.sim(training_sequences, test_sequences); 96 | 97 | 98 | end -------------------------------------------------------------------------------- /+experimental_scripts/repetitive_binding.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | 25 | %% binding and unbinding properties (repetitive binding/unbinding 26 | % refered to the paper "A comparison of Vector Symbolic Architectures" 27 | % experimental setup is similar to [Gosmann 2019] with source code 28 | % https://github.com/ctn-archive/vtb/blob/master/Comparison%20of%20binding%20operations%20(VTB%20paper).ipynb 29 | % default parameters are used in the original paper 30 | % 31 | % scken, 2020 32 | 33 | dim_range_bind=[2:2:35].^2; 34 | bind_repetitions=40; 35 | 36 | % init empty result tensor 37 | sim_tensor=zeros([numel(dim_range_bind),bind_repetitions,number_iterations]); 38 | 39 | 40 | for it=1:number_iterations 41 | sim_array=[]; 42 | 43 | disp(['iteration: ' num2str(it)]); 44 | parfor d_idx=1:numel(dim_range_bind) 45 | % create VSA object 46 | VSA = vsa_env('vsa',vsa_dict{i,1},'dim',dim_range_bind(d_idx)); 47 | 48 | similarities=[]; 49 | 50 | % to normalize the similarity, calculate to highes and the lowest 51 | % similarity 52 | v1 = VSA.add_vector('add_item',0); 53 | v2 = VSA.add_vector('add_item',0); 54 | sim_equal=VSA.sim(v1,v1); 55 | sim_dif=VSA.sim(v1,v2); 56 | 57 | vec_a = VSA.add_vector('add_item',0); 58 | recovered_a = vec_a; % recovered vector after each unbinding 59 | rand_vectors = []; 60 | bound = [vec_a]; 61 | 62 | for r=1:bind_repetitions 63 | % repeat binding r times 64 | rand_vectors=[rand_vectors VSA.add_vector('add_item',0)]; 65 | bound=[bound VSA.bind(rand_vectors(:,end),bound(:,end))]; 66 | inverse=bound(:,end); 67 | for p=r:-1:1 68 | inverse=VSA.unbind(rand_vectors(:,p),inverse); 69 | end 70 | 71 | similarities=[similarities max([(VSA.sim(inverse,vec_a)-sim_dif)/(sim_equal-sim_dif) 0])]; 72 | 73 | end 74 | sim_array=[sim_array; similarities]; 75 | 76 | end 77 | sim_tensor(:,:,it)=sim_array; 78 | 79 | end 80 | 81 | results_bind_unbind1_mean{i}=[results_bind_unbind1_mean{i}; mean(sim_tensor,3)]; 82 | results_bind_unbind1_var{i}=[results_bind_unbind1_var{i}; var(sim_tensor,1,3)]; 83 | -------------------------------------------------------------------------------- /+experimental_scripts/save_results.m: -------------------------------------------------------------------------------- 1 | %% save results 2 | 3 | if check_bundle_capacity 4 | save([results_path 'bundle_capacity_' replace(datestr(datetime),{':', ' ','-'},'_') '.mat'],... 5 | 'results_capacity',... 6 | 'dim_range_cap',... 7 | 'k_range',... 8 | 'number_iterations',... 9 | 'item_memory_size',... 10 | 'vsa_dict') 11 | end 12 | 13 | if check_boundpairs 14 | save([results_path 'boundpairs_' replace(datestr(datetime),{':', ' ','-'},'_') '.mat'],... 15 | 'results_bindpairs_mean',... 16 | 'results_bindpairs_var',... 17 | 'dim_range_pairs',... 18 | 'k_range',... 19 | 'item_memory_size',... 20 | 'number_iterations',... 21 | 'vsa_dict') 22 | end 23 | 24 | 25 | if check_repetitive_binding 26 | save([results_path 'repetitive_binding_' replace(datestr(datetime),{':', ' ','-'},'_') '.mat'],... 27 | 'results_bind_unbind1_mean',... 28 | 'results_bind_unbind2_mean',... 29 | 'results_bind_unbind1_var',... 30 | 'results_bind_unbind2_var',... 31 | 'bind_repetitions',... 32 | 'dim_range_bind',... 33 | 'number_iterations',... 34 | 'vsa_dict') 35 | end 36 | 37 | if check_langRec 38 | save([results_path 'language_recognition_' replace(datestr(datetime),{':', ' ','-'},'_') '.mat'],... 39 | 'results_langRec',... 40 | 'results_langRec_VSAs',... 41 | 'dim_range_lang',... 42 | 'vsa_dict') 43 | end 44 | 45 | -------------------------------------------------------------------------------- /+experimental_scripts/visual_place_recognition.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | %% VPR experiment 25 | 26 | % select datasets for evaluation 27 | evals={}; 28 | 29 | if 1, evals(end+1,:)= {'Nordland288', 'fall', 'spring'}; end 30 | if 1, evals(end+1,:)= {'Nordland288', 'fall', 'winter'}; end 31 | if 1, evals(end+1,:)= {'Nordland288', 'spring', 'winter'}; end 32 | if 1, evals(end+1,:)= {'Nordland288', 'winter', 'spring'}; end 33 | if 1, evals(end+1,:)= {'Nordland288', 'summer', 'spring'}; end 34 | if 1, evals(end+1,:)= {'Nordland288', 'summer', 'fall'}; end 35 | if 1, evals(end+1,:)= {'oxford_2018_06_13', '141209', '141216'}; end 36 | if 1, evals(end+1,:)= {'oxford_2018_06_13', '141209', '150203'}; end 37 | if 1, evals(end+1,:)= {'oxford_2018_06_13', '141209', '150519'}; end 38 | if 1, evals(end+1,:)= {'oxford_2018_06_13', '150519', '150203'}; end 39 | if 1, evals(end+1,:)= {'StLucia', '100909_0845', '190809_0845'}; end 40 | if 1, evals(end+1,:)= {'StLucia', '100909_1000', '210809_1000'}; end 41 | if 1, evals(end+1,:)= {'StLucia', '100909_1210', '210809_1210'}; end 42 | if 1, evals(end+1,:)= {'StLucia', '100909_1410', '190809_1410'}; end 43 | if 1, evals(end+1,:)= {'StLucia', '110909_1545', '180809_1545'}; end 44 | if 1, evals(end+1,:)= {'CMU', '20110421', '20100901'}; end 45 | if 1, evals(end+1,:)= {'CMU', '20110421', '20100915'}; end 46 | if 1, evals(end+1,:)= {'CMU', '20110421', '20101221'}; end 47 | if 1, evals(end+1,:)= {'CMU', '20110421', '20110202'}; end 48 | if 1, evals(end+1,:)= {'GardensPointWalking', 'day_left', 'night_right'}; end 49 | if 1, evals(end+1,:)= {'GardensPointWalking', 'day_right', 'day_left'}; end 50 | if 1, evals(end+1,:)= {'GardensPointWalking', 'day_right', 'night_right'}; end 51 | 52 | normalization = 1 53 | netvlad = 0 54 | dim=4096 55 | sequence=5 56 | 57 | VSA_objects = cell([numel(vsa_dict) 1]); 58 | 59 | for d=1:size(evals,1) 60 | 61 | dataset = evals{d,1}; 62 | training_saison = evals{d,2}; 63 | test_saison = evals{d,3}; 64 | 65 | workspace_path = mfilename('fullpath'); 66 | workspace_path = workspace_path(1:find(workspace_path == '/',1,'last')); 67 | results_path=[workspace_path '../experimental_results/vpr/']; 68 | 69 | if ~exist(results_path, 'dir') 70 | mkdir(results_path) 71 | end 72 | 73 | dataset_path = 'datasets/'; 74 | 75 | names_mapping = containers.Map; 76 | names_mapping('NONE')='orig. Encoding'; 77 | names_mapping('Proj')='projected orig. Encoding'; 78 | names_mapping('MAP_B')='MAP {-1,1}'; 79 | names_mapping('MAP_C')='MAP [-1,1]'; 80 | names_mapping('MAP_I')='MAP integer'; 81 | names_mapping('HRR') = 'HRR'; 82 | names_mapping('HRR_VTB') = 'HRR with VTB'; 83 | names_mapping('FHRR')='FHRR uniform encod.'; 84 | names_mapping('FHRR_fft')='FHRR FFT encod.'; 85 | names_mapping('BSC')='BSC'; 86 | names_mapping('BSC_cosine')='BSC with cosine sim'; 87 | names_mapping('BSDC_SHIFT')='sparse binary with shifting'; 88 | names_mapping('BSDC_25')='sparse binary d=0.25'; 89 | names_mapping('BSDC_SEG')='sparse binary with segment binding'; 90 | names_mapping('MBAT')='MBAT'; 91 | 92 | disp('%%%%%%%%%%%%%%%%%%%%%%%%%%') 93 | disp(['Dataset: ' dataset '_' training_saison '_' test_saison]) 94 | 95 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 96 | %% load and convert data 97 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 98 | 99 | % training 100 | if netvlad==0 101 | D1=load([dataset_path 'descriptors/' dataset '/' training_saison '/alexnet_conv3.mat']); 102 | Y_train = D1.Y; 103 | else 104 | D1=load([dataset_path 'descriptors/' dataset '/' training_saison '/netvlad.mat']); 105 | if max(strcmp(dataset,{'StLucia','CMU','GardensPointWalking'}))>0 106 | Y_train = D1.Y; 107 | else 108 | Y_train = D1.Y'; 109 | end 110 | end 111 | % testing 112 | if netvlad==0 113 | D2=load([dataset_path 'descriptors/' dataset '/' test_saison '/alexnet_conv3.mat']); 114 | Y_test = D2.Y; 115 | else 116 | D2=load([dataset_path 'descriptors/' dataset '/' test_saison '/netvlad.mat']); 117 | if max(strcmp(dataset,{'StLucia','CMU','GardensPointWalking'}))>0 118 | Y_test = D2.Y; 119 | else 120 | Y_test = D2.Y'; 121 | end 122 | end 123 | 124 | %load GT 125 | if exist([dataset_path 'ground_truth/' dataset '/' training_saison '-' test_saison '/gt.mat']) 126 | load([dataset_path 'ground_truth/' dataset '/' training_saison '-' test_saison '/gt.mat']); 127 | else 128 | disp('GT is not defined!') 129 | end 130 | 131 | if sum(strcmp(dataset,{'StLucia';'CMU';'GardensPointWalking'}))>0 132 | GThard = GT.GThard; 133 | GTsoft = GT.GTsoft; 134 | end 135 | 136 | disp('finished data loading') 137 | 138 | values_train=cell([numel(vsa_dict) 1]); 139 | values_test=cell([numel(vsa_dict) 1]); 140 | 141 | % random projection matrix 142 | % set random seed 143 | rng('default') 144 | rng(1) 145 | 146 | PN = randn(dim, size(Y_train,2)); 147 | PN = normr(PN); 148 | if normalization==1 149 | Y_train_proj = normalize(Y_train * PN'); 150 | Y_test_proj = normalize(Y_test * PN'); 151 | Y_train = normalize(Y_train); 152 | Y_test = normalize(Y_test); 153 | % half the number of dimensions for sparse vectors (because sLSBH 154 | % doubled dimensions) 155 | Y_test_proj_half = normalize(Y_test * PN(1:floor(size(PN,1)/2),:)'); 156 | Y_train_proj_half = normalize(Y_train * PN(1:floor(size(PN,1)/2),:)'); 157 | 158 | else 159 | Y_train_proj = Y_train * PN'; 160 | Y_test_proj = Y_test * PN'; 161 | 162 | Y_test_proj_half = Y_test * PN(1:floor(size(PN,1)/2),:)'; 163 | Y_train_proj_half = Y_train * PN(1:floor(size(PN,1)/2),:)'; 164 | end 165 | 166 | 167 | % convert training and test values 168 | for i=1:size(vsa_dict,1) 169 | % convert values into specific ranges 170 | switch vsa_dict{i} 171 | case 'NONE' 172 | values_train{i}=Y_train'; 173 | values_test{i}=Y_test'; 174 | case 'Proj' 175 | values_train{i}=Y_train_proj'; 176 | values_test{i}=Y_test_proj'; 177 | case {'BSDC_SHIFT','BSDC_SEG'} 178 | VSA = vsa_env('vsa',vsa_dict{i},'dim',dim); 179 | values_train{i}=VSA.convert(Y_train_proj)'; 180 | values_test{i}=VSA.convert(Y_test_proj)'; 181 | VSA.dim = size(values_train{i},1); 182 | VSA_objects{i} = VSA; 183 | otherwise 184 | VSA = vsa_env('vsa',vsa_dict{i},'dim',dim); 185 | values_train{i}=VSA.convert(Y_train_proj)'; 186 | values_test{i}=VSA.convert(Y_test_proj)'; 187 | VSA_objects{i} = VSA; 188 | end 189 | end 190 | 191 | clear D1 D2 PN; 192 | disp('finished data converting') 193 | 194 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 195 | %% pairwise comparison 196 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 197 | disp('pairwise comparison') 198 | 199 | % compute similarities 200 | sim_arrays = cell([numel(vsa_dict) 1]); 201 | % sim_arrays(:) = zeros([size(Y_train,1) size(Y_test,1)]); 202 | 203 | for i=1:size(vsa_dict,1) 204 | disp(['compute sim matrix of: ' vsa_dict{i}]) 205 | sim_arrays{i}=operations.compute_sim(vsa_dict{i},values_train{i},values_test{i}); 206 | end 207 | 208 | %compare the results 209 | mAP_pairwise=zeros([numel(vsa_dict) 1]); 210 | 211 | for i=1:size(vsa_dict,1) 212 | % [p,r] = pr_hard_soft(sim_arrays{i},GThard,GTsoft,100); 213 | [p, r, V, ~, ~, ~] = functions.createPR(sim_arrays{i},GThard,GTsoft,0,0,0); 214 | mAP_pairwise(i)=trapz(r,p); 215 | end 216 | 217 | 218 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 219 | %% sequence SLAM with VSAs 220 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 221 | disp('sequence SLAM with VSAs') 222 | 223 | mAP=zeros([numel(vsa_dict) 1]); 224 | precision=cell([numel(vsa_dict) 1]); 225 | recall=cell([numel(vsa_dict) 1]); 226 | 227 | 228 | for i=1:size(vsa_dict,1) 229 | disp(['Place Recognition with VSA: ' vsa_dict{i}]) 230 | sim_matrix = zeros(size(sim_arrays{1})); 231 | 232 | switch vsa_dict{i} 233 | case {'NONE';'Proj'} 234 | sim_matrix = functions.seqSLAMConv(sim_arrays{i},sequence); 235 | 236 | otherwise 237 | sim_matrix = experimental_scripts.place_recognition(VSA_objects{i},size(values_train{i},1),values_train{i},values_test{i},sequence); 238 | end 239 | 240 | [precision{i}, recall{i}, ~, ~, ~, ~] = functions.createPR(sim_matrix,GThard,GTsoft,0,0,0); 241 | 242 | mAP(i)=trapz(recall{i},precision{i}); 243 | end 244 | 245 | 246 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 247 | %% sequence SLAM with convolution for all encodings 248 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 249 | disp('original sequence SLAM for all encodings') 250 | 251 | mAP_seqSLAMConv=zeros([numel(vsa_dict) 1]); 252 | precision_seqSLAMConv=cell([numel(vsa_dict) 1]); 253 | recall_seqSLAMConv=cell([numel(vsa_dict) 1]); 254 | 255 | 256 | for i=1:size(vsa_dict,1) 257 | disp(['Place Recognition with VSA: ' vsa_dict{i}]) 258 | sim_matrix = zeros(size(sim_arrays{1})); 259 | 260 | sim_matrix = functions.seqSLAMConv(sim_arrays{i},sequence); 261 | 262 | [precision_seqSLAMConv{i}, recall_seqSLAMConv{i}, ~, ~, ~, ~] = functions.createPR(sim_matrix,GThard,GTsoft,0,0,0); 263 | 264 | 265 | mAP_seqSLAMConv(i)=trapz(recall_seqSLAMConv{i},precision_seqSLAMConv{i}); 266 | end 267 | 268 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 269 | %% save the results 270 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 271 | 272 | for i=1:size(vsa_dict,1) 273 | current_path = [results_path vsa_dict{i} '/']; 274 | if ~exist(current_path, 'dir') 275 | mkdir(current_path); 276 | end 277 | 278 | 279 | if netvlad==1 280 | save_path = [current_path dataset '_' training_saison '_' test_saison '_normalize_' num2str(normalization) '_netvlad.mat']; 281 | else 282 | save_path = [current_path dataset '_' training_saison '_' test_saison '_normalize_' num2str(normalization) '_alexnet.mat']; 283 | end 284 | 285 | mAP_pairwise_ = mAP_pairwise(i,:); 286 | mAP_ = mAP(i,:); 287 | mAP_seqSLAMConv_ = mAP_seqSLAMConv(i,:); 288 | 289 | save(save_path,... 290 | 'mAP_pairwise_','mAP_','mAP_seqSLAMConv_',... 291 | 'vsa_dict', 'sequence') 292 | end 293 | end -------------------------------------------------------------------------------- /+functions/createPR.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Peer Neubert % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | % S ... similarity matrix 25 | % GThard ... ground truth matching matrix: places that MUST be matched; 26 | % must have the same shape as S 27 | % GTsoft ... ground truth places that CAN be matched without harm; must 28 | % have the same shape as S 29 | % removeDiagFlag ... use this if S is created from a single sequence and of 30 | % course the similarity on the main diagonal is maximal. 31 | % This uses the enlarged main diagonal from GTsoft if 32 | % available. 33 | % singleMatchFlag ... use this if only the best match in a row should be 34 | % considered as a match 35 | % 36 | % P ... precision values 37 | % R ... recall values corresponding to P values 38 | % bestP ... precision for maximum F1 score 39 | % bestR ... recall for maximum F1 score 40 | % bestF ... maximum F1 score 41 | % V ... visualization at maximum F1 score 42 | function [P, R, V, bestP, bestR, bestF] = createPR(S, GThard, GTsoft, removeDiagFlag, singleMatchFlag, evalAllSValuesFlag) 43 | if ~exist('evalAllSValuesFlag', 'var') 44 | evalAllSValuesFlag=0; 45 | end 46 | 47 | GT = logical(GThard); 48 | 49 | % remove main diagonals 50 | if removeDiagFlag 51 | % use enlarged main diagonal from GTsoft if available 52 | if ~isempty(GTsoft) 53 | seedIm = zeros(size(GT)); 54 | seedIm(1,1) = 1; 55 | maindiaMask = logical(imreconstruct(seedIm,GTsoft)); 56 | maindiaMask = maindiaMask | maindiaMask'; % expand to both sides of maindiagonal 57 | else 58 | maindiaMask = eye(size(GT),'logical'); 59 | end 60 | 61 | % also remove lower triangle 62 | maindiaMask = logical(max(maindiaMask, tril(ones(size(S))))); 63 | 64 | S(maindiaMask) = min(S(:)); 65 | GT(maindiaMask) = 0; 66 | end 67 | 68 | % remove soft-but-not-hard-entries 69 | if ~isempty(GTsoft) 70 | S(GTsoft & ~GThard) = min(S(:)); 71 | end 72 | 73 | 74 | % only keep highest value per column 75 | if nargin>4 && singleMatchFlag 76 | [~, hIdx] = max(S); 77 | hIdxInd = sub2ind(size(S), hIdx,1:size(S,2)); 78 | T = min(S(:))*ones(size(S)); 79 | T(hIdxInd) = S(hIdxInd); 80 | S = T; 81 | end 82 | 83 | R=[0]; 84 | P=[1]; 85 | 86 | startV = max(S(:)); 87 | endV = min(S(:)); 88 | 89 | bestF = 0; 90 | bestT = startV; 91 | bestP = 0; 92 | bestR = 0; 93 | 94 | if evalAllSValuesFlag 95 | s_vals = (sort(unique(S), 'descend'))'; 96 | else 97 | s_vals = linspace(startV, endV, 100); 98 | end 99 | 100 | GT_sparse = sparse(GT); % exploit (mostly) sparsity of gt-matrix 101 | for i=s_vals %linspace(startV, endV, 100)%linspace(startV, endV, 100)%sort(unique(S), 'descend')'%startV:stepV:endV 102 | B = S>=i; 103 | 104 | TP = nnz( GT_sparse & B ); 105 | FN = nnz( GT_sparse & (~B) ); 106 | FP = nnz( (~GT) & B ); 107 | 108 | P(end+1) = TP/(TP + FP); 109 | R(end+1) = TP/(TP + FN); 110 | 111 | F = 2 * P(end) * R(end) / (P(end)+R(end)); 112 | 113 | if F>bestF 114 | bestF = F; 115 | bestT = i; 116 | bestP = P(end); 117 | bestR = R(end); 118 | end 119 | end 120 | 121 | R(end+1) = 1; 122 | P(end+1) = 0; 123 | 124 | V = visualizePRAtThresh(S,GT,bestT); 125 | end 126 | 127 | 128 | function V = visualizePRAtThresh(S,GT,t) 129 | 130 | B = S>=t; 131 | 132 | TP = double(GT & B); 133 | FN = double(GT & (~B)); 134 | FP = double((~GT) & B); 135 | 136 | V = cat(3,full(FP), full(TP), full(FN)); 137 | 138 | end 139 | 140 | -------------------------------------------------------------------------------- /+functions/get_sLSBH.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Peer Neubert % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | %% sLSBH creation 24 | % Y ... descriptors as m-by-n matrix with m descriptors and n features 25 | % P ... Projection matrix; e.g. P = normc(randn(8192, 2*8192, 'single')); 26 | % s ... sparsity with s = (0,1] 27 | function L = get_sLSBH(Y, s) 28 | 29 | n = round(size(Y,2)*s); 30 | 31 | % random projection 32 | Y2 = Y; % (already done) 33 | 34 | % sort 35 | [~, IDX] = sort(Y2,2, 'descend'); 36 | 37 | % sparsification 38 | L1 = zeros(size(Y2), 'single'); 39 | % L = zeros(size(Y2), 'single'); 40 | 41 | for i = 1:size(Y2,1) 42 | L1(i,IDX(i,1:n)) = 1; 43 | % L(i,IDX(i,1:floor(n/2))) = 1; 44 | end 45 | 46 | % sort 47 | [~, IDX] = sort(Y2,2, 'ascend'); 48 | 49 | % sparsification 50 | L2 = zeros(size(Y2), 'single'); 51 | 52 | for i = 1:size(Y2,1) 53 | L2(i,IDX(i,1:n)) = 1; 54 | % L(i,IDX(i,1:floor(n/2))) = 1; 55 | end 56 | 57 | % concat 58 | L = [L1, L2]; 59 | 60 | end 61 | 62 | -------------------------------------------------------------------------------- /+functions/seqSLAMConv.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Peer Neubert % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | % Approximated SeqSLAM using convolutions 25 | % 26 | % DD ... input distance matrix 27 | % n ... approx. seq length (n ~ past+1+future) 28 | % 29 | % nepe, 2018 30 | function DDD = seqSLAMConv(DD, n) 31 | 32 | % setup possible velocities 33 | % v = 1; 34 | % v = 0.8:0.1:1.2; 35 | v = 0.5:0.1:1.5; 36 | 37 | % compute and apply filter masks 38 | T = zeros(size(DD,1), size(DD,2), numel(v)); 39 | supVal = 0; %abs(max(DD(:))) * 1.1; 40 | prevFilter = []; 41 | idx = 1; 42 | for i = 1:numel(v) 43 | H = getFilter(n,v(i)); 44 | if ~isSame(H, prevFilter) 45 | T(:,:,idx) = imfilter(DD, H, supVal, 'same'); 46 | 47 | % weight to account for boundaries 48 | W = imfilter(ones(size(DD)), H, 0, 'same'); 49 | T(:,:,idx) = T(:,:,idx) ./ W; 50 | 51 | idx = idx+1; 52 | prevFilter = H; 53 | end 54 | end 55 | 56 | T(:,:,idx:end) = []; 57 | 58 | DDD = max(T,[],3); 59 | 60 | end 61 | 62 | % Generate a [~v*n, n] mask H with a line of 1 with slope v. Dimensions of 63 | % H are odd, the line goes through the center element. 64 | % n ... number of ones 65 | % v ... slope 66 | function H = getFilter(n,v) 67 | assert(v>0); 68 | assert(v>=0.5); 69 | 70 | nh = floor(n/2); 71 | 72 | % get bottom right part 73 | x = 1:nh; 74 | y = round(x*v); 75 | hh = max(y); 76 | wh = max(x); 77 | 78 | idx = sub2ind([hh,wh], y, x); 79 | Hh = zeros(hh,wh); 80 | Hh(idx) = 1; 81 | 82 | % combine: top-left is Hh, centre is 1, bottom-right is Hh 83 | H = [Hh, zeros(hh, wh+1); 84 | zeros(1,wh), 1, zeros(1,wh); 85 | zeros(hh,wh+1), Hh]; 86 | 87 | % don't use future 88 | % H(nh+11:end, nh+1:end) = 0; 89 | 90 | end 91 | 92 | % Are matrices X and Y identical? 93 | function r = isSame(X,Y) 94 | if size(X,1) == size(Y,1) && size(X,2) == size(Y,2) && sum(X(:)==Y(:)) == numel(X) 95 | r=1; 96 | else 97 | r=0; 98 | end 99 | end -------------------------------------------------------------------------------- /+operations/bind_vectors.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | function bound_vectors = bind_vectors(vsa,vectors_1, vectors_2, varargin) 25 | % bind given vectors (vectors_1 bind vectors_2) --> it is possible to bind 26 | % multiple vectors (column-wise in vectors_1 and vectors_2) - it is an 27 | % vector-wise operation: m x n input vectors (m vectors with dimension n) 28 | % produce an m x n output 29 | % 30 | % INPUT: 31 | % vsa: vsa type 32 | % vectors_1: first vectors to bound (vector array) 33 | % vectors_2: second vectors to bound (vector array) 34 | % optional: 35 | % density: density of ones in a vector (important for binary 36 | % sparse vectors) 37 | % OUTPUT: 38 | % bound_vectors: bound vectors 1 and 2 39 | % 40 | % scken, 2020 41 | 42 | default_density=1/sqrt(size(vectors_1,1)); % density computing is optained from rachkovskji (most capacity and good stability) 43 | default_M = 0; % basic matrix for MBAT VSA 44 | 45 | p=inputParser; 46 | 47 | addParameter(p,'M',default_M); 48 | addParameter(p,'density',default_density); 49 | 50 | parse(p,varargin{:}); 51 | 52 | density = p.Results.density; 53 | M = p.Results.M; 54 | 55 | % assert(sum(size(vectors_1)==size(vectors_2))==2,'Size of vector-arrays 1 and 2 has to be the same!'); 56 | 57 | switch vsa 58 | case {'MAP_B','MAP_C','MAP_I'} 59 | % elementwise multiplication 60 | bound_vectors = vectors_1.*vectors_2; 61 | case {'BSC'} 62 | % efficient xor implementation for multi inputs 63 | bound_vectors=double(bsxfun(@plus,vectors_1,vectors_2)==1); 64 | case {'BSDC'} 65 | % disjunction of given vectors 66 | values_disj=double(bsxfun(@plus,vectors_1,vectors_2)); 67 | 68 | % CDT 69 | Z=operations.cdt(values_disj,50,1/sqrt(size(vectors_1,1))); 70 | bound_vectors = Z; 71 | case {'BSDC_SHIFT'} 72 | % calculate the shift number (sum of all ones-index) 73 | idx = [1:size(vectors_1,1)]*vectors_1; 74 | % shift each column with specific index number 75 | bound_vectors = zeros(size(vectors_1)); 76 | for i=1:numel(idx) 77 | bound_vectors(:,i) = circshift(vectors_2(:,i),idx(i)); 78 | end 79 | case {'HRR',} 80 | % circular convolution 81 | ccirc = ifft(fft(vectors_1,size(vectors_1,1),1).*fft(vectors_2,size(vectors_2,1),1)); 82 | bound_vectors=ccirc; 83 | case 'HRR_VTB' 84 | % vector-derived transformation binding 85 | val_x=vectors_1; 86 | val_y=vectors_2; 87 | num_vecs = size(vectors_1,2); 88 | dim = size(vectors_1,1); 89 | sub_d=round(sqrt(dim)); 90 | 91 | % check whether vector size has an even root 92 | assert(size(val_x,1)==sub_d^2,"In VTB: The number of dimensions must have an even root."); 93 | 94 | bound_vectors = zeros(size(vectors_1)); 95 | V_x = M; 96 | 97 | for i=1:num_vecs 98 | V_x_1 = reshape(val_x(:,i),[sub_d, sub_d]); 99 | for j=1:sub_d 100 | V_x((j-1)*sub_d+1:j*sub_d,(j-1)*sub_d+1:j*sub_d) = V_x_1; 101 | end 102 | bound_vectors(:,i) = sqrt(sub_d)*(V_x*val_y(:,i)); 103 | end 104 | case {'FHRR'} 105 | % elementwise complex multiplication 106 | bound_vectors = wrapToPi(bsxfun(@plus,vectors_1,vectors_2)); 107 | case 'BSDC_SEG' 108 | % sparse vectors with segements 109 | dim = size(vectors_1,1); 110 | num_segments = floor(dim*density); 111 | size_segments = floor(dim/num_segments); 112 | num_vecs = size(vectors_1,2); 113 | role = vectors_1(1:num_segments*size_segments,:); 114 | filler = vectors_2(1:num_segments*size_segments,:); 115 | 116 | % first part of the vector 117 | role_segments = reshape(role,[size_segments, num_segments, num_vecs]); 118 | filler_segments = reshape(filler,[size_segments, num_segments, num_vecs]); 119 | role_idx = find(role_segments); 120 | filler_idx = find(filler_segments); 121 | 122 | [role_rows, ~, ~] = ind2sub(size(role_segments),role_idx); 123 | [filler_rows, filler_cols, filler_tables] = ind2sub(size(filler_segments),filler_idx); 124 | 125 | result_rows = mod(role_rows(filler_cols.*filler_tables) + filler_rows -1, size_segments)+1; 126 | bound_vectors = zeros(size(role_segments)); 127 | 128 | idx = sub2ind(size(role_segments), result_rows, filler_cols, filler_tables); 129 | bound_vectors(idx) = 1; 130 | bound_vectors = reshape(bound_vectors,[size_segments*num_segments, num_vecs]); 131 | 132 | % if there is a remain part 133 | bound_vectors_part2 = []; 134 | if num_segments*size_segments ~= dim 135 | filler = vectors_2(num_segments*size_segments+1:end,:); 136 | bound_vectors_part2 = filler; 137 | end 138 | 139 | bound_vectors = [bound_vectors; bound_vectors_part2]; 140 | case 'MBAT' 141 | % matrix multiplication 142 | % basically from Gallant and [1] M. D. Tissera and M. D. McDonnell, “Enabling ‘question answering’ in the MBAT vector symbolic architecture by exploiting orthogonal random matrices,” Proc. - 2014 IEEE Int. Conf. Semant. Comput. ICSC 2014, pp. 171–174, 2014. 143 | num_vecs = size(vectors_1,2); 144 | bound_vectors = zeros(size(vectors_1)); 145 | 146 | for i=1:num_vecs 147 | role = vectors_1(:,i); 148 | filler = vectors_2(:,i); 149 | % generate specific order for the M matrix 150 | idx = (1:numel(role))*(role>0); 151 | M_ = circshift(M,[idx floor(idx/2)]); 152 | % M_ = M^idx; 153 | 154 | bound_vectors(:,i) = M_*filler; 155 | end 156 | 157 | otherwise 158 | disp('Representation is not defined!') 159 | 160 | end 161 | 162 | end -------------------------------------------------------------------------------- /+operations/bundle_vectors.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | function bundled_vectors = bundle_vectors(vsa, vectors_1, vectors_2, varargin) 25 | % bundle vector array 1 and vector array 2 26 | % INPUT: 27 | % vsa: VSA type 28 | % vectors_1: vectors to bundle (column-wise vector array) 29 | % if array has more than 2 dimensions, the last 30 | % dimension is used for addition 31 | % vectors_2: vectors to bundle (column-wise vector array) 32 | % normalize: if set (bool), the resulting vector will be 33 | % normalized after bundling (default is true) 34 | % density: density of the input vectors (important for 35 | % sparse vectors - CDT procedure) 36 | % max_density: maximum density after bundling (for BSDC 37 | % archtiectures) 38 | % OUTPUT: 39 | % bundled_vectors: result of bundling vectors_1 with vectors_2 40 | % 41 | % scken, 2020 42 | 43 | default_normalize = 1; 44 | default_density = 0.5; 45 | default_max_density = 1; 46 | 47 | p=inputParser; 48 | 49 | addParameter(p,'normalize', default_normalize); 50 | addParameter(p,'density',default_density); 51 | addParameter(p,'max_density',default_max_density); 52 | 53 | parse(p,varargin{:}); 54 | 55 | density = p.Results.density; 56 | normalize = p.Results.normalize; 57 | max_density = p.Results.max_density; 58 | 59 | % concatenate the two input vectors 60 | vector_array=[vectors_1, vectors_2]; 61 | dim = size(vector_array,1); 62 | 63 | n_dim = numel(size(vectors_1)); 64 | 65 | switch vsa 66 | case 'MAP_B' 67 | % majority rule 68 | values=sum(vector_array,n_dim); 69 | if normalize 70 | values(find(values<-1))=-1; 71 | values(find(values>1))=1; 72 | random_choise=double(rand([dim 1])>0.5)*2-1; 73 | values(find(values==0))=random_choise(find(values==0)); 74 | end 75 | bundled_vectors = values; 76 | case {'MAP_C'} 77 | values=sum(vector_array,n_dim); 78 | if normalize 79 | % normalization of bundeld vectors 80 | values(find(values>1))=1; 81 | values(find(values<-1))=-1; 82 | end 83 | bundled_vectors = values; 84 | case {'MAP_I'} 85 | % sum 86 | bundled_vectors = sum(vector_array,n_dim); 87 | case {'BSC'} 88 | values=sum(vector_array,n_dim); 89 | if normalize 90 | % check if number of vectors is odd (apply majority rule) 91 | number_vec=size(vector_array,2); 92 | if mod(number_vec,2)==0 93 | random_choise=double(rand([dim 1])>0.5)*1; 94 | values=values+random_choise; 95 | number_vec=number_vec+1; 96 | end 97 | 98 | thresh=number_vec/2; 99 | % if threshold highly differ from mean, than use mean 100 | % as threshold 101 | if abs(thresh-mean(values))>2 102 | thresh = mean(values); 103 | end 104 | values = double(values>thresh); 105 | end 106 | bundled_vectors = values; 107 | case {'BSDC'} 108 | % elementwise disjunction 109 | % if normalize true, thinning of the resulting bundle 110 | k = floor(max_density*size(vector_array,1)); 111 | 112 | values = sum(vector_array,n_dim); 113 | if normalize 114 | bundled_vectors = zeros([size(vector_array,1) 1]); 115 | [~, idx] = maxk(values,k); 116 | bundled_vectors(idx) = values(idx)>0; 117 | else 118 | bundled_vectors = double(values>=1); 119 | end 120 | case {'HRR', 'HRR_VTB','MBAT'} 121 | % elementwise addition 122 | values = sum(vector_array,n_dim); 123 | if normalize 124 | values = values/norm(values); 125 | end 126 | bundled_vectors = values; 127 | case {'FHRR'} 128 | % average angle 129 | 130 | vectors = zeros(size(vectors_1,1),size(vectors_1,2)+size(vectors_2,2)); 131 | vectors = [vectors_1, vectors_2]; 132 | 133 | vcos = cos(vectors); 134 | vsin = sin(vectors); 135 | 136 | vcos_sum = sum(vcos,n_dim); 137 | vsin_sum = sum(vsin,n_dim); 138 | 139 | if normalize 140 | values = atan2(vsin_sum,vcos_sum); 141 | else 142 | values = complex(vcos,vsin); 143 | end 144 | bundled_vectors = values; 145 | case {'BSDC_SHIFT'} 146 | % elementwise disjunction 147 | % select the k highest values (k is computed with the density) 148 | k = floor(max_density*size(vector_array,1)); 149 | 150 | values = sum(vector_array,n_dim); 151 | if normalize 152 | bundled_vectors = zeros([size(vector_array,1) 1]); 153 | [~, idx] = maxk(values,k); 154 | bundled_vectors(idx) = values(idx)>0; 155 | else 156 | bundled_vectors = single(values>0); 157 | end 158 | case 'BSDC_SEG' 159 | num_segments = floor(dim*density); 160 | size_segments = floor(dim/num_segments); 161 | k = floor(max_density*size_segments); 162 | 163 | values = sum(vector_array,n_dim); 164 | 165 | if normalize 166 | values_segments = reshape(values(1:size_segments*num_segments),[size_segments, num_segments]); 167 | [~, idx] = maxk(values_segments,k); 168 | idx = sub2ind(size(values_segments), idx, repmat(1:num_segments,[size(idx,1) 1])); 169 | bundled_vectors = zeros(size(values_segments)); 170 | bundled_vectors(idx) = values_segments(idx); 171 | bundled_vectors = reshape(bundled_vectors, [], 1)>0; 172 | else 173 | bundled_vectors = values; 174 | end 175 | 176 | if size_segments*num_segments~=size(values,1) 177 | bundled_vectors = [bundled_vectors; values(size_segments*num_segments+1:end)]; 178 | end 179 | 180 | otherwise 181 | disp('Representation is not defined!') 182 | end 183 | bundled_vectors = single(bundled_vectors); 184 | end -------------------------------------------------------------------------------- /+operations/cdt.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | function Z = cdt(superposition_vector, max_iters, density) 25 | % apply the CDT Procedure at given vector (superposition) 26 | % INPUT: 27 | % superposition_vector: superimposed vector of all inputs 28 | % max_iters: max number of iterations within CDT 29 | % procedure 30 | % density: density of original vector 31 | % OUTPUT: 32 | % Z: thinned output vector 33 | 34 | % apply CDT procedure 35 | Z=superposition_vector; 36 | counter=1; 37 | % rng('default') 38 | % rng(0); 39 | while mean(sum(Z)/size(Z,1))>density 40 | % r=randi(size(Z,1),1); % random permutation 41 | r = counter; % detemine the shifting 42 | permutation=circshift(superposition_vector,r); 43 | thinned=and(superposition_vector,permutation); 44 | Z(thinned)=0; 45 | if counter>max_iters %if more then max_iters iteration, break loop 46 | break 47 | end 48 | counter=counter+1; 49 | 50 | end 51 | % rng('shuffle') 52 | end 53 | 54 | -------------------------------------------------------------------------------- /+operations/complexSim.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | function sim_matrix = complexSim(v1,v2) 25 | % compute the similarity between vectors of angles (from complex numbers 26 | % --> FHRR) 27 | 28 | sim_matrix = zeros(size(v1,1),size(v2,1)); 29 | 30 | for i=1:size(v1,1) 31 | sim_matrix(i,:)=sum(cos(v1(i,:)-v2),2)/size(v1,2); 32 | end 33 | 34 | 35 | end -------------------------------------------------------------------------------- /+operations/compute_sim.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | function [sim_matrix] = compute_sim(vsa,vectors_1,vectors_2) 25 | % compute similarity between vector array 1 and 2 26 | % INPUT: 27 | % vectors_1 - vector array 1 (column wise) 28 | % vectors_2 - vector array 2 (column wise) 29 | % OUTPUT: 30 | % sim_matrix:- similarity array (or value if both are single 31 | % vectors) 32 | % 33 | % scken, 2020 34 | 35 | % first transpose the arrays 36 | vectors_1 = vectors_1'; 37 | vectors_2 = vectors_2'; 38 | 39 | sim_matrix = zeros([size(vectors_1,1) size(vectors_2,1)]); 40 | 41 | warning('off') 42 | switch vsa 43 | case {'MAP_B','MAP_C','HRR','HRR_VTB','NONE','MAP_I','MBAT','Proj','FHRR_cos'} 44 | % cosine similarity 45 | sim_matrix = (vectors_1./sqrt(sum(vectors_1.^2,2)))*(vectors_2./sqrt(sum(vectors_2.^2,2)))'; 46 | case 'BSC' 47 | % hamming distance 48 | sim_matrix = 1-pdist2(vectors_1,vectors_2,'hamming'); 49 | case {'BSDC','BSDC_SHIFT','BSDC_25', 'BSDC_SEG','BSDC_THIN'} 50 | % overlap 51 | vectors_1 = vectors_1>0; 52 | vectors_2 = vectors_2>0; 53 | sim_matrix = vectors_1*vectors_2'; 54 | case {'FHRR_fft','FHRR'} 55 | % average of cosine of distance 56 | 57 | % convert to complex values 58 | sim_matrix = real(exp(vectors_1*1i)*exp(vectors_2*1i)')/size(vectors_1,2); 59 | otherwise 60 | disp('Representation is not defined!') 61 | end 62 | 63 | warning('on') 64 | 65 | end 66 | -------------------------------------------------------------------------------- /+operations/convert_vectors.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | function values = convert_vectors(vsa, Y, density) 25 | %CONVERT_NUMBERS 26 | % convert the number space respective to the vsa 27 | % INPUT: 28 | % Y: data values (each row is one data-point-vector) 29 | % vsa: name of the vsa (string) 30 | % optional: 31 | % density: density of on bits (for sparse binary vectors) 32 | % OUTPUT: 33 | % values: converted values of input data (respective to the vsa) 34 | 35 | if nargin >2 36 | density = density; 37 | else 38 | % set default density 39 | switch vsa 40 | case {'BSDC', 'BSDC_test','BSDC_SHIFT'} 41 | density=1/sqrt(size(Y,2)); % density computing is optains from rachkovskji (most capacity and good stability) 42 | case 'BSDC_25' 43 | density=0.25; 44 | case 'BSDC_SEG' 45 | density=1/sqrt(size(Y,2)); 46 | otherwise 47 | density=0.5; 48 | end 49 | end 50 | 51 | switch vsa 52 | case {'MAP_C'} 53 | % convert 54 | values=Y; 55 | % values=(values-min(values,[],2))./(max(values,[],2)-min(values,[],2)); 56 | values(values>1)=1; 57 | values(values<-1)=-1; 58 | case 'map_trans_uniform' 59 | % convert 60 | values=Y; 61 | parfor i=1:size(Y,1) 62 | pd = makedist('Normal','mu',mean(Y(i,:)),'sigma',sqrt(var(Y(i,:)))); 63 | values(i,:)=cdf(pd,Y(i,:))*2-1; 64 | end 65 | case {'MAP_B','MAP_I'} 66 | % convert 67 | values=double(Y>0)*2-1; 68 | case {'BSC'} 69 | % convert 70 | values=double(Y>0); 71 | case {'HRR', 'HRR_VTB','MBAT'} 72 | % convert 73 | values=normr(Y); 74 | case {'FHRR'} 75 | % convert 76 | values=angle(fft(Y,size(Y,2),2)); 77 | case {'BSDC','BSDC_SHIFT','BSDC_SEG'} 78 | % project values 79 | values = functions.get_sLSBH(Y,density); 80 | case {'NONE', 'Proj.'} 81 | % use the original vectors without converting 82 | values = Y; 83 | otherwise 84 | disp('Representation is not defined!') 85 | end 86 | 87 | end 88 | 89 | -------------------------------------------------------------------------------- /+operations/fractional_binding.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | function v = fractional_binding(vsa, vector, k) 25 | % FRAC_BINDING Apply fractional binding of a vector with an scalar 26 | % k (see Eliasmith) 27 | % INPUT: 28 | % vsa: VSA tpe 29 | % vector: initial vector 30 | % k: scalar for fractional binding of vector (can be a array 31 | % with multiple scalars) 32 | % OUTPUT: 33 | % v: fractional bound vector (k encoded in vector) 34 | 35 | switch vsa 36 | case {'FHRR','FHRR_fft'} 37 | v=wrapToPi(repmat(vector,[size(k)]).*k); 38 | case {'BSDC','BSDC_SEG','BSDC_SHIFT','BSC','BSDC_25'} 39 | values = ifft(fft(repmat(vector,[1 numel(k)]),size(vector,1),1).^k,size(vector,1),1); 40 | v=angle(values)>0; 41 | otherwise 42 | values = ifft(fft(repmat(vector,[1 numel(k)]),size(vector,1),1).^k,size(vector,1),1); 43 | v=real(values); 44 | end 45 | 46 | end -------------------------------------------------------------------------------- /+operations/generate_vectors.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | function gen_vecs = generate_vectors(varargin) 25 | % generate vectors within the specific ranges 26 | % INPUT (optinal): 27 | % dim - number of dimensions 28 | % vsa - vsa representation 29 | % num - number of to generated vectors 30 | % density - density (for binary) 31 | % OUTPUT: 32 | % gen_vecs: - column-wise matrix with generated vectors 33 | 34 | 35 | default_dim = 10000; 36 | default_vsa = 'map'; 37 | default_density = -1; 38 | default_num = 1; 39 | 40 | p=inputParser; 41 | 42 | addOptional(p, 'dim', default_dim) 43 | addOptional(p, 'vsa', default_vsa) 44 | addOptional(p, 'num', default_num) 45 | addOptional(p, 'density', default_density) 46 | 47 | parse(p,varargin{:}) 48 | dim = p.Results.dim; 49 | vsa = p.Results.vsa; 50 | num = p.Results.num; 51 | 52 | if p.Results.density == -1 53 | % define default density 54 | switch vsa 55 | case {'BSDC', 'BSDC_test','BSDC_SHIFT','BSDC_THIN'} 56 | density=1/sqrt(dim); % density computing is optains from rachkovskji (most capacity and good stability) 57 | case 'BSDC_25' 58 | density=0.25; 59 | case 'BSDC_SEG' 60 | density=1/sqrt(dim); 61 | otherwise 62 | density=0.5; 63 | end 64 | else 65 | density = p.Results.density; 66 | end 67 | 68 | 69 | 70 | switch vsa 71 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 72 | % MAP and MBAT 73 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 74 | case {'MAP_B','MAP_I'} % Gaylers Multiplication, Addition and Permutaiton Architecture with bipolar vector space {-1,1} 75 | % gen_vecs = binornd(1,0.5,[dim num])*2-1; 76 | gen_vecs = single(rand([dim num],'single')>0.5)*2-1; 77 | 78 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 79 | % MAP 80 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 81 | case {'MAP_C'} % Gaylers Multiplication, Addition and Permutaiton Architecture 82 | 83 | gen_vecs = rand([dim num],'single')*2-1; 84 | 85 | % quantize to 4 bits 86 | % gen_vecs = quantize(fi(gen_vecs),numerictype(1,8,4)); 87 | 88 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 89 | % BSC 90 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 91 | case {'BSC'} 92 | % gen_vecs = binornd(1,0.5,[dim num]); 93 | gen_vecs = single(rand([dim num],'single')>0.5); 94 | 95 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 96 | % BSDC 97 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 98 | case {'BSDC','BSDC_SHIFT','BSDC_25','BSDC_THIN'} 99 | 100 | rand_values = rand([dim num],'single'); 101 | 102 | % find the k highest idex (k correspond to 103 | % density) 104 | [~,rows] = maxk(rand_values, ceil(dim*density)); 105 | values = zeros(size(rand_values)); 106 | idx=sub2ind(size(rand_values),rows,repmat(1:size(rand_values,2),[size(rows,1) 1])); 107 | values(idx) = 1; 108 | 109 | gen_vecs = single(values); 110 | 111 | 112 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 113 | % BSDC-SEG 114 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 115 | case {'BSDC_SEG'} 116 | % create segments (depending on density) and set one bit per 117 | % segment to 1 118 | num_segments = floor(dim*density); 119 | size_segments = floor(dim/num_segments); 120 | 121 | z = zeros([size_segments num_segments num],'single'); 122 | rand_r = randi(size_segments,[num_segments num],'single'); 123 | rand_c = repmat((1:num_segments)', [1 num]); 124 | rand_t = repmat(1:num,[num_segments 1]); 125 | indices = sub2ind(size(z),rand_r, rand_c, rand_t); 126 | z(indices) = 1; 127 | 128 | gen_vecs = reshape(z,[], num); 129 | if dim~=num_segments*size_segments 130 | d = dim-num_segments*size_segments; 131 | gen_vecs = [gen_vecs; zeros([d num])]; 132 | end 133 | 134 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 135 | % HRR 136 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 137 | case {'HRR','HRR_VTB','MBAT'} 138 | gen_vecs = randn([dim num],'single')*sqrt(1/dim); 139 | 140 | 141 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 142 | % HRR complex 143 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 144 | case {'FHRR','FHRR_fft','FHRR_cos'} 145 | gen_vecs = rand([dim num],'single')*2*pi-pi; 146 | 147 | 148 | otherwise 149 | disp('Representation is not defined!') 150 | end 151 | 152 | end -------------------------------------------------------------------------------- /+operations/getNgram.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | function ngram = getNgram(VSA, keys, char_item_memory, seq_item_memory) 25 | 26 | key_codes = double(keys); 27 | num_ngrams = length(key_codes); 28 | %create ngrams 29 | ngram = VSA.permute(char_item_memory(:,key_codes(1))); 30 | for i=2:num_ngrams 31 | ngram = VSA.bind(ngram,VSA.permute(char_item_memory(:,key_codes(i)),i)); 32 | end 33 | 34 | end 35 | 36 | -------------------------------------------------------------------------------- /+operations/unbind_vectors.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | function unbound_vectors = unbind_vectors(vsa,vectors_1, vectors_2, varargin) 25 | % unbind given vectors (vectors_1 unbind vectors_2) --> it is possible to unbind 26 | % multiple vectors (column-wise in vectors_1 and vectors_2) - it is an 27 | % vector-wise operation: m x n input vectors (m vectors with dimension n) 28 | % produce an m x n output 29 | % 30 | % INPUT: 31 | % vsa: vsa type 32 | % vectors_1: first vectors to unbound 33 | % vectors_2: second vectors to unbound 34 | % optional: 35 | % density: density of ones in a vector (important for binary 36 | % sparse vectors) 37 | % OUTPUT: 38 | % unbound_vectors: bound vectors 1 and 2 39 | % 40 | % scken, 2020 41 | 42 | 43 | default_density=1/sqrt(size(vectors_1,1)); % density computing is optained from rachkovskji (most capacity and good stability) 44 | default_M = 0; % basic matrix for MBAT VSA 45 | 46 | p=inputParser; 47 | 48 | addParameter(p,'M',default_M); 49 | addParameter(p,'density',default_density); 50 | 51 | parse(p,varargin{:}); 52 | 53 | density = p.Results.density; 54 | M = p.Results.M; 55 | 56 | 57 | switch vsa 58 | case {'MAP_B','MAP_C','MAP_I'} 59 | % elementwise multiplication 60 | unbound_vectors = vectors_1.*vectors_2; 61 | case {'BSC'} 62 | % efficient xor implementation for multi inputs 63 | unbound_vectors = double(bsxfun(@plus,vectors_1,vectors_2)==1); 64 | case {'BSDC'} 65 | % find the most similar item in item_mem 66 | disp('There is no specific unbind operator for the selected VSA - use the finding of the most similar vectors in item memory instead!'); 67 | case {'BSDC_SHIFT'} 68 | % calculate the shift number (sum of all ones-index) 69 | idx = [1:size(vectors_1,1)]*vectors_1; 70 | % shift each column with specific index number 71 | unbound_vectors = zeros(size(vectors_1)); 72 | for i=1:numel(idx) 73 | unbound_vectors(:,i) = circshift(vectors_2(:,i),-idx(i)); 74 | end 75 | case {'HRR',} 76 | % involution as approximate inverse 77 | inverse=[vectors_1(1,:); flip(vectors_1(2:end,:))]; 78 | unbound_vectors = ifft(fft(inverse,size(vectors_1,1),1).*fft(vectors_2,size(vectors_2,1),1)); 79 | case 'HRR_VTB' 80 | val_x = vectors_1; 81 | val_y = vectors_2; 82 | dim = size(vectors_1,1); 83 | sub_d = round(sqrt(dim)); 84 | assert(size(val_x,1)==sub_d^2,"In VTB: The number of dimensions must have an even root."); 85 | num_vecs = size(vectors_1,2); 86 | 87 | unbound_vectors = zeros(size(vectors_1)); 88 | V_x = M; 89 | 90 | for i=1:num_vecs 91 | % transpose the y vector 92 | V_x_1 = reshape(val_x(:,i),[sub_d, sub_d])'; 93 | 94 | for j=1:sub_d 95 | V_x((j-1)*sub_d+1:j*sub_d,(j-1)*sub_d+1:j*sub_d) = V_x_1; 96 | end 97 | unbound_vectors(:,i) = sqrt(sub_d)*V_x*val_y(:,i); 98 | end 99 | case {'FHRR'} 100 | % complex multiplication with negative 'role' vector 101 | unbound_vectors = wrapToPi(bsxfun(@minus,vectors_2,vectors_1)); 102 | case 'BSDC_SEG' 103 | % sparse vectors with segements 104 | 105 | dim = size(vectors_1,1); 106 | num_segments = floor(dim*density); 107 | num_vecs = size(vectors_1,2); 108 | size_segments = floor(dim/num_segments); 109 | role = vectors_1(1:num_segments*size_segments,:); 110 | filler = vectors_2(1:num_segments*size_segments,:); 111 | 112 | % first part of the vector 113 | role_segments = reshape(role,[size_segments, num_segments, num_vecs]); 114 | filler_segments = reshape(filler,[size_segments, num_segments, num_vecs]); 115 | role_idx = find(role_segments); 116 | filler_idx = find(filler_segments); 117 | 118 | [role_rows, role_cols, role_tables] = ind2sub(size(role_segments),role_idx); 119 | [filler_rows, filler_cols, filler_tables] = ind2sub(size(filler_segments),filler_idx); 120 | 121 | result_rows = mod(filler_rows - role_rows(filler_cols.*filler_tables) -1, size_segments)+1; 122 | unbound_vectors = zeros(size(role_segments)); 123 | 124 | idx = sub2ind(size(role_segments), result_rows, filler_cols, filler_tables); 125 | unbound_vectors(idx) = 1; 126 | unbound_vectors = reshape(unbound_vectors,[size_segments*num_segments, num_vecs]); 127 | 128 | % if there is a remain part 129 | unbound_vectors_part2 = []; 130 | if num_segments*size_segments ~= dim 131 | filler = vectors_2(num_segments*size_segments+1:end,:); 132 | unbound_vectors_part2 = filler; 133 | end 134 | 135 | unbound_vectors = [unbound_vectors; unbound_vectors_part2]; 136 | case 'MBAT' 137 | % matrix multiplication 138 | num_vecs = size(vectors_1,2); 139 | unbound_vectors = zeros(size(vectors_1)); 140 | 141 | for i=1:num_vecs 142 | role = vectors_1(:,i); 143 | filler = vectors_2(:,i); 144 | % generate specific order for the M matrix 145 | idx = (1:numel(role))*(role>0); 146 | M_ = circshift(M,[idx floor(idx/2)])'; 147 | % M = (M^idx)'; 148 | 149 | unbound_vectors(:,i) = M_*filler; 150 | end 151 | 152 | otherwise 153 | disp('Representation is not defined!') 154 | end 155 | 156 | end -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VSA_toolbox 2 | 3 | The VSA_toolbox is a MATLAB implementation to develop and apply different kinds of VSA within one environment. 4 | It is also the source code to the paper [1]. 5 | 6 | [1] K. Schlegel, P. Neubert, and P. Protzel, “[A comparison of vector symbolic architectures](https://link.springer.com/article/10.1007/s10462-021-10110-3),” Artif. Intell. Rev., Dec. 2021. 7 | 8 | 9 | ## Requirements 10 | 11 | * MATLAB shadedErrorBar function to plot the results (https://de.mathworks.com/matlabcentral/fileexchange/26311-raacampbell-shadederrorbar) 12 | Clone the folder to your workspace: 13 | ``` 14 | git clone https://github.com/raacampbell/shadedErrorBar 15 | ``` 16 | * [optional] MATLAB export_fig function to export the plots as pdf - if not installed, the script saves the plots as png (https://de.mathworks.com/matlabcentral/fileexchange/23629-export_fig) 17 | 18 | 19 | ## Installation 20 | 21 | * no specific installation is required 22 | * start the scripts from the "VSA_toolbox" folder 23 | 24 | ## Usage 25 | 26 | ### Use the toolbox 27 | 28 | * the script "demo.m" contains a demonstration of using the toolbox 29 | * first, create an object with "vsa_env.m" and specify the architecture 30 | * available architectures are: **MAP-B, MAP-C, MAP-I, BSC, HRR, VTB, FHRR, BSDC, BSDC-S, BSDC-SEG, MBAT** (see paper for explanation) 31 | * methods of such an VSA environment object are the operations, like bundling, binding, unbinding and similarity measurement 32 | * the folder "+operation" contains the implementations of the operators for each VSA 33 | 34 | ### Reproduce the experiments 35 | 36 | * start the experiment main script: 37 | ``` experiments_main ``` 38 | * it contains subscripts for bundle capacity, binding pairs capacity, repetitive binding/unbinding and language recognition (place recognition will be published as soon as possible) 39 | * default parameters are used in the paper 40 | * after execution, a folder named "experimental_results" is created in the main folder with a sub-folder "plots", which contains the plotted curves 41 | 42 | 43 | ### Plot the figures from the paper 44 | 45 | * the folder "experimental_results" contains the original .mat files from the experiments in the paper 46 | * to plot the figures, start the script "visualize_all.mat" with the default parameter setup: 47 | ```experimental_scripts.visualization.visualize_all ``` 48 | 49 | 50 | ## License 51 | This code is released under the GNU General Public License version 3. 52 | -------------------------------------------------------------------------------- /demo.m: -------------------------------------------------------------------------------- 1 | %% DEMO of VSA environment scripting 2 | clear all 3 | close all 4 | 5 | % create the object of a specific VSA type 6 | type = 'MAP_B'; % available types: 'MAP_C'; 'MAP_B'; 'MAP_I'; 'BSC'; 'BSDC'; 'BSDC_SHIFT'; 'BSDC_SEG'; 'HRR'; 'HRR_VTB'; 'FHRR' 7 | VSA = vsa_env('vsa',type,'dim',1024); 8 | 9 | % add vectors to item memory (randomly chosen) 10 | VSA.add_vector('num',100); 11 | % the VSA has the 100 random vectors in the item memory with random names 12 | 13 | % another way is to generate vectors without adding to the item memory 14 | vectors = VSA.add_vector('num',100,'add_item',0); % set add_item to 0 15 | 16 | %%%%%%%%%%%%%%%%%%%%%%%%%%%% 17 | %% 1. bundling 18 | %%%%%%%%%%%%%%%%%%%%%%%%%%%% 19 | 20 | %%% single vector bundling 21 | v1 = VSA.add_vector('num',1,'add_item',0); 22 | v2 = VSA.add_vector('num',1,'add_item',0); 23 | v3 = VSA.add_vector('num',1,'add_item',0); 24 | bundle = VSA.bundle(v1,v2); 25 | 26 | % bundle is similar to v1 and v2 but not to v3 27 | sim = VSA.sim(bundle,[v1 v2 v3]); 28 | disp('------- single vector bundling:') 29 | disp(['Similarity of bundle to v1 = ' num2str(sim(1))]); 30 | disp(['Similarity of bundle to v2 = ' num2str(sim(2))]); 31 | 32 | 33 | %%% multiple vector bundling 34 | % it is also possible to bundle multiple vectors (vectors arrays) 35 | % e.g. vectors array 1 as well as array 2 contain 10 vectors and can be 36 | % bundled together into one vector 37 | v_array_1 = VSA.add_vector('num',10,'add_item',0); 38 | v_array_2 = VSA.add_vector('num',10,'add_item',0); 39 | bundle = VSA.bundle(v_array_1, v_array_2); 40 | 41 | % bundle is similar to all vectors of array 1 and 2 42 | sim_array = VSA.sim(bundle,[v_array_1 v_array_2]); 43 | disp('------- multiple vector bundling:') 44 | disp(['Similarity of bundle to the first vector from vector array 1 = ' num2str(sim_array(1))]); 45 | 46 | 47 | 48 | %%%%%%%%%%%%%%%%%%%%%%%%%%%% 49 | %% 2. binding / unbinding 50 | %%%%%%%%%%%%%%%%%%%%%%%%%%%% 51 | 52 | %%% single vector binding 53 | v1 = VSA.add_vector('num',1,'add_item',0); 54 | v2 = VSA.add_vector('num',1,'add_item',0); 55 | 56 | bound_v = VSA.bind(v1,v2); 57 | 58 | % bound_v is neither similar to v1 nor to v2 59 | sim_bound = VSA.sim(bound_v,[v1 v2]); 60 | disp('------- single vector binding:') 61 | disp(['Similarity of bound vector to v1 = ' num2str(sim_bound(1))]); 62 | disp(['Similarity of bound vector to v2 = ' num2str(sim_bound(2))]); 63 | 64 | % unbinding and recovering of vector v2 65 | r = VSA.unbind(v1,bound_v); 66 | 67 | sim_v1 = VSA.sim(r,v1); 68 | sim_v2 = VSA.sim(r,v2); 69 | disp('------- unbinding:') 70 | disp(['Similarity of recoverd (unbound) vector to v1 = ' num2str(sim_v1) ' and to v2: ' num2str(sim_v2)]); 71 | 72 | %%% multiple vector binding 73 | % it is possible to bind multiple vectors (vector-wise) 74 | % e.g. vectors array 1 and 2 have 100 vectors (two array must have the same 75 | % size) and can be bind together (vector-wise) -> output is an array with 76 | % also 100 vectors 77 | v_array_1 = VSA.add_vector('num',10,'add_item',0); 78 | v_array_2 = VSA.add_vector('num',10,'add_item',0); 79 | bound_array = VSA.bind(v_array_1, v_array_2); 80 | 81 | 82 | %%%%%%%%%%%%%%%%%%%%%%%%%%%% 83 | %% 3. use the item memory to find vectors 84 | %%%%%%%%%%%%%%%%%%%%%%%%%%%% 85 | 86 | % fill the item memor with random vectors 87 | VSA = vsa_env('vsa',type,'dim',1024); 88 | VSA.add_vector('num',10000); 89 | 90 | % generate a probe vector 91 | v = VSA.add_vector('name','probe'); 92 | 93 | % finde the probe vector in item memory 94 | [v_clean, name, s] = VSA.find_k_nearest(v,1); 95 | disp('----------- find vector in item memory:') 96 | disp(['Found vector ' name{1} ' with similarity of ' num2str(s)]); 97 | 98 | % bundle the probe with noise vector 99 | noise = VSA.add_vector('add_item',0); 100 | bundle = VSA.bundle(v,noise); 101 | [v_clean, name, s] = VSA.find_k_nearest(bundle,1); 102 | disp(['Found noisy vector ' name{1} ' with similarity of ' num2str(s)]); 103 | 104 | 105 | -------------------------------------------------------------------------------- /experimental_results/boundpairs.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUC-ProAut/VSA_Toolbox/5f60b6e3bcf9fe6a87fa50f04e79214194759d65/experimental_results/boundpairs.mat -------------------------------------------------------------------------------- /experimental_results/bundle_capacity.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUC-ProAut/VSA_Toolbox/5f60b6e3bcf9fe6a87fa50f04e79214194759d65/experimental_results/bundle_capacity.mat -------------------------------------------------------------------------------- /experimental_results/language_recognition.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUC-ProAut/VSA_Toolbox/5f60b6e3bcf9fe6a87fa50f04e79214194759d65/experimental_results/language_recognition.mat -------------------------------------------------------------------------------- /experimental_results/repetitive_binding.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TUC-ProAut/VSA_Toolbox/5f60b6e3bcf9fe6a87fa50f04e79214194759d65/experimental_results/repetitive_binding.mat -------------------------------------------------------------------------------- /experiments_main.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | %% experiments on different vsa's 25 | clear all 26 | close all 27 | 28 | vsa_dict={}; 29 | % chose the appropriate VSAs 30 | if 1, vsa_dict{end+1,1} = 'MAP_B'; end; 31 | if 1, vsa_dict{end+1,1} = 'MAP_C'; end; 32 | if 1, vsa_dict{end+1,1} = 'MAP_I'; end; 33 | if 1, vsa_dict{end+1,1} = 'HRR'; end; 34 | if 1, vsa_dict{end+1,1} = 'FHRR'; end; 35 | if 1, vsa_dict{end+1,1} = 'HRR_VTB'; end; 36 | if 1, vsa_dict{end+1,1} = 'BSC'; end; 37 | if 1, vsa_dict{end+1,1} = 'BSDC_SHIFT'; end; 38 | if 1, vsa_dict{end+1,1} = 'BSDC'; end; 39 | if 1, vsa_dict{end+1,1} = 'BSDC_SEG'; end; 40 | if 1, vsa_dict{end+1,1} = 'MBAT'; end; 41 | 42 | number_iterations = 10; % for statisitcal evaluation (mean, variance of the experiments) 43 | 44 | 45 | %% check properties of given vsa's 46 | % select the sub-experiment (set 1 to select and 0 to deselect) 47 | 48 | check_repetitive_binding = 1; 49 | check_bundle_capacity = 1; 50 | check_boundpairs = 1; 51 | 52 | check_langRec = 1; 53 | check_vpr = 0; % you will need the datasets for testing the VPR experiment (not provided yet - comming soon) 54 | 55 | % decide visualization 56 | vis=true; % set true, if you want to plot the results 57 | 58 | %% path setup 59 | 60 | workspace_path = mfilename('fullpath'); 61 | workspace_path = workspace_path(1:find(workspace_path == '/',1,'last')); 62 | results_path=[workspace_path 'experimental_results/']; 63 | 64 | %% define empty results arrays 65 | 66 | results_capacity = cell([size(vsa_dict,1) 1]); 67 | results_bindpairs_mean=cell([size(vsa_dict,1) 1]); 68 | results_bindpairs_var=cell([size(vsa_dict,1) 1]); 69 | results_bind_unbind1_mean=cell([size(vsa_dict,1) 1]); 70 | results_bind_unbind1_var=cell([size(vsa_dict,1) 1]); 71 | results_bind_unbind2_mean=cell([size(vsa_dict,1) 1]); 72 | results_bind_unbind2_var=cell([size(vsa_dict,1) 1]); 73 | results_bundle_mean=[]; 74 | results_bundle_var=[]; 75 | results_langRec = cell([size(vsa_dict,1) 1]); 76 | results_langRec_VSAs = cell([size(vsa_dict,1) 1]); 77 | 78 | %% main for loop (for all VSAs) 79 | for i=1:size(vsa_dict,1) 80 | 81 | disp('####') 82 | disp(vsa_dict{i,1}) 83 | disp('####') 84 | 85 | 86 | %% check binding and unbinding properties 87 | if check_repetitive_binding 88 | disp('---- check repetitive binding ----') 89 | 90 | experimental_scripts.repetitive_binding 91 | end 92 | 93 | %% capacity computing (k nearest nighbors) 94 | if check_bundle_capacity 95 | disp('---- check bundling capacity ----') 96 | fix_number = 1; % set 1 if use a fixed number of stored items, else 0 for vary the item memory size 97 | if fix_number 98 | % fix number of stored item (1000) 99 | item_memory_size = 1000; 100 | experimental_scripts.bundle_capacity 101 | else 102 | % variable number of stored item 103 | item_memory_size = [15 20 30 50 100 200 300 500]% 1000 2000 3000 5000 10000 1e5 1e6]; 104 | experimental_scripts.bundle_capacity 105 | end 106 | end 107 | 108 | %% binding k pairs and retrive them 109 | if check_boundpairs 110 | disp('---- check bound pairs capacity ----') 111 | 112 | experimental_scripts.boundpairs 113 | end 114 | 115 | %% language recognition experiment 116 | if check_langRec 117 | disp('---- language recognition experiment ----') 118 | dim_range_lang = [10:4:50].^2; 119 | results = zeros([1 numel(dim_range_lang)]); 120 | for d=1:numel(dim_range_lang) 121 | disp(['Dim = ' num2str(dim_range_lang(d))]) 122 | [results(d), ~] = experimental_scripts.language_recognition(vsa_dict{i,1},dim_range_lang(d), 3); 123 | end 124 | results_langRec{i}=results; 125 | end 126 | 127 | %% binding k pairs and retrive them 128 | % datasets will be provided as soon as possible 129 | if check_vpr 130 | disp('---- check visual place recognition ----') 131 | 132 | experimental_scripts.visual_place_recognition 133 | end 134 | end 135 | %% save results in mat 136 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 137 | 138 | if ~exist(results_path, 'dir') 139 | mkdir(results_path) 140 | end 141 | 142 | experimental_scripts.save_results 143 | 144 | %% call visualization script 145 | 146 | if vis 147 | use_saved_data=0; % if you want to use saved data, set to true 148 | experimental_scripts.visualization.visualize_all; 149 | end 150 | -------------------------------------------------------------------------------- /vsa_env.m: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % This file is part of VSA_Toolbox. % 3 | % % 4 | % Copyright (C) 2020 Chair of Automation Technology / TU Chemnitz % 5 | % For more information see https://www.tu-chemnitz.de/etit/proaut/vsa % 6 | % % 7 | % VSA_Toolbox is free software: you can redistribute it and/or modify % 8 | % it under the terms of the GNU General Public License as published by % 9 | % the Free Software Foundation, either version 3 of the License, or % 10 | % (at your option) any later version. % 11 | % % 12 | % VSA_Toolbox is distributed in the hope that it will be useful, % 13 | % but WITHOUT ANY WARRANTY; without even the implied warranty of % 14 | % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % 15 | % GNU General Public License for more details. % 16 | % % 17 | % You should have received a copy of the GNU General Public License % 18 | % along with Foobar. If not, see . % 19 | % % 20 | % Author: Kenny Schlegel (kenny.schlegel@etit.tu-chemnitz.de) % 21 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 | 23 | 24 | %% MATLAB class of different VSA implementation 25 | 26 | 27 | classdef vsa_env < handle 28 | 29 | properties 30 | dim % number of dimensions 31 | vsa % type of representation 32 | item_mem % vectors in item memory (cell array--> first cell contains the matrix with column-wise vectors; second cell contains the names of the vectors) 33 | density % density of the vetors (important for binary vectors) 34 | max_density% maximum density (important for thinng after bundling) 35 | M % the basic M matrix (for MBAT vsa, all other VSAs do not use this property) 36 | end 37 | 38 | methods 39 | function obj = vsa_env(varargin) 40 | 41 | default_vsa = 'MAP_B'; 42 | default_dim = 10000; 43 | default_density = -1; % if -1, default density will be computed later 44 | default_max_density = 1; 45 | 46 | p=inputParser; 47 | 48 | addParameter(p,'vsa',default_vsa,@ischar); 49 | addParameter(p,'dim',default_dim); 50 | addParameter(p,'density',default_density); 51 | addParameter(p,'max_density',default_max_density); 52 | 53 | parse(p,varargin{:}); 54 | 55 | % check if vsa is defined 56 | availabel_VSAs = {'MAP_C'; 'MAP_B'; 'MAP_I'; 'BSC'; 'BSDC'; 'BSDC_SHIFT'; 'HRR'; 'HRR_VTB'; 'FHRR'; 'BSDC_SEG';'MBAT'}; 57 | assert(any(strcmp(availabel_VSAs,p.Results.vsa)),['The selected VSA is not defined. Please chose one out of ' cell2mat(join(availabel_VSAs))]); 58 | 59 | obj.dim = p.Results.dim; 60 | obj.vsa = p.Results.vsa; 61 | obj.item_mem = cell([1 2]); 62 | obj.item_mem{1,2} = {}; 63 | obj.max_density = p.Results.max_density; 64 | 65 | % define default density 66 | if p.Results.density == -1 67 | switch p.Results.vsa 68 | case {'BSDC', 'BSDC_SHIFT'} 69 | density=1/sqrt(obj.dim); % density computing is optains from rachkovskji (most capacity and good stability) 70 | case 'BSDC_25' 71 | density=0.25; 72 | case 'BSDC_SEG' 73 | % density=0.05; % mean sparsity value of [1] M. Laiho, J. H. Poikonen, P. Kanerva, and E. Lehtonen, “High-dimensional computing with sparse vectors,” IEEE Biomed. Circuits Syst. Conf. Eng. Heal. Minds Able Bodies, BioCAS 2015 - Proc., pp. 1–4, 2015. 74 | density=1/sqrt(obj.dim); % show better results 75 | otherwise 76 | density=0.5; 77 | end 78 | obj.density = density; 79 | else 80 | obj.density = p.Results.density; 81 | end 82 | 83 | % create the basic M matrix for the MBAT VSA 84 | if strcmp(obj.vsa,'MBAT') 85 | obj.M = rand([obj.dim obj.dim]); 86 | obj.M = orth(obj.M); 87 | end 88 | 89 | % preallocate a matrix of zeros for the HRR_VTB matrix (otherwise it 90 | % takes a long time while binding) 91 | if strcmp(obj.vsa,'HRR_VTB') 92 | obj.M = zeros([obj.dim obj.dim]); 93 | end 94 | 95 | end 96 | 97 | function vectors = add_vector(obj, varargin) 98 | % add vector to item memory 99 | % INPUT (optinal): 100 | % vec - predefined hypervectors (column-wise) 101 | % num - number of to defined vectors (if no predefined 102 | % vectors are given) 103 | % name - name [string], if nothing --> random name 104 | % add_item - [bool] true, if vectors should be added to the item 105 | % memory 106 | % OUTPUT: 107 | % vec_out: - generated hypervectors 108 | 109 | default_name = -1; 110 | default_num = 1; 111 | default_vec = 0; 112 | default_add_item = 1; 113 | default_return = 1; 114 | p=inputParser; 115 | 116 | addOptional(p, 'vec', default_vec) 117 | addOptional(p, 'name', default_name) 118 | addOptional(p, 'num', default_num) 119 | addOptional(p, 'add_item', default_add_item) 120 | addOptional(p, 'return_vector', default_return) 121 | 122 | parse(p,varargin{:}); 123 | 124 | num = p.Results.num; 125 | 126 | 127 | if p.Results.vec==0 128 | % no input vectors given, generate radom vectors 129 | vectors = operations.generate_vectors('vsa',obj.vsa,'dim',obj.dim,'num',num, 'density',obj.density); 130 | else 131 | vectors = p.Results.vec; 132 | num = size(vectors,2); 133 | end 134 | 135 | if p.Results.add_item 136 | obj.item_mem{1,1}=[obj.item_mem{1,1} vectors]; 137 | 138 | % generate names (if not given) 139 | if isnumeric(p.Results.name) % if name is -1, then generate random name 140 | names = obj.item_mem{1,2}; 141 | rand_names = cellstr(obj.rnd_name('size',[8,num])); 142 | obj.item_mem{1,2} = cat(1,[rand_names(:); cellstr(names)]); 143 | else 144 | names = obj.item_mem{1,2}; 145 | obj.item_mem{1,2} = cat(1,[names(:); cellstr(p.Results.name)]); 146 | end 147 | end 148 | 149 | % return vectors only if param is set 150 | if p.Results.return_vector == 0 151 | clear vectors; 152 | end 153 | end 154 | 155 | function [sim_matrix] = sim(obj,vectors_1,vectors_2) 156 | % compute the similarty between two vectors (arrays) 157 | sim_matrix = operations.compute_sim(obj.vsa, vectors_1, vectors_2); 158 | end 159 | 160 | function bound_vectors = bind(obj, vectors_1, vectors_2) 161 | % bind vectors_1 and vectors_2 --> see function bind_vectors.m 162 | bound_vectors = operations.bind_vectors(obj.vsa, vectors_1, vectors_2, 'density',obj.density, 'M', obj.M); 163 | end 164 | 165 | function unbound_vectors = unbind(obj, vectors_1, vectors_2) 166 | % unbind vectors_1 and vectors_2 --> see function unbind_vectors.m 167 | unbound_vectors = operations.unbind_vectors(obj.vsa, vectors_1, vectors_2, 'density', obj.density, 'M', obj.M); 168 | end 169 | 170 | function bundled_vectors = bundle(obj, vectors_1, vectors_2, normalize) 171 | % bundle vectors_1 and vectors_2 --> see function bundle_vectors.m 172 | if nargin <= 3 173 | bundled_vectors = operations.bundle_vectors(obj.vsa, vectors_1, vectors_2, 'density', obj.density, 'max_density', obj.max_density); 174 | else 175 | bundled_vectors = operations.bundle_vectors(obj.vsa, vectors_1, vectors_2, 'normalize',normalize, 'density', obj.density, 'max_density', obj.max_density); 176 | end 177 | end 178 | 179 | function permuted_vector = permute(obj, vector, p) 180 | % permute input vetor 181 | if nargin<=2 182 | p=1; 183 | end 184 | 185 | permuted_vector = circshift(vector,p); 186 | end 187 | 188 | function [vectors, names, s]=find_k_nearest(obj, vectors_in, k) 189 | % find the k best matches in item memory with input vector 190 | % INPUT: 191 | % vectors_in: input vectors (can be more than one) 192 | % k: k nearest neighbors (default = 1) 193 | % OUTPUT: 194 | % name: name of matched vectors (cell array) 195 | % s: similarity of best match (array) 196 | if nargin<=2 197 | k=1; 198 | end 199 | sim_vec = obj.sim(obj.item_mem{1,1},vectors_in); 200 | [sim_vec_sort, idx]=sort(sim_vec,'descend'); 201 | s_highest=sim_vec_sort(1:k,:); 202 | 203 | rows = idx(1:k,:); 204 | 205 | names = obj.item_mem{1,2}; 206 | names = names(rows,:); 207 | names = reshape(names,[k,size(vectors_in,2)]); 208 | vecs = obj.item_mem{1,1}; 209 | vectors = vecs(:,rows); 210 | vectors = reshape(vectors,[size(vectors,1),k,size(vectors_in,2)]); 211 | s = sim_vec(rows); 212 | s = reshape(s,[k,size(vectors_in,2)]); 213 | 214 | 215 | end 216 | 217 | function [vector] = find_by_name(obj, vector_name) 218 | % find the vector by name 219 | % INPUT: 220 | % vector_name: vector name 221 | % OUTPUT: 222 | % vecotr: vector with name 'vector_name' 223 | 224 | idx = strcmp(obj.item_mem{2},vector_name); 225 | if sum(idx)>=1 226 | vector = obj.item_mem{1}(:,idx); 227 | else 228 | disp(['No vector for name ' vector_name ' found!']); 229 | vector = []; 230 | end 231 | end 232 | 233 | function v = frac_binding(obj, vector, k) 234 | % FRAC_BINDING BETA - currently not in use 235 | v = operations.fractional_binding(obj.vsa, vector, k); 236 | end 237 | 238 | function converted_vectors = convert(obj, vector_array) 239 | % convert the input into the specific range of the 240 | % corresponding vsa type 241 | % INPUT: 242 | % vector_array: vectors (each row is a vector) 243 | % OUTPUT: 244 | % converted_vectors: converted vectors 245 | 246 | converted_vectors = operations.convert_vectors(obj.vsa, vector_array, obj.density); 247 | end 248 | 249 | end 250 | 251 | methods (Static, Access = public) 252 | function name = rnd_name(varargin) 253 | % generate random names 254 | % INPUT: 255 | % size: vector with number of characters per name and 256 | % number of random names 257 | % OUTPUT: 258 | % name: random names as char-array 259 | 260 | 261 | default_size = [8,1]; 262 | 263 | p=inputParser; 264 | 265 | addOptional(p, 'size', default_size) 266 | 267 | 268 | parse(p,varargin{:}) 269 | 270 | % if no name defined, create a random name 271 | s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; 272 | rnd_idx=randi(numel(s), [p.Results.size(2) p.Results.size(1)]); 273 | s=s(rnd_idx); 274 | %find number of random characters to choose from 275 | numRands = length(s); 276 | 277 | %specify length of random string to generate 278 | sLength = p.Results.size(1); 279 | 280 | %generate random string 281 | name = s( ceil(rand(p.Results.size(2),sLength)*numRands) ); 282 | end 283 | end 284 | end 285 | 286 | 287 | 288 | --------------------------------------------------------------------------------