classdef measure
    
    properties(Constant)
        lex = [
            utterance("sova",  lang2_sound.SOVA,  lang2_meaning.SOVA)
            utterance("roza",  lang2_sound.ROZA,  lang2_meaning.ROZA)
            utterance("kot",   lang2_sound.KOT,   lang2_meaning.KOT)
            utterance("bot",   lang2_sound.BOT,   lang2_meaning.BOT)
            utterance("moj",   lang2_sound.MOJ,   lang2_meaning.MOJ)
            utterance("zhar",  lang2_sound.ZHAR,  lang2_meaning.ZHAR)
            utterance("zhaba", lang2_sound.ZHABA, lang2_meaning.ZHABA)
            utterance("taz",   lang2_sound.TAZ,   lang2_meaning.TAZ)
            utterance("bar",   lang2_sound.BAR,   lang2_meaning.BAR)
            utterance("rab",   lang2_sound.RAB,   lang2_meaning.RAB)
        ]
        gen = [
            utterance("roza",  lang2_sound.ROZA,  lang2_meaning.ROZA)
            utterance("kot",   lang2_sound.KOT,   lang2_meaning.KOT)
            utterance("boty",   lang2_sound.BOTY,   lang2_meaning.BOTY)
        ]
    end

    methods (Static)
        function similarities(lang, samples_per_utterance, n_learners)
            % 1) generates sample_per_utterance samples for language lang
            % 2) trains DBM on this set n_learners times
            % 3) after every training, uses it for every sound and meaning and measures similarity 
            %    between
            %    - 1st hidden levels
            %    - 2nd hidden levels
            %    - both levels
        
            
            dataset = data_set(lang, samples_per_utterance);
            
            % PROFICIENCY
            io_comprehension_similarity = zeros(lang.n_utterances, lang.n_utterances, n_learners);
            io_production_similarity_unclamped = zeros(lang.n_utterances, lang.n_utterances, n_learners);
            io_production_similarity_clamped = zeros(lang.n_utterances, lang.n_utterances, n_learners);

            % PHONOLOGY WORDS
            similarity_sounds{1} = zeros(lang.n_utterances, lang.n_utterances, n_learners);
            similarity_sounds{2} = zeros(lang.n_utterances, lang.n_utterances, n_learners);
            similarity_sounds{3} = zeros(lang.n_utterances, lang.n_utterances, n_learners);
            
            similarity_meanings_clamped{1} = zeros(lang.n_utterances, lang.n_utterances, n_learners);
            similarity_meanings_clamped{2} = zeros(lang.n_utterances, lang.n_utterances, n_learners);
            similarity_meanings_clamped{3} = zeros(lang.n_utterances, lang.n_utterances, n_learners);
            
            similarity_meanings_unclamped{1} = zeros(lang.n_utterances, lang.n_utterances, n_learners);
            similarity_meanings_unclamped{2} = zeros(lang.n_utterances, lang.n_utterances, n_learners);
            similarity_meanings_unclamped{3} = zeros(lang.n_utterances, lang.n_utterances, n_learners);

            similarity_faithfullness{1} = zeros(lang.n_utterances*2, lang.n_utterances*2, n_learners);
            similarity_faithfullness{2} = zeros(lang.n_utterances*2, lang.n_utterances*2, n_learners);
            similarity_faithfullness{3} = zeros(lang.n_utterances*2, lang.n_utterances*2, n_learners);
            
            % PHONOLOGY SOUNDS-PHONEMES
            similarity_first_vowels{1} = zeros(lang2_sound.n_vowels, lang2_sound.n_vowels, n_learners);
            similarity_first_vowels{2} = zeros(lang2_sound.n_vowels, lang2_sound.n_vowels, n_learners);
            similarity_first_vowels{3} = zeros(lang2_sound.n_vowels, lang2_sound.n_vowels, n_learners);
            
            similarity_second_vowels{1} = zeros(lang2_sound.n_vowels, lang2_sound.n_vowels, n_learners);
            similarity_second_vowels{2} = zeros(lang2_sound.n_vowels, lang2_sound.n_vowels, n_learners);
            similarity_second_vowels{3} = zeros(lang2_sound.n_vowels, lang2_sound.n_vowels, n_learners);

            similarity_three_sounds{1} = zeros(3 * size(measure.lex, 1), 3 * size(measure.lex, 1), ...
                n_learners);
            similarity_three_sounds{2} = zeros(3 * size(measure.lex, 1), 3 * size(measure.lex, 1), ...
                n_learners);
            similarity_three_sounds{3} = zeros(3 * size(measure.lex, 1), 3 * size(measure.lex, 1), ...
                n_learners);

            similarity_lex = cell(size(measure.lex, 1), 3);
            for j=1:size(measure.lex, 1)
                similarity_lex{j, 1} = zeros(4, 4, n_learners);
                similarity_lex{j, 2} = zeros(4, 4, n_learners);
                similarity_lex{j, 3} = zeros(4, 4, n_learners);
            end
            
            similarity_gen = cell(size(measure.gen, 1), 3);
            for j=1:size(measure.gen, 1)
                similarity_gen{j, 1} = zeros(6, 6, n_learners);
                similarity_gen{j, 2} = zeros(6, 6, n_learners);
                similarity_gen{j, 3} = zeros(6, 6, n_learners);
            end
            
            for i=1:n_learners
                comment(lang.name + ": generating new data for learner " ...
                    + i + " of " + n_learners, 'header');
                data = dataset.generate_observations;
                
                comment("Training DBM", 'else');
                dbm_instance = dbm(lang);
                dbm_instance.learn(data)
                
                full_vectors = measure.create_word_input(lang);
                sound_vectors = measure.create_sound_input(lang);
                meaning_vectors = measure.create_meaning_input(lang);
                unclamped_all = measure.unclamped(lang.n_input_nodes, lang.n_utterances);
                unclamped_sound = measure.unclamped(lang.n_sound_nodes, lang.n_utterances);
                
                % PROFICIENCY
                comment("Measure input-output comprehension similarity for learner " ...
                    + i + " of " + n_learners, 'else')
                io_comprehension_similarity(:,:,i) = dbm_instance.measure_io_similarity( ...
                    sound_vectors, full_vectors, unclamped_all);

                comment("Measure input-output production similarity (meaning unclamped) for learner " ...
                    + i + " of " + n_learners, 'else')
                io_production_similarity_unclamped(:,:,i) = dbm_instance.measure_io_similarity( ...
                    meaning_vectors, full_vectors, unclamped_all);

                comment("Measure input-output production similarity (meaning clamped) for learner " ...
                    + i + " of " + n_learners, 'else')
                io_production_similarity_clamped(:,:,i) = dbm_instance.measure_io_similarity( ...
                    meaning_vectors, full_vectors, unclamped_sound);

                % PHONOLOGY
                comment("Measure similarity comprehension for learner " ...
                    + i + " of " + n_learners, 'else')
                similarity = dbm_instance.measure_phonological_similarity(sound_vectors, unclamped_all);
                similarity_sounds{1}(:,:,i) = similarity{1};
                similarity_sounds{2}(:,:,i) = similarity{2};
                similarity_sounds{3}(:,:,i) = similarity{3};

                comment("Measure similarity production (meaning clamped) for learner " ...
                    + i + " of " + n_learners, 'else')
                similarity = dbm_instance.measure_phonological_similarity(meaning_vectors, ...
                    unclamped_sound);
                similarity_meanings_clamped{1}(:,:,i) = similarity{1};
                similarity_meanings_clamped{2}(:,:,i) = similarity{2};
                similarity_meanings_clamped{3}(:,:,i) = similarity{3};

                comment("Measure similarity production (meaning UNclamped) for learner " ...
                    + i + " of " + n_learners, 'else')
                similarity = dbm_instance.measure_phonological_similarity(meaning_vectors, ...
                    unclamped_all);
                similarity_meanings_unclamped{1}(:,:,i) = similarity{1};
                similarity_meanings_unclamped{2}(:,:,i) = similarity{2};
                similarity_meanings_unclamped{3}(:,:,i) = similarity{3};
                
                comment("Measure similarity comprehension-production (faithfullness) for learner " ...
                    + i + " of " + n_learners, 'else')
                similarity = dbm_instance.measure_phonological_similarity( ...
                    [sound_vectors; meaning_vectors], ...
                    [unclamped_all; unclamped_sound]);
                similarity_faithfullness{1}(:,:,i) = similarity{1};
                similarity_faithfullness{2}(:,:,i) = similarity{2};
                similarity_faithfullness{3}(:,:,i) = similarity{3};

                % PHONOLOGY SOUNDS-PHONEMES
                if strcmp(lang.name, "lang2")
                    comment("Measure similarity first vowel for learner " ...
                        + i + " of " + n_learners, 'else')
                    input_vectors = measure.create_first_vowel_input;
                    similarity = dbm_instance.measure_phonological_similarity( ...
                        input_vectors, measure.unclamped(lang.n_input_nodes, lang2_sound.n_vowels));
                    similarity_first_vowels{1}(:,:,i) = similarity{1};
                    similarity_first_vowels{2}(:,:,i) = similarity{2};
                    similarity_first_vowels{3}(:,:,i) = similarity{3};

                    comment("Measure similarity second vowel for learner " ...
                        + i + " of " + n_learners, 'else')
                    input_vectors = measure.create_second_vowel_input;
                    similarity = dbm_instance.measure_phonological_similarity( ...
                        input_vectors, measure.unclamped(lang.n_input_nodes, lang2_sound.n_vowels));
                    similarity_second_vowels{1}(:,:,i) = similarity{1};
                    similarity_second_vowels{2}(:,:,i) = similarity{2};
                    similarity_second_vowels{3}(:,:,i) = similarity{3};

                    comment("Measure similarity three first sounds for learner " ...
                        + i + " of " + n_learners, 'else')
                    input_vectors = measure.create_three_sounds_input;
                    similarity = dbm_instance.measure_phonological_similarity( ...
                        input_vectors, measure.unclamped(lang.n_input_nodes, 3 * size(measure.lex, 1)));
                    similarity_three_sounds{1}(:,:,i) = similarity{1};
                    similarity_three_sounds{2}(:,:,i) = similarity{2};
                    similarity_three_sounds{3}(:,:,i) = similarity{3};

                    comment("Measure lexical mapping for learner " ...
                        + i + " of " + n_learners, 'else');
                    for j=1:size(measure.lex, 1)
                        input_vectors = measure.create_lex_input(j);
                        similarity = dbm_instance.measure_phonological_similarity( ...
                            input_vectors, measure.unclamped_lex);
                        similarity_lex{j, 1}(:,:,i) = similarity{1};
                        similarity_lex{j, 2}(:,:,i) = similarity{2};
                        similarity_lex{j, 3}(:,:,i) = similarity{3};
                    end
                    
                    comment("Measure morphosyntactic mapping for learner " ...
                        + i + " of " + n_learners, 'else');
                    for j=1:size(measure.gen, 1)
                        input_vectors = measure.create_gen_input(j);
                        similarity = dbm_instance.measure_phonological_similarity( ...
                            input_vectors, measure.unclamped_gen);
                        similarity_gen{j, 1}(:,:,i) = similarity{1};
                        similarity_gen{j, 2}(:,:,i) = similarity{2};
                        similarity_gen{j, 3}(:,:,i) = similarity{3};
                    end
                end
            end

            % average over all learners
            % PROFICIENCY
            table_io_comprehension_similarity = measure.average_input_output( ...
                io_comprehension_similarity);
            table_io_production_similarity_clamped = measure.average_input_output( ...
                io_production_similarity_clamped);
            table_io_production_similarity_unclamped = measure.average_input_output( ...
                io_production_similarity_unclamped);
            
            % PHONOLOGY WORDS
            table_similarity_sounds = measure.average(similarity_sounds);
            table_similarity_meanings_clamped = measure.average(similarity_meanings_clamped);
            table_similarity_meanings_unclamped = measure.average(similarity_meanings_unclamped);
            table_similarity_faithfullness = measure.average(similarity_faithfullness);
            
            % PHONOLOGY SOUNDS-PHONEMES
            if strcmp(lang.name, "lang2")
                table_similarity_first_vowels = measure.average(similarity_first_vowels);
                table_similarity_second_vowels = measure.average(similarity_second_vowels);
                table_similarity_three_sounds = measure.average(similarity_three_sounds);

                table_similarity_lex = cell(size(measure.lex, 1), 1); %cell array of 10 cell arrays
                for j=1:size(measure.lex, 1)
                    s{1} = similarity_lex{j, 1};
                    s{2} = similarity_lex{j, 2};
                    s{3} = similarity_lex{j, 3};
                    table_similarity_lex{j} = measure.average(s); % cell array of 6 elements
                end
                table_similarity_gen = cell(size(measure.gen, 1), 1); %cell array of 3 cell arrays
                for j=1:size(measure.gen, 1)
                    s{1} = similarity_gen{j, 1};
                    s{2} = similarity_gen{j, 2};
                    s{3} = similarity_gen{j, 3};
                    table_similarity_gen{j} = measure.average(s); % cell array of 6 elements
                end
            end

            % create tables with column and row names
            utterance_names_comp = strings(1, lang.n_utterances);
            for i=1:lang.n_utterances
                utterance_names_comp(1, i) = char("[" + lang.utterances(i).name + "]");
            end
            utterance_names_comp = cellstr(utterance_names_comp);
            
            utterance_names_prod = strings(1, lang.n_utterances);
            for i=1:lang.n_utterances
                utterance_names_prod(1, i) = char("<" + lang.utterances(i).name+ ">");
            end
            utterance_names_prod = cellstr(utterance_names_prod);
            
            % PROFICIENCY
            table_io_comprehension_similarity = measure.create_tables_input_output( ...
                table_io_comprehension_similarity, utterance_names_comp);
            table_io_production_similarity_clamped = measure.create_tables_input_output( ...
                table_io_production_similarity_clamped, utterance_names_prod);
            table_io_production_similarity_unclamped = measure.create_tables_input_output( ...
                table_io_production_similarity_unclamped, utterance_names_prod);

            % PHONOLOGY WORDS
            table_similarity_sounds = measure.create_tables( ...
                table_similarity_sounds, utterance_names_comp);
            table_similarity_meanings_clamped = measure.create_tables( ...
                table_similarity_meanings_clamped, utterance_names_prod);
            table_similarity_meanings_unclamped = measure.create_tables( ...
                table_similarity_meanings_unclamped, utterance_names_prod);
            table_similarity_faithfullness = measure.create_tables( ...
                table_similarity_faithfullness, [utterance_names_comp utterance_names_prod]);

            % PHONOLOGY SOUNDS-PHONEMES
            if strcmp(lang.name, "lang2")
                % first and second vowels
                vowel_names = strings(1, lang2_sound.n_vowels);
                for i=1:lang2_sound.n_vowels
                    vowel_names(1, i) = char(lang2_sound.vowels(i));
                end
                vowel_names = cellstr(vowel_names);
                table_similarity_first_vowels = measure.create_tables( ...
                    table_similarity_first_vowels, vowel_names);
                table_similarity_second_vowels = measure.create_tables( ...
                    table_similarity_second_vowels, vowel_names);

                % three sounds
                three_sounds_names = strings(1, 3 * size(measure.lex, 1));
                j = 1;
                for i=1:size(measure.lex, 1)
                    c1 = lang2_sound.cons(measure.lex(i).sound.c1_index);
                    c2 = lang2_sound.cons(measure.lex(i).sound.c2_index);

                    three_sounds_names(1, j) = char("[" + c1 + lang2_sound.vowels(1) + c2 + "]");
                    j = j + 1;

                    three_sounds_names(1, j) = char("[" + c1 + lang2_sound.vowels(2) + c2 + "]");
                    j = j + 1;
                    
                    three_sounds_names(1, j) = char("[" + c1 + lang2_sound.vowels(3) + c2 + "]");
                    j = j + 1;
                end
                three_sounds_names = cellstr(three_sounds_names);
                
                table_similarity_three_sounds = measure.create_tables( ...
                    table_similarity_three_sounds, three_sounds_names);

                % lexical
                table_similarity_lex = measure.create_lex_table(table_similarity_lex);

                % morphosyntactic
                table_similarity_gen = measure.create_gen_table(table_similarity_gen);
            end

            % write similarity matrices to files
            % PROFICIENCY
            measure.write_to_file_input_output(table_io_comprehension_similarity, ...
                "io_comprehension", lang, samples_per_utterance, n_learners)
            measure.write_to_file_input_output(table_io_production_similarity_clamped, ...
                "io_production_clamped", lang, samples_per_utterance, n_learners)
            measure.write_to_file_input_output(table_io_production_similarity_unclamped, ...
                "io_production_unclamped", lang, samples_per_utterance, n_learners)

            % PHONOLOGY WORDS
            measure.write_to_file(table_similarity_sounds, ...
                "comprehension", lang, samples_per_utterance, n_learners)
            measure.write_to_file(table_similarity_meanings_clamped, ...
                "production_meaning_clamped", lang, samples_per_utterance, n_learners)            
            measure.write_to_file(table_similarity_meanings_unclamped, ...
                "production_meaning_unclamped", lang, samples_per_utterance, n_learners)            
            measure.write_to_file(table_similarity_faithfullness, ...
                "faithfullness", lang, samples_per_utterance, n_learners)
            
            % PHONOLOGY SOUNDS-PHONEMES
            if strcmp(lang.name, "lang2")
                measure.write_to_file(table_similarity_first_vowels, ...
                    "first_vowels", lang, samples_per_utterance, n_learners)
                measure.write_to_file(table_similarity_second_vowels, ...
                    "second_vowels", lang, samples_per_utterance, n_learners)         
                measure.write_to_file(table_similarity_three_sounds, ...
                    "three_sounds", lang, samples_per_utterance, n_learners)
                measure.write_to_file(table_similarity_lex, ...
                    "lexical_mapping", lang, samples_per_utterance, n_learners)            
                measure.write_to_file(table_similarity_gen, ...
                    "gender_number_mapping", lang, samples_per_utterance, n_learners)            
            end
        end
    end
    

    methods (Static, Access=private)
        function input_vectors = create_word_input(lang)
            input_vectors = zeros(lang.n_utterances, lang.n_input_nodes);
            for j=1:lang.n_utterances
                input_vectors(j, :) = [lang.utterances(j).sound.create_input_vector ...
                    lang.utterances(j).meaning.create_input_vector];
            end
        end
            
        function input_vectors = create_sound_input(lang)
            input_vectors = zeros(lang.n_utterances, lang.n_input_nodes);
            for j=1:lang.n_utterances
                input_vectors(j, :) = [lang.utterances(j).sound.create_input_vector ...
                    zeros(1, lang.utterances(j).meaning.n_semantic_nodes)];
            end
        end
            
        function input_vectors = create_meaning_input(lang)
            input_vectors = zeros(lang.n_utterances, lang.n_input_nodes);
            for j=1:lang.n_utterances
                input_vectors(j, :) = [zeros(1, lang.utterances(j).sound.n_auditory_nodes) ...
                        lang.utterances(j).meaning.create_input_vector];
            end
        end
        
        function input_vectors = create_first_vowel_input()
            input_vectors = zeros(lang2_sound.n_vowels, lang2.n_input_nodes);
            
            c1_vector = lang2_sound.create_zero_consonant_input_vector;
            c2_vector = lang2_sound.create_zero_consonant_input_vector;
            v2_vector = vowel.create_zero_input_vector;          

            for j=1:lang2_sound.n_vowels
                v1_vector = vowel.create_input_vector(lang2_sound.f1_erbs(j), lang2_sound.f2_erbs(j));
                input_vectors(j, :) = [c1_vector v1_vector c2_vector v2_vector ...
                    zeros(1, lang2_meaning.n_semantic_nodes)];
            end
        end
        
        function input_vectors = create_second_vowel_input()
            input_vectors = zeros(lang2_sound.n_vowels, lang2.n_input_nodes);
            
            c1_vector = lang2_sound.create_zero_consonant_input_vector;
            c2_vector = lang2_sound.create_zero_consonant_input_vector;
            v1_vector = vowel.create_zero_input_vector;          

            for j=1:lang2_sound.n_vowels
                v2_vector = vowel.create_input_vector(lang2_sound.f1_erbs(j), lang2_sound.f2_erbs(j));
                input_vectors(j, :) = [c1_vector v1_vector c2_vector v2_vector ...
                    zeros(1, lang2_meaning.n_semantic_nodes)];
            end
        end
        
        function input_vectors = create_three_sounds_input()
            n_comparisons = 3 * size(measure.lex, 1);
            input_vectors = zeros(n_comparisons, lang2.n_input_nodes);
            
            i = 1;
            for j=1:size(measure.lex, 1)
                c1_vector = lang2_sound.create_consonant_input_vector(measure.lex(j).sound.c1_index);
                c2_vector = lang2_sound.create_consonant_input_vector(measure.lex(j).sound.c2_index);
                v2_vector = vowel.create_zero_input_vector;          
                
                % [a]
                v1_vector = vowel.create_input_vector(lang2_sound.f1_erbs(1), lang2_sound.f2_erbs(1));
                input_vectors(i, :) = [c1_vector v1_vector c2_vector v2_vector ...
                    zeros(1, lang2_meaning.n_semantic_nodes)];
                i = i + 1;
                
                % [o]
                v1_vector = vowel.create_input_vector(lang2_sound.f1_erbs(2), lang2_sound.f2_erbs(2));
                input_vectors(i, :) = [c1_vector v1_vector c2_vector v2_vector ...
                    zeros(1, lang2_meaning.n_semantic_nodes)];
                i = i + 1;
    
                % [ɐ]
                v1_vector = vowel.create_input_vector(lang2_sound.f1_erbs(3), lang2_sound.f2_erbs(3));
                input_vectors(i, :) = [c1_vector v1_vector c2_vector v2_vector ...
                    zeros(1, lang2_meaning.n_semantic_nodes)];
                i = i + 1;
            end
        end
            
        function input_vectors = create_lex_input(i)
            input_vectors = zeros(4, lang2.n_input_nodes);

            % sounds
            c1_vector = lang2_sound.create_consonant_input_vector(measure.lex(i).sound.c1_index);
            c2_vector = lang2_sound.create_consonant_input_vector(measure.lex(i).sound.c2_index);
            v2_vector = vowel.create_zero_input_vector;
            meaning_vector = measure.lex(i).meaning.create_lex_input_vector;
            
            % input vector with lexical meaning
            input_vectors(1, :) = [ ...
                lang2_sound.create_zero_consonant_input_vector ...
                vowel.create_zero_input_vector ...
                lang2_sound.create_zero_consonant_input_vector ...
                vowel.create_zero_input_vector ...
                meaning_vector];
            
            % [a] 
            v1_vector = vowel.create_input_vector(lang2_sound.f1_erbs(1), lang2_sound.f2_erbs(1));
            input_vectors(2, :) = [c1_vector v1_vector c2_vector v2_vector ...
                zeros(1, lang2_meaning.n_semantic_nodes)];
        
            % [o]
            v1_vector = vowel.create_input_vector(lang2_sound.f1_erbs(2), lang2_sound.f2_erbs(2));
            input_vectors(3, :) = [c1_vector v1_vector c2_vector v2_vector ...
                zeros(1, lang2_meaning.n_semantic_nodes)];

            % [ɐ]
            v1_vector = vowel.create_input_vector(lang2_sound.f1_erbs(3), lang2_sound.f2_erbs(3));
            input_vectors(4, :) = [c1_vector v1_vector c2_vector v2_vector ...
                zeros(1, lang2_meaning.n_semantic_nodes)];
        end
        
        function input_vectors = create_gen_input(i)
            input_vectors = zeros(4, lang2.n_input_nodes);
            % sounds
            c1_vector = lang2_sound.create_zero_consonant_input_vector;
            v1_vector = vowel.create_zero_input_vector;
            c2_vector = lang2_sound.create_zero_consonant_input_vector;
            v2_vector = vowel.create_zero_input_vector;
            meaning_vector = measure.gen(i).meaning.create_gen_input_vector;
            
            % input vector with morphosyntactic meaning
            input_vectors(1, :) = [c1_vector v1_vector c2_vector v2_vector meaning_vector];
                   
            % [a] 
            v2_vector = vowel.create_input_vector(lang2_sound.f1_erbs(1), lang2_sound.f2_erbs(1));
            input_vectors(2, :) = [c1_vector v1_vector c2_vector v2_vector ...
                zeros(1, lang2_meaning.n_semantic_nodes)];
        
            % [ɨ]
            v2_vector = vowel.create_input_vector(lang2_sound.f1_erbs(4), lang2_sound.f2_erbs(4));
            input_vectors(3, :) = [c1_vector v1_vector c2_vector v2_vector ...
                zeros(1, lang2_meaning.n_semantic_nodes)];

            % [ə]
            v2_vector = vowel.create_input_vector(lang2_sound.f1_erbs(5), lang2_sound.f2_erbs(5));
            input_vectors(4, :) = [c1_vector v1_vector c2_vector v2_vector ...
                zeros(1, lang2_meaning.n_semantic_nodes)];

            % [ɪ]
            v2_vector = vowel.create_input_vector(lang2_sound.f1_erbs(6), lang2_sound.f2_erbs(6));
            input_vectors(5, :) = [c1_vector v1_vector c2_vector v2_vector ...
                zeros(1, lang2_meaning.n_semantic_nodes)];

            % [NONE]
            v2_vector = vowel.create_input_vector(0, 0);
            input_vectors(6, :) = [c1_vector v1_vector c2_vector v2_vector ...
                zeros(1, lang2_meaning.n_semantic_nodes)];
        end
        
        function table_similarity = average(similarity)
            m{1} = round(mean(similarity{1}, 3)*100);
            m{2} = round(mean(similarity{2}, 3)*100);
            m{3} = round(mean(similarity{3}, 3)*100);
            
            sd{1} = round(std(similarity{1}, 0, 3)*100);
            sd{2} = round(std(similarity{2}, 0, 3)*100);
            sd{3} = round(std(similarity{3}, 0, 3)*100);

            table_similarity{1} = string(m{1}) + " (" + string(sd{1}) + ")";
            table_similarity{2} = string(m{2}) + " (" + string(sd{2}) + ")";
            table_similarity{3} = string(m{3}) + " (" + string(sd{3}) + ")";

            table_similarity{4} = string(m{1});
            table_similarity{5} = string(m{2});
            table_similarity{6} = string(m{3});
        end   

        function table_similarity = average_input_output(similarity)
            m = round(mean(similarity, 3)*100);
            sd = round(std(similarity, 0, 3)*100);
            table_similarity{1} = string(m) + " (" + string(sd) + ")";
            table_similarity{2} = string(m);
        end   

        function result_table_similarity = create_tables(table_similarity, headers)
            result_table_similarity = cell(6, 1);
            for i=1:6
                result_table_similarity{i} = array2table(table_similarity{i});
                result_table_similarity{i}.Properties.RowNames = headers;
                result_table_similarity{i}.Properties.VariableNames = headers;
                result_table_similarity{i}.Properties.DimensionNames{1} = ' ';
            end
        end    
        
        function result_table_similarity = create_tables_input_output(table_similarity, headers)
            result_table_similarity = cell(2, 1);
            for i=1:2
                result_table_similarity{i} = array2table(table_similarity{i});
                result_table_similarity{i}.Properties.RowNames = headers;
                result_table_similarity{i}.Properties.VariableNames = headers;
                result_table_similarity{i}.Properties.DimensionNames{1} = ' ';
            end
        end    
        
        function result_table_similarity_lex = create_lex_table(table_similarity_lex)
            % table_similarity_lex: cell array of 10 cell arrays of 6 elements
            % for output, we want to return one cell array of 6 elements        
            result_table_similarity_lex = cell(6, 1);
            for i=1:6
                lex_matrix = strings(size(measure.lex, 1), 3);
                row_names = strings(size(measure.lex, 1), 1);
                
                for j=1:size(measure.lex, 1)
                    lex_matrix(j, :) = table_similarity_lex{j}{i}(1, 2:4);
                    row_names(j) = ...
                        "<" + measure.lex(j).meaning.lex(measure.lex(j).meaning.lex_index) + ">";
                end
                
                result_table_similarity_lex{i} = array2table(lex_matrix);
                result_table_similarity_lex{i}.Properties.RowNames = row_names;
                result_table_similarity_lex{i}.Properties.VariableNames = ["a", "o", "ɐ"];
                result_table_similarity_lex{i}.Properties.DimensionNames{1} = ' ';
            end
        end    

        function result_table_similarity_gen = create_gen_table(table_similarity_gen)
            % table_similarity_lex: cell array of 10 cell arrays of 6 elements
            % for output, we want to return one cell array of 6 elements        
            result_table_similarity_gen = cell(6, 1);
            for i=1:6
                gen_matrix = strings(size(measure.gen, 1), 5);
                row_names = strings(size(measure.gen, 1), 1);
                
                for j=1:size(measure.gen, 1)
                    gen_matrix(j, :) = table_similarity_gen{j}{i}(1, 2:6);
                    row_names(j) = measure.gen(j).meaning.gen(measure.gen(j).meaning.gen_index);
                end
                result_table_similarity_gen{i} = array2table(gen_matrix);
                result_table_similarity_gen{i}.Properties.RowNames = row_names;
                result_table_similarity_gen{i}.Properties.VariableNames = ["a", "ɨ", "ə", "ɪ̈" "NONE"];
                result_table_similarity_gen{i}.Properties.DimensionNames{1} = ' ';
            end
        end    

        function write_to_file(table_similarity, name, lang, n_samples, n_learners)
            f_common = fullfile(config.getInstance.path_measures, lang.name ...
                    + "_" + name + "_similarities_" ...
                    + n_samples + "samples_" ...
                    + n_learners + "learners_h");
            filename{1} = strcat(f_common, "_with_std_1.csv");
            filename{2} = strcat(f_common, "_with_std_2.csv");
            filename{3} = strcat(f_common, "_with_std_12.csv");
            filename{4} = strcat(f_common, "_without_std_1.csv");
            filename{5} = strcat(f_common, "_without_std_2.csv");
            filename{6} = strcat(f_common, "_without_std_12.csv");
            
            writetable(table_similarity{1}, filename{1}, 'WriteRowNames', true, 'Encoding', 'UTF-8')
            writetable(table_similarity{2}, filename{2}, 'WriteRowNames', true, 'Encoding', 'UTF-8')
            writetable(table_similarity{3}, filename{3}, 'WriteRowNames', true, 'Encoding', 'UTF-8')
            writetable(table_similarity{4}, filename{4}, 'WriteRowNames', true, 'Encoding', 'UTF-8')
            writetable(table_similarity{5}, filename{5}, 'WriteRowNames', true, 'Encoding', 'UTF-8')
            writetable(table_similarity{6}, filename{6}, 'WriteRowNames', true, 'Encoding', 'UTF-8')
        end

        function write_to_file_input_output(table_similarity, name, lang, n_samples, n_learners)
            f_common = fullfile(config.getInstance.path_measures, lang.name ...
                    + "_" + name + "_similarities_" ...
                    + n_samples + "samples_" ...
                    + n_learners + "learners_h");
            filename{1} = strcat(f_common, "_with_std.csv");
            filename{2} = strcat(f_common, "_without_std.csv");
            
            writetable(table_similarity{1}, filename{1}, 'WriteRowNames', true, 'Encoding', 'UTF-8')
            writetable(table_similarity{2}, filename{2}, 'WriteRowNames', true, 'Encoding', 'UTF-8')
        end

        function unclamped_indeces = unclamped(n_nodes, n_comparisons)
            unclamped_indeces = repmat(1:n_nodes, n_comparisons, 1);
            unclamped_indeces = mat2cell( ...
                unclamped_indeces, ones(1, size(unclamped_indeces, 1)), size(unclamped_indeces, 2));
        end
        
        function unclamped_indeces = unclamped_lex()
            % only for lang2
            unclamped_indeces = {
                1:lang2.n_sound_nodes;
                1:lang2.n_input_nodes;
                1:lang2.n_input_nodes;
                1:lang2.n_input_nodes;
            };
        end
        
        function unclamped_indeces = unclamped_gen()
            % only for lang2
            unclamped_indeces = {
                1:lang2.n_sound_nodes;
                1:lang2.n_input_nodes;
                1:lang2.n_input_nodes;
                1:lang2.n_input_nodes;
                1:lang2.n_input_nodes;
                1:lang2.n_input_nodes;
            };
        end
    end
end

