% Results = TrialAndErrorLearning(nIter, Isigma, Csigma, modeltype, envChangeTime) % nIter - number of iteration % Isigma - standard deviation for trial-and-error phase % Csigma - standard deviation for social copy (error) % modeltype - 1: copy template and try until success % 2: update template according to trial-and-error % 3: variable environment % envChangeTime (optional) - Time for major environmental change % (default = never) % % Output: % Results.NumOfSkilled = Number of skilled individuals in each iteration; % Results.TemplateAcquired = Iteration when a template was socially acquired for each individual; % Results.FirstSuccess = Iteration when each individual first performed a successful attempt % function Results = TrialAndErrorLearning(nIter, Isigma, Csigma, modeltype, envChangeTime) if nargin < 5 envChangeTime = nIter; end if ~ismember(modeltype,1:3) disp('Model type must be between 1,2, or 3'); return; end N = 100; % Number of agents linA = 1; % Slope of linear relation between environment and best action in model 3 linB = 0; % Intercept of linear relation between environment and best action in model 3 Valuefun = @(x,y)(exp(-(x-(linA*y+linB) ).^2)); % Value function maxval = Valuefun(0,0); goodenough = 0.95 * maxval; % Success threshold gotit = false(1,N); templateA = zeros(1,N); template = NaN(1,N); actions = NaN(nIter,N); E = 10; % burn-in time before template updating env(1:envChangeTime,:) = normrnd(0,1,envChangeTime,N); env(envChangeTime+1:nIter,:) = normrnd(0,20,nIter-envChangeTime,N); % major environmental change - variance sharply increases values = zeros(nIter,N); NumOfSkilled = zeros(1,nIter); TemplateAcquired = Inf(1,N); FirstSuccess = Inf(1,N); if modeltype < 3 env(:) = 0; end % Agent #1 is the skilled individual gotit(1) = true; actions(:,1) = env(:,1)*linA+linB; values(:,1) = maxval; templateA(1) = linA; template(1) = linB; for i = 2:nIter demos = randinoi(N,1:N); update = find(~gotit & gotit(demos) & isnan(template)); % & (rand(1,N)<0.1)); if ~isempty(update) template(update) = normrnd(actions(i-1,demos(update)),Csigma); end TemplateAcquired(~isnan(template) & isinf(TemplateAcquired)) = i; if modeltype >= 2 && i > 2 envs = env(1:i-1,:); acts = actions(1:i-1,:); vals = values(1:i-1,:); vals( logical(ones(i-1,1)*(sum(~isnan(vals))= goodenough; FirstSuccess(gotit & isinf(FirstSuccess)) = i; NumOfSkilled(i) = sum(gotit); end Results.NumOfSkilled = NumOfSkilled; Results.TemplateAcquired = TemplateAcquired; Results.FirstSuccess = FirstSuccess; end function I = nanmeantopf(A,f) A(isnan(A)) = -Inf; [A,ii] = sort(A,'descend'); nn = ones(size(A,1),1)*ceil(sum(~isinf(A))*f); NN = (1:size(A,1))'*ones(1,size(A,2)); I = NN>nn | isinf(A); [~,jj] = sort(ii); I = ~indByRow(I,jj); end function [m,I] = nanmeantopfx(A,f,B) I = nanmeantopf(A,f); B(~I) = NaN; m = nanmean(B); end function [A,B] = linreg(x,y) X = [ones(length(x),1) x]; A = X\y; B = A(1); A = A(2); end function n = randinoi(N,i) if length(i) == 1 x = [1:i-1,i+1:N]; n = x(randi(N-1)); else others = (1:N)'*ones(1,N); others(logical(eye(N))) = []; others = reshape(others,[N-1,N]); n = others(sub2ind(size(others),randi(N-1,1,length(i)),i)); end end