



% BEBA_CreateAgentParameters.m script template


clearvars 

% Body of the script

% Instructions:

% 'AllAgentParameters' is a cell with 3528 rows and 1 column. Each row
% corresponds to one set of agent parameters and depends on the type of
% model. For instance, in the 'CB' model each cell contains a 3x'num_agent'
% matrix where column 'i' corresponds to the parameters of agent 'i' and
% the three rows represent the conformist, radical, and stubborn traits. In
% that case each column adds to 100. For the 'FJ' model it is simply a row
% vector with 'num_agent' coefficients that represent the susceptibility of
% each agent.

% The number of rows does not necessarily have to be 3528 but is nice if
% the space of agent parameters has a number of elements comparable to the 
% one of other models

% max_iterations = 1e4; % 
max_iterations = 20; % 

AllAgentParameters = cell(1764*2,1);

section_size = 300;
num_sections = ceil(size(AllAgentParameters,1)/section_size);

section_indices = nan*ones(2,num_sections);
section_indices(1,1) = 1;

for id_section = 2:num_sections
    section_indices(2,id_section-1) = section_indices(1,id_section-1) + section_size - 1;
    section_indices(1,id_section) = section_indices(2,id_section-1) + 1;
end

section_indices(2,end) = size(AllAgentParameters,1);

for id_section = 1:size(section_indices,2)

    num_AllAgentParameters = section_indices(2,id_section) - section_indices(1,id_section) + 1;
    temp_AllAgentParameters = cell(num_AllAgentParameters,1);
    
    susc_counter = 0;
    internal_counter = 0;
    
    while susc_counter<num_AllAgentParameters
    
        internal_counter = internal_counter + 1;
    
        % 1.) Create the vector of random numbers
    
        if mod(internal_counter,20) == 0
    
            random_value_1 = 2*rand(1);
            random_value_2 = 2*rand(1);
    
            % if mod(internal_counter,3) == 0
            %     sus_param = random_value_1 + (random_value_2*rand(1,num_agents));
            % else
                sus_param = random_value_1 + (random_value_2*randn(1,num_agents));
            % end
        else
    
            random_value_1 = (2*rand(1)) + 0.1 + (0.1*randi(5,1));
            random_value_2 = (2*rand(1)) + 0.1 + (0.1*randi(5,1));
            
            temp_integer = randi(3,1) + 1;
            
            mitad_1 = floor(num_agents/temp_integer);
            mitad_2 = (num_agents) - mitad_1;
    
            random_sign = sign(randn(1));
            
            sus_param_1 = (random_value_1*randn(1,mitad_1)) + (1.3*ones(1,mitad_1)) - (random_sign*sin(internal_counter*0.1)*ones(1,mitad_1));
            sus_param_2 = (random_value_2*randn(1,mitad_2)) + (1.2*ones(1,mitad_2)) + (random_sign*sin(internal_counter*0.09)*ones(1,mitad_2));

%             sus_param_1 = (random_value_1*randn(1,mitad_1)) + (1.3*ones(1,mitad_1)) - (random_sign*1.2*cos(internal_counter*0.1)*ones(1,mitad_1));
%             sus_param_2 = (random_value_2*randn(1,mitad_2)) + (1.5*ones(1,mitad_2)) + (random_sign*1.2*cos(internal_counter*0.09)*ones(1,mitad_2));
            
            sus_param = [sus_param_1, sus_param_2];
            [~, random_sort] = sort(rand(1,num_agents));
            sus_param = sus_param(random_sort);
    
        end
    
    
        for id_point = 1:size(sus_param,2)
            sus_param(id_point) = max([0 min([ 3.5 sus_param(id_point) ])]);
        end
    
        % 2.) Transform it until its mean close to the reference
    
        accept_reference = 0;
        while ~accept_reference
    
            if mod(internal_counter,10) == 0
                reference = (0.5*randn(1)) + 0.7;
                if (reference>=0)&&(reference<=1.5)
                    accept_reference = 1;
                end
            else
                reference = 0.5 + (2*rand(1));
                accept_reference = 1;
            end
    
        end
        
        local_mean = mean(sus_param);
    
        while_counter = 0;
        
        while (abs(local_mean - reference)>0.01)&&(while_counter<max_iterations)
    
            while_counter = while_counter + 1;
        
            a_value =  reference/local_mean;
        
            for id_point = 1:size(sus_param,2)
                if sus_param(id_point)<local_mean
                    sus_param(id_point) = sus_param(id_point) *  a_value;
                else
                    y_temp = 1 - sus_param(id_point);
                    y_temp = y_temp*(1 + (1-a_value));
                    sus_param(id_point) = 1 - y_temp;
                end
        
                sus_param(id_point) = max([0 min([3.5 round(sus_param(id_point),3)])]);
        
            end
            
            local_mean = mean(sus_param);
        
        end
    
        % 3.) Check that it is unique among representations
    
    
        if while_counter<max_iterations
    
            if susc_counter > 0
                Current_Representations = BEBA_RepresentationAgentParameter(temp_AllAgentParameters(1:susc_counter));
                Aug_Current_Representations = [Current_Representations; mean(sus_param), var(sus_param)];
    
                Aug_Current_Representations = round(Aug_Current_Representations,1);
            
                if size(unique(Aug_Current_Representations, 'rows'),1) == (size(Current_Representations,1) + 1)
                    % If the new one is also unique, then add it
                    susc_counter = susc_counter + 1;
                    temp_AllAgentParameters{susc_counter} = sus_param;
    
                    disp([ 9 9 num2str(susc_counter) '/' num2str(size(temp_AllAgentParameters,1)) ' ~ ' num2str(id_section) ' / ' num2str(num_sections)])
    
                    % plot(mean(sus_param), var(sus_param), 'x', 'linewidth', 3, 'Color', LineColor), drawnow
                    % pause(0.1)
        
                end
            else
                
                susc_counter = susc_counter + 1;
                temp_AllAgentParameters{susc_counter} = sus_param;
    
                disp([ 9 9 num2str(susc_counter) '/' num2str(size(temp_AllAgentParameters,1)) ' ~ ' num2str(id_section) ' / ' num2str(num_sections) ])
    
                % plot(mean(sus_param), var(sus_param), 'x', 'linewidth', 3, 'Color', LineColor), drawnow
                % axis([0 2.5 0 2])
                % hold on, grid on
        
            end
    
        end
    
    end

    % Add them to the global set

    for id_global_set = 1:size(temp_AllAgentParameters,1)
        AllAgentParameters{section_indices(1,id_section)-1+id_global_set} = temp_AllAgentParameters{id_global_set};
    end


end

RepresentationAgentParameters = BEBA_RepresentationAgentParameter(AllAgentParameters);

num_agent_parameters = size(AllAgentParameters,1);

unique_average_agent_parameters = size(unique(RepresentationAgentParameters, 'rows'),1);

disp([ 9 9 9 ' ~ Total agent parameters = ' num2str(num_agent_parameters) ' ~~ Total different agent parameters = ' num2str(unique_average_agent_parameters) ])

% plot(RepresentationAgentParameters(:,1), RepresentationAgentParameters(:,2), 'x')

% keyboard

save([  'BEBA_AgentParameters_' num2str(num_agents) '_agents.mat'], 'AllAgentParameters')




