Hierarchical Gaussian Filter (HGF) model of conditioned hallucinations task (Powers et al 2017)

 Download zip file 
Help downloading and running models
Accession:229278
This is an instantiation of the Hierarchical Gaussian Filter (HGF) model for use with the Conditioned Hallucinations Task.
Reference:
1 . Powers AR, Mathys C, Corlett PR (2017) Pavlovian conditioning-induced hallucinations result from overweighting of perceptual priors. Science 357:596-600 [PubMed]
Citations  Citation Browser
Model Information (Click on a link to find other models with that property)
Model Type:
Brain Region(s)/Organism:
Cell Type(s):
Channel(s):
Gap Junctions:
Receptor(s):
Gene(s):
Transmitter(s):
Simulation Environment: MATLAB;
Model Concept(s): Hallucinations;
Implementer(s): Powers, Al [albert.powers at yale.edu]; Mathys, Chris H ;
/
HGF
analysis
hgfToolBox_condhalluc1.4
README
COPYING *
example_binary_input.txt
example_categorical_input.mat
example_usdchf.txt
Manual.pdf
tapas_autocorr.m
tapas_bayes_optimal.m
tapas_bayes_optimal_binary.m
tapas_bayes_optimal_binary_config.m
tapas_bayes_optimal_binary_transp.m
tapas_bayes_optimal_categorical.m
tapas_bayes_optimal_categorical_config.m
tapas_bayes_optimal_categorical_transp.m
tapas_bayes_optimal_config.m
tapas_bayes_optimal_transp.m
tapas_bayes_optimal_whatworld.m
tapas_bayes_optimal_whatworld_config.m
tapas_bayes_optimal_whatworld_transp.m
tapas_bayes_optimal_whichworld.m
tapas_bayes_optimal_whichworld_config.m
tapas_bayes_optimal_whichworld_transp.m
tapas_bayesian_parameter_average.m
tapas_beta_obs.m
tapas_beta_obs_config.m
tapas_beta_obs_namep.m
tapas_beta_obs_sim.m
tapas_beta_obs_transp.m
tapas_boltzmann.m
tapas_cdfgaussian_obs.m
tapas_cdfgaussian_obs_config.m
tapas_cdfgaussian_obs_transp.m
tapas_condhalluc_obs.m
tapas_condhalluc_obs_config.m
tapas_condhalluc_obs_namep.m
tapas_condhalluc_obs_sim.m
tapas_condhalluc_obs_transp.m
tapas_condhalluc_obs2.m
tapas_condhalluc_obs2_config.m
tapas_condhalluc_obs2_namep.m
tapas_condhalluc_obs2_sim.m
tapas_condhalluc_obs2_transp.m
tapas_Cov2Corr.m
tapas_datagen_categorical.m
tapas_fit_plotCorr.m
tapas_fit_plotResidualDiagnostics.m
tapas_fitModel.m
tapas_gaussian_obs.m
tapas_gaussian_obs_config.m
tapas_gaussian_obs_namep.m
tapas_gaussian_obs_sim.m
tapas_gaussian_obs_transp.m
tapas_hgf.m
tapas_hgf_ar1.m
tapas_hgf_ar1_binary.m
tapas_hgf_ar1_binary_config.m
tapas_hgf_ar1_binary_namep.m
tapas_hgf_ar1_binary_plotTraj.m
tapas_hgf_ar1_binary_transp.m
tapas_hgf_ar1_config.m
tapas_hgf_ar1_mab.m
tapas_hgf_ar1_mab_config.m
tapas_hgf_ar1_mab_plotTraj.m
tapas_hgf_ar1_mab_transp.m
tapas_hgf_ar1_namep.m
tapas_hgf_ar1_plotTraj.m
tapas_hgf_ar1_transp.m
tapas_hgf_binary.m
tapas_hgf_binary_condhalluc_plotTraj.m
tapas_hgf_binary_config.m
tapas_hgf_binary_config_startpoints.m
tapas_hgf_binary_mab.m
tapas_hgf_binary_mab_config.m
tapas_hgf_binary_mab_plotTraj.m
tapas_hgf_binary_mab_transp.m
tapas_hgf_binary_namep.m
tapas_hgf_binary_plotTraj.m
tapas_hgf_binary_pu.m
tapas_hgf_binary_pu_config.m
tapas_hgf_binary_pu_namep.m
tapas_hgf_binary_pu_tbt.m
tapas_hgf_binary_pu_tbt_config.m
tapas_hgf_binary_pu_tbt_namep.m
tapas_hgf_binary_pu_tbt_transp.m
tapas_hgf_binary_pu_transp.m
tapas_hgf_binary_transp.m
tapas_hgf_categorical.m
tapas_hgf_categorical_config.m
tapas_hgf_categorical_namep.m
tapas_hgf_categorical_norm.m
tapas_hgf_categorical_norm_config.m
tapas_hgf_categorical_norm_transp.m
tapas_hgf_categorical_plotTraj.m
tapas_hgf_categorical_transp.m
tapas_hgf_config.m
tapas_hgf_demo.m
tapas_hgf_demo_commands.m
tapas_hgf_jget.m
tapas_hgf_jget_config.m
tapas_hgf_jget_plotTraj.m
tapas_hgf_jget_transp.m
tapas_hgf_namep.m
tapas_hgf_plotTraj.m
tapas_hgf_transp.m
tapas_hgf_whatworld.m
tapas_hgf_whatworld_config.m
tapas_hgf_whatworld_namep.m
tapas_hgf_whatworld_plotTraj.m
tapas_hgf_whatworld_transp.m
tapas_hgf_whichworld.m
tapas_hgf_whichworld_config.m
tapas_hgf_whichworld_namep.m
tapas_hgf_whichworld_plotTraj.m
tapas_hgf_whichworld_transp.m
tapas_hhmm.m
tapas_hhmm_binary_displayResults.m
tapas_hhmm_config.m
tapas_hhmm_transp.m
tapas_hmm.m
tapas_hmm_binary_displayResults.m
tapas_hmm_config.m
tapas_hmm_transp.m
tapas_kf.m
tapas_kf_config.m
tapas_kf_namep.m
tapas_kf_plotTraj.m
tapas_kf_transp.m
tapas_logit.m
tapas_logrt_linear_binary.m
tapas_logrt_linear_binary_config.m
tapas_logrt_linear_binary_minimal.m
tapas_logrt_linear_binary_minimal_config.m
tapas_logrt_linear_binary_minimal_transp.m
tapas_logrt_linear_binary_namep.m
tapas_logrt_linear_binary_sim.m
tapas_logrt_linear_binary_transp.m
tapas_logrt_linear_whatworld.m
tapas_logrt_linear_whatworld_config.m
tapas_logrt_linear_whatworld_transp.m
tapas_ph_binary.m
tapas_ph_binary_config.m
tapas_ph_binary_namep.m
tapas_ph_binary_plotTraj.m
tapas_ph_binary_transp.m
tapas_quasinewton_optim.m
tapas_quasinewton_optim_config.m
tapas_riddersdiff.m
tapas_riddersdiff2.m
tapas_riddersdiffcross.m
tapas_riddersgradient.m
tapas_riddershessian.m
tapas_rs_belief.m
tapas_rs_belief_config.m
tapas_rs_precision.m
tapas_rs_precision_config.m
tapas_rs_precision_whatworld.m
tapas_rs_precision_whatworld_config.m
tapas_rs_surprise.m
tapas_rs_surprise_config.m
tapas_rs_transp.m
tapas_rs_whatworld_transp.m
tapas_rw_binary.m
tapas_rw_binary_config.m
tapas_rw_binary_dual.m
tapas_rw_binary_dual_config.m
tapas_rw_binary_dual_plotTraj.m
tapas_rw_binary_dual_transp.m
tapas_rw_binary_namep.m
tapas_rw_binary_plotTraj.m
tapas_rw_binary_transp.m
tapas_sgm.m
tapas_simModel.m
tapas_softmax.m
tapas_softmax_2beta.m
tapas_softmax_2beta_config.m
tapas_softmax_2beta_transp.m
tapas_softmax_binary.m
tapas_softmax_binary_config.m
tapas_softmax_binary_namep.m
tapas_softmax_binary_sim.m
tapas_softmax_binary_transp.m
tapas_softmax_config.m
tapas_softmax_namep.m
tapas_softmax_sim.m
tapas_softmax_transp.m
tapas_squared_pe.m
tapas_squared_pe_config.m
tapas_squared_pe_transp.m
tapas_sutton_k1_binary.m
tapas_sutton_k1_binary_config.m
tapas_sutton_k1_binary_plotTraj.m
tapas_sutton_k1_binary_transp.m
tapas_unitsq_sgm.m
tapas_unitsq_sgm_config.m
tapas_unitsq_sgm_mu3.m
tapas_unitsq_sgm_mu3_config.m
tapas_unitsq_sgm_mu3_transp.m
tapas_unitsq_sgm_namep.m
tapas_unitsq_sgm_sim.m
tapas_unitsq_sgm_transp.m
                            
function optim = tapas_quasinewton_optim(f, init, varargin)
% This function implements the quasi-Newton minimization algorithm
% introduced by Broyden, Fletcher, Goldfarb, and Shanno (BFGS).
%
% INPUT:
%     f            Function handle of the function to be optimised
%     init         The point at which to initialize the algorithm
%     varargin     Optional settings structure that can contain the
%                  following fields:
%       tolGrad    Convergence tolerance in the gradient
%       tolArg     Convergence tolerance in the argument
%       maxIter    Maximum number of iterations
%       maxRegu    Maximum number of regularizations
%       verbose    Boolean flag to turn output on (true) or off (false)
%
% OUTPUT:
%     optim        Structure containing results in the following fields
%       valMin     The value of the function at its minimum
%       argMin     The argument of the function at its minimum
%       T          The inverse Hessian at the minimum calculated as a
%                  byproduct of optimization
%
% --------------------------------------------------------------------------------------------------
% Copyright (C) 2012-2013 Christoph Mathys, TNU, UZH & ETHZ
%
% This file is part of the HGF toolbox, which is released under the terms of the GNU General Public
% Licence (GPL), version 3. You can redistribute it and/or modify it under the terms of the GPL
% (either version 3 or, at your option, any later version). For further details, see the file
% COPYING or <http://www.gnu.org/licenses/>.

% Dimension count
n = length(init);

% Defaults
verbose = false;
tolGrad = 1e-3;
tolArg  = 1e-3;
maxStep = 2;
maxIter = 1e3;
maxRegu = 4;
maxRst  = 4;

% Overrides
if nargin > 2
    options = varargin{1};
    
    if isfield(options,'tolGrad')
        tolGrad = options.tolGrad;
    end
    
    if isfield(options,'tolArg')
        tolArg = options.tolArg;
    end
    
    if isfield(options,'maxStep')
        maxStep = options.maxStep;
    end
    
    if isfield(options,'maxIter')
        maxIter = options.maxIter;
    end
    
    if isfield(options,'maxRegu')
        maxRegu = options.maxRegu;
    end
    
    if isfield(options,'maxRst')
        maxRst = options.maxRst;
    end

    if isfield(options,'verbose')
        verbose = options.verbose;
    end
end

% Make sure init is a column vector
if ~iscolumn(init)
    init = init';
    if ~iscolumn(init)
        error('tapas:hgf:QuasinewtonOptim:InitPointNotRow', 'Initial point has to be a row vector.');
    end
end

% Evaluate initial value of objective function
x = init;
val = f(x);

if verbose
    disp(' ')
    disp(['Initial argument: ', num2str(x')])
    disp(['Initial value: ' num2str(val)])
end

% Calculate gradient
gradoptions.min_steps = 10;
grad = tapas_riddersgradient(f, x, gradoptions);

% Initialize negative Sigma (here called T) as the unit matrix
T = eye(n);

% Initialize descent vector and slope
descvec = -grad';
slope   =  grad*descvec;

% Initialize new point and new value
newx    = NaN;
newval  = NaN;
dval    = NaN;

% Initialize reset count
resetcount = 0;

% Iterate
for i = 1:maxIter
    
    % Limit step size
    stepSize = sqrt(descvec'*descvec);
    if stepSize > maxStep
        descvec = descvec*maxStep/sqrt(descvec'*descvec);
    end
        
    regucount = 0;
    % Move in the descent direction, looping through regularizations
    for j = 0:maxRegu
        regucount = j;
        
        % Begin with t=1 and halve on each step
        t       = 0.5^j;
        newx    = x+t.*descvec;
        newval  = f(newx);
        dval    = newval-val;
        
        % Stop if the new value is sufficiently smaller
        if dval < 1e-4*t*slope
            break
        end
    end

    % Update point and value if regularizations have not been exhausted;
    % otherwise, reset and start again by jumping back 10% of the way to
    % the first initialization.
    if regucount < maxRegu
        dx   = newx-x;
        x    = newx;
        val  = newval;
    elseif resetcount < maxRst
        T       = eye(n);
        x       = x+0.1*(init-x);
        val     = f(x);

        grad = tapas_riddersgradient(f, x, gradoptions);
        descvec = -grad';
        slope   =  grad*descvec;

        i = 0;
        resetcount = resetcount+1;

        if  verbose
            disp(' ')
            disp('Regularizations exhausted - resetting algorithm.')
            disp(['Initial argument: ', num2str(x')])
            disp(['Initial value: ' num2str(val)])
        end
        continue
    else
        disp(' ')
        disp('Warning: optimization terminated because the maximum number of resets is reached.')
        break
    end
    
    if verbose
        disp(' ')
        disp(['Argument: ', num2str(x')])
        disp(['Value: ' num2str(val)])
        disp(['Improvement: ' num2str(-dval)])
        disp(['Regularizations: ' num2str(regucount)])
    end

    % Test for convergence
    if max(abs(dx)./abs(max(x,1))) < tolArg
        if verbose
            disp(' ')
            disp('Converged on step size')
        end
        break
    end
    
    % Update gradient
    oldgrad = grad;
    grad    = tapas_riddersgradient(f, x, gradoptions);
    dgrad   = grad-oldgrad;
    
    % Test for convergence
    if max(abs(grad').*max(abs(x),1)./max(abs(val),1)) < tolGrad
        if verbose
            disp(' ')
            disp('Converged on gradient size')
        end
        break
    end

    % Update T according to BFGS
    if dgrad*dx > sqrt(eps*(dgrad*dgrad')*(dx'*dx))

        dgdx  = dgrad*dx;
        dgT   = dgrad*T;
        dgTdg = dgrad*T*dgrad';
        u     = dx/dgdx-dgT'/dgTdg;
        
        T = T + dx*dx'/dgdx - dgT'*dgT/dgTdg + dgTdg*(u*u');
    end
    
    % Update descent vector
    descvec = -T*grad';
    
    % Update slope
    slope = grad*descvec;
    
    % Warn if termination is only due to maximum of iterations being reached
    if i == maxIter
        disp(' ')
        disp('Warning: optimization terminated because the maximum number of iterations is reached.')
    end
end

% Collect results
optim.valMin = val;
optim.argMin = x;
optim.T      = T;

return;