├── +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 |
--------------------------------------------------------------------------------