function q=QuestUpdate(q,intensity,response)
% q=QuestUpdate(q,intensity,response)
% Update the struct q to reflect the results of this trial. The historical
% records q.intensity and q.response are always updated, but q.pdf is only
% updated if q.updatePdf is true. You can always call QuestRecompute to
% recreate q.pdf from scratch from the historical record.
% See QuestDemo, QuestCreate, QuestUpdate, QuestRecompute, 
% QuestQuantile, QuestMean, QuestMode, QuestSd, and QuestSimulate.

% Denis Pelli, 6/11/96
% 2/28/97 dgp Updated for Matlab 5: call round.
% 4/12/99 dgp Dropped support for Matlab 4.
% 4/30/99 dgp Give explanatory error message when intensity is out of bounds.
%
% Copyright (c) 1996-1999 Denis Pelli

if nargin~=3
	error('Usage: q=QuestUpdate(q,intensity,response)')
end
if length(q)>1
	error('can''t deal with q being a vector')
end
if response<0 | response>=size(q.s2,1)
	error(sprintf('response %g out of range 0 to %d',response,size(q.s2,1)-1))
end
if q.updatePdf
	inten=max(-1e10,min(1e10,intensity)); % make intensity finite
	ii=size(q.pdf,2)+q.i-round((inten-q.tGuess)/q.grain);
	if ii(1)<1 | ii(end)>size(q.s2,2)
		if q.warnPdf
			low=(1-size(q.pdf,2)-q.i(1))*q.grain+q.tGuess;
			high=(size(q.s2,2)-size(q.pdf,2)-q.i(end))*q.grain+q.tGuess;
			oldWarning=warning;
			if strcmp(oldWarning,'backtrace')
				warning('on'); % no backtrace
			end
			warning(sprintf('QuestUpdate: intensity %.2f out of range %.2f to %.2f. Pdf will be inexact.',intensity,low,high));
			warning(oldWarning);
		end
		if ii(1)<1
			ii=ii+1-ii(1);
		else
			ii=ii+size(q.s2,2)-ii(end);
		end
	end
	q.pdf=q.pdf.*q.s2(response+1,ii); % 4 ms
	if q.normalizePdf
		q.pdf=q.pdf/sum(q.pdf);		% keep the pdf normalized	% 3 ms
	end
end

% keep a historical record of the trials
q.intensity=[q.intensity,intensity];
q.response=[q.response,response];

