classdef thesis_simulation < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        UIFigure                        matlab.ui.Figure
        TabGroup                        matlab.ui.container.TabGroup
        Language1Tab                    matlab.ui.container.Tab
        Sound1Panel                     matlab.ui.container.Panel
        Vowel1DropDown                  matlab.ui.control.DropDown
        Vowel1SampleButton              matlab.ui.control.Button
        F1erbV1Slider                   matlab.ui.control.Slider
        F2erbV1Slider                   matlab.ui.control.Slider
        F1erbV1EditField                matlab.ui.control.EditField
        F2erbV1EditField                matlab.ui.control.EditField
        Vowel1InputImage                matlab.ui.control.Image
        Comprehend1Button               matlab.ui.control.Button
        Meaning1Panel                   matlab.ui.container.Panel
        Meaning1InputImageLabels        matlab.ui.control.Image
        Meaning1DropDown                matlab.ui.control.DropDown
        LexicalMeaning1DropDown         matlab.ui.control.DropDown
        GenderMeaning1DropDown          matlab.ui.control.DropDown
        GendermeaningDropDown_2Label    matlab.ui.control.Label
        LexicalmeaningDropDown_2Label   matlab.ui.control.Label
        Meaning1InputImage              matlab.ui.control.Image
        Produce1Button                  matlab.ui.control.Button
        DBM1Panel                       matlab.ui.container.Panel
        TrainingIterations1ButtonGroup  matlab.ui.container.ButtonGroup
        TrainingIterations11Button      matlab.ui.control.RadioButton
        TrainingIterations12Button      matlab.ui.control.RadioButton
        TrainingIterations13Button      matlab.ui.control.RadioButton
        TrainDbm1Button                 matlab.ui.control.Button
        ResetDdm1Button                 matlab.ui.control.Button
        PretrainedDbm1DropDown          matlab.ui.control.DropDown
        PretrainedDbm1DropDownLabel     matlab.ui.control.Label
        Dbm1IstrainedLamp               matlab.ui.control.Lamp
        Dbm1IstrainedLabel              matlab.ui.control.Label
        UseDbm1Lamp                     matlab.ui.control.Lamp
        UseDbm1Label                    matlab.ui.control.Label
        Output1Panel                    matlab.ui.container.Panel
        Meaning1OutputImageLabels       matlab.ui.control.Image
        Meaning1OutputImage             matlab.ui.control.Image
        Vowel1OutputImage               matlab.ui.control.Image
        DBM1Tab                         matlab.ui.container.Tab
        Meaning1DbmLabels               matlab.ui.control.Image
        UseDbm1Label_2                  matlab.ui.control.Label
        UseDbm1Lamp_2                   matlab.ui.control.Lamp
        Dbm1IstrainedLamp_2             matlab.ui.control.Lamp
        Dbm1IstrainedLabel_2            matlab.ui.control.Label
        Lang1DbmImage                   matlab.ui.control.Image
        Language2Tab                    matlab.ui.container.Tab
        Sound2Panel                     matlab.ui.container.Panel
        Comprehend2Button               matlab.ui.control.Button
        Sound2DropDown                  matlab.ui.control.DropDown
        Consonant21Panel                matlab.ui.container.Panel
        Consonant21InputImage           matlab.ui.control.Image
        Consonant21DropDown             matlab.ui.control.DropDown
        Vowel21Panel                    matlab.ui.container.Panel
        Vowel21DropDown                 matlab.ui.control.DropDown
        Vowel21SampleButton             matlab.ui.control.Button
        F1erbV21Slider                  matlab.ui.control.Slider
        F2erbV21Slider                  matlab.ui.control.Slider
        F1erbV21EditField               matlab.ui.control.EditField
        F2erbV21EditField               matlab.ui.control.EditField
        Vowel21InputImage               matlab.ui.control.Image
        ConsonantV22Panel               matlab.ui.container.Panel
        Consonant22InputImage           matlab.ui.control.Image
        Consonant22DropDown             matlab.ui.control.DropDown
        Vowel22Panel                    matlab.ui.container.Panel
        Vowel22InputImage               matlab.ui.control.Image
        Vowel22DropDown                 matlab.ui.control.DropDown
        Vowel22SampleButton             matlab.ui.control.Button
        F1erbV22Slider                  matlab.ui.control.Slider
        F2erbV22Slider                  matlab.ui.control.Slider
        F1erbV22EditField               matlab.ui.control.EditField
        F2erbV22EditField               matlab.ui.control.EditField
        DBM2Panel                       matlab.ui.container.Panel
        TrainingIterations2ButtonGroup  matlab.ui.container.ButtonGroup
        TrainingIterations21Button      matlab.ui.control.RadioButton
        TrainingIterations22Button      matlab.ui.control.RadioButton
        TrainingIterations23Button      matlab.ui.control.RadioButton
        TrainDbm2Button                 matlab.ui.control.Button
        ResetDbm2Button                 matlab.ui.control.Button
        PretrainedDbm2DropDownLabel     matlab.ui.control.Label
        PretrainedDbm2DropDown          matlab.ui.control.DropDown
        Dbm2IstrainedLamp               matlab.ui.control.Lamp
        Dbm2IstrainedLabel              matlab.ui.control.Label
        UseDbm2Lamp                     matlab.ui.control.Lamp
        UseDbm2Label                    matlab.ui.control.Label
        Meaning2Panel                   matlab.ui.container.Panel
        Meaning2InputImageLabels        matlab.ui.control.Image
        GenderMeaning2DropDown          matlab.ui.control.DropDown
        GendermeaningDropDownLabel      matlab.ui.control.Label
        Meaning2InputImage              matlab.ui.control.Image
        LexicalMeaning2DropDown         matlab.ui.control.DropDown
        LexicalmeaningDropDownLabel     matlab.ui.control.Label
        Produce2Button                  matlab.ui.control.Button
        Meaning2DropDown                matlab.ui.control.DropDown
        Output2Panel                    matlab.ui.container.Panel
        Meaning2OutputImageLabels       matlab.ui.control.Image
        Vowel22OutputImage              matlab.ui.control.Image
        Consonant22OutputImage          matlab.ui.control.Image
        Consonant21OutputImage          matlab.ui.control.Image
        Meaning2OutputImage             matlab.ui.control.Image
        Vowel21OutputImage              matlab.ui.control.Image
        DBM2Tab                         matlab.ui.container.Tab
        Meaning2DbmLabels               matlab.ui.control.Image
        UseDbm2Label_2                  matlab.ui.control.Label
        UseDbm2Lamp_2                   matlab.ui.control.Lamp
        Dbm2IstrainedLabel_2            matlab.ui.control.Label
        Dbm2IstrainedLamp_2             matlab.ui.control.Lamp
        Lang2DbmImage                   matlab.ui.control.Image
    end

    properties (Constant)
        dbm_colors = [          % 2-dim array of DBM state lamp colors (state x RGB)
            [0.85,0.33,0.10]    % not trained: tint of red
            [0.93,0.69,0.13]    % training: tint of yellow
            [0.39,0.83,0.07]    % trained: tint of green
        ];

        lang1_dataset1 = data_set(lang1, 200);  % dataset 1 for language 1
        lang1_dataset2 = data_set(lang1, 600);  % dataset 2 for language 1
        lang1_dataset3 = data_set(lang1, 2000); % dataset 3 for language 1
        
        lang2_dataset1 = data_set(lang2, 200);  % dataset 1 for language 2
        lang2_dataset2 = data_set(lang2, 600);  % dataset 2 for language 2
        lang2_dataset3 = data_set(lang2, 2000); % dataset 3 for language 2
    end
    
    properties (Access = private)
        lang1_dbm                % DBM for language 1
        dbm1_state                  % 0: not trained, 1: training, 2: trained
        sound1_state                % 0: not set, 1: set
        meaning1_state              % 0: not set, 1: set
        pretrained_dbm1_list     % current list of available pretrained DBMs

        lang2_dbm                % DBM for language 2
        dbm2_state                  % 0: not trained, 1: training, 2: trained
        sound2_state                % 0: not set, 1: set
        meaning2_state              % 0: not set, 1: set
        pretrained_dbm2_list     % current list of available pretrained DBMs
    end

    methods (Access = private)

        function updatePretrainedDbm1List(app)
            % get a list of files for dbm1-layer1
            dbms_path = fullfile(config.getInstance.path_dbms, ...
                "lang1_dbm_layer1_*." + config.getInstance.dbm_format);
            files = dir(dbms_path);
            
            % set up app.pretrained_dbm1_list
            n_dbms = length(files);
            app.pretrained_dbm1_list = zeros(1, n_dbms, 'double');
            for i = 1:n_dbms
                n_ins = erase(files(i).name, "lang1_dbm_layer1_");
                n_ins = erase(n_ins, "." + config.getInstance.dbm_format);
                app.pretrained_dbm1_list(i) = str2double(n_ins);
            end
            app.pretrained_dbm1_list = sort(app.pretrained_dbm1_list);

            % create a string array of dropdown items and set up the dropdown
            items = string(app.pretrained_dbm1_list) + " data instances";
            app.PretrainedDbm1DropDown.Items = ["-" items];
            app.PretrainedDbm1DropDown.ItemsData = 1:length(items) + 1;
            app.PretrainedDbm1DropDown.Value = 1;
        end
        
         function updatePretrainedDbm2List(app)
            % get a list of files for dbm2-layer1
            dbms_path = fullfile(config.getInstance.path_dbms, ...
                "lang2_dbm_layer1_*." + config.getInstance.dbm_format);
            files = dir(dbms_path);
            
            % set up app.pretrained_dbm2_list
            n_dbms = length(files);
            app.pretrained_dbm2_list = zeros(1, n_dbms, 'double');
            for i = 1:n_dbms
                n_ins = erase(files(i).name, "lang2_dbm_layer1_");
                n_ins = erase(n_ins, "." + config.getInstance.dbm_format);
                app.pretrained_dbm2_list(i) = str2double(n_ins);
            end
            app.pretrained_dbm2_list = sort(app.pretrained_dbm2_list);

            % create a string array of dropdown items and set up the dropdown
            items = string(app.pretrained_dbm2_list) + " data instances";
            app.PretrainedDbm2DropDown.Items = ["-" items];
            app.PretrainedDbm2DropDown.ItemsData = 1:length(items) + 1;
            app.PretrainedDbm2DropDown.Value = 1;
        end
        
       function updateUseButtons1(app)
            if app.dbm1_state == 2 && app.sound1_state
                app.Comprehend1Button.Enable = "on";
            else
                app.Comprehend1Button.Enable = "off";
            end
            if app.dbm1_state == 2 && app.meaning1_state
                app.Produce1Button.Enable = "on";
            else
                app.Produce1Button.Enable = "off";
            end
        end
        
        function updateUseButtons2(app)
            if app.dbm2_state == 2 && app.sound2_state
                app.Comprehend2Button.Enable = "on";
            else
                app.Comprehend2Button.Enable = "off";
            end
            if app.dbm2_state == 2 && app.meaning2_state
                app.Produce2Button.Enable = "on";
            else
                app.Produce2Button.Enable = "off";
            end
        end
        
        function updateDbm1State(app, new_state, legend)
            app.dbm1_state = new_state;

            app.Dbm1IstrainedLamp.Color = thesis_simulation.dbm_colors(new_state + 1, :);
            app.Dbm1IstrainedLabel.Text = legend;
           
            app.Dbm1IstrainedLamp_2.Color = thesis_simulation.dbm_colors(new_state + 1, :);
            app.Dbm1IstrainedLabel_2.Text = legend;
           
            app.updateUseButtons1;
            drawnow
        end
        
        function updateDbm2State(app, new_state, legend)
            app.dbm2_state = new_state;
            
            app.Dbm2IstrainedLamp.Color = thesis_simulation.dbm_colors(new_state + 1, :);
            app.Dbm2IstrainedLabel.Text = legend;
           
            app.Dbm2IstrainedLamp_2.Color = thesis_simulation.dbm_colors(new_state + 1, :);
            app.Dbm2IstrainedLabel_2.Text = legend;
           
            app.updateUseButtons2;
            drawnow
        end
        
        function updateUseDbm1State(app, state, legend)
            app.UseDbm1Lamp.Color = thesis_simulation.dbm_colors(state + 1, :);
            app.UseDbm1Label.Text = legend;
            
            app.UseDbm1Lamp_2.Color = thesis_simulation.dbm_colors(state + 1, :);
            app.UseDbm1Label_2.Text = legend;
            drawnow
        end
        
        function updateUseDbm2State(app, state, legend)
            app.UseDbm2Lamp.Color = thesis_simulation.dbm_colors(state + 1, :);
            app.UseDbm2Label.Text = legend;

            app.UseDbm2Lamp_2.Color = thesis_simulation.dbm_colors(state + 1, :);
            app.UseDbm2Label_2.Text = legend;
            drawnow
        end
        
        function updateSound1State(app, new_state)
            % sound state
            app.sound1_state = new_state;
            
            % update Produce and Comprehend buttons
            app.updateUseButtons1
            drawnow
        end
        
        function updateSound2State(app, new_state)
            % sound state
            app.sound2_state = new_state;
            
            % update Produce and Comprehend buttons
            app.updateUseButtons2
            drawnow
        end
        
        function updateMeaning1State(app, new_state)
            % meaning state
            app.meaning1_state = new_state;
            
            % update Produce and Comprehend buttons
            app.updateUseButtons1
            drawnow
        end
        
        function updateMeaning2State(app, new_state)
            % meaning state
            app.meaning2_state = new_state;
            
            % update Produce and Comprehend buttons
            app.updateUseButtons2
            drawnow
        end
        
        function setSound1FromMeaning(app)
            % sound dropdown
            meaning = app.Meaning1DropDown.Value;
            if meaning == lang1_meaning.n_meanings + 2
                v_index = lang1_sound.n_vowels + 1;
            else
                v_index = lang1.get_sound_of_meaning(meaning);
            end
            app.Vowel1DropDown.Value = v_index;

            % sound -> components
            app.updateVowel1Components(lang1_sound.f1_erbs(v_index), lang1_sound.f2_erbs(v_index))
        end
        
        function setSound2FromMeaning(app)
            % sound dropdown
            meaning = app.Meaning2DropDown.Value;
            if meaning == lang2_meaning.n_meanings + 2
                sound = lang2_sound.n_sounds + 1;
            else
                sound = lang2.get_sound_of_meaning(meaning);
            end
            app.Sound2DropDown.Value = sound;

            % sound -> components
            app.updateSound2Components
        end

        function setSound2FromComponents(app)
            % sound dropdown
            c1_index = app.Consonant21DropDown.Value;
            c2_index = app.Consonant22DropDown.Value;
            v1_index = app.Vowel21DropDown.Value;
            v2_index = app.Vowel22DropDown.Value;
            
            % if one of the vowels is "manually specified", 
            if v1_index == lang2_sound.n_vowels + 2 || v2_index ==lang2_sound.n_vowels + 2
                app.Sound2DropDown.Value = lang2_sound.n_sounds + 2;
            else
                found = false;
                for i = 1:lang2_sound.n_sounds + 1
                    if (strcmp(lang2_sound.cons(c1_index), lang2_sound.all_sounds(2, i)) ...
                            && strcmp(lang2_sound.vowels(v1_index), lang2_sound.all_sounds(3, i)) ...
                            && strcmp(lang2_sound.cons(c2_index), lang2_sound.all_sounds(4, i)) ...
                            && strcmp(lang2_sound.vowels(v2_index), lang2_sound.all_sounds(5, i)) ...
                            )  
                        found = true;
                        app.Sound2DropDown.Value = i;
                        break
                    end
                end
                if ~found
                    app.Sound2DropDown.Value = lang2_sound.n_sounds + 2;
                end
            end
            
            % sound state, zero if "NONE"
            if app.Sound2DropDown.Value == lang2_sound.n_sounds + 1
                app.updateSound2State(0)
            else
                app.updateSound2State(1)
            end

            % sound -> meaning
            app.setMeaning2FromSound
        end

        function updateSound2Components(app)
            sound = app.Sound2DropDown.Value;
            if sound == lang2_sound.n_sounds + 2
                return
            end
            
            c1 = lang2_sound.all_sounds(2, sound);
            v1 = lang2_sound.all_sounds(3, sound);
            c2 = lang2_sound.all_sounds(4, sound);
            v2 = lang2_sound.all_sounds(5, sound);

            c1_index = find(strcmp(lang2_sound.cons, c1), 1, "first");
            c2_index = find(strcmp(lang2_sound.cons, c2), 1, "first");
            v1_index = find(strcmp(lang2_sound.vowels, v1), 1, "first");
            v2_index = find(strcmp(lang2_sound.vowels, v2), 1, "first");

            % consonants
            app.Consonant21DropDown.Value = c1_index;
            app.Consonant22DropDown.Value = c2_index;
            
            % vowels
            app.Vowel21DropDown.Value = v1_index;
            app.Vowel22DropDown.Value = v2_index;
            app.updateVowel21Components(lang2_sound.f1_erbs(v1_index), lang2_sound.f2_erbs(v1_index))
            app.updateVowel22Components(lang2_sound.f1_erbs(v2_index), lang2_sound.f2_erbs(v2_index))

            % images
            app.redrawConsonant21InputImage
            app.redrawConsonant22InputImage
            app.redrawVowel21InputImage
            app.redrawVowel22InputImage

            % sound state, zero if "NONE"
            if app.Sound2DropDown.Value == lang2_sound.n_sounds + 1
                app.updateSound2State(0)
            else
                app.updateSound2State(1)
            end
        end

        function setMeaning1FromSound(app)
            % meaning dropdown
            sound = app.Vowel1DropDown.Value;
            if sound == lang1_sound.n_vowels + 2
                meaning = lang1_meaning.n_meanings + 1;
            else
                meaning = lang1.get_meaning_of_sound(sound);
            end
            app.Meaning1DropDown.Value = meaning;

            % meaning -> components
            app.updateMeaning1Components
        end

        function setMeaning1FromComponents(app)
            lex_index = app.LexicalMeaning1DropDown.Value;
            gen_index = app.GenderMeaning1DropDown.Value;

            % meaning dropdown
            found = false;
            for i = 1:lang1_meaning.n_meanings + 1
                if (strcmp(lang1_meaning.lex(lex_index),lang1_meaning.all_meanings(2, i)) ...
                        && strcmp(lang1_meaning.gen(gen_index), lang1_meaning.all_meanings(3, i)))  
                    found = true;
                    app.Meaning1DropDown.Value = i;
                    break
                end
            end
            if ~found
                app.Meaning1DropDown.Value = lang1_meaning.n_meanings + 2;
            end
            
            % meaning state, zero if "NONE"
            if app.Meaning1DropDown.Value == lang1_meaning.n_meanings + 1
                app.updateMeaning1State(0)
            else
                app.updateMeaning1State(1)
            end
        
            % images
            app.redrawMeaning1InputImage

            % meaning -> sound
            app.setSound1FromMeaning
        end

        function updateMeaning1Components(app)
            meaning = app.Meaning1DropDown.Value;
            lex = lang1_meaning.all_meanings(2, meaning);
            gen = lang1_meaning.all_meanings(3, meaning);

            lex_index = find(strcmp(lang1_meaning.lex, lex), 1, "first");
            gen_index = find(strcmp(lang1_meaning.gen, gen), 1, "first");
            
            % dropdowns
            app.LexicalMeaning1DropDown.Value = lex_index;
            app.GenderMeaning1DropDown.Value = gen_index;
            
            % images
            app.redrawMeaning1InputImage

            % meaning state, zero if "NONE"
            if app.Meaning1DropDown.Value == lang1_meaning.n_meanings + 1
                app.updateMeaning1State(0)
            else
                app.updateMeaning1State(1)
            end
        end

        function setMeaning2FromSound(app)
            % meaning dropdown
            sound = app.Sound2DropDown.Value;
            if sound == lang2_sound.n_sounds + 2
                meaning = lang2_meaning.n_meanings + 1;
            else
                meaning = lang2.get_meaning_of_sound(sound);
            end
            app.Meaning2DropDown.Value = meaning;

            % meaning -> components
            app.updateMeaning2Components
        end

        function setMeaning2FromComponents(app)
            lex_index = app.LexicalMeaning2DropDown.Value;
            gen_index = app.GenderMeaning2DropDown.Value;

            % meaning dropdown
            found = false;
            for i = 1:lang2_meaning.n_meanings + 1
                if (strcmp(lang2_meaning.lex(lex_index),lang2_meaning.all_meanings(2, i)) ...
                        && strcmp(lang2_meaning.gen(gen_index), lang2_meaning.all_meanings(3, i)))  
                    found = true;
                    app.Meaning2DropDown.Value = i;
                    break
                end
            end
            if ~found
                app.Meaning2DropDown.Value = lang2_meaning.n_meanings + 2;
            end
            
            % meaning state, zero if "NONE"
            if app.Meaning2DropDown.Value == lang2_meaning.n_meanings + 1
                app.updateMeaning2State(0)
            else
                app.updateMeaning2State(1)
            end
        
            % images
            app.redrawMeaning2InputImage

            % meaning -> sound
            app.setSound2FromMeaning
        end

        function updateMeaning2Components(app)
            meaning = app.Meaning2DropDown.Value;
            if meaning == lang2_meaning.n_meanings + 2
                return
            end
            
            lex = lang2_meaning.all_meanings(2, meaning);
            gen = lang2_meaning.all_meanings(3, meaning);

            lex_index = find(strcmp(lang2_meaning.lex, lex), 1, "first");
            gen_index = find(strcmp(lang2_meaning.gen, gen), 1, "first");
            
            % dropdowns
            app.LexicalMeaning2DropDown.Value = lex_index;
            app.GenderMeaning2DropDown.Value = gen_index;
            
            % images
            app.redrawMeaning2InputImage

            % meaning state, zero if "NONE"
            if app.Meaning2DropDown.Value == lang2_meaning.n_meanings + 1
                app.updateMeaning2State(0)
            else
                app.updateMeaning2State(1)
            end
        end

        function setVowel1FromErbs(app)
            f1_erb = str2double(app.F1erbV1EditField.Value);
            f2_erb = str2double(app.F2erbV1EditField.Value);
            
            % vowel dropdown
            app.Vowel1DropDown.Value = lang1_sound.find_vowel_by_erbs(f1_erb, f2_erb);
            % sound (vowel) -> meaning
            app.setMeaning1FromSound
        end   

        function setVowel21FromErbs(app)
            f1_erb = str2double(app.F1erbV21EditField.Value);
            f2_erb = str2double(app.F2erbV21EditField.Value);
            
            % vowel dropdown
            app.Vowel21DropDown.Value = lang2_sound.find_vowel_by_erbs(f1_erb, f2_erb);
            % vowel -> sound
            app.setSound2FromComponents
        end

        function setVowel22FromErbs(app)
            f1_erb = str2double(app.F1erbV22EditField.Value);
            f2_erb = str2double(app.F2erbV22EditField.Value);
            
            % vowel dropdown
            app.Vowel22DropDown.Value = lang2_sound.find_vowel_by_erbs(f1_erb, f2_erb);
            % vowel -> sound
            app.setSound2FromComponents
        end
        
        function updateVowel1Components(app, f1_erb, f2_erb)
            if f1_erb == 0 && f2_erb == 0
                % sliders
                app.F1erbV1Slider.Value = 4;
                app.F2erbV1Slider.Value = 4;
                % text fields
                app.F1erbV1EditField.Value = "";
                app.F2erbV1EditField.Value = "";
                % sample button
                app.Vowel1SampleButton.Enable = "off";
                % sound state
                app.updateSound1State(0)
            else
                if f1_erb < 4 
                    f1_erb = 4;
                elseif f1_erb > 28
                    f1_erb = 28;
                end
                if f2_erb < 4
                    f2_erb = 4;
                elseif f2_erb > 28
                    f2_erb = 28;
                end
            
                % sliders
                app.F1erbV1Slider.Value = f1_erb;
                app.F2erbV1Slider.Value = f2_erb;
                % text fields
                app.F1erbV1EditField.Value = sprintf('%.2f', f1_erb);
                app.F2erbV1EditField.Value = sprintf('%.2f', f2_erb);
                % sample button
                app.Vowel1SampleButton.Enable = "on";
                % sound state
                app.updateSound1State(1)
            end

            app.redrawVowel1InputImage
        end

        function updateVowel21Components(app, f1_erb, f2_erb)
            if f1_erb == 0 && f2_erb == 0
                % sliders
                app.F1erbV21Slider.Value = 4;
                app.F2erbV21Slider.Value = 4;
                % text fields
                app.F1erbV21EditField.Value = "";
                app.F2erbV21EditField.Value = "";
                % sample button
                app.Vowel21SampleButton.Enable = "off";
            else
                if f1_erb < 4 
                    f1_erb = 4;
                elseif f1_erb > 28
                    f1_erb = 28;
                end
                if f2_erb < 4
                    f2_erb = 4;
                elseif f2_erb > 28
                    f2_erb = 28;
                end
            
                % sliders
                app.F1erbV21Slider.Value = f1_erb;
                app.F2erbV21Slider.Value = f2_erb;
                % text fields
                app.F1erbV21EditField.Value = sprintf('%.2f', f1_erb);
                app.F2erbV21EditField.Value = sprintf('%.2f', f2_erb);
                % sample button
                app.Vowel21SampleButton.Enable = "on";
            end

            app.redrawVowel21InputImage
        end

        function updateVowel22Components(app, f1_erb, f2_erb)
            if f1_erb == 0 && f2_erb == 0
                % sliders
                app.F1erbV22Slider.Value = 4;
                app.F2erbV22Slider.Value = 4;
                % text fields
                app.F1erbV22EditField.Value = "";
                app.F2erbV22EditField.Value = "";
                % sample button
                app.Vowel22SampleButton.Enable = "off";
            else
                if f1_erb < 4 
                    f1_erb = 4;
                elseif f1_erb > 28
                    f1_erb = 28;
                end
                if f2_erb < 4
                    f2_erb = 4;
                elseif f2_erb > 28
                    f2_erb = 28;
                end
            
                % sliders
                app.F1erbV22Slider.Value = f1_erb;
                app.F2erbV22Slider.Value = f2_erb;
                % text fields
                app.F1erbV22EditField.Value = sprintf('%.2f', f1_erb);
                app.F2erbV22EditField.Value = sprintf('%.2f', f2_erb);
                % sample button
                app.Vowel22SampleButton.Enable = "on";
            end

            app.redrawVowel22InputImage
        end

        function redrawVowel1InputImage(app)
            f1_erb = app.F1erbV1Slider.Value;
            f2_erb = app.F2erbV1Slider.Value;
            if (f1_erb == 4 && f2_erb == 4)
                f1_erb = 0;
                f2_erb = 0;
            end
            lang1_sound.draw_input(vowel.create_input_vector(f1_erb, f2_erb));

            app.Vowel1InputImage.ImageSource = imread(draw.img_filename(draw.lang1_vowel_input));
        end
        
        function redrawVowel21InputImage(app)
            f1_erb = app.F1erbV21Slider.Value;
            f2_erb = app.F2erbV21Slider.Value;
            if (f1_erb == 4 && f2_erb == 4)
                f1_erb = 0;
                f2_erb = 0;
            end
            draw.vowel(vowel.create_input_vector(f1_erb, f2_erb), draw.lang2_vowel1_input)

            app.Vowel21InputImage.ImageSource = imread(draw.img_filename(draw.lang2_vowel1_input));
        end
        
        function redrawVowel22InputImage(app)
            f1_erb = app.F1erbV22Slider.Value;
            f2_erb = app.F2erbV22Slider.Value;
            if (f1_erb == 4 && f2_erb == 4)
                f1_erb = 0;
                f2_erb = 0;
            end
            draw.vowel(vowel.create_input_vector(f1_erb, f2_erb), draw.lang2_vowel2_input)

            app.Vowel22InputImage.ImageSource = imread(draw.img_filename(draw.lang2_vowel2_input));
        end

        function redrawConsonant21InputImage(app)
            cons_index = app.Consonant21DropDown.Value;
            input_vector = lang2_sound.create_consonant_input_vector(cons_index);
            draw.consonant(input_vector, draw.lang2_consonant1_input);

            app.Consonant21InputImage.ImageSource = imread(draw.img_filename(draw.lang2_consonant1_input));
        end

        function redrawConsonant22InputImage(app)
            cons_index = app.Consonant22DropDown.Value;
            input_vector = lang2_sound.create_consonant_input_vector(cons_index);
            draw.consonant(input_vector, draw.lang2_consonant2_input);

            app.Consonant22InputImage.ImageSource = imread(draw.img_filename(draw.lang2_consonant2_input));
        end

        function redrawMeaning1InputImage(app)
            lex_index = app.LexicalMeaning1DropDown.Value;
            gen_index = app.GenderMeaning1DropDown.Value;
            lang1_meaning.draw_input(lang1_meaning.create_custom_input_vector(lex_index, gen_index));
            
            app.Meaning1InputImage.ImageSource = imread(draw.img_filename(draw.lang1_meaning_input));
        end

        function redrawMeaning2InputImage(app)
            lex_index = app.LexicalMeaning2DropDown.Value;
            gen_index = app.GenderMeaning2DropDown.Value;
            lang2_meaning.draw_input(lang2_meaning.create_custom_input_vector(lex_index, gen_index));
            
            app.Meaning2InputImage.ImageSource = imread(draw.img_filename(draw.lang2_meaning_input));
        end

        function redrawOutput1Images(app)
            lang1.draw_output(app.lang1_dbm.activities{1})

            app.Vowel1OutputImage.ImageSource = imread(draw.img_filename(draw.lang1_vowel_output));
            app.Meaning1OutputImage.ImageSource = imread(draw.img_filename(draw.lang1_meaning_output));
        end
        
        function redrawOutput2Images(app)
            lang2.draw_output(app.lang2_dbm.activities{1})
            
            app.Consonant21OutputImage.ImageSource = imread(draw.img_filename(draw.lang2_consonant1_output));
            app.Vowel21OutputImage.ImageSource = imread(draw.img_filename(draw.lang2_vowel1_output));
            app.Consonant22OutputImage.ImageSource = imread(draw.img_filename(draw.lang2_consonant2_output));
            app.Vowel22OutputImage.ImageSource = imread(draw.img_filename(draw.lang2_vowel2_output));
            app.Meaning2OutputImage.ImageSource = imread(draw.img_filename(draw.lang2_meaning_output));
        end

        function redrawTrainedDbm1Image(app)
            app.lang1_dbm.draw_trained
            app.Lang1DbmImage.ImageSource = imread(draw.img_filename(draw.lang1_trained_dbm));
        end

        function redrawTrainedDbm2Image(app)
            app.lang2_dbm.draw_trained
            app.Lang2DbmImage.ImageSource = imread(draw.img_filename(draw.lang2_trained_dbm));
        end

        function redrawDbm1Image(app)
            app.lang1_dbm.draw
            app.Lang1DbmImage.ImageSource = imread(draw.img_filename(draw.lang1_dbm));
        end

        function redrawDbm2Image(app)
            app.lang2_dbm.draw
            app.Lang2DbmImage.ImageSource = imread(draw.img_filename(draw.lang2_dbm));
        end

        function loadEmptyOutput1Images(app)
            app.Vowel1OutputImage.ImageSource = imread(fullfile(config.getInstance.path_initial_images, "vowel.png"));
            app.Meaning1OutputImage.ImageSource = imread(fullfile(config.getInstance.path_initial_images, "lang1_meaning.png"));
        end

        function loadEmptyOutput2Images(app)
            app.Consonant21OutputImage.ImageSource = imread(fullfile(config.getInstance.path_initial_images, "consonant.png"));
            app.Vowel21OutputImage.ImageSource = imread(fullfile(config.getInstance.path_initial_images, "vowel.png"));
            app.Consonant22OutputImage.ImageSource = imread(fullfile(config.getInstance.path_initial_images, "consonant.png"));
            app.Vowel22OutputImage.ImageSource = imread(fullfile(config.getInstance.path_initial_images, "vowel.png"));
            app.Meaning2OutputImage.ImageSource = imread(fullfile(config.getInstance.path_initial_images, "lang2_meaning.png"));
        end

        function loadEmptyDbm1Image(app)
            app.Lang1DbmImage.ImageSource = imread(fullfile(config.getInstance.path_initial_images, "lang1_dbm.png"));
        end

        function loadEmptyDbm2Image(app)
            app.Lang2DbmImage.ImageSource = imread(fullfile(config.getInstance.path_initial_images, "lang2_dbm.png"));
        end

        function loadTrainedDbm1Image(app)
            app.Lang1DbmImage.ImageSource = imread(draw.img_filename(draw.lang1_trained_dbm));
        end

        function loadTrainedDbm2Image(app)
            app.Lang2DbmImage.ImageSource = imread(draw.img_filename(draw.lang2_trained_dbm));
        end    
    end

    % Callbacks that handle component events
    methods (Access = private)

        % Code that executes after component creation
        function startupFcn(app)
            rng('shuffle'); % so the training data is as random as possible
            
            % look and feel
            app.TabGroup.FontName = 'Georgia';

            % DBMs
            app.lang1_dbm = dbm(lang1);
            app.updatePretrainedDbm1List
            app.updateDbm1State(0, "DBM not trained")
            app.updateUseDbm1State(0, "DBM not used")
            app.updateSound1State(0)
            app.updateMeaning1State(0)
           
            app.lang2_dbm = dbm(lang2);
            app.updatePretrainedDbm2List
            app.updateDbm2State(0, "DBM not trained")
            app.updateUseDbm2State(0, "DBM not used")
            app.updateSound2State(0)
            app.updateMeaning2State(0)
            
            % buttons
            app.Vowel1SampleButton.Enable = "off";
            app.Vowel21SampleButton.Enable = "off";
            app.Vowel22SampleButton.Enable = "off";
   
            % radio buttons
            app.TrainingIterations11Button.Text = strcat("+ ", int2str(thesis_simulation.lang1_dataset1.n_samples));
            app.TrainingIterations12Button.Text = strcat("+ ", int2str(thesis_simulation.lang1_dataset2.n_samples));
            app.TrainingIterations13Button.Text = strcat("+ ", int2str(thesis_simulation.lang1_dataset3.n_samples));

            app.TrainingIterations21Button.Text = strcat("+ ", int2str(thesis_simulation.lang2_dataset1.n_samples));
            app.TrainingIterations22Button.Text = strcat("+ ", int2str(thesis_simulation.lang2_dataset2.n_samples));
            app.TrainingIterations23Button.Text = strcat("+ ", int2str(thesis_simulation.lang2_dataset3.n_samples));
            
            % dropdowns
            app.Vowel1DropDown.Items = [lang1_sound.vowels, "manually specified"];
            app.Vowel1DropDown.ItemsData = 1:lang1_sound.n_vowels + 2;
            app.Vowel1DropDown.Value = lang1_sound.n_vowels + 1;

            app.Meaning1DropDown.Items = [lang1_meaning.all_meanings(1,:), "manually specified"];
            app.Meaning1DropDown.ItemsData = 1:lang1_meaning.n_meanings + 2;
            app.Meaning1DropDown.Value = lang1_meaning.n_meanings + 1;

            app.LexicalMeaning1DropDown.Items = lang1_meaning.lex;
            app.LexicalMeaning1DropDown.ItemsData = 1:lang1_meaning.n_lex + 1;
            app.LexicalMeaning1DropDown.Value = lang1_meaning.n_lex + 1;

            app.GenderMeaning1DropDown.Items = lang1_meaning.gen;
            app.GenderMeaning1DropDown.ItemsData = 1:lang1_meaning.n_gen + 1;
            app.GenderMeaning1DropDown.Value = lang1_meaning.n_gen + 1;

            app.Sound2DropDown.Items = [lang2_sound.all_sounds(1,:), "manually specified"];
            app.Sound2DropDown.ItemsData = 1:lang2_sound.n_sounds + 2;
            app.Sound2DropDown.Value = lang2_sound.n_sounds + 1;

            app.Consonant21DropDown.Items = [lang2_sound.cons, "NONE"];
            app.Consonant21DropDown.ItemsData = 1:lang2_sound.n_cons + 1;
            app.Consonant21DropDown.Value = lang2_sound.n_cons + 1;

            app.Vowel21DropDown.Items = [lang2_sound.vowels, "manually specified"];
            app.Vowel21DropDown.ItemsData = 1:lang2_sound.n_vowels + 2;
            app.Vowel21DropDown.Value = lang2_sound.n_vowels + 1;

            app.Consonant22DropDown.Items = [lang2_sound.cons, "NONE"];
            app.Consonant22DropDown.ItemsData = 1:lang2_sound.n_cons + 1;
            app.Consonant22DropDown.Value = lang2_sound.n_cons + 1;

            app.Vowel22DropDown.Items = [lang2_sound.vowels, "manually specified"];
            app.Vowel22DropDown.ItemsData = 1:lang2_sound.n_vowels + 2;
            app.Vowel22DropDown.Value = lang2_sound.n_vowels + 1;

            app.Meaning2DropDown.Items = [lang2_meaning.all_meanings(1,:), "manually specified"];
            app.Meaning2DropDown.ItemsData = 1:lang2_meaning.n_meanings + 2;
            app.Meaning2DropDown.Value = lang2_meaning.n_meanings + 1;

            app.LexicalMeaning2DropDown.Items = lang2_meaning.lex;
            app.LexicalMeaning2DropDown.ItemsData = 1:lang2_meaning.n_lex + 1;
            app.LexicalMeaning2DropDown.Value = lang2_meaning.n_lex + 1;

            app.GenderMeaning2DropDown.Items = lang2_meaning.gen;
            app.GenderMeaning2DropDown.ItemsData = 1:lang2_meaning.n_gen + 1;
            app.GenderMeaning2DropDown.Value = lang2_meaning.n_gen + 1;
        end

        % Value changed function: Sound2DropDown
        function Sound2DropDownValueChanged(app, event)
            % revert sound dropdown if it is set to"manually specified"
            if app.Sound2DropDown.Value == lang2_sound.n_sounds + 2
                app.setSound2FromComponents
                return
            end
            
            % sound components
            app.updateSound2Components
            
            % sound -> meaning
            app.setMeaning2FromSound
        end

        % Value changed function: Consonant21DropDown
        function Consonant21DropDownValueChanged(app, event)
            % image
            app.redrawConsonant21InputImage
            
            % consonant -> sound
            app.setSound2FromComponents
        end

        % Value changed function: Consonant22DropDown
        function Consonant22DropDownValueChanged(app, event)
            % image
            app.redrawConsonant22InputImage
            
            % consonant -> sound
            app.setSound2FromComponents
        end

        % Value changed function: Vowel1DropDown
        function Vowel1DropDownValueChanged(app, event)
            % index in lang1_sound.vowels or +1 for "manually.."
            v_index = app.Vowel1DropDown.Value; 

            if v_index == lang1_sound.n_vowels + 2
                f1_erb = app.F1erbV1Slider.Value;
                f2_erb = app.F2erbV1Slider.Value;
            else
                f1_erb = lang1_sound.f1_erbs(v_index);
                f2_erb = lang1_sound.f2_erbs(v_index);
            end
            app.updateVowel1Components(f1_erb, f2_erb)

            % sound (vowel) -> meaning
            app.setMeaning1FromSound
        end

        % Value changed function: Vowel21DropDown
        function Vowel21DropDownValueChanged(app, event)
            % index in lang2_sound.vowels or +1 for "manually.."
            v_index = app.Vowel21DropDown.Value; 

            % vowel components
            if v_index == lang2_sound.n_vowels + 2
                f1_erb = app.F1erbV21Slider.Value;
                f2_erb = app.F2erbV21Slider.Value;
            else
                f1_erb = lang2_sound.f1_erbs(v_index);
                f2_erb = lang2_sound.f2_erbs(v_index);
            end
            app.updateVowel21Components(f1_erb, f2_erb)
            
            % vowel -> sound
            app.setSound2FromComponents
        end

        % Value changed function: Vowel22DropDown
        function Vowel22DropDownValueChanged(app, event)
            % index in lang2_sound.vowels or +1 for "manually.."
            v_index = app.Vowel22DropDown.Value; 

            % vowel components
            if v_index == lang2_sound.n_vowels + 2
                f1_erb = app.F1erbV22Slider.Value;
                f2_erb = app.F2erbV22Slider.Value;
            else
                f1_erb = lang2_sound.f1_erbs(v_index);
                f2_erb = lang2_sound.f2_erbs(v_index);
            end
            app.updateVowel22Components(f1_erb, f2_erb)

            % vowel -> sound
            app.setSound2FromComponents
        end

        % Value changed function: F1erbV1Slider
        function F1erbV1SliderValueChanged(app, event)
            f1 = app.F1erbV1Slider.Value;
            f2 = app.F2erbV1Slider.Value;

            % vowel components
            app.updateVowel1Components(f1, f2)

            % erbs -> vowel
            app.setVowel1FromErbs
        end

        % Value changed function: F2erbV1Slider
        function F2erbV1SliderValueChanged(app, event)
            f1 = app.F1erbV1Slider.Value;
            f2 = app.F2erbV1Slider.Value;

            % vowel components
            app.updateVowel1Components(f1, f2)

            % erbs -> vowel
            app.setVowel1FromErbs
        end

        % Value changed function: F1erbV1EditField
        function F1erbV1EditFieldValueChanged(app, event)
            f1 = str2double(app.F1erbV1EditField.Value);
            f2 = app.F2erbV1Slider.Value;
            
            % vowel components
            app.updateVowel1Components(f1, f2)

            % erbs -> vowel
            app.setVowel1FromErbs
        end

        % Value changed function: F2erbV1EditField
        function F2erbV1EditFieldValueChanged(app, event)
            f1 = app.F1erbV1Slider.Value;
            f2 = str2double(app.F2erbV1EditField.Value);
            
            % vowel components
            app.updateVowel1Components(f1, f2)

            % erbs -> vowel
            app.setVowel1FromErbs
        end

        % Value changed function: F1erbV21Slider
        function F1erbV21SliderValueChanged(app, event)
            f1 = app.F1erbV21Slider.Value;
            f2 = app.F2erbV21Slider.Value;

            % vowel components
            app.updateVowel21Components(f1, f2)

            % erbs -> vowel
            app.setVowel21FromErbs
        end

        % Value changed function: F2erbV21Slider
        function F2erbV21SliderValueChanged(app, event)
            f1 = app.F1erbV21Slider.Value;
            f2 = app.F2erbV21Slider.Value;

            % vowel components
            app.updateVowel21Components(f1, f2)

            % erbs -> vowel
            app.setVowel21FromErbs
        end

        % Value changed function: F1erbV21EditField
        function F1erbV21EditFieldValueChanged(app, event)
            f1 = str2double(app.F1erbV21EditField.Value);
            f2 = app.F2erbV21Slider.Value;

            % vowel components
            app.updateVowel21Components(f1, f2)

            % erbs -> vowel
            app.setVowel21FromErbs
        end

        % Value changed function: F2erbV21EditField
        function F2erbV21EditFieldValueChanged(app, event)
            f1 = app.F1erbV21Slider.Value;
            f2 = str2double(app.F2erbV21EditField.Value);
            
            % vowel components
            app.updateVowel21Components(f1, f2)

            % erbs -> vowel
            app.setVowel21FromErbs
        end

        % Value changed function: F1erbV22Slider
        function F1erbV22SliderValueChanged(app, event)
            f1 = app.F1erbV22Slider.Value;
            f2 = app.F2erbV22Slider.Value;
            
            % vowel components
            app.updateVowel22Components(f1, f2)

            % erbs -> vowel
            app.setVowel22FromErbs
        end

        % Value changed function: F2erbV22Slider
        function F2erbV22SliderValueChanged(app, event)
            f1 = app.F1erbV22Slider.Value;
            f2 = app.F2erbV22Slider.Value;
            
            % vowel components
            app.updateVowel22Components(f1, f2)

            % erbs -> vowel
            app.setVowel22FromErbs
        end

        % Value changed function: F1erbV22EditField
        function F1erbV22EditFieldValueChanged(app, event)
            f1 = str2double(app.F1erbV22EditField.Value);
            f2 = app.F2erbV22Slider.Value;
             
            % vowel components
            app.updateVowel22Components(f1, f2)

            % erbs -> vowel
            app.setVowel22FromErbs
        end

        % Value changed function: F2erbV22EditField
        function F2erbV22EditFieldValueChanged(app, event)
            f1 = app.F1erbV22Slider.Value;
            f2 = str2double(app.F2erbV22EditField.Value);
            
            % vowel components
            app.updateVowel22Components(f1, f2)

            % erbs -> vowel
            app.setVowel22FromErbs
        end

        % Button pushed function: Vowel1SampleButton
        function Vowel1SampleButtonPushed(app, event)
            f1_erb = app.F1erbV1Slider.Value;
            f2_erb = app.F2erbV1Slider.Value;
            [f1_erb, f2_erb] = vowel.sample(f1_erb, f2_erb);
            
            % vowel components
            app.updateVowel1Components(f1_erb, f2_erb)

            % erbs -> vowel
            app.setVowel1FromErbs
        end

        % Button pushed function: Vowel21SampleButton
        function Vowel21SampleButtonPushed(app, event)
            f1_erb = app.F1erbV21Slider.Value;
            f2_erb = app.F2erbV21Slider.Value;
            [f1_erb, f2_erb] = vowel.sample(f1_erb, f2_erb);
            
            % vowel components
            app.updateVowel21Components(f1_erb, f2_erb)

            % erbs -> vowel
            app.setVowel21FromErbs
        end

        % Button pushed function: Vowel22SampleButton
        function Vowel22SampleButtonPushed(app, event)
            f1_erb = app.F1erbV22Slider.Value;
            f2_erb = app.F2erbV22Slider.Value;
            [f1_erb, f2_erb] = vowel.sample(f1_erb, f2_erb);
            
            % vowel components
            app.updateVowel22Components(f1_erb, f2_erb)

            % erbs -> vowel
            app.setVowel22FromErbs
        end

        % Button pushed function: Comprehend1Button
        function Comprehend1ButtonPushed(app, event)
            % first find what we want to comprehend
            if app.Vowel1DropDown.Value == lang1_sound.n_vowels + 2
                f1_erb = str2double(app.F1erbV1EditField.Value);
                f2_erb = str2double(app.F2erbV1EditField.Value);
                v_text = " (" + int32(f1_erb) + "erb, " + int32(f2_erb) + "erb) ";
            else
                f1_erb = lang1_sound.f1_erbs(app.Vowel1DropDown.Value);
                f2_erb = lang1_sound.f2_erbs(app.Vowel1DropDown.Value);
                v_text = " " + lang1_sound.vowels(app.Vowel1DropDown.Value) + " ";
            end

            % state
            app.updateUseDbm1State(1, "Comprehending [" + v_text + "]")

            % then reset the output and DBM images
            app.loadEmptyOutput1Images
            app.loadTrainedDbm1Image
            drawnow

            % create input vector
            input_vector = [vowel.create_input_vector(f1_erb, f2_erb) zeros(1, lang1_meaning.n_semantic_nodes)];
            
            % comprehend
            app.lang1_dbm.comprehend(input_vector)
            
            % images
            app.redrawOutput1Images
            app.redrawDbm1Image

            % state
            app.updateUseDbm1State(2, "Comprehended [" + v_text + "]")
        end

        % Button pushed function: Comprehend2Button
        function Comprehend2ButtonPushed(app, event)
            % first find what we want to comprehend
            if app.Vowel21DropDown.Value == lang2_sound.n_vowels + 2
                v1_f1_erb = str2double(app.F1erbV21EditField.Value);
                v1_f2_erb = str2double(app.F2erbV21EditField.Value);
                v1_text = " (" + int32(v1_f1_erb) + "erb, " + int32(v1_f2_erb) + "erb) ";
            elseif app.Vowel21DropDown.Value == lang2_sound.n_vowels + 1
                v1_f1_erb = 0;
                v1_f2_erb = 0;
                v1_text = " _ ";
            else
                v1_f1_erb = lang2_sound.f1_erbs(app.Vowel21DropDown.Value);
                v1_f2_erb = lang2_sound.f2_erbs(app.Vowel21DropDown.Value);
                v1_text = " " + lang2_sound.vowels(app.Vowel21DropDown.Value) + " ";
            end
            if app.Vowel22DropDown.Value == lang2_sound.n_vowels + 2
                v2_f1_erb = str2double(app.F1erbV22EditField.Value);
                v2_f2_erb = str2double(app.F2erbV22EditField.Value);
                v2_text = " (" + int32(v2_f1_erb) + "erb, " + int32(v2_f2_erb) + "erb) ";
            elseif app.Vowel22DropDown.Value == lang2_sound.n_vowels + 1
                v2_f1_erb = 0;
                v2_f2_erb = 0;
                v2_text = " _ ";
            else
                v2_f1_erb = lang2_sound.f1_erbs(app.Vowel22DropDown.Value);
                v2_f2_erb = lang2_sound.f2_erbs(app.Vowel22DropDown.Value);
                v2_text = " " + lang2_sound.vowels(app.Vowel22DropDown.Value) + " ";
            end
            
            if app.Consonant21DropDown.Value == lang2_sound.n_cons + 1
                c1_text = " _ ";
            else
                c1_text = lang2_sound.cons(app.Consonant21DropDown.Value);
            end
            if app.Consonant22DropDown.Value == lang2_sound.n_cons + 1
                c2_text = " _ ";
            else
                c2_text = lang2_sound.cons(app.Consonant22DropDown.Value);
            end
            
            % status
            app.updateUseDbm2State(1, "Comprehending [" + c1_text + v1_text + c2_text + v2_text + "]")
            
            % then reset the output and DBM images
            app.loadEmptyOutput2Images
            app.loadTrainedDbm2Image
            drawnow

            % create input vector
            c1_vector = lang2_sound.create_consonant_input_vector(app.Consonant21DropDown.Value);
            c2_vector = lang2_sound.create_consonant_input_vector(app.Consonant22DropDown.Value);
            v1_vector = vowel.create_input_vector(v1_f1_erb, v1_f2_erb);
            v2_vector = vowel.create_input_vector(v2_f1_erb, v2_f2_erb);            
            input_vector = [c1_vector v1_vector c2_vector v2_vector zeros(1, lang2_meaning.n_semantic_nodes)];
            
            % comprehend
            app.lang2_dbm.comprehend(input_vector);
            
            % images
            app.redrawOutput2Images
            app.redrawDbm2Image

            % status
            app.updateUseDbm2State(2, "Comprehended [" + c1_text + v1_text + c2_text + v2_text + "]")
        end

        % Button pushed function: Produce1Button
        function Produce1ButtonPushed(app, event)
            % first find what we want to produce
            lex_index = app.LexicalMeaning1DropDown.Value;
            gen_index = app.GenderMeaning1DropDown.Value;

            % status
            m_text = lang1_meaning.lex(lex_index) + "." + lang1_meaning.gen(gen_index);
            app.updateUseDbm1State(1, "Producing '" + m_text + "'")
            
            % then reset the output and DBM images
            app.loadEmptyOutput1Images
            app.loadTrainedDbm1Image
            drawnow

            % create input vector
            input_vector = [zeros(1, lang1_sound.n_auditory_nodes) ...
                lang1_meaning.create_custom_input_vector(lex_index, gen_index)];
            
            % produce
            app.lang1_dbm.produce(input_vector);

            % images
            app.redrawOutput1Images
            app.redrawDbm1Image

            % status
            app.updateUseDbm1State(2, "Produced '" + m_text + "'")
        end

        % Button pushed function: Produce2Button
        function Produce2ButtonPushed(app, event)
            % first find what we want to produce
            lex_index = app.LexicalMeaning2DropDown.Value;
            gen_index = app.GenderMeaning2DropDown.Value;
            
            % status
            m_text = lang2_meaning.lex(lex_index) + "." + lang2_meaning.gen(gen_index);
            app.updateUseDbm2State(1, "Producing '" + m_text + "'")
            
            % then reset the output and DBM images
            app.loadEmptyOutput2Images
            app.loadTrainedDbm2Image
            drawnow

            % create input vector
            input_vector = [zeros(1, lang2_sound.n_auditory_nodes) ...
                lang2_meaning.create_custom_input_vector(lex_index, gen_index)];
            
            % produce
            app.lang2_dbm.produce(input_vector);

            % redraw output and DBM images
            app.redrawOutput2Images
            app.redrawDbm2Image
            
            % status
            app.updateUseDbm2State(2, "Produced '" + m_text + "'")
        end

        % Value changed function: Meaning1DropDown
        function Meaning1DropDownValueChanged(app, event)
            % revert meaning dropdown if it is set to"manually specified"
            if app.Meaning1DropDown.Value == lang1_meaning.n_meanings + 2
                app.setMeaning1FromComponents
                return
            end

            % meaning components
            app.updateMeaning1Components
            
            % meaning -> sound
            app.setSound1FromMeaning
        end

        % Value changed function: LexicalMeaning1DropDown
        function LexicalMeaning1DropDownValueChanged(app, event)
            app.setMeaning1FromComponents
        end

        % Value changed function: GenderMeaning1DropDown
        function GenderMeaning1DropDownValueChanged(app, event)
            app.setMeaning1FromComponents
        end

        % Value changed function: Meaning2DropDown
        function Meaning2DropDownValueChanged(app, event)
            % revert meaning dropdown if it is set to"manually specified"
            if app.Meaning2DropDown.Value == lang2_meaning.n_meanings + 2
                app.setMeaning2FromComponents
                return
            end

            % meaning components
            app.updateMeaning2Components
            
            % meaning -> sound
            app.setSound2FromMeaning
        end

        % Value changed function: LexicalMeaning2DropDown
        function LexicalMeaning2DropDownValueChanged(app, event)
            app.setMeaning2FromComponents
        end

        % Value changed function: GenderMeaning2DropDown
        function GenderMeaning2DropDownValueChanged(app, event)
            app.setMeaning2FromComponents
        end

        % Button pushed function: TrainDbm1Button
        function TrainDbm1ButtonPushed(app, event)
            % find out how many observations to generate
            if app.TrainingIterations11Button.Value
                ds = app.lang1_dataset1;
            elseif app.TrainingIterations12Button.Value
                ds = app.lang1_dataset2;
            elseif app.TrainingIterations13Button.Value
                ds = app.lang1_dataset3;
            else
                error("runtime error: no proper dadaset")
            end
            
            app.updateDbm1State(1, "Training (" + int2str(ds.n_samples) + " data instances)")
            app.updateUseDbm1State(0, "DBM not used")

            % first clean up the output and DBM images
            app.loadEmptyOutput1Images
            app.loadEmptyDbm1Image
            drawnow
            
            % training DBM
            app.lang1_dbm.learn(ds.generate_observations);
            
            % image
            app.redrawTrainedDbm1Image

            % add pre-trained DBM to the list
            app.updatePretrainedDbm1List

            % status
            app.updateDbm1State(2, "DBM trained on " + app.lang1_dbm.n_training_iterations + " data instances"); 
        end

        % Button pushed function: TrainDbm2Button
        function TrainDbm2ButtonPushed(app, event)
            % find out how many observations to generate
            if app.TrainingIterations21Button.Value
                ds = app.lang2_dataset1;
            elseif app.TrainingIterations22Button.Value
                ds = app.lang2_dataset2;
            elseif app.TrainingIterations23Button.Value
                ds = app.lang2_dataset3;
            else
                error("runtime error: no proper dadaset")
            end

            app.updateDbm2State(1, "Training (" + int2str(ds.n_samples) + " data instances)")
            app.updateUseDbm2State(0, "DBM not used")

            % first clean up the output and DBM images
            app.loadEmptyOutput2Images
            app.loadEmptyDbm2Image
            drawnow
            
            % training DBM
            app.lang2_dbm.learn(ds.generate_observations)
            
            % image
            app.redrawTrainedDbm2Image

            % add pre-trained DBM to the list
            app.updatePretrainedDbm2List

            % status
            app.updateDbm2State(2, "DBM trained on " + app.lang2_dbm.n_training_iterations + " data instances");
        end

        % Button pushed function: ResetDdm1Button
        function ResetDdm1ButtonPushed(app, event)
            app.updateDbm1State(1, "Resetting")

            % image
            app.loadEmptyOutput1Images
            app.loadEmptyDbm1Image
            
            app.lang1_dbm.reset;
            app.updateUseDbm1State(0, "DBM not used")
            app.updateDbm1State(0, "DBM not trained")
        end

        % Button pushed function: ResetDbm2Button
        function ResetDbm2ButtonPushed(app, event)
            app.updateDbm2State(1, "Resetting")

            % image
            app.loadEmptyOutput2Images
            app.loadEmptyDbm2Image
            
            app.lang2_dbm.reset;
            app.updateUseDbm2State(0, "DBM not used")
            app.updateDbm2State(0, "DBM not trained")
        end

        % Value changed function: PretrainedDbm1DropDown
        function PretrainedDbm1DropDownValueChanged(app, event)
            % find what was requested to load
            n_instances = app.pretrained_dbm1_list(app.PretrainedDbm1DropDown.Value-1);
            
            app.updateDbm1State(1, "Loading (" + string(n_instances) + " data instances)")
            app.updateUseDbm1State(0, "DBM not used")
            
            % loading pre-trained DBM from disk
            app.lang1_dbm.load_trained_dbm(n_instances);

            % images
            app.loadEmptyOutput1Images
            app.redrawTrainedDbm1Image
            
            app.PretrainedDbm1DropDown.Value = 1;
            app.updateDbm1State(2, "DBM trained on " + n_instances + " data instances");
        end

        % Value changed function: PretrainedDbm2DropDown
        function PretrainedDbm2DropDownValueChanged(app, event)
            % find what was requested to load
            n_instances = app.pretrained_dbm2_list(app.PretrainedDbm2DropDown.Value-1);
            
            app.updateDbm2State(1, "Loading (" + string(n_instances) + " data instances)")
            app.updateUseDbm2State(0, "DBM not used")

            % loading pre-trained DBM from disk
            app.lang2_dbm.load_trained_dbm(n_instances);

            % images
            app.loadEmptyOutput2Images
            app.redrawTrainedDbm2Image
            
            app.PretrainedDbm2DropDown.Value = 1;
            app.updateDbm2State(2, "DBM trained on " + n_instances + " data instances");
        end
    end

    % Component initialization
    methods (Access = private)

        % Create UIFigure and components
        function createComponents(app)

            % Get the file path for locating images
            pathToMLAPP = fileparts(mfilename('fullpath'));

            % Create UIFigure and hide until all components are created
            app.UIFigure = uifigure('Visible', 'off');
            app.UIFigure.AutoResizeChildren = 'off';
            app.UIFigure.Position = [10 50 1530 760];
            app.UIFigure.Name = 'MATLAB App';
            app.UIFigure.Scrollable = 'on';

            % Create TabGroup
            app.TabGroup = uitabgroup(app.UIFigure);
            app.TabGroup.AutoResizeChildren = 'off';
            app.TabGroup.Position = [10 10 1510 740];

            % Create Language1Tab
            app.Language1Tab = uitab(app.TabGroup);
            app.Language1Tab.AutoResizeChildren = 'off';
            app.Language1Tab.Title = 'Language 1';

            % Create Output1Panel
            app.Output1Panel = uipanel(app.Language1Tab);
            app.Output1Panel.AutoResizeChildren = 'off';
            app.Output1Panel.Title = 'Output';
            app.Output1Panel.FontName = 'Georgia';
            app.Output1Panel.FontSize = 18;
            app.Output1Panel.Position = [10 10 715 140];

            % Create Vowel1OutputImage
            app.Vowel1OutputImage = uiimage(app.Output1Panel);
            app.Vowel1OutputImage.HorizontalAlignment = 'left';
            app.Vowel1OutputImage.Position = [5 15 504 81];
            app.Vowel1OutputImage.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'vowel.png');

            % Create Meaning1OutputImage
            app.Meaning1OutputImage = uiimage(app.Output1Panel);
            app.Meaning1OutputImage.HorizontalAlignment = 'left';
            app.Meaning1OutputImage.Position = [519 15 64 81];
            app.Meaning1OutputImage.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'lang1_meaning.png');

            % Create Meaning1OutputImageLabels
            app.Meaning1OutputImageLabels = uiimage(app.Output1Panel);
            app.Meaning1OutputImageLabels.Position = [524 16 53 34];
            app.Meaning1OutputImageLabels.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'lang1_meaning_labels.png');

            % Create DBM1Panel
            app.DBM1Panel = uipanel(app.Language1Tab);
            app.DBM1Panel.AutoResizeChildren = 'off';
            app.DBM1Panel.Title = 'DBM';
            app.DBM1Panel.FontName = 'Georgia';
            app.DBM1Panel.FontSize = 18;
            app.DBM1Panel.Position = [29 160 1461 100];

            % Create UseDbm1Label
            app.UseDbm1Label = uilabel(app.DBM1Panel);
            app.UseDbm1Label.FontName = 'Georgia';
            app.UseDbm1Label.FontSize = 14;
            app.UseDbm1Label.Position = [1200 23 250 23];
            app.UseDbm1Label.Text = 'Comprehended / Produced';

            % Create UseDbm1Lamp
            app.UseDbm1Lamp = uilamp(app.DBM1Panel);
            app.UseDbm1Lamp.Position = [1175 25 20 20];
            app.UseDbm1Lamp.Color = [0.851 0.3255 0.098];

            % Create Dbm1IstrainedLabel
            app.Dbm1IstrainedLabel = uilabel(app.DBM1Panel);
            app.Dbm1IstrainedLabel.FontName = 'Georgia';
            app.Dbm1IstrainedLabel.FontSize = 14;
            app.Dbm1IstrainedLabel.Position = [850 23 250 23];
            app.Dbm1IstrainedLabel.Text = 'DBM is trained on 10000 instances';

            % Create Dbm1IstrainedLamp
            app.Dbm1IstrainedLamp = uilamp(app.DBM1Panel);
            app.Dbm1IstrainedLamp.Position = [825 25 20 20];
            app.Dbm1IstrainedLamp.Color = [0.851 0.3255 0.098];

            % Create PretrainedDbm1DropDownLabel
            app.PretrainedDbm1DropDownLabel = uilabel(app.DBM1Panel);
            app.PretrainedDbm1DropDownLabel.HorizontalAlignment = 'right';
            app.PretrainedDbm1DropDownLabel.FontName = 'Georgia';
            app.PretrainedDbm1DropDownLabel.FontSize = 14;
            app.PretrainedDbm1DropDownLabel.Position = [476 23 171 22];
            app.PretrainedDbm1DropDownLabel.Text = 'Select DBM pre-trained on';

            % Create PretrainedDbm1DropDown
            app.PretrainedDbm1DropDown = uidropdown(app.DBM1Panel);
            app.PretrainedDbm1DropDown.Items = {};
            app.PretrainedDbm1DropDown.ValueChangedFcn = createCallbackFcn(app, @PretrainedDbm1DropDownValueChanged, true);
            app.PretrainedDbm1DropDown.FontName = 'Georgia';
            app.PretrainedDbm1DropDown.FontSize = 14;
            app.PretrainedDbm1DropDown.Position = [662 23 100 22];
            app.PretrainedDbm1DropDown.Value = {};

            % Create ResetDdm1Button
            app.ResetDdm1Button = uibutton(app.DBM1Panel, 'push');
            app.ResetDdm1Button.ButtonPushedFcn = createCallbackFcn(app, @ResetDdm1ButtonPushed, true);
            app.ResetDdm1Button.FontName = 'Georgia';
            app.ResetDdm1Button.FontSize = 14;
            app.ResetDdm1Button.Position = [345 10 90 50];
            app.ResetDdm1Button.Text = 'Reset';

            % Create TrainDbm1Button
            app.TrainDbm1Button = uibutton(app.DBM1Panel, 'push');
            app.TrainDbm1Button.ButtonPushedFcn = createCallbackFcn(app, @TrainDbm1ButtonPushed, true);
            app.TrainDbm1Button.FontName = 'Georgia';
            app.TrainDbm1Button.FontSize = 14;
            app.TrainDbm1Button.Position = [245 10 90 50];
            app.TrainDbm1Button.Text = 'Train';

            % Create TrainingIterations1ButtonGroup
            app.TrainingIterations1ButtonGroup = uibuttongroup(app.DBM1Panel);
            app.TrainingIterations1ButtonGroup.AutoResizeChildren = 'off';
            app.TrainingIterations1ButtonGroup.Title = 'Training iterations';
            app.TrainingIterations1ButtonGroup.FontName = 'Georgia';
            app.TrainingIterations1ButtonGroup.FontSize = 14;
            app.TrainingIterations1ButtonGroup.Position = [10 10 225 50];

            % Create TrainingIterations13Button
            app.TrainingIterations13Button = uiradiobutton(app.TrainingIterations1ButtonGroup);
            app.TrainingIterations13Button.Text = '';
            app.TrainingIterations13Button.FontName = 'Georgia';
            app.TrainingIterations13Button.Position = [150 3 70 22];

            % Create TrainingIterations12Button
            app.TrainingIterations12Button = uiradiobutton(app.TrainingIterations1ButtonGroup);
            app.TrainingIterations12Button.Text = '';
            app.TrainingIterations12Button.FontName = 'Georgia';
            app.TrainingIterations12Button.Position = [80 3 70 22];

            % Create TrainingIterations11Button
            app.TrainingIterations11Button = uiradiobutton(app.TrainingIterations1ButtonGroup);
            app.TrainingIterations11Button.Text = '';
            app.TrainingIterations11Button.FontName = 'Georgia';
            app.TrainingIterations11Button.Position = [10 3 70 22];
            app.TrainingIterations11Button.Value = true;

            % Create Meaning1Panel
            app.Meaning1Panel = uipanel(app.Language1Tab);
            app.Meaning1Panel.AutoResizeChildren = 'off';
            app.Meaning1Panel.Title = 'Meaning';
            app.Meaning1Panel.FontName = 'Georgia';
            app.Meaning1Panel.FontSize = 18;
            app.Meaning1Panel.Position = [534 270 191 430];

            % Create Produce1Button
            app.Produce1Button = uibutton(app.Meaning1Panel, 'push');
            app.Produce1Button.ButtonPushedFcn = createCallbackFcn(app, @Produce1ButtonPushed, true);
            app.Produce1Button.FontName = 'Georgia';
            app.Produce1Button.FontSize = 14;
            app.Produce1Button.Position = [10 10 100 25];
            app.Produce1Button.Text = 'Produce';

            % Create Meaning1InputImage
            app.Meaning1InputImage = uiimage(app.Meaning1Panel);
            app.Meaning1InputImage.Position = [5 60 64 81];
            app.Meaning1InputImage.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'lang1_meaning.png');

            % Create LexicalmeaningDropDown_2Label
            app.LexicalmeaningDropDown_2Label = uilabel(app.Meaning1Panel);
            app.LexicalmeaningDropDown_2Label.FontName = 'Georgia';
            app.LexicalmeaningDropDown_2Label.FontSize = 14;
            app.LexicalmeaningDropDown_2Label.Position = [10 313 152 22];
            app.LexicalmeaningDropDown_2Label.Text = 'Lexical meaning';

            % Create GendermeaningDropDown_2Label
            app.GendermeaningDropDown_2Label = uilabel(app.Meaning1Panel);
            app.GendermeaningDropDown_2Label.FontName = 'Georgia';
            app.GendermeaningDropDown_2Label.FontSize = 14;
            app.GendermeaningDropDown_2Label.Position = [10 240 152 22];
            app.GendermeaningDropDown_2Label.Text = 'Gender meaning';

            % Create GenderMeaning1DropDown
            app.GenderMeaning1DropDown = uidropdown(app.Meaning1Panel);
            app.GenderMeaning1DropDown.Items = {'∅'};
            app.GenderMeaning1DropDown.ValueChangedFcn = createCallbackFcn(app, @GenderMeaning1DropDownValueChanged, true);
            app.GenderMeaning1DropDown.FontName = 'Georgia';
            app.GenderMeaning1DropDown.FontSize = 14;
            app.GenderMeaning1DropDown.Position = [10 215 130 25];
            app.GenderMeaning1DropDown.Value = '∅';

            % Create LexicalMeaning1DropDown
            app.LexicalMeaning1DropDown = uidropdown(app.Meaning1Panel);
            app.LexicalMeaning1DropDown.Items = {'∅'};
            app.LexicalMeaning1DropDown.ValueChangedFcn = createCallbackFcn(app, @LexicalMeaning1DropDownValueChanged, true);
            app.LexicalMeaning1DropDown.FontName = 'Georgia';
            app.LexicalMeaning1DropDown.FontSize = 14;
            app.LexicalMeaning1DropDown.Position = [10 288 130 25];
            app.LexicalMeaning1DropDown.Value = '∅';

            % Create Meaning1DropDown
            app.Meaning1DropDown = uidropdown(app.Meaning1Panel);
            app.Meaning1DropDown.Items = {'∅.∅'};
            app.Meaning1DropDown.ValueChangedFcn = createCallbackFcn(app, @Meaning1DropDownValueChanged, true);
            app.Meaning1DropDown.FontName = 'Georgia';
            app.Meaning1DropDown.FontSize = 14;
            app.Meaning1DropDown.Position = [10 360 160 25];
            app.Meaning1DropDown.Value = '∅.∅';

            % Create Meaning1InputImageLabels
            app.Meaning1InputImageLabels = uiimage(app.Meaning1Panel);
            app.Meaning1InputImageLabels.Position = [10 61 53 34];
            app.Meaning1InputImageLabels.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'lang1_meaning_labels.png');

            % Create Sound1Panel
            app.Sound1Panel = uipanel(app.Language1Tab);
            app.Sound1Panel.AutoResizeChildren = 'off';
            app.Sound1Panel.Title = 'Sound';
            app.Sound1Panel.FontName = 'Georgia';
            app.Sound1Panel.FontSize = 18;
            app.Sound1Panel.Position = [10 270 514 430];

            % Create Comprehend1Button
            app.Comprehend1Button = uibutton(app.Sound1Panel, 'push');
            app.Comprehend1Button.ButtonPushedFcn = createCallbackFcn(app, @Comprehend1ButtonPushed, true);
            app.Comprehend1Button.FontName = 'Georgia';
            app.Comprehend1Button.FontSize = 14;
            app.Comprehend1Button.Position = [404 10 100 25];
            app.Comprehend1Button.Text = 'Comprehend';

            % Create Vowel1InputImage
            app.Vowel1InputImage = uiimage(app.Sound1Panel);
            app.Vowel1InputImage.HorizontalAlignment = 'left';
            app.Vowel1InputImage.Position = [5 60 504 81];
            app.Vowel1InputImage.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'vowel.png');

            % Create F2erbV1EditField
            app.F2erbV1EditField = uieditfield(app.Sound1Panel, 'text');
            app.F2erbV1EditField.ValueChangedFcn = createCallbackFcn(app, @F2erbV1EditFieldValueChanged, true);
            app.F2erbV1EditField.FontName = 'Georgia';
            app.F2erbV1EditField.Position = [460 229 44 25];

            % Create F1erbV1EditField
            app.F1erbV1EditField = uieditfield(app.Sound1Panel, 'text');
            app.F1erbV1EditField.ValueChangedFcn = createCallbackFcn(app, @F1erbV1EditFieldValueChanged, true);
            app.F1erbV1EditField.FontName = 'Georgia';
            app.F1erbV1EditField.Position = [460 289 44 25];

            % Create F2erbV1Slider
            app.F2erbV1Slider = uislider(app.Sound1Panel);
            app.F2erbV1Slider.Limits = [4 28];
            app.F2erbV1Slider.MajorTicks = [4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28];
            app.F2erbV1Slider.MajorTickLabels = {'4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28'};
            app.F2erbV1Slider.ValueChangedFcn = createCallbackFcn(app, @F2erbV1SliderValueChanged, true);
            app.F2erbV1Slider.MinorTicks = [];
            app.F2erbV1Slider.FontName = 'Georgia';
            app.F2erbV1Slider.Position = [10 251 440 3];
            app.F2erbV1Slider.Value = 4;

            % Create F1erbV1Slider
            app.F1erbV1Slider = uislider(app.Sound1Panel);
            app.F1erbV1Slider.Limits = [4 28];
            app.F1erbV1Slider.MajorTicks = [4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28];
            app.F1erbV1Slider.MajorTickLabels = {'4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28'};
            app.F1erbV1Slider.ValueChangedFcn = createCallbackFcn(app, @F1erbV1SliderValueChanged, true);
            app.F1erbV1Slider.MinorTicks = [];
            app.F1erbV1Slider.FontName = 'Georgia';
            app.F1erbV1Slider.Position = [10 311 440 3];
            app.F1erbV1Slider.Value = 4;

            % Create Vowel1SampleButton
            app.Vowel1SampleButton = uibutton(app.Sound1Panel, 'push');
            app.Vowel1SampleButton.ButtonPushedFcn = createCallbackFcn(app, @Vowel1SampleButtonPushed, true);
            app.Vowel1SampleButton.FontName = 'Georgia';
            app.Vowel1SampleButton.FontSize = 14;
            app.Vowel1SampleButton.Position = [404 360 100 25];
            app.Vowel1SampleButton.Text = 'Sample';

            % Create Vowel1DropDown
            app.Vowel1DropDown = uidropdown(app.Sound1Panel);
            app.Vowel1DropDown.Items = {'NONE'};
            app.Vowel1DropDown.ValueChangedFcn = createCallbackFcn(app, @Vowel1DropDownValueChanged, true);
            app.Vowel1DropDown.FontName = 'Georgia';
            app.Vowel1DropDown.FontSize = 14;
            app.Vowel1DropDown.Position = [10 360 160 25];
            app.Vowel1DropDown.Value = 'NONE';

            % Create DBM1Tab
            app.DBM1Tab = uitab(app.TabGroup);
            app.DBM1Tab.AutoResizeChildren = 'off';
            app.DBM1Tab.Title = 'DBM 1';

            % Create Lang1DbmImage
            app.Lang1DbmImage = uiimage(app.DBM1Tab);
            app.Lang1DbmImage.Position = [10 80 1490 575];
            app.Lang1DbmImage.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'lang1_dbm.png');

            % Create Dbm1IstrainedLabel_2
            app.Dbm1IstrainedLabel_2 = uilabel(app.DBM1Tab);
            app.Dbm1IstrainedLabel_2.FontName = 'Georgia';
            app.Dbm1IstrainedLabel_2.FontSize = 14;
            app.Dbm1IstrainedLabel_2.Position = [70 675 434 22];
            app.Dbm1IstrainedLabel_2.Text = 'DBM is trained on 10000 instances';

            % Create Dbm1IstrainedLamp_2
            app.Dbm1IstrainedLamp_2 = uilamp(app.DBM1Tab);
            app.Dbm1IstrainedLamp_2.Position = [45 677 20 20];
            app.Dbm1IstrainedLamp_2.Color = [0.851 0.3255 0.098];

            % Create UseDbm1Lamp_2
            app.UseDbm1Lamp_2 = uilamp(app.DBM1Tab);
            app.UseDbm1Lamp_2.Position = [1169 677 20 20];
            app.UseDbm1Lamp_2.Color = [0.851 0.3255 0.098];

            % Create UseDbm1Label_2
            app.UseDbm1Label_2 = uilabel(app.DBM1Tab);
            app.UseDbm1Label_2.FontName = 'Georgia';
            app.UseDbm1Label_2.FontSize = 14;
            app.UseDbm1Label_2.Position = [1194 675 233 22];
            app.UseDbm1Label_2.Text = 'Comprehended / Produced';

            % Create Meaning1DbmLabels
            app.Meaning1DbmLabels = uiimage(app.DBM1Tab);
            app.Meaning1DbmLabels.Position = [1226 91 113 70];
            app.Meaning1DbmLabels.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'lang1_meaning_labels.png');

            % Create Language2Tab
            app.Language2Tab = uitab(app.TabGroup);
            app.Language2Tab.AutoResizeChildren = 'off';
            app.Language2Tab.Title = 'Language 2';

            % Create Output2Panel
            app.Output2Panel = uipanel(app.Language2Tab);
            app.Output2Panel.AutoResizeChildren = 'off';
            app.Output2Panel.Title = 'Output';
            app.Output2Panel.FontName = 'Georgia';
            app.Output2Panel.FontSize = 18;
            app.Output2Panel.Position = [10 10 1490 140];

            % Create Vowel21OutputImage
            app.Vowel21OutputImage = uiimage(app.Output2Panel);
            app.Vowel21OutputImage.HorizontalAlignment = 'left';
            app.Vowel21OutputImage.Position = [149 14 504 81];
            app.Vowel21OutputImage.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'vowel.png');

            % Create Meaning2OutputImage
            app.Meaning2OutputImage = uiimage(app.Output2Panel);
            app.Meaning2OutputImage.HorizontalAlignment = 'left';
            app.Meaning2OutputImage.Position = [1341 15 144 81];
            app.Meaning2OutputImage.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'lang2_meaning.png');

            % Create Consonant21OutputImage
            app.Consonant21OutputImage = uiimage(app.Output2Panel);
            app.Consonant21OutputImage.Position = [15 15 114 81];
            app.Consonant21OutputImage.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'consonant.png');

            % Create Consonant22OutputImage
            app.Consonant22OutputImage = uiimage(app.Output2Panel);
            app.Consonant22OutputImage.Position = [673 15 114 81];
            app.Consonant22OutputImage.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'consonant.png');

            % Create Vowel22OutputImage
            app.Vowel22OutputImage = uiimage(app.Output2Panel);
            app.Vowel22OutputImage.Position = [807 15 504 81];
            app.Vowel22OutputImage.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'vowel.png');

            % Create Meaning2OutputImageLabels
            app.Meaning2OutputImageLabels = uiimage(app.Output2Panel);
            app.Meaning2OutputImageLabels.Position = [1346 19 132 31];
            app.Meaning2OutputImageLabels.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'lang2_meaning_labels.png');

            % Create Meaning2Panel
            app.Meaning2Panel = uipanel(app.Language2Tab);
            app.Meaning2Panel.AutoResizeChildren = 'off';
            app.Meaning2Panel.Title = 'Meaning';
            app.Meaning2Panel.FontName = 'Georgia';
            app.Meaning2Panel.FontSize = 18;
            app.Meaning2Panel.Position = [1346 270 154 432];

            % Create Meaning2DropDown
            app.Meaning2DropDown = uidropdown(app.Meaning2Panel);
            app.Meaning2DropDown.Items = {'NONE'};
            app.Meaning2DropDown.ValueChangedFcn = createCallbackFcn(app, @Meaning2DropDownValueChanged, true);
            app.Meaning2DropDown.FontName = 'Georgia';
            app.Meaning2DropDown.FontSize = 14;
            app.Meaning2DropDown.Position = [10 366 135 25];
            app.Meaning2DropDown.Value = 'NONE';

            % Create Produce2Button
            app.Produce2Button = uibutton(app.Meaning2Panel, 'push');
            app.Produce2Button.ButtonPushedFcn = createCallbackFcn(app, @Produce2ButtonPushed, true);
            app.Produce2Button.FontName = 'Georgia';
            app.Produce2Button.FontSize = 14;
            app.Produce2Button.Position = [10 10 100 25];
            app.Produce2Button.Text = 'Produce';

            % Create LexicalmeaningDropDownLabel
            app.LexicalmeaningDropDownLabel = uilabel(app.Meaning2Panel);
            app.LexicalmeaningDropDownLabel.FontName = 'Georgia';
            app.LexicalmeaningDropDownLabel.FontSize = 14;
            app.LexicalmeaningDropDownLabel.Position = [10 315 152 22];
            app.LexicalmeaningDropDownLabel.Text = 'Lexical meaning';

            % Create LexicalMeaning2DropDown
            app.LexicalMeaning2DropDown = uidropdown(app.Meaning2Panel);
            app.LexicalMeaning2DropDown.Items = {'NONE'};
            app.LexicalMeaning2DropDown.ValueChangedFcn = createCallbackFcn(app, @LexicalMeaning2DropDownValueChanged, true);
            app.LexicalMeaning2DropDown.FontName = 'Georgia';
            app.LexicalMeaning2DropDown.FontSize = 14;
            app.LexicalMeaning2DropDown.Position = [10 290 100 25];
            app.LexicalMeaning2DropDown.Value = 'NONE';

            % Create Meaning2InputImage
            app.Meaning2InputImage = uiimage(app.Meaning2Panel);
            app.Meaning2InputImage.Position = [5 60 144 81];
            app.Meaning2InputImage.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'lang2_meaning.png');

            % Create GendermeaningDropDownLabel
            app.GendermeaningDropDownLabel = uilabel(app.Meaning2Panel);
            app.GendermeaningDropDownLabel.FontName = 'Georgia';
            app.GendermeaningDropDownLabel.FontSize = 14;
            app.GendermeaningDropDownLabel.Position = [10 242 152 22];
            app.GendermeaningDropDownLabel.Text = 'Gender meaning';

            % Create GenderMeaning2DropDown
            app.GenderMeaning2DropDown = uidropdown(app.Meaning2Panel);
            app.GenderMeaning2DropDown.Items = {'NONE'};
            app.GenderMeaning2DropDown.ValueChangedFcn = createCallbackFcn(app, @GenderMeaning2DropDownValueChanged, true);
            app.GenderMeaning2DropDown.FontName = 'Georgia';
            app.GenderMeaning2DropDown.FontSize = 14;
            app.GenderMeaning2DropDown.Position = [10 217 100 25];
            app.GenderMeaning2DropDown.Value = 'NONE';

            % Create Meaning2InputImageLabels
            app.Meaning2InputImageLabels = uiimage(app.Meaning2Panel);
            app.Meaning2InputImageLabels.Position = [11 64 132 31];
            app.Meaning2InputImageLabels.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'lang2_meaning_labels.png');

            % Create DBM2Panel
            app.DBM2Panel = uipanel(app.Language2Tab);
            app.DBM2Panel.AutoResizeChildren = 'off';
            app.DBM2Panel.Title = 'DBM';
            app.DBM2Panel.FontName = 'Georgia';
            app.DBM2Panel.FontSize = 18;
            app.DBM2Panel.Position = [29 160 1461 100];

            % Create UseDbm2Label
            app.UseDbm2Label = uilabel(app.DBM2Panel);
            app.UseDbm2Label.FontName = 'Georgia';
            app.UseDbm2Label.FontSize = 14;
            app.UseDbm2Label.Position = [1200 23 250 23];
            app.UseDbm2Label.Text = 'Comprehended / Produced';

            % Create UseDbm2Lamp
            app.UseDbm2Lamp = uilamp(app.DBM2Panel);
            app.UseDbm2Lamp.Position = [1175 25 20 20];
            app.UseDbm2Lamp.Color = [0.851 0.3255 0.098];

            % Create Dbm2IstrainedLabel
            app.Dbm2IstrainedLabel = uilabel(app.DBM2Panel);
            app.Dbm2IstrainedLabel.FontName = 'Georgia';
            app.Dbm2IstrainedLabel.FontSize = 14;
            app.Dbm2IstrainedLabel.Position = [850 23 250 23];
            app.Dbm2IstrainedLabel.Text = 'DBM is trained or not';

            % Create Dbm2IstrainedLamp
            app.Dbm2IstrainedLamp = uilamp(app.DBM2Panel);
            app.Dbm2IstrainedLamp.Position = [825 25 20 20];
            app.Dbm2IstrainedLamp.Color = [0.851 0.3255 0.098];

            % Create PretrainedDbm2DropDown
            app.PretrainedDbm2DropDown = uidropdown(app.DBM2Panel);
            app.PretrainedDbm2DropDown.Items = {};
            app.PretrainedDbm2DropDown.ValueChangedFcn = createCallbackFcn(app, @PretrainedDbm2DropDownValueChanged, true);
            app.PretrainedDbm2DropDown.FontName = 'Georgia';
            app.PretrainedDbm2DropDown.FontSize = 14;
            app.PretrainedDbm2DropDown.Position = [662 23 100 22];
            app.PretrainedDbm2DropDown.Value = {};

            % Create PretrainedDbm2DropDownLabel
            app.PretrainedDbm2DropDownLabel = uilabel(app.DBM2Panel);
            app.PretrainedDbm2DropDownLabel.HorizontalAlignment = 'right';
            app.PretrainedDbm2DropDownLabel.FontName = 'Georgia';
            app.PretrainedDbm2DropDownLabel.FontSize = 14;
            app.PretrainedDbm2DropDownLabel.Position = [476 23 171 22];
            app.PretrainedDbm2DropDownLabel.Text = 'Select DBM pre-trained on';

            % Create ResetDbm2Button
            app.ResetDbm2Button = uibutton(app.DBM2Panel, 'push');
            app.ResetDbm2Button.ButtonPushedFcn = createCallbackFcn(app, @ResetDbm2ButtonPushed, true);
            app.ResetDbm2Button.FontName = 'Georgia';
            app.ResetDbm2Button.FontSize = 14;
            app.ResetDbm2Button.Position = [345 10 90 50];
            app.ResetDbm2Button.Text = 'Reset';

            % Create TrainDbm2Button
            app.TrainDbm2Button = uibutton(app.DBM2Panel, 'push');
            app.TrainDbm2Button.ButtonPushedFcn = createCallbackFcn(app, @TrainDbm2ButtonPushed, true);
            app.TrainDbm2Button.FontName = 'Georgia';
            app.TrainDbm2Button.FontSize = 14;
            app.TrainDbm2Button.Position = [245 10 90 50];
            app.TrainDbm2Button.Text = 'Train';

            % Create TrainingIterations2ButtonGroup
            app.TrainingIterations2ButtonGroup = uibuttongroup(app.DBM2Panel);
            app.TrainingIterations2ButtonGroup.AutoResizeChildren = 'off';
            app.TrainingIterations2ButtonGroup.Title = 'Training iterations';
            app.TrainingIterations2ButtonGroup.FontName = 'Georgia';
            app.TrainingIterations2ButtonGroup.FontSize = 14;
            app.TrainingIterations2ButtonGroup.Position = [10 10 225 50];

            % Create TrainingIterations23Button
            app.TrainingIterations23Button = uiradiobutton(app.TrainingIterations2ButtonGroup);
            app.TrainingIterations23Button.Text = '+ 44000';
            app.TrainingIterations23Button.FontName = 'Georgia';
            app.TrainingIterations23Button.Position = [150 3 70 22];

            % Create TrainingIterations22Button
            app.TrainingIterations22Button = uiradiobutton(app.TrainingIterations2ButtonGroup);
            app.TrainingIterations22Button.Text = ' + 13200';
            app.TrainingIterations22Button.FontName = 'Georgia';
            app.TrainingIterations22Button.Position = [80 3 70 22];

            % Create TrainingIterations21Button
            app.TrainingIterations21Button = uiradiobutton(app.TrainingIterations2ButtonGroup);
            app.TrainingIterations21Button.Text = '+ 4400';
            app.TrainingIterations21Button.FontName = 'Georgia';
            app.TrainingIterations21Button.Position = [10 3 70 22];
            app.TrainingIterations21Button.Value = true;

            % Create Sound2Panel
            app.Sound2Panel = uipanel(app.Language2Tab);
            app.Sound2Panel.AutoResizeChildren = 'off';
            app.Sound2Panel.Title = 'Sound';
            app.Sound2Panel.FontName = 'Georgia';
            app.Sound2Panel.FontSize = 18;
            app.Sound2Panel.Position = [10 270 1326 430];

            % Create Vowel22Panel
            app.Vowel22Panel = uipanel(app.Sound2Panel);
            app.Vowel22Panel.AutoResizeChildren = 'off';
            app.Vowel22Panel.Title = 'Vowel 2';
            app.Vowel22Panel.FontName = 'Georgia';
            app.Vowel22Panel.Position = [802 45 514 300];

            % Create F2erbV22EditField
            app.F2erbV22EditField = uieditfield(app.Vowel22Panel, 'text');
            app.F2erbV22EditField.ValueChangedFcn = createCallbackFcn(app, @F2erbV22EditFieldValueChanged, true);
            app.F2erbV22EditField.FontName = 'Georgia';
            app.F2erbV22EditField.Position = [460 138 44 25];

            % Create F1erbV22EditField
            app.F1erbV22EditField = uieditfield(app.Vowel22Panel, 'text');
            app.F1erbV22EditField.ValueChangedFcn = createCallbackFcn(app, @F1erbV22EditFieldValueChanged, true);
            app.F1erbV22EditField.FontName = 'Georgia';
            app.F1erbV22EditField.Position = [460 196 44 25];

            % Create F2erbV22Slider
            app.F2erbV22Slider = uislider(app.Vowel22Panel);
            app.F2erbV22Slider.Limits = [4 28];
            app.F2erbV22Slider.MajorTicks = [4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28];
            app.F2erbV22Slider.MajorTickLabels = {'4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28'};
            app.F2erbV22Slider.ValueChangedFcn = createCallbackFcn(app, @F2erbV22SliderValueChanged, true);
            app.F2erbV22Slider.MinorTicks = [];
            app.F2erbV22Slider.FontName = 'Georgia';
            app.F2erbV22Slider.Position = [10 158 440 3];
            app.F2erbV22Slider.Value = 4;

            % Create F1erbV22Slider
            app.F1erbV22Slider = uislider(app.Vowel22Panel);
            app.F1erbV22Slider.Limits = [4 28];
            app.F1erbV22Slider.MajorTicks = [4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28];
            app.F1erbV22Slider.MajorTickLabels = {'4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28'};
            app.F1erbV22Slider.ValueChangedFcn = createCallbackFcn(app, @F1erbV22SliderValueChanged, true);
            app.F1erbV22Slider.MinorTicks = [];
            app.F1erbV22Slider.FontName = 'Georgia';
            app.F1erbV22Slider.Position = [10 218 440 3];
            app.F1erbV22Slider.Value = 4;

            % Create Vowel22SampleButton
            app.Vowel22SampleButton = uibutton(app.Vowel22Panel, 'push');
            app.Vowel22SampleButton.ButtonPushedFcn = createCallbackFcn(app, @Vowel22SampleButtonPushed, true);
            app.Vowel22SampleButton.FontName = 'Georgia';
            app.Vowel22SampleButton.FontSize = 14;
            app.Vowel22SampleButton.Position = [404 245 100 25];
            app.Vowel22SampleButton.Text = 'Sample';

            % Create Vowel22DropDown
            app.Vowel22DropDown = uidropdown(app.Vowel22Panel);
            app.Vowel22DropDown.Items = {'NONE'};
            app.Vowel22DropDown.ValueChangedFcn = createCallbackFcn(app, @Vowel22DropDownValueChanged, true);
            app.Vowel22DropDown.FontName = 'Georgia';
            app.Vowel22DropDown.FontSize = 14;
            app.Vowel22DropDown.Position = [4 245 160 25];
            app.Vowel22DropDown.Value = 'NONE';

            % Create Vowel22InputImage
            app.Vowel22InputImage = uiimage(app.Vowel22Panel);
            app.Vowel22InputImage.HorizontalAlignment = 'left';
            app.Vowel22InputImage.Position = [5 15 504 81];
            app.Vowel22InputImage.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'vowel.png');

            % Create ConsonantV22Panel
            app.ConsonantV22Panel = uipanel(app.Sound2Panel);
            app.ConsonantV22Panel.AutoResizeChildren = 'off';
            app.ConsonantV22Panel.Title = 'Consonant 2';
            app.ConsonantV22Panel.FontName = 'Georgia';
            app.ConsonantV22Panel.Position = [668 45 124 300];

            % Create Consonant22DropDown
            app.Consonant22DropDown = uidropdown(app.ConsonantV22Panel);
            app.Consonant22DropDown.Items = {'NONE'};
            app.Consonant22DropDown.ValueChangedFcn = createCallbackFcn(app, @Consonant22DropDownValueChanged, true);
            app.Consonant22DropDown.FontName = 'Georgia';
            app.Consonant22DropDown.FontSize = 14;
            app.Consonant22DropDown.Position = [11 245 100 25];
            app.Consonant22DropDown.Value = 'NONE';

            % Create Consonant22InputImage
            app.Consonant22InputImage = uiimage(app.ConsonantV22Panel);
            app.Consonant22InputImage.Position = [5 15 114 81];
            app.Consonant22InputImage.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'consonant.png');

            % Create Vowel21Panel
            app.Vowel21Panel = uipanel(app.Sound2Panel);
            app.Vowel21Panel.AutoResizeChildren = 'off';
            app.Vowel21Panel.Title = 'Vowel 1';
            app.Vowel21Panel.FontName = 'Georgia';
            app.Vowel21Panel.Position = [144 45 514 300];

            % Create Vowel21InputImage
            app.Vowel21InputImage = uiimage(app.Vowel21Panel);
            app.Vowel21InputImage.HorizontalAlignment = 'left';
            app.Vowel21InputImage.Position = [5 15 504 81];
            app.Vowel21InputImage.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'vowel.png');

            % Create F2erbV21EditField
            app.F2erbV21EditField = uieditfield(app.Vowel21Panel, 'text');
            app.F2erbV21EditField.ValueChangedFcn = createCallbackFcn(app, @F2erbV21EditFieldValueChanged, true);
            app.F2erbV21EditField.FontName = 'Georgia';
            app.F2erbV21EditField.Position = [460 138 44 25];

            % Create F1erbV21EditField
            app.F1erbV21EditField = uieditfield(app.Vowel21Panel, 'text');
            app.F1erbV21EditField.ValueChangedFcn = createCallbackFcn(app, @F1erbV21EditFieldValueChanged, true);
            app.F1erbV21EditField.FontName = 'Georgia';
            app.F1erbV21EditField.Position = [460 196 44 25];

            % Create F2erbV21Slider
            app.F2erbV21Slider = uislider(app.Vowel21Panel);
            app.F2erbV21Slider.Limits = [4 28];
            app.F2erbV21Slider.MajorTicks = [4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28];
            app.F2erbV21Slider.MajorTickLabels = {'4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28'};
            app.F2erbV21Slider.ValueChangedFcn = createCallbackFcn(app, @F2erbV21SliderValueChanged, true);
            app.F2erbV21Slider.MinorTicks = [];
            app.F2erbV21Slider.FontName = 'Georgia';
            app.F2erbV21Slider.Position = [10 158 440 3];
            app.F2erbV21Slider.Value = 4;

            % Create F1erbV21Slider
            app.F1erbV21Slider = uislider(app.Vowel21Panel);
            app.F1erbV21Slider.Limits = [4 28];
            app.F1erbV21Slider.MajorTicks = [4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28];
            app.F1erbV21Slider.MajorTickLabels = {'4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28'};
            app.F1erbV21Slider.ValueChangedFcn = createCallbackFcn(app, @F1erbV21SliderValueChanged, true);
            app.F1erbV21Slider.MinorTicks = [];
            app.F1erbV21Slider.FontName = 'Georgia';
            app.F1erbV21Slider.Position = [10 218 440 3];
            app.F1erbV21Slider.Value = 4;

            % Create Vowel21SampleButton
            app.Vowel21SampleButton = uibutton(app.Vowel21Panel, 'push');
            app.Vowel21SampleButton.ButtonPushedFcn = createCallbackFcn(app, @Vowel21SampleButtonPushed, true);
            app.Vowel21SampleButton.FontName = 'Georgia';
            app.Vowel21SampleButton.FontSize = 14;
            app.Vowel21SampleButton.Position = [405 245 100 25];
            app.Vowel21SampleButton.Text = 'Sample';

            % Create Vowel21DropDown
            app.Vowel21DropDown = uidropdown(app.Vowel21Panel);
            app.Vowel21DropDown.Items = {'NONE'};
            app.Vowel21DropDown.ValueChangedFcn = createCallbackFcn(app, @Vowel21DropDownValueChanged, true);
            app.Vowel21DropDown.FontName = 'Georgia';
            app.Vowel21DropDown.FontSize = 14;
            app.Vowel21DropDown.Position = [5 245 160 25];
            app.Vowel21DropDown.Value = 'NONE';

            % Create Consonant21Panel
            app.Consonant21Panel = uipanel(app.Sound2Panel);
            app.Consonant21Panel.AutoResizeChildren = 'off';
            app.Consonant21Panel.Title = 'Consonant 1';
            app.Consonant21Panel.FontName = 'Georgia';
            app.Consonant21Panel.Position = [10 45 124 300];

            % Create Consonant21DropDown
            app.Consonant21DropDown = uidropdown(app.Consonant21Panel);
            app.Consonant21DropDown.Items = {'NONE'};
            app.Consonant21DropDown.ValueChangedFcn = createCallbackFcn(app, @Consonant21DropDownValueChanged, true);
            app.Consonant21DropDown.FontName = 'Georgia';
            app.Consonant21DropDown.FontSize = 14;
            app.Consonant21DropDown.Position = [10 245 100 25];
            app.Consonant21DropDown.Value = 'NONE';

            % Create Consonant21InputImage
            app.Consonant21InputImage = uiimage(app.Consonant21Panel);
            app.Consonant21InputImage.Position = [5 15 114 81];
            app.Consonant21InputImage.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'consonant.png');

            % Create Sound2DropDown
            app.Sound2DropDown = uidropdown(app.Sound2Panel);
            app.Sound2DropDown.Items = {'NONE'};
            app.Sound2DropDown.ValueChangedFcn = createCallbackFcn(app, @Sound2DropDownValueChanged, true);
            app.Sound2DropDown.FontName = 'Georgia';
            app.Sound2DropDown.FontSize = 14;
            app.Sound2DropDown.Position = [10 366 160 25];
            app.Sound2DropDown.Value = 'NONE';

            % Create Comprehend2Button
            app.Comprehend2Button = uibutton(app.Sound2Panel, 'push');
            app.Comprehend2Button.ButtonPushedFcn = createCallbackFcn(app, @Comprehend2ButtonPushed, true);
            app.Comprehend2Button.FontName = 'Georgia';
            app.Comprehend2Button.FontSize = 14;
            app.Comprehend2Button.Position = [1216 10 100 25];
            app.Comprehend2Button.Text = 'Comprehend';

            % Create DBM2Tab
            app.DBM2Tab = uitab(app.TabGroup);
            app.DBM2Tab.AutoResizeChildren = 'off';
            app.DBM2Tab.Title = 'DBM 2';

            % Create Lang2DbmImage
            app.Lang2DbmImage = uiimage(app.DBM2Tab);
            app.Lang2DbmImage.Position = [10 80 1490 575];
            app.Lang2DbmImage.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'lang2_dbm.png');

            % Create Dbm2IstrainedLamp_2
            app.Dbm2IstrainedLamp_2 = uilamp(app.DBM2Tab);
            app.Dbm2IstrainedLamp_2.Position = [45 677 20 20];
            app.Dbm2IstrainedLamp_2.Color = [0.851 0.3255 0.098];

            % Create Dbm2IstrainedLabel_2
            app.Dbm2IstrainedLabel_2 = uilabel(app.DBM2Tab);
            app.Dbm2IstrainedLabel_2.FontName = 'Georgia';
            app.Dbm2IstrainedLabel_2.FontSize = 14;
            app.Dbm2IstrainedLabel_2.Position = [70 675 346 22];
            app.Dbm2IstrainedLabel_2.Text = 'DBM';

            % Create UseDbm2Lamp_2
            app.UseDbm2Lamp_2 = uilamp(app.DBM2Tab);
            app.UseDbm2Lamp_2.Position = [1043 677 20 20];
            app.UseDbm2Lamp_2.Color = [0.851 0.3255 0.098];

            % Create UseDbm2Label_2
            app.UseDbm2Label_2 = uilabel(app.DBM2Tab);
            app.UseDbm2Label_2.FontName = 'Georgia';
            app.UseDbm2Label_2.FontSize = 14;
            app.UseDbm2Label_2.Position = [1068 675 427 22];
            app.UseDbm2Label_2.Text = 'Comprehended / Produced';

            % Create Meaning2DbmLabels
            app.Meaning2DbmLabels = uiimage(app.DBM2Tab);
            app.Meaning2DbmLabels.Position = [1349 222 145 33];
            app.Meaning2DbmLabels.ImageSource = fullfile(pathToMLAPP, 'initial_images', 'lang2_meaning_labels.png');

            % Show the figure after all components are created
            app.UIFigure.Visible = 'on';
        end
    end

    % App creation and deletion
    methods (Access = public)

        % Construct app
        function app = thesis_simulation

            % Create UIFigure and components
            createComponents(app)

            % Register the app with App Designer
            registerApp(app, app.UIFigure)

            % Execute the startup function
            runStartupFcn(app, @startupFcn)

            if nargout == 0
                clear app
            end
        end

        % Code that executes before app deletion
        function delete(app)

            % Delete UIFigure when app is deleted
            delete(app.UIFigure)
        end
    end
end