Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
new functions added/fixing count function overlap
  • Loading branch information
jeon11 committed Aug 22, 2019
1 parent 294035a commit b646136
Show file tree
Hide file tree
Showing 11 changed files with 1,355 additions and 2 deletions.
20 changes: 20 additions & 0 deletions helpers/masks/make_mask_only_final2d.m
@@ -0,0 +1,20 @@
function mask = make_mask_only_final2d(recalls_matrix)
% mask = make_mask_only_final2d(recalls_matrix)
% Makes a mask of the same shape as recalls_matrix, which is true at
% the final recalled items
%

% sanity:
if ~exist('recalls_matrix', 'var')
error('You must pass an recalls matrix.')
elseif ndims(recalls_matrix) ~= 2
error('recalls_matrix must be two-dimensional.')
end

rows = size(recalls_matrix, 1);
mask = ~make_blank_mask(recalls_matrix);

for i = 1:rows
mask(i, :) = make_mask_only_final1d(recalls_matrix(i, :));
end
%endfunction
4 changes: 3 additions & 1 deletion helpers/matrixops/collect.m
Expand Up @@ -42,7 +42,9 @@
% columns as values has
value_counts = zeros(1, length(values));
for i = 1:length(values)
value_counts(i) = count(data_matrix, values(i));
value_counts(i) = count_value(data_matrix, values(i));
% value_counts(i) = nnz(data_matrix==values(i)); % alternative way of
% doing it
end

%endfunction
Expand Down
@@ -1,4 +1,4 @@
function value_count = count(data_matrix, value)
function value_count = count_value(data_matrix, value)
% COUNT Returns the number of times a value occurs in a vector
%
% value_count = count(data_matrix, value)
Expand Down
88 changes: 88 additions & 0 deletions paradigms/fr/arc.m
@@ -0,0 +1,88 @@
function [arc_scores] = arc(catrecalls_matrix, subjects, mask)
%ARC Adjusted Ratio of Clustering.
%
% ARC quantifies the degree of clustering in a recall sequence.
% ARC = (R - E(R)) / (maxR - E(R)), where R is the total number of
% observed category repetitions, maxR is the maximum number of possible
% category repetitions, and E(R) is the expected number of chance
% repetitions. Based on Roenker et al., 1971.
%
% arc_scores = arc(catrecall_matrix, subjects, mask);
%
% INPUTS:
% catrecalls_matrix: a matrix whose elements are the category
% identities of recalled items. The rows of
% this matrix should represent recalls made by
% a single subject on a single trial. After
% all valid recalls, the terminal positions
% should be filled by negative values, which
% will be masked.
%
% subjects: a column vector which indexes the rows of
% catrecalls_matrix with a subject number (or
% other identifier). That is, the recall
% trials of subject S should be located in
% catrecalls_matrix(find(subjects==S), :)
%
% OUTPUTS:
% arc_scores: a vector of scores. Each score is the mean
% arc score for a particular subject.
%
% EXAMPLES:
% >> catrecalls_matrix = [0 1 1 1 2 1 0 0 NaN NaN NaN; ...
% 2 2 2 1 1 0 1 NaN NaN NaN NaN];
% >> subjects = [1; 2]; cats = [0 1 2];
% >> arc_scores = arc(catrecall_matrix, subjects, cats);

% sanity checks
if ~exist('catrecalls_matrix', 'var')
error('You must pass a recalls matrix.')
elseif ~exist('subjects', 'var')
error('You must pass a subjects vector.')
elseif size(catrecalls_matrix, 1) ~= length(subjects)
error('catrecalls matrix must have the same number of rows as subjects.')
elseif ~exist('mask', 'var')
% create not nan mask if none was given
mask = ~isnan(catrecalls_matrix);
end
if size(mask) ~= size(catrecalls_matrix)
error('recalls_matrix and mask must have the same shape.')
end

arc_scores = apply_by_index(@arc_for_subj, ...
subjects, ...
1, ...
{catrecalls_matrix, mask});
%endfunction

function subj_arc_score = arc_for_subj(cat_recalls, mask)
% Helper for arc:
% calculates the adjusted ratio of clustering for one subject's
% recall trials; returns a score.

num_trials = size(cat_recalls,1);
trial_arc_scores = NaN(1,num_trials);

for i=1:num_trials

cat_trial = cat_recalls(i,mask(i,:));
cats = unique(cat_trial);
num_cat = length(cats);

% R is observed cat repetitions
R = sum(diff(cat_trial)==0);
% N is total # of items recalled
N = length(cat_trial);
% maxR is total possible cat repetitions
maxR = N - num_cat;
% E_R is expected or chance number of category repetitions
n = zeros(1,num_cat);
for j=1:num_cat
n(j) = sum(cat_trial==cats(j));
end
E_R = (sum(n.^2)/N) - 1;
trial_arc_scores(i) = (R - E_R) / (maxR - E_R);
%keyboard
end

subj_arc_score = nanmean(trial_arc_scores);
144 changes: 144 additions & 0 deletions paradigms/fr/dist_fact.m
@@ -0,0 +1,144 @@
function dist_facts = dist_fact(recalls_itemnos, pres_itemnos, subjects, ...
dist_mat, rec_mask, pres_mask)
%DIST_FACT Distance-based clustering factor.
%
% dist_facts = dist_fact(recalls_itemnos, pres_itemnos, subjects, ...
% dist_mat, rec_mask, pres_mask)
%
% INPUTS:
% recalls_itemnos: a matrix whose elements are identifying item numbers of
% recalled items. The rows of this matrix should represent
% recalls made by a single subject on a single trial.
%
% pres_itemnos: a matrix whose elements are identifying item numbers of
% presented items. The rows of this matrix should represent
% presentations to a single subject on a single trial.
%
% dist_mat: a matrix whose elements are similarity values for pairs of
% presented items. For two item numbers i1 and i2,
% dist_mat(i1, i2) contains the similarity of those items.
%
% subjects: a column vector which indexes the rows of recalls_matrix
% with a subject number (or other identifier). That is,
% the recall trials of subject S should be located in
% recalls_matrix(find(subjects==S), :)
%
% rec_mask: if given, a logical matrix of the same shape as
% recalls_itemnos, which is false at positions (i, j) where
% the value at recalls_itemnos(i, j) should be excluded from
% the analyses. If NOT given, a standard clean recalls mask
% is used, which excludes repeats, intrusions and empty cells
%
% pres_mask: if given, a logical matrix of the same shape as the
% item presentation matrix (i.e., num_trials x
% list_length). This mask should be true at
% positions (t, sp) where an item in the condition
% of interest was presented at serial position sp on
% trial t; and false everywhere else. If NOT given,
% a blank mask of this shape is used.
% OUTPUTS:
% dist_facts: a vector of distance clustering factors, one
% for each subject.


% sanity checks
if ~exist('recalls_itemnos', 'var')
error('You must pass a recalls item number matrix.')
elseif ~exist('pres_itemnos', 'var')
error('You must pass a presented item number matrix.')
elseif ~exist('subjects', 'var')
error('You must pass a subjects vector.')
elseif size(recalls_itemnos, 1) ~= length(subjects)
error('recalls matrix must have the same number of rows as subjects.')
end
if ~exist('rec_mask', 'var')
% create standard clean recalls mask if none was given
rec_mask = make_clean_recalls_mask2d(recalls_itemnos);
rec_mask = remove_intrusions(rec_mask, recalls_itemnos, pres_itemnos);
end
if ~exist('pres_mask', 'var')
% if no mask given, include all item presentations
pres_mask = true(size(pres_itemnos));
end
if size(rec_mask) ~= size(recalls_itemnos)
error('recalls_matrix and mask must have the same shape.')
end


% dist_fact_for_subj will do the work:
dist_facts = apply_by_index(@dist_fact_for_subj, subjects, 1, ...
{recalls_itemnos, pres_itemnos, rec_mask, ...
pres_mask}, dist_mat);
%endfunction

function subj_dist_fact = dist_fact_for_subj(recalls_itemnos, pres_itemnos, ...
rec_mask, pres_mask, dist_mat)
% helper for dist_fact

step = 1;
params = struct('dist_mat',dist_mat);

% call conditional_transitions for each trial
num_trials = size(recalls_itemnos, 1);
trial_facts = [];

for i = 1:num_trials
% set parameters for this trial to be sent to conditional_transitions
params.trial_pres_itemnos = pres_itemnos(i,:);
params.trial_pres_mask = pres_mask(i,:);
fact = [];

[act_dists, pos_dists] = conditional_transitions(recalls_itemnos(i,:), ...
rec_mask(i,:), rec_mask(i,:), @similarity, @possible_sim_transitions, ...
step, params);

% determine actual and possible distances that could be transitioned to
valid = ~isnan(act_dists);
act_dists = act_dists(valid);
pos_dists = pos_dists(valid);

if isempty(act_dists)
trial_facts(i) = NaN;
continue
end

% using the possible and actual distances, rank the transition
for j = 1:length(act_dists)
possible = pos_dists{j};
actual = act_dists(j);
fact(j) = percentile_rank(actual,possible);
end
% aggregate the transition ranks to get the trial level rank
trial_facts(i) = mean(fact);
end

% aggregate the trial factors to get the subject temporal factor
subj_dist_fact = nanmean(trial_facts);
%endfunction

function pd = possible_sim_transitions(item, prior_items, item_sim, params)
% Helper to return the possible similarity values for each
% transition. This is the condition function passed
% to conditional_transitions.
unmasked_pres_items = params.trial_pres_itemnos(params.trial_pres_mask);
poss_items = setdiff(unmasked_pres_items, [item prior_items]);
pd = params.dist_mat(item, poss_items);
%endfunction


function d = similarity(item1, item2, params)
% Helper to return the actual similarity of items
% in a transition. This is the transition function passed to
% conditional_transitions.
d = params.dist_mat(item1, item2);
%endfunction


function mask_out = remove_intrusions(mask_in, rec_itemnos, pres_itemnos)
% Helper to remove intrusions based on item numbers
mask_out = mask_in;
for i=1:size(mask_out,1)
mask_out(i,:) = mask_out(i,:) & ...
ismember(rec_itemnos(i,:), pres_itemnos(i,:));
end
%endfunction

0 comments on commit b646136

Please sign in to comment.