A Cardiovascular Simulator for Research 1.0.0

File: <base>/src/simulate.m (49,107 bytes)
% The function simulate.m implements various computational models of the
% human cardiovascular system.  The models include the following three
% major components:
%
% 1) Lumped parameter, pulsatile heart and circulation
%    (various preparations)
% 2) Short-term regulatory system
%    a) Arterial baroreflex system
%    b) Cardiopulmonary baroreflex system
%    c) Direct neural coupling mechanism between Qlu and F
% 3) Resting physiologic perturbations
%    a) respiratory activity
%    b) eExogenous disturbances to
%         i) Ra
%        ii) F
%	iii) Qvo
%	 iv) Pasp
%
% Function arguments:
%	flag - 8x1 vector indicating the status of the model
%	       (overrides parameter values assigned in th)
%	     - [preparation breathing dncm baro dra dpasp df dqvo]
% 
%	     - preparation - status of pulsatile heart and circulation
%			   - 0 - intact circulation (nominal)
%			   - 1 - heart-lung unit designed for measuring cardiac function curves 
%			   - 2 - systemic circulation designed for measuring venous return curves
%			   - 3 - left ventricle
%			         (automated step changes in Ppv and Pa NOT implemented)
%			   - 4 - intact circulation for measurement of single ventricular
%				 contraction Pa response
%			   - 5 - intact circulation with only linear elements
%			   - 6 - intact circulation with third-order systemic arteries
%			   - 7 - intact circulation with nonlinear systemic arterial compliance
%			   - 8 - intact circulation with third-order systemic arteries
%				 and nonlinear large, elastic arterial compliance
%			   - 9 - intact circulation with an arterial pressure reservoir
%			   - 10 - intact circulation with contracting atria
%	     -	breathing - status of breathing (Qlu)
%			  - 0 - no breathing (Qlu constant)
%			  - 1 - fixed-rate breathing (Qlu periodic)
%			  - 2 - random-interval breathing (Qlu random; 5 s mean period)
%			        instantaneous alveolar ventilation rate constant over time
%			  - 3 - random-interval breathing (Qlu random; 5 s mean period)
%				tidal volume fixed; instantaneous alveolar ventilation rate
%				not constant
%			  - 4 - step increase in breathing (Qlu step)
%			  - 5 - impulse increase in breathing (Qlu impulse)
%	     - dncm - status of direct neural coupling mechanism between Qlu and F
%		    - 0 - dncm off
%		    - 1 - dncm on (not applicable for step increase in Qlu)
%	     - baro - status of baroreflexes
%		    - 0 - arterial and cardiopulmonary baroreflexes off
%		    - 1 - arterial baroreflex on only
%		    - 2 - cardiopulmonary baroreflex on only
%		    - 3 - arterial and cardiopulmonary baroreflexes on
%	     - dra - status of bandlimited disturbance to Ra
%		   - 0 - dra off
%		   - 1-3 - dra on
%		         - 1 - 1/f fluctuations
%			 - 2 - bandlimited, white fluctuations
%			 - 3 - sinusoidal fluctuations
%	     - dpasp - status of sinusoidal disturbance to Pasp
%		  - 0 - dpasp off
%		  - 1 - dpasp on
%	     - df - status of 1/f disturbance to F
%		  - 0 - df off
%		  - 1 - df on
%	     - dqvo - status of bandlimited disturbance to Qvo
%		    - 0 - dqvo off
%		    - 1 - dqvo on
%	th - 113x1 vector containing the parameter values characterizing
%            the simulation
%       outputfile - prefix of the output files in MIT format generated by the model
%	parameterfile - name of a file which contains the parameter values
%                       characterizing the model and its execution
%	signals - the signals to be viewed by WAVE as the data are generated
%
%	NOTE: If this program is executed in the MATLAB environment, it will
%             not be possible to implement on-line viewing and parameter updating
%             Thus, the last three arguments should be omitted.
%             
% Function outputs:
%	P - matrix representing simulated pressures [mmHg]
%	  = [Pl Pe Pv Pr Ppa Ppv Pth Palv Pra Pm] for preparation == 6,8
%	  = [Pl Pa Pv Pr Ppa Ppv Pth Palv Pra Pla] for preparation == 10
%	  = [Pl Pa Pv Pr Ppa Ppv Pth Palv Pra] otherwise
%	Q - matrix representing simulated volumes [ml]
%	  = [Ql Qe Qv Qr Qpa Qpv Qlu Qm] for preparation == 6,8
%	  = [Ql Qa Qv Qr Qpa Qpv Qlu Qra Qla] for preparation == 10
%	  = [Ql Qa Qv Qr Qpa Qpv Qlu] otherwise
%	q - matrix representing simulated flow rates [ml/s]
%	  = [qpv ql qm qv qr qpa qe] for preparation == 6,8
%	  = [qla ql qa qra qr qpa qv qpv] for preparation == 10
%	  = [qpv ql qa qv qr qpa] otherwise
%	ap - matrix representing simulated adjustable parameters
%	   = [Cls Crs Qvo Ra F Tsys]
%	ve - matrix representing the ventricular variable elastances
%            [mmHg/ml]
%	   = [El Er Ela Era] for preparation == 10
%	   = [El Er] otherwise
%	qrs - vector representing times of ventricular contractions [s]
%	t - vector representing the associated time [s]
%	num - matrix representing either cardiac function or venous
%	      return curve numerics
%	    = [mra mpa mco] for preparation == 1
%	    = [mra mco] for preparation == 2
%	    = [0, 0] otherwise
%
% Function usage (in MATLAB):
%
%	[P,Q,q,ap,ve,qrs,t,num] = simulate(flag,th);
%

function [P,Q,q,ap,ve,qrs,t,num] = simulate(flag,th,outputfile,parameterfile,signals)

% Declaring C functions.
%#function wave_remote read_key write_param

% Checking number of arguments.  If there are only two arguments,
% this indicates MATLAB execution and thus on-line viewing is 
% turned off.  (If it were left on, MATLAB would produce an error.)
if (nargin == 2)
   signals = '-1';
end

% Checking dimensionality of the argument flag -- status parameters.
% If flag is of incorrect dimension, the program will exit in error.
if (length(flag) ~= 8)
	error('flag is not of correct dimension');
end

% Assigning status parameters to new variable names.

preparation = flag(1);
breathing = flag(2);
dncm = flag(3);
baro = flag(4);
dra = flag(5);
dpasp = flag(6);
df = flag(7);
dqvo = flag(8);

% Assigning numerical integration variables.

   % Number of integration steps.
   tics = th(106);

   % Integration step size (s).
   deltaT = 1/th(113);

% Assigning integrate and fire variables.

   % Fraction of current cardiac cycle that integration step is at.
   ipfm = 0; 

   % Current number of ventricular contractions.
   qrs_index = 1;

   % Time in current cardiac cycle that integration is at. 
   sumdeltaT = 0; 

% Short-term regulatory systems and resting physiologic 
% perturbation variables.
% Note there are restrictions on altering Sgran and Sratio.
% 1) Sgran*Sratio <= 1.0.
% 2) (1.5/Sgran) must be an integer.
% 3) ((2/Sgran)-((Sratio*Sgran/2)/Sgran)) must be an integer. 
% 4) (0.5-(Sratio*Sgran/2))/Sgran must be an integer. 

  % Granularity (s).
  Sgran = 0.0625;

  % Ratio of length of averaging window to Sgran
  % (must be an integer).
  Sratio = 4;

  % Duration (samples).
  Slength = 40/Sgran;


% Generation of a vector of arrival times for each respiratory cycle.  

   % at(1) = 0 & length(at) ~= 1: Qlu periodic
   if (breathing == 1)

	at = zeros(ceil((deltaT*tics)+1)+1,1);      
	i = 2;
	x = (at(i) <= deltaT*tics+1);
	mbintscalar(x);
	while (x)
		i = i+1;
		at(i) = at(i-1)+th(42);
		x = (at(i) <= deltaT*tics+1);
		mbintscalar(x);
	end	
	at = at(1:i); 

   % at(1) = 1: Qlu random with constant alveolar ventilation rate (2)
   % at(1) = 2: Qlu random with fixed tidal volume (3)
   elseif (breathing == 2 | breathing == 3)

	at = zeros(ceil((deltaT*tics)+1)+1,1);
	if (breathing == 2)
		at(1) = 1;
	else
		at(1) = 2;
	end

	i = 2;
	at(i) = rand_int_breath;
	x = (at(i) <= deltaT*tics+1);
	mbintscalar(x);
	while (x)
		i = i+1;
		at(i) = at(i-1) + rand_int_breath;
		x = (at(i) <= deltaT*tics+1);
		mbintscalar(x);
	end
	at = at(1:i);

   % at(1) = 0 & length(at) == 1: Qlu constant
   elseif (breathing == 0) 

	at = 0;

   % at(1) = 3 (length(at) == 2): step Qlu (cannot implement dncm)
   elseif (breathing == 4)

	at = [3; th(36)];

   % at(1) = 4 (length(at) == 3): impulse Qlu
   elseif (breathing == 5)

	at = [4; th(36); (((deltaT*tics)+1)+1)];

   % Exiting program with error if breathing is not valid.
   else

	error('breathing is not a valid option');

   end	

% Pre-calculating Qlu, Pth, dPth, and Ppac (Palv) over the entire
% integration period from the generated arrival time vector.
thbreathe = resp_act(th,at,deltaT/2,0,(tics-1)*deltaT);

% Adding a step change to Qlu, Pth, dPth, and Ppac, if mandated via Qfrs.
if ((breathing == 0 | breathing == 1 | breathing == 2) & th(36) ~= 0)
   
   th(103) = 0;
   thbreathes = resp_act(th,[3; th(36)],deltaT/2,0,(tics-1)*deltaT);
   dthbreathe = [-th(98)*ones(1,length(thbreathes)); -th(23)*ones(1,length(thbreathes)); zeros(2,length(thbreathes))]; 
   thbreathe = thbreathe+thbreathes+dthbreathe;

end
   

% Creating the filter characterizing direct neural coupling mechanism
% betweeen Qlu and F at a sampling period of Sgran.  Decimating the 
% above Qlu to a sampling period of Sgran in order to implement this filter.
% (not applicable to step input of Qlu)
if (dncm == 1)

	hilvhr = dncm_filt(th,[Sgran; Slength; Sratio]);
	ilv = ilv_dec(thbreathe(1,:),deltaT/2,Sgran);
	% Taking care of filtering edge effects.
	ilv = [th(98)*ones(length(hilvhr)-(1.5/Sgran),1); ilv'; th(98)*ones(1.5/Sgran,1)];
	rsastep = 1;

% Exiting program with error if dncm is not valid.
elseif (dncm ~= 0)

        error('dncm is not a valid option');

end

% Autoregulation of local vascular beds -- exogenous disturbance to Ra.

   % Generating sinusoidal Ra disturbance at a sampling period of Sgran
   % for entire integration period.
   if (dra == 3)

	amp = th(61);
	freq = th(62);
	n = floor(((deltaT*tics)+1)/Sgran)+(Sratio-1);
	i = 1:n;
	tr = (i-1)*Sgran;
	Ralvrp = (amp/(Sgran*2*pi*freq))*(cos(2*pi*freq*tr)-cos(2*pi*freq*(tr+Sgran)));
	Ralvr = zeros(1,length(Ralvrp)-Sratio+1);
	for kt = Sratio:length(Ralvrp)
		Ralvr(kt-(Sratio-1)) = sum(Ralvrp(kt-(Sratio-1):kt))/Sratio;
	end
	Ralvr = Ralvr+((0.01*amp)/sqrt(Sgran))*randn(1,length(Ralvr));

	lvrstep = 2;

   % Generating bandlimited 1/f Ra disturbance at a sampling period of Sgran
   % for entire integration period.
   elseif (dra == 1)

	hra = bl_filt(th(44),Sgran);
	n = floor(((deltaT*tics)+1)/Sgran)+length(hra);
	whitenoise = sqrt(1/Sgran)*th(47)*randn(1,n);
	dmin = -4;
	dmax = 0;
        honeoverfra = oneoverf_filt(th,Sgran,dmin,dmax);
	Ralvrw = conv(honeoverfra,whitenoise);
	Ralvrw = Ralvrw(length(Ralvrw)-length(n)+1:length(Ralvrw));	

	% Filtering 1/f disturbance to Ra.
	Ralvr = conv(hra,Ralvrw);
	Ralvr = Ralvr(length(hra)+1:length(Ralvrw));

	lvrstep = 2;

   % Generating white noise at a sampling period of Sgran for bandlimited 
   % disturbance to Ra.
   elseif (dra == 2)

	wra = sqrt(1/Sgran)*th(47)*randn(length(-60:Sgran:60),1);

   % Exiting program with error if dra is not valid.
   elseif (dra ~= 0)

	error('dra is not a valid option');

   end

% Generating sinusoidal Pasp disturbance at a sampling period of Sgran
% for entire integration period.
if (dpasp == 1);

	amp = th(63);
	freq = th(64);
	n = floor(((deltaT*tics)+1)/Sgran)+(Sratio-1)+Slength;
	i = 1:n;
	tr = (i-1)*Sgran;
	tempPsp = (amp/(Sgran*2*pi*freq))*(cos(2*pi*freq*tr)-cos(2*pi*freq*(tr+Sgran)));
	deltaPsp = zeros(length(tempPsp)-Sratio+1,1);
	for kt = Sratio:length(tempPsp)
		deltaPsp(kt-(Sratio-1)) = sum(tempPsp(kt-(Sratio-1):kt))/Sratio;
	end
	deltaPsp = deltaPsp+((0.1*amp)/sqrt(Sgran))*randn(length(deltaPsp),1);

	ceostep = 2;

elseif (dpasp == 0)

	deltaPsp = 0;

% Exiting program with error if dpasp is not valid.
else
	error('dpasp is not valid');
end

% Creating 1/f filter and white noise at a sampling period of Sgran
% for the exogenous disturbance to F. 
if (df == 1)

        dmin = -4; % Desired minimum frequency decade with 1/f character 
	dmax = 0; % Desired maximum frequency decade with 1/f character
	hans = ans_filt(th,[Sgran; Slength; Sratio]);
	honeoverf = oneoverf_filt(th,Sgran,dmin,dmax);
	hf = conv(honeoverf,hans);
	wf = sqrt(1/Sgran)*th(48)*randn(length(hf),1);

% Exiting program with error if df is not valid.
elseif (df ~= 0)

       error('df is not a valid option');

end

% Generating bandlimited, white disturbance to Qvo at a sampling period of Sgran
% for entire integration period.
if (dqvo == 1)

	hvvo = bl_filt(th(65),Sgran);	
	n = floor(((deltaT*tics)+1)/Sgran)+length(hvvo);
	Vvow = sqrt(1/Sgran)*th(66)*randn(1,n);
	Vvo = conv(hvvo,Vvow);
	Vvo = Vvo(length(hvvo)+1:length(Vvow));
	nvvostep = 2;

% Exiting program with error if dqvo is not valid.
elseif (dqvo ~= 0)

       error('dqvo is not a valid option');

end

% Pre-allocating memory for function output waveforms which is
% necessary for dramatic improvement in execution speed.
P = zeros(11,tics);
Q = zeros(9,tics);
q = zeros(8,tics);
t = zeros(1,tics);
ap = zeros(9,tics);
ve = zeros(4,tics);

% Pre-allocating memory and initializing variables for 
% cardiac function/venous return curve generation.

   if (preparation == 1)

      % Pre-allocating memory.
      Crd = ((th(27)-th(12))/th(32))*th(6);
      final = round((th(27)-th(12)-20)/Crd)+3;
      rarange = [final:-th(88):0, th(23)+1];
      lengthra = length(rarange);
      if (lengthra == 2);

         lengthra = 1;
         rarange = final;

      end
      lengthsa = length(30:th(90):th(31)-10);
      lengtht = lengthra*lengthsa;
      num = zeros(3,lengtht);

      % Initializing variables for family of cardiac function curves.
      if (lengthra > 1 & lengthsa > 1)

         countn = 0;
         countj = 0;
         th(30) = final;
         th(29) = 30;
         tmp = 0;

      % Initializing variables for a single cardiac function curve.
      elseif (lengthra > 1 & lengthsa == 1)

         countn = 0;
         countj = 0;
         th(30) = final;
         tmp = 0;

      % Initializing variables for curve of average ql versus Pa.
      elseif (lengthra == 1 & lengthsa > 1)

          final = th(30);
          rarange = final;
          th(29) = 30;
          tmp = 0;
   
      end
   
      % Initializing variables for averaging Pra and ql over each cardiac cycle.
      summrap = 0;
      summco = 0;
   
      % Initializing variable representing number of beats until voltage
      % source(s) is varied.
      fb_int = 10;
      
   elseif (preparation == 2)

      % Pre-allocating memory.
      Crs = ((th(27)-th(12))/th(32))*th(5);
      lengthra = length([Crs:th(89):60]);
      num = zeros(2,lengthra);
      if (length(num(1,:)) > 1)

         countn = 0;
         Crd = Crs;
         th(6) = (th(32)/(th(27)-th(12)))*Crd;

      end

      % Initializing variables for integrating Pra and qv over each cardiac cycle.
      summrap = 0;
      summco = 0;

      % Initializing variable representing number of beats until Crd
      % is varied.
      fb_int = 10;

   else

      num = zeros(2,1);       

   end

% Resetting ventricular compliance values for the intact circulatory
% preparation with only linear elements.
if (preparation == 5)
   th(1) = th(1)*((th(26)-th(9))/th(31));
   th(2) = th(2)*((th(26)-th(9))/th(31));
   th(5) = th(5)*((th(27)-th(12))/th(32));
   th(6) = th(6)*((th(27)-th(12))/th(32));
   th(31) = th(26)-th(9);
   th(32) = th(27)-th(12);
end

% Initializing the function output waveforms.

   % Adjustable parameters.
   ap(1:6,1) = [th(1)*((th(26)-th(9))/th(31)) th(5)*((th(27)-th(12))/th(32)) th(11) th(16) th(22) .3*sqrt(th(24))]';

   % Pulsatile heart and circulation preparation.
   if (preparation == 0 | preparation == 4 | preparation == 5 | preparation == 7)

	[P(1:6,1),Q(1:6,1),q(1:6,1),ve(1:2,1)] = intact_init_cond(th);

   elseif (preparation == 1)

	[P(1:6,1),Q(1:6,1),q(1:6,1),ve(1:2,1)] = hlu_init_cond(th);

   elseif (preparation == 2)

	[P(1:6,1),Q(1:6,1),q(1:6,1),ve(1:2,1)] = sc_init_cond(th);

   elseif (preparation == 3)

	[P(1:6,1),Q(1:6,1),q(1:6,1),ve(1:2,1)] = lv_init_cond(th);

   elseif (preparation == 5)

	[P(1:6,1),Q(1:6,1),q(1:6,1),ve(1:2,1)] = init_cond(th);

   elseif (preparation == 6)

	[Ptemp,Q(1:7,1),q(1:7,1),ve(1:2,1)] = third_init_cond(th);
	P(1:6,1) = Ptemp(1:6);
	P(10:11,1) = Ptemp(7:8);
	Q(8,1) = Q(7,1); 

   elseif (preparation == 7)

	[P(1:6,1),Q(1:6,1),q(1:6,1),ve(1:2,1)] = nac_init_cond(th);

   elseif (preparation == 8)

	[Ptemp,Q(1:7,1),q(1:7,1),ve(1:2,1)] = third_nac_init_cond(th);
	P(1:6,1) = Ptemp(1:6);
	P(10:11,1) = Ptemp(7:8);
	Q(8,1) = Q(7,1); 

   elseif (preparation == 9)

	[P(1:6,1),Q(1:6,1),q(1:6,1),ve(1:2,1)] = apr_init_cond(th);

   elseif (preparation == 10)

        [tempp,tempv,q(1:8,1),ve(:,1)] = a_init_cond(th);
	P(1:6,1) = tempp(1:6);
	P(9,1) = tempp(7);
	P(10:11,1) = tempp(7:8);
	Q(1:6,1) = tempv(1:6);
	Q(8:9,1) = tempv(7:8);

   % Exiting program with error if preparation is not valid,
   else

	error('preparation is not a valid option');

   end

   if (preparation ~= 10)

      P(9,1) = P(4,1);

   end

   % Respiratory-related waveforms.
   P(7,1) = thbreathe(2,1);
   P(8,1) = thbreathe(4,1);
   Q(7,1) = thbreathe(1,1);


% Assigning setpoint variables

  % Setpoint pressure for arterial baroreflex (mmHg).
  Pasp = th(40); 

  % Setpoint pressure for cardiopulmonary baroreflex (mmHg).
  Pratrsp = th(41);

  % F setpoint value (Hz).
  Fsp = th(22); 

  % Ra setpoint value (mmHg-s/ml).
  Rasp = th(16); 

  % Cls, Crs setpoint value (ml/mmHg).
  Clssp = th(1); 
  Crssp = th(5);

  % Qvo setpoint value (ml). 
  Qvosp = th(11); 

  % 7x1 vector of setpoint values.
  thsp = [Pasp; Fsp; Rasp; Clssp; Crssp; Qvosp; Pratrsp];

% Initializing baroreflex-related variables.
if (baro > 0 & baro < 4)

   % Initializing input pressures.  (The lowest
   % index indicates the most recent pressure.)
   bP = zeros(Slength,1);
   bPratr = zeros(Slength,1);
   for i = 1:Slength;
      bP(i) = P(2,1);
      bPratr(i) = P(9,1)-P(7,1);
   end		  
   bPtemp = zeros(Sratio,1);
   bPratrtemp = zeros(Sratio,1);
   for i = 1:Sratio
      bPtemp(i) = P(2,1);
      bPratrtemp(i) = P(9,1)-P(7,1);
   end

   % Initializing variables for integrating Pa, Pratr,
   % and t over each Sgran interval.
   sumP = 0; 
   sumPratr = 0;
   sumt = 0; 

% Exiting program with error if baro is not valid,
elseif (baro ~= 0)

   error('baro is not a valid option');

end

% Initializing parameter vector and other variables in order to
% implement linear interpolation of the controllable parameters.
thn = th;
thp = th;
tn = 0;
tp = 0;

% Initializing parameters for writing data and annotations to file
% in MIT format.  Calling the WAVE window.
if (strcmp(signals,'-1') == 0)

   % Initializing waveform file variables.
   kstart = 1;
   qrs_index_start = 1;
   fid = fopen([outputfile '.dat'],'wa');

   % Initializing annotation file.
   fid2 = fopen([outputfile '.qrs'],'wa');
   fwrite(fid2,1,'bit10');
   fwrite(fid2,1,'ubit6');
   fwrite(fid2,-1,'bit10');
   fwrite(fid2,62,'ubit6');
   Nbytes = length(parameterfile)+2;
   fwrite(fid2,Nbytes,'bit10');
   fwrite(fid2,63,'ubit6');
   fwrite(fid2,[parameterfile '.' num2str(0)],[num2str(Nbytes) '*uchar']);

   % Assigning annotation flag.
   if (th(105) == 0)
      annotator = '-1';
   else
      annotator = 'qrs';
   end

   % Initializing parameter update counter.
   count_pc = 0;

   % Calling the WAVE window.
   wave_remote( outputfile, annotator, 0, signals );

   % Initializing variables which permit annotation flag to be
   % updated on-line.
   wrflag = 1;
   outputfile2 = ['./' outputfile];
	       
end

% Generating the function output waveforms for each integration step.
for k = 2:tics


	% Generating the pressure waveforms and associated time for 
	% the current integration step -- fourth-order Runge-Kutta
	% integration.
	Ptempn = rk4([P(1:6,k-1); P(10:11,k-1)],[Q(1,k-1);Q(4,k-1)],thbreathe(:,2*(k-1)+1:2*(k-1)+3),th,ipfm,sumdeltaT,deltaT,preparation);
	P(1:6,k) = Ptempn(1:6);
	if (preparation == 10)
		P(9,k) = Ptempn(7);
	end
	P(10,k) = Ptempn(7);
	P(11,k) = Ptempn(8);

	% Updating time.
	t(k) = t(k-1)+deltaT;

	% Computing fraction of cardiac cycle that was surpassed
	% during the integration step.
	frac = deltaT*th(22);

	% Obtaining Pth, Ppac (Palv), and Qlu at the current integration step
	P(7,k) = thbreathe(2,2*(k-1)+1);
	P(8,k) = thbreathe(4,2*(k-1)+1);
	Q(7,k) = thbreathe(1,2*(k-1)+1);

	% Integrating Pa data using the Backward Euler method and 
	% denoting the time into the integration.
	sumt = sumt+deltaT;
	sumP = sumP+P(2,k)*deltaT;

	% Computing Pra and integrating Pratr using the Backward
	% Euler method.
	if (preparation ~= 10)
		x = (P(4,k) >= P(3,k));
		mbintscalar(x);
		if (x)
			P(9,k) = P(3,k);
		else
			P(9,k) = P(4,k);
		end
	end
	sumPratr = sumPratr+(P(9,k)-P(7,k))*deltaT;

	% Implementing the short-term regulatory system and/or resting
	% physiologic perturbations each Sgran s.
	x = (sumt > Sgran);
	mbintscalar(x);
	if (x)

		% Setting final th values of previous Sgran to initial th
		% value of current Sgran. 
		thp = thn;
		tp = tn;

		% Initializing thc -- a vector which contains the mandated
		% adjustments to controllable parameters of sampling period
		% Sgran.
		thc = zeros(5,1);

		% Implementing the arterial baroreflex.
		if (baro == 1 | baro == 3)

			% Calculating the integral of Pa precisely
			% over the Sgran interval.
			sumP = sumP-P(2,k)*deltaT;
			sumP = sumP+P(2,k)*(deltaT-(sumt-Sgran));

			% Placing the averaged Pa over the Sgran*Sratio 
			% interval in the most recent slot of the arterial 
			% baroreflex input.
			bPtemp = [(sumP/Sgran); bPtemp(1:Sratio-1)];
			avebP = sum(bPtemp)/Sratio;
			bP = [avebP; bP(1:Slength-1)];

			% Calculating the new baroreflex adjusted parameters 
			% for the next Sgran interval.
			
			   % For constant Pasp.
			   if (length(deltaPsp) == 1)
				thc = thc+abreflex([Sgran; Slength; Sratio],bP,th,thsp,deltaPsp);
			   % For sinusoidally varying Pasp.
			   else 
				thc = thc+abreflex([Sgran; Slength; Sratio],bP,th,thsp,deltaPsp(dpasp:dpasp+length(bP)-1));
				dpasp=dpasp+1;	
			   end
		end

		% Implementing the cardiopulmonary baroreflex.
		if (baro == 2 | baro == 3)

			% Calculating the integral of Pratr precisely
			% over the Sgran interval.
			sumPratr = sumPratr-(P(9,k)-P(7,k))*deltaT;
			sumPratr = sumPratr+(P(9,k)-P(7,k))*(deltaT-(sumt-Sgran));

			% Placing the averaged Pratr over the Sgran*Sratio interval 
			% in the most recent slot of the cardiopulmonary baroreflex 
			% input.
			bPratrtemp = [(sumPratr/Sgran); bPratrtemp(1:Sratio-1)];
			avebPratr = sum(bPratrtemp)/Sratio;
			bPratr = [avebPratr; bPratr(1:Slength-1)];

			% Calculating the new baroreflex adusted parameters 
			% for the next Sgran interval.
			thc = thc+cpreflex([Sgran; Slength; Sratio],bPratr,th,thsp);
		
		end

		% Implementing the direct neural coupling mechanism between
		% Qlu and F.
		if (dncm == 1)

                        % Creating the dncm filter.
			hilvhr = dncm_filt(th,[Sgran; Slength; Sratio]);
                        % Creating the input Qlu vector to be convolved with the filter.
			tempilv = ilv(rsastep:rsastep+length(hilvhr)-1);
			tempilv = tempilv-th(98);
                        % Compute the mandated change in F from the convolution.
			thc(1) = thc(1)+sum(tempilv.*hilvhr(length(hilvhr):-1:1));
			rsastep = rsastep+1;

		end

		% Implementing the exogenous disturbance to Ra.
		if (dra ~= 0)

                   % Bandlimited, white disturbance
		   if (dra == 2)
                        
                        % Creating the bandlimited filter.
		        hra = bl_filt(th(44),Sgran);
                        % Creating white noise input to be convolved with the filter.
		        wra = [sqrt(1/Sgran)*th(47)*randn(1); wra(1:length(wra)-1)];
                        % Computing the mandated change to Ra.
		        thc(2) = thc(2)+sum(wra.*hra');

                   % Other Ra disturbance.
		   else

                        % Assigning mandated change to Ra which was pre-computed.
			thc(2) = thc(2)+Ralvr(lvrstep);
			lvrstep = lvrstep+1;

		   end

		end

		% Implementing the 1/f disturbance to F.
		if (df == 1)

                        % Creating a filter which is a cascade combination of 
                        % an autonomic filter and 1/f filter.
			hans = ans_filt(th,[Sgran; Slength; Sratio]);
			hf = conv(honeoverf,hans);
                        % Creating white noise input to be convolved with the filter.
		        wf = [sqrt(1/Sgran)*th(48)*randn(1); wf(1:length(wf)-1)];
                        % Computing mandated change to F.
			thc(1) = thc(1)+sum(wf.*hf);

		end

		% Implementing disturbance to Qvo.
		if (dqvo == 1)

                        % Assigning mandated change to Qvo which was pre-computed.
			thc(5) = thc(5)+Vvo(nvvostep);
			nvvostep = nvvostep+1;

		end

		% Calculating the values of the adjustable parameters at the 
                % end of the next Sgran interval and assigning these values
                % to the thn vector.
		thn = th;		
		thn(1) = thsp(4)+thc(3);
		thn(5) = thsp(5)+thc(4);
		thn(11) = thsp(6)+thc(5);
		thn(16) = thsp(3)+thc(2);
		thn(22) = thsp(2)+thc(1);

		% Denoting the time at the start of the next Sgran interval.
		tn = t(k)-(sumt-Sgran);	

		% Resetting the initial values for the integration 
		% of Pa, Pratr, and t over the next Sgran interval.
		sumP = P(2,k)*(sumt-Sgran);
		sumPratr = (P(9,k)-P(7,k))*(sumt-Sgran);
		sumt = sumt-Sgran;

	end

	% Calculating the new values of the adjustable parameters
	% at the current time step via linear interpolation and assigning
        % the values to the vector tha.  (Note that the mandated changes
        % to Cls and Crs are implemented at the start of each beat.)
	tha = th;
	tha(11) = ((thn(11)-thp(11))/Sgran)*(t(k)-(tp+Sgran))+thp(11);
	tha(16) = ((thn(16)-thp(16))/Sgran)*(t(k)-(tp+Sgran))+thp(16);
	tha(22) = ((thn(22)-thp(22))/Sgran)*(t(k)-(tp+Sgran))+thp(22);

	% Adjusting Pv in response to any mandated change in Qvo -- for 
        % constant volume considerations.
	P(3,k) = P(3,k)+(th(11)-tha(11))/th(4);
	
	% Setting the th vector to its current values.
	th = tha;

	% Computing Pra and qpv or qv over each cardiac cycle in order
	% to establish cardiac function/venous return curves.
        % (Note that ql is not computed, because it is relatively
        % inaccurate for large integration steps.)
	if (preparation == 1)

		summrap = summrap+0.5*deltaT*(P(9,k-1)+P(9,k));
		x = (P(6,k) > P(1,k));
		mbintscalar(x);
		if (x)
		        qpv = (P(6,k)-P(1,k))/th(20);
		else
		        qpv = 0;
		end
		summco = summco+0.5*deltaT*(q(1,k-1)+qpv);
		
	elseif (preparation == 2)

		summrap = summrap+0.5*deltaT*(P(9,k-1)+P(9,k));
		x = (P(3,k) > P(4,k) & P(4,k) >= th(91));
		y = (P(3,k) > th(91) & th(91) > P(4,k));
		mbintscalar(x);
		mbintscalar(y);
		if (x)
			qv = (P(3,k)-P(4,k))/th(17);
		elseif (y)
			qv = (P(3,k)-th(91))/th(17);
		else
			qv = 0;
		end
		summco = summco+0.5*deltaT*(q(4,k-1)+qv);
	end

	% Recalculating the fraction advance in the cardiac cycle to account 
	% for the mandated change to F. 
	frac = ((deltaT-(sumt-Sgran))*th(22)) + ((sumt-Sgran)*tha(22));

	% Updating time in and fraction of current cardiac cycle.
	% These values are associated with the newly calculated pressure
	% and time data.  The integration of the ipfm parameter is achieved
	% with the Backward Euler method.
	
           sumdeltaT = sumdeltaT + deltaT;

	   % Stopping the initiation of ventricular contractions after a 
           % desired number of beats.
	   if (preparation == 4 & qrs_index > th(43))

		sumdelta = 0;
		frac = 0;

	   end
	   ipfm = ipfm + frac;

	% Completing a cardiac cycle when ipfm is greater than or equal to one.
	ipfmcond = (ipfm >= 1);
	mbintscalar(ipfmcond)
	if (ipfmcond)
	
		% Resetting the ipfm model once the current cardiac contraction
		% is complete.
		sumdeltaT = (ipfm - 1)/th(22);
		ipfm = ipfm - 1;
		qrs_index = qrs_index+1; % Number of beats.
		ap(7,qrs_index) = t(k)-sumdeltaT; % Time of each beat.
		ap(8,qrs_index) = k; % Sample number of each beat.

		% Setting next systolic interval based on previous
		% cardiac cycle length.
		th(24) = t(k)-sumdeltaT-ap(7,qrs_index-1);

		% Implementing mandated changes to Cls and Crs.
			th(1) = thn(1);
		        th(5) = thn(5);

                % Varying parameters and computing averages for generation 
                % of cardiac function/venous return curves
		if (preparation == 1)

			% Calculating the integral of Pra and qpv
			% precisely over the previous cardiac cycle. 	
			summrap = summrap-0.5*deltaT*(P(9,k-1)+P(9,k));
			summrap = summrap+0.5*(deltaT-sumdeltaT)*(P(9,k-1)+P(9,k));
			summco = summco-0.5*deltaT*(q(1,k-1)+qpv);
			summco = summco+0.5*(deltaT-sumdeltaT)*(q(1,k-1)+qpv);

			% Computing the average Pra and qpv over the
			% previous cardiac cycle. 			.
			mrap = summrap/(t(k)-sumdeltaT-ap(7,qrs_index-1));
			mco = summco/(t(k)-sumdeltaT-ap(7,qrs_index-1));

			% Recording mean Pra, Pa, and qpv to the num matrix
			% and varying Pv and/or Pa every fb_int beats until
                        % all of the pre-determined variations have been 
                        % implemented.
			if (qrs_index == fb_int & countn < lengtht)
			       countn = countn+1;
			       countj = countj+1;
			       num(1,countn) = mrap;
			       num(2,countn) = P(2,k);
			       num(3,countn) = mco;
			       if (countj ~= lengthra)
				  th(30) = rarange(countj+1);
			       end
			       if (countj == lengthra & countn ~= lengtht)
			          th(29) = th(29)+th(90);
				  P(2,k) = th(29);
				  % Adjusting range of Pv for large Pa values.
				  if (th(29) > 180) 
				     tmp = tmp+1;
				     final = final-0.5*tmp;
				     rarangei = final:-th(88):0;
				     while (length(rarangei) < lengthra-1)
					   rarangei = [rarangei, rarangei(length(rarangei))-th(88)];
				     end
				     rarange = [rarangei, th(23)+1];
				     if (lengthra == 2);
					lengthra = 1;
					rarange = final;
				     end
				     th(30) = final;
				  end
				  fb_int = fb_int+5;
				  countj = 0;
				  P(3,k) = rarange(countj+1);
			       elseif (countn ~= lengtht)
				  P(3,k) = th(30);
				  fb_int = fb_int+5;
			       end	  
			end

			% Resetting the initial values for the integration 
			% of Pra and qpv over the next cardiac cycle.
			summrap = 0.5*sumdeltaT*(P(9,k-1)+P(9,k));
			summco = 0.5*sumdeltaT*(q(1,k-1)+qpv);
			
		end

		if (preparation == 2)

			% Calculating the integral of Pra and qv
			% precisely over the previous cardiac cycle. 	
			summrap = summrap-0.5*deltaT*(P(9,k-1)+P(9,k));
			summrap = summrap+0.5*(deltaT-sumdeltaT)*(P(9,k-1)+P(9,k));
			summco = summco-0.5*deltaT*(q(4,k-1)+qv);
			summco = summco+0.5*(deltaT-sumdeltaT)*(q(4,k-1)+qv);

			% Computing mean Pra and ql over the previous cardiac cycle.
			mrap = summrap/(t(k)-sumdeltaT-ap(7,qrs_index-1));
			mco = summco/(t(k)-sumdeltaT-ap(7,qrs_index-1));

			% Recording mean Pra and ql to the num matrix
			% and varying Crd after every fb_int beats 
                        % until all the pre-determined variations have
                        % been implemented.
			if (qrs_index == fb_int & Crd <= 60 & lengthra ~= 1)
			   countn = countn+1;		   
			   num(1,countn)=mrap;
			   num(2,countn)=mco;
			   Crdo = Crd;
			   Crd = Crd+th(89);

			   % Adjustment of Pr in response to variation in Crd -- for
                           % constant volume considerations.
			   th(6) = (th(32)/(th(27)-th(12)))*Crd;
			   ypres = (P(4,k)-P(7,k))/th(32);
			   xvol = vent_vol(Q(4,k-1),ypres,1/Crdo);
			   alpha = 1/th(6);
			   x0 = 1/(alpha+1);
			   kscale = 50;
			   c1 = 1+exp(-kscale*(1-x0));
			   d1 = 1+exp(kscale*x0);
			   denb1 = (1+(1/kscale)*log(c1/d1));
			   beta = (1-alpha)/denb1;
		  	   c = 1+exp(-kscale*(xvol-x0));
			   d = 1+exp(kscale*x0);
			   denb = (xvol+(1/kscale)*log(c/d));
			   P(4,k) = th(32)*(alpha*xvol+beta*denb)+P(7,k);

			   % Incrementing fb_int.
			   fb_int = fb_int+5;

			end

			% Resetting the initial values for the integration 
			% of Pra and qv over the next cardiac cycle.
			summrap = 0.5*sumdeltaT*(P(9,k-1)+P(9,k));
			summco = 0.5*sumdeltaT*(q(4,k-1)+qv);

		end


	end

	% Recording the adjustable parameter values at the current integration step.
	ap(1:6,k) = [th(1)*((th(26)-th(9))/th(31)) th(5)*((th(27)-th(12))/th(32)) th(11) th(16) th(22) .3*sqrt(th(24))]';

	% Recording the variable elastance values at the current integration step.
	if (preparation ~= 10)
		[El,dEl] = var_cap(th(1),th(2),th(24),sumdeltaT);
		[Er,dEr] = var_cap(th(5),th(6),th(24),sumdeltaT);
		ve(1:2,k) = [El*(th(31)/(th(26)-th(9))); Er*(th(32)/(th(27)-th(12)))];
	else
		[El,dEl] = var_vcap(th(1),th(2),th(24),sumdeltaT);
		[Er,dEr] = var_vcap(th(5),th(6),th(24),sumdeltaT);
		[Ela,dEla] = var_acap(th(80),th(81),th(24),sumdeltaT);
		[Era,dEra] = var_acap(th(84),th(85),th(24),sumdeltaT);
		ve(:,k) = [El*(th(31)/(th(26)-th(9))); Er*(th(32)/(th(27)-th(12))); Ela; Era];
	end		

	% Obtaining the volume values at the current integration step.  Equations depend
	% on the preparation being implemented.
	if (preparation ~= 10)
		Q(1:6,k) = [(1/El) th(3) th(4) (1/Er) th(7) th(8)]'.*(P(1:6,k)-P(7,k)*[1 0 0 1 1 1]') + [th(9:14)];
	else
		Q(1:6,k) = [(1/El) th(3) th(4) (1/Er) th(7) th(8)]'.*([P(1:6,k)]-P(7,k)*[1 0 0 1 1 1]')+[th(9:14)];
		Q(8:9,k) = [(1/Era) (1/Ela)]'.*([P(10:11,k)]-P(7,k)*[1 1]')+[th(86); th(82)];
	end

	if (preparation == 6)
		Q(2,k) = th(72)*P(2,k)+th(74);
		Q(8,k) = th(73)*P(10,k)+th(75);
	elseif (preparation == 1)
		Q(2,k) = 0;
		Q(3,k) = 0;
	elseif (preparation == 3)
		Q(2,k) = 0;
		Q(6,k) = 0;
	elseif (preparation == 7)
		alphatau = -th(70)/th(3);
		Qamax = th(71)-th(3)^2/th(70);
		Qao = th(71)+(th(3)^2/th(70))*exp(-th(70)*th(40)/th(3))*(1-exp(th(70)*th(40)/th(3)));
		Q(2,k) = (Qamax-Qao)*(1-exp(-alphatau*P(2,k)))+Qao;
	elseif (preparation == 8)
		alphatau = -th(70)/th(72);
		Qamax = th(76)-th(72)^2/th(70);
		Qao = th(76)+(th(72)^2/th(70))*exp(-th(70)*th(40)/th(72))*(1-exp(th(70)*th(40)/th(72)));
		Q(2,k) = (Qamax-Qao)*(1-exp(-alphatau*P(2,k)))+Qao;
		Q(8,k) = th(73)*P(10,k)+th(75);
	end

	if (preparation ~= 5)
		x = (P(1,k) < P(7,k));
		mbintscalar(x);
		if (x)
			Q(1,k) = th(9)*(2/pi)*atan(((P(1,k)-P(7,k))/((2/pi)*th(9)*El))) + th(9);
		else
			yl = (P(1,k)-P(7,k))/th(31);
			xl = vent_vol(Q(1,k-1),yl,El);
			Q(1,k) = (th(26)-th(9))*xl+th(9);
		end

		x = (P(4,k) < P(7,k));
		mbintscalar(x);
		if (x)
			Q(4,k) = th(12)*(2/pi)*atan(((P(4,k)-P(7,k))/((2/pi)*th(12)*Er))) + th(12);
		else
			yr = (P(4,k)-P(7,k))/th(32);
			xr = vent_vol(Q(4,k-1),yr,Er);
			Q(4,k) = (th(27)-th(12))*xr+th(12);
		end
	end

	% Correcting Qv and Pv in order to keep total blood volume in the
        % intact circulatory preparations, which may vary due to integration
	% error, constant.
	if (preparation == 0 | preparation == 4 | preparation == 5 | preparation == 6 | preparation == 7 | preparation == 8 | preparation == 9 | preparation == 10)

		if (preparation == 6 | preparation == 8)
		   Qtot = sum(Q([1:6 8],k));
		elseif (preparation == 10)
		   Qtot = sum(Q([1:6 8 9],k));
		else
		   Qtot = sum(Q(1:6,k));
		end
		Q(3,k) = Q(3,k) - (Qtot-th(21));
		P(3,k) = (Q(3,k)-th(11))/th(4);

	end

	% Checking for a request to pause simulation after the completion
	% of every beat provided that waveforms are being viewed on-line.
	if (strcmp(signals,'-1') == 0 & ipfmcond)

	   flagnew = read_key;

	   if (flagnew == 1)

	       % Re-reading parameter file, in the event of a possible update.
	       thspold = thsp;
	       thold = th;
	       fidp = fopen(parameterfile,'r');
	       [th,signals] = read_param(fidp);
	       fclose(fidp);

	       % Precluding adjustment of unchangeable parameters.
	       th(98) = thold(98); % Qfr
	       th(33) = thold(33); % Pms
	       th(88) = thold(88); % Pvs
	       th(89) = thold(89); % Crds
	       th(90) = thold(90); % Pas	       

	       % Precluding adjustment of Pv, Pa, and Crd if they are being
	       % automatically varied.
	       if (preparation == 1 & lengthra > 1)
		  th(30) = thold(30);
	       end
	       if (preparation == 1 & lengthsa > 1)
		  th(29) = thold(29);
	       end
	       if (preparation == 2 & lengthra > 1)
		  th(6) = thold(6);
	       end

	       % Setting annotator flag. 
	       if (th(105) == 0)
		  annotator = 'wqrs';
	       else
		  annotator = 'qrs';
	       end
	       
	       % Determining if parameter update is relevant to
	       % status of current simulation.
	       parameter_change = param_change(th,thold,flag);	       

	       mbintscalar(parameter_change == 1);
	       if (parameter_change == 1)

	          % Annotating and documenting the relevant parameter update.
		  count_pc = count_pc+1;
		  ap(9,qrs_index) = count_pc;
		  write_param(parameterfile,num2str(count_pc));

		  % Adjusting setpoint pressures.
		  thsp(1) = th(40);
		  thsp(7) = th(41);

		  % Conserving Qfr by altering Pth at the functional reserve
		  % volume of the lungs.
	          th(23) = th(25)-((th(98)-th(102))/th(101));

		  % Updating respiratory-related pressures and volumes
		  % over the remainder of the integration period, if necessary.

		  % No breathing.
		  if (breathing == 0 & th(23) ~= thold(23))

		     thbreathe = resp_act(th,at,deltaT/2,0,(tics-1)*deltaT);

		  % Fixed-rate breathing.
		  elseif (breathing == 1 & (th(42) ~= thold(42) | th(77) ~= thold(77) | th(23) ~= thold(23) | th(100) ~= thold(100)))

		     atcount = 2;
		     x = (at(atcount) < t(k)+1.5);
		     mbintscalar(x);
		     while (x)
			atcount=atcount+1;
			x = (at(atcount) < t(k)+1.5);
			mbintscalar(x);
		     end

		     start_index = k+ceil((at(atcount)-t(k))/deltaT);
		     start_time = t(k)+deltaT*ceil((at(atcount)-t(k))/deltaT)-at(atcount);
		     end_time = (length(thbreathe)-(2*(start_index-1)+1))*(deltaT/2)+start_time;

		     if (start_index < tics)

			at = [at(1:atcount); zeros(length(start_index:tics)+1,1)];      
			x = (at(atcount) <= deltaT*tics+1);
			mbintscalar(x);
			while (x)
			   atcount=atcount+1;
			   at(atcount) = at(atcount-1)+th(42);
			   x = (at(atcount) <= deltaT*tics+1);
			   mbintscalar(x);
		        end	
			at = at(1:atcount); 

			thbreathe(:,2*(start_index-1)+1:end) = resp_act(th,zeros(4,1),deltaT/2,start_time,end_time);

			ilv = ilv_dec(thbreathe(1,:),deltaT/2,Sgran);
			ilv = [th(98)*ones(length(hilvhr)-(1.5/Sgran),1); ilv'; th(98)*ones(1.5/Sgran,1)];

		    end

                  % Random-interval breathing.
		  elseif (breathing == 2 & (th(42) ~= thold(42) | th(77) ~= thold(77) | th(99) ~= thold(99) | th(23) ~= thold(23) | th(100) ~= thold(100)))

		       atcount = 2;
		       x = (at(atcount) < t(k)+1.5);
		       mbintscalar(x);
		       while (x)
			  atcount=atcount+1;
			  x = (at(atcount) < t(k)+1.5);
			  mbintscalar(x);
		       end

		       start_index = k+ceil((at(atcount)-t(k))/deltaT);
		       start_time = t(k)+deltaT*ceil((at(atcount)-t(k))/deltaT)-at(atcount);
		       end_time = (length(thbreathe)-(2*(start_index-1)+1))*(deltaT/2)+start_time;

		       if (start_index < tics)

		          thbreathe(:,2*(start_index-1)+1:end) = resp_act(th,[1; (at(atcount+1:end)-at(atcount))],deltaT/2,start_time,end_time);
 		          ilv = ilv_dec(thbreathe(1,:),deltaT/2,Sgran); 
			  ilv = [th(98)*ones(length(hilvhr)-(1.5/Sgran),1); ilv'; th(98)*ones(1.5/Sgran,1)];

		       end

		  end

		  % Implementing a step change to Qlu, if mandated. 
		  if (th(36) ~= 0)
   
		    if (breathing == 1 | breathing == 2)

			 atcount = 2;
			 x = (at(atcount) < t(k)+1.5);
			 mbintscalar(x);
			 while (x)
			    atcount=atcount+1;
			    x = (at(atcount) < t(k)+1.5);
			    mbintscalar(x);
		         end

			 start_index = k+ceil((at(atcount)-t(k))/deltaT);
			 start_time = (start_index-1)*deltaT;
			 th(103) = start_time+1.5;

		    elseif (breathing == 0)

			    th(103) = t(k)+1.5;

		    end			
		  
		    if (th(103) < (tics-1)*deltaT)

			 thbreathes = resp_act(th,[3; th(36)],deltaT/2,0,(tics-1)*deltaT);
			 dthbreathe = [-th(98)*ones(1,length(thbreathes)); -th(23)*ones(1,length(thbreathes)); zeros(2,length(thbreathes))]; 
			 thbreathe = thbreathe+thbreathes+dthbreathe;
			 ilv = ilv_dec(thbreathe(1,:),deltaT/2,Sgran); 
			 ilv = [th(98)*ones(length(hilvhr)-(1.5/Sgran),1); ilv'; th(98)*ones(1.5/Sgran,1)];

		    end

                 end

                 % Assigning values to Pth, Ppac (Palv), and Qlu
		 P(7,k) = thbreathe(2,2*(k-1)+1);
		 P(8,k) = thbreathe(4,2*(k-1)+1);
		 Q(7,k) = thbreathe(1,2*(k-1)+1);

                 % Conserving volume in each compartment of the pulsatile
                 % heart and circulation through pressure adjustments.
		 P(1:6,k) = conserve_vol(th,sumdeltaT,Q(1:6,k),P(7,k));
		 if (preparation == 1)
		    P(2,k) = th(29);
		    P(3,k) = th(30);
		 end

		 % Updating adjustable parameters via instantaneous values
                 % and setpoint values.
		   if (thspold(3) ~= th(16))
		      thn(16) = th(16);
		      thp(16) = th(16);
		      thsp(3) = th(16);
		      ap(4,k) = th(16);
		   else
		      th(16) = thold(16);
		   end

		   if (thspold(2) ~= th(22))
		      thn(22) = th(22);
		      thp(22) = th(22);
		      thsp(2) = th(22);
		      ap(5,k) = th(22);	
		  else
		      th(22) = thold(22);
		  end

		  if (thspold(6) ~= th(11))
		     thn(11) = th(11);
		     thp(11) = th(11);
		     thsp(6) = th(11);
		     ap(3,k) = th(11);
		  else
		     th(11) = thold(11);
		     if (preparation == 0)
			P(3,k) = (Q(3,k)-th(11))/th(4);
		     end	
		  end

		  thn([1:10 12:15 17:21 23:end]) = th([1:10 12:15 17:21 23:end]);
		  thp([1:10 12:15 17:21 23:end]) = th([1:10 12:15 17:21 23:end]);


		  if (thspold(4) ~= th(1))
		     thsp(4) = th(1);
		  else
		     th(1) = thold(1);
		  end

		  if (thspold(5) ~= th(5))
		     thsp(5) = th(5);
		  else
		     th(5) = thold(5);
		  end

	       end

	       end

	end

	% Obtaining the flow rate values at the current integration step.  Equations
        % are dependent on the preparation being implemented.
	if (preparation == 0 | preparation == 1 | preparation == 2 | preparation == 4 | preparation == 5 | preparation == 6 | preparation == 7 | preparation == 8)
		x = (P(6,k) > P(1,k));
		mbintscalar(x);
		if (x)
		        q(1,k) = (P(6,k)-P(1,k))/th(20);
		else
		        q(1,k) = 0;
		end
	elseif (preparation == 3)
		x = (th(34) > P(1,k));
		mbintscalar(x);
		if (x)
		        q(1,k) = (th(34)-P(1,k))/th(20);
		else
		        q(1,k) = 0;
		end
	elseif (preparation == 10)
	        x = (P(11,k) > P(1,k));
		mbintscalar(x);
		if (x)
			q(1,k) = (P(11,k)-P(1,k))/th(83);
		else
		        q(1,k) = 0;
		end

	end
	
	if (preparation == 0 | preparation == 1 | preparation == 4 | preparation == 5 | preparation == 6 | preparation == 7 | preparation == 8 | preparation == 9 | preparation == 10) 
		x = (P(1,k) > P(2,k));
		mbintscalar(x);
		if (x)
		        q(2,k) = (P(1,k)-P(2,k))/th(15);
		else
		        q(2,k) = 0;	
		end
	elseif (preparation == 2)
		x = (P(1,k) > th(33));
		mbintscalar(x);
		if (x)
		        q(2,k) = (P(1,k)-th(33))/th(15);
		else
		        q(2,k) = 0;
		end
	elseif (preparation == 3)
		x = (P(1,k) > th(29));
		mbintscalar(x);
		if (x)
		        q(2,k) = (P(1,k)-th(29))/th(15);
		else
		        q(2,k) = 0;	
		end
	end

	if (preparation == 0 | preparation == 2 | preparation == 4 | preparation == 5 | preparation == 7 | preparation == 9 | preparation == 10)
		q(3,k) = (P(2,k)-P(3,k))/th(16);
	elseif (preparation == 1 | preparation == 3)
		q(3,k) = 0;
	elseif (preparation == 6 | preparation == 8)
		q(3,k) = (P(10,k)-P(3,k))/th(16);
	end

	if (preparation ~= 10 & preparation ~= 5)
		x = (P(3,k) > P(4,k) & P(4,k) >= th(91));
		y = (P(3,k) > th(91) & th(91) > P(4,k));
		mbintscalar(x);
		mbintscalar(y);
		if (x)
			q(4,k) = (P(3,k)-P(4,k))/th(17);
		elseif (y)
			q(4,k) = (P(3,k)-th(91))/th(17);
		else
			q(4,k) = 0;
		end
	elseif (preparation == 5)
	       x = (P(3,k) >= P(4,k));
	       mbintscalar(x);
	       if (x)
			q(4,k) = (P(3,k)-P(4,k))/th(17);
	       else
			q(4,k) = 0;
	       end
	else
		x = (P(9,k) >= P(4,k));
		mbintscalar(x);
		if (x)
			   q(4,k) = (P(9,k)-P(4,k))/th(87);
		else
			   q(4,k) = 0;
		end

	end

	if (preparation ~= 2)
		x = (P(4,k) > P(5,k));
		mbintscalar(x);
		if (x)
		        q(5,k) = (P(4,k)-P(5,k))/th(18);
		else
		        q(5,k) = 0;
		end
	elseif (preparation == 2)
		x = (P(4,k) > th(28));
		mbintscalar(x);
		if (x)
		        q(5,k) = (P(4,k)-th(28))/th(18);
		else
		        q(5,k) = 0;
		end
	end

	if (preparation == 2 | preparation == 5)
		q(6,k) = (P(5,k)-P(6,k))/th(19);
	elseif (preparation == 0 | preparation == 1 | preparation == 4 | preparation == 6 |preparation == 7 | preparation == 8 | preparation == 9 | preparation == 10)
		h1 = (1330/(1.06*980))*(P(6,k)-P(8,k));
		x = h1 < -10;
		mbintscalar(x);
		y = h1 > 20;
		mbintscalar(y);
		if (x)
			h1 = -10;
		elseif (y)	
			h1 = 20;
		end

		h2 = (1330/(1.06*980))*(P(5,k)-P(8,k));
		x = h2 < -10;
		mbintscalar(x);
		y = h2 > 20;
		mbintscalar(y);
		if (x)
			h2 = -10;
		elseif (y)	
			h2 = 20;
		end

		q(6,k) = (((P(5,k)-P(6,k))/(30*th(19)))*(h1+10)) + (((P(5,k)-P(8,k))/(30*th(19)))*(h2-h1)) - (((1.06*980)/(2660*(30*th(19))))*(h2^2-h1^2));

	elseif (preparation == 3)
		q(6,k) = 0;
	end

	if (preparation == 10)
		x = (P(3,k) >= th(91) & P(9,k) >= th(91));
		y = (P(3,k) > th(91) & th(91) > P(9,k));
		z = (P(9,k) > th(91) & th(91) > P(3,k));
		mbintscalar(x);
		mbintscalar(y);
		mbintscalar(z);
		if (x)
			 q(7,k) = (P(3,k)-P(9,k))/th(17);
		elseif (y)	 
			 q(7,k) = (P(3,k)-th(91))/th(17);
		elseif (z)	 
			 q(7,k) = (th(91)-P(9,k))/th(17);
		else
			 q(7,k) = 0;
		end
	elseif (preparation == 6 | preparation == 8)
		q(7,k) = P(11,k);
	end

        if (preparation == 10)
		q(8,k) = (P(6,k)-P(11,k))/th(20);
	end	


	% Writing waveforms and annotations to files in MIT format every step parameter
        % seconds once a window parameter duration of data have been calculated.
	if (strcmp(signals,'-1') == 0 & t(k) > th(104) & (t(k)-t(kstart)) > th(78))

           % Writing newly generated waveform data to MIT format files.
	   X = [P(1:9,kstart:k); Q(1:6,kstart:k); Q(7,kstart:k)*0.1; q(1:6,kstart:k); ap(1:2,kstart:k)*100; ap(3,kstart:k); ap(4,kstart:k)*100; ap(5,kstart:k)*600; ve(1:2,kstart:k)*10]*10;
	   fwrite(fid,X,'short');

           % Updating variables necessary for writing waveforms.
	   kstart = k+1;
	   start_time = t(k)-th(104);

           % Writing newly generated annotations to MIT format files.
	   qrso = [];
	   qrso = diff(ap(8,qrs_index_start:qrs_index))';
	   for i = 1:length(qrso)
	       fwrite(fid2,qrso(i),'bit10');
	       fwrite(fid2,1,'ubit6');

	       % If parameter update has been made, writing auxillary information.
	       x = (ap(9,qrs_index_start+i) ~= 0);
	       mbintscalar(x)
	       if (x)
		  suffix = num2str(ap(9,qrs_index_start+i));
		  fwrite(fid2,Nbytes+(length(suffix)-1),'bit10');
		  fwrite(fid2,63,'ubit6');
		  fwrite(fid2,[parameterfile '.' suffix],[num2str(Nbytes+length(suffix)-1) '*uchar']);
	       end
	   end
	   qrs_index_start = qrs_index;

           % Alternating outputfile signaled to WAVE in order to permit
	   % on-line updating of the annotation flag.
	   if (wrflag == 0)

	      wave_remote( outputfile, annotator, start_time, signals );
	      wrflag = 1;

	   else
	      
	      wave_remote( outputfile2, annotator, start_time, signals );
	      wrflag = 0;

	   end

	end

	% If cardiac function/venous return curves are complete, there
	% is no need for further integration.  That is, for-loop is exited.
	if (preparation == 1 | preparation == 2)
	   if (countn >= length(num'))
	      tics = k;
	      break;
	   end
	end

end

% Writing remaining portion of simulated data to the MIT format files.
if (strcmp(signals,'-1') == 0)

        % Writing last portion of generated waveform data.
	X = [P(1:9,kstart:tics); Q(1:6,kstart:tics); Q(7,kstart:tics)*0.1; q(1:6,kstart:tics); ap(1:2,kstart:tics)*100; ap(3,kstart:tics); ap(4,kstart:tics)*100; ap(5,kstart:tics)*600; ve(1:2,kstart:tics)*10]*10;
	fwrite(fid,X,'short');
     
        % Writing last annotations.
	qrso = [];
	qrso = diff(ap(8,qrs_index_start:qrs_index))';
	for i = 1:length(qrso)

	    fwrite(fid2,qrso(i),'bit10');
	    fwrite(fid2,1,'ubit6');

	    % If parameter updates have been made, writing auxillary info. 
	    x = (ap(9,qrs_index_start+i) ~= 0);
	    mbintscalar(x)
	    if (x)

		suffix = num2str(ap(9,qrs_index_start+i));
		fwrite(fid2,Nbytes+(length(suffix)-1),'bit10');
		fwrite(fid2,63,'ubit6');
		fwrite(fid2,[parameterfile '.' suffix],[num2str(Nbytes+length(suffix)-1) '*uchar']);

	    end

	end
	fwrite(fid2,0,'bit10');
	fwrite(fid2,0,'ubit6');
	fclose(fid2);
	fclose(fid);

end

% If MATLAB execution, writing qrs vector as times of ventricular contractions.
% If Linux execution, writing qrs vector as samples of ventricular contractions.
if (nargin == 2)
   qrs = ap(7,1:qrs_index);
else
   qrs = ap(8,1:qrs_index);
end

% Only supplying as output the pressures that are generated by
% the model, for MATLAB execution only.
if (preparation == 6 | preparation == 8)

	P = P(1:10,:);
	q = q(1:7,:);
	Q = Q(1:8,:);
	ve = ve(1:2,:);

elseif (preparation == 10 | preparation == 13)	

        P = P([1:9 11],:);

else

	P = P(1:9,1:tics);
	q = q(1:6,1:tics);
	Q = Q(1:7,1:tics);
	ve = ve(1:2,1:tics);
	ap = ap(:,1:tics);
	t = t(1:tics);

end