/usr/share/psychtoolbox-3/PsychProbability/BalanceTrials.m is in psychtoolbox-3-common 3.0.11.20131230.dfsg1-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | function varargout = BalanceTrials (nTrials, randomize, varargin)
% BalanceTrials balances a set of factors given the factor levels. It is
% identical to BalanceFactors except that the first argument is the number
% of trials desired. It outputs one or more vectors containing factor
% values for each trial, balanced and, optionally, randomized.
%
% [F1, F2, ...] = BalanceTrials(NTRIALS, RND, LVL1, LVL2, ...)
%
% BalanceTrials must be called with three or more input arguments. The
% first argument, NTRIALS, specifies the number of trials desired. The
% second argument, RAND, determines whether or not the returned factors
% should be shuffled (non-zero values lead to shuffling).
%
% The remaining input arguments specify the levels for each of a set of
% factors. Factor levels can be specified as numeric vectors or cell
% arrays (e.g., for category names). The returned factor lists will be the
% same class as the corresponding levels.
%
% WARNING: If NTRIALS is not a multiple of the product of the number of
% levels, then the actual number of trials generated will be more than
% NTRIALS. To detect this situation, test whether numel(F1) == NTRIALS.
%
% EXAMPLES:
%
% [targetPresent, setSize] = BalanceTrials(80, 0, 0:1, [3 6 9 12]);
%
% [target, setSize, dur] = ...
% BalanceTrials(72, 1, [0 1], [4 8 12], [0 100 200]);
%
% [samediff, mask] = ...
% BalanceTrials(20, 1, {'same', 'diff'}, {'pattern', 'meta'});
%
% See also: BalanceFactors
% Author: David E. Fencsik (david.fencsik@csueastbay.edu)
% Last Changed: July 6, 2010
%%% BEGIN ARGUMENT CHECKING %%%
if nargin < 3
error('%s must have at least three input arguments', mfilename);
end
if numel(nTrials) ~= 1
error('First argument to %s must be a single integer', mfilename);
end
if numel(randomize) ~= 1
error('Second argument to %s must be a single integer', mfilename);
end
% make sure number of input IVs match number of output IVs
nFactors = nargin - 2;
if nargout ~= nFactors
error('%d input argument(s) does not match %d output arguments', ...
nFactors, nargout);
end
%%% END ARGUMENT CHECKING %%%
% count up number of levels in each factor and the minimum number of trials
% needed for one observation per cell
nLevels = zeros(nFactors, 1);
for f = 1:nFactors
nLevels(f) = length(varargin{f});
end
minTrials = prod(nLevels);
% determine the number of replicates
N = ceil(nTrials / minTrials);
% initialize cell array that will hold balanced variables
varargout = cell(1, nFactors);
% the following initializes and runs the main loop in the function, which
% generates enough repetitions of each factor, ensuring a balanced design,
% and randomizes them
len1 = minTrials;
len2 = 1;
[dummy, index] = sort(rand(N * minTrials, 1));
for f = 1:nFactors
len1 = len1 / nLevels(f);
if size(varargin{f}, 1) ~= 1
% ensure that factor levels are arranged in one row
varargin{f} = reshape(varargin{f}, 1, numel(varargin{f}));
end
% this is the critical line: it ensures there are enough repetitions
% of the current factor in the correct order
varargout{f} = repmat(reshape(repmat(varargin{f}, len1, len2), ...
minTrials, 1), N, 1);
if randomize
varargout{f} = varargout{f}(index);
end
len2 = len2 * nLevels(f);
end
|