Home > . > DIVA_MotorCortex.m

DIVA_MotorCortex

PURPOSE ^

DIVA_MotorCortex Motor cortex model

SYNOPSIS ^

function out=DIVA_MotorCortex(varargin)

DESCRIPTION ^

 DIVA_MotorCortex Motor cortex model

 This model receives the forward and feedback motor commands and
 sends control commands to the vocal tract

 DIVA_MotorCortex('init' [,SessionName]);          Initializes the module
 DIVA_MotorCortex('save' [,SessionName] );         Saves state
 DIVA_MotorCortex('exit');                         Exits the module (without saving)
 DIVA_MotorCortex(PropertyName [,PropertyValue] )  Reads and writes internal
                                                   model properties

 DIVA_MotorCortex('target',idx,'error_sound',e1,'error_somatosensory',e2);
 The motor target is represented as an index 'idx' into the a set
 of learned weights ('WeightsFromTargets') representing the
 learned forward commands. The auditory and somatosensory errors
 are represented as vectors of AuditoryCortex and
 SomatosensoryCortex activations respectively.  Corrective
 movements are calculated from the auditory and somatosensory
 error via explicit pseudoinverse of the ForwardModel.

 Current DIVA_MotorCortex properties are: (* requires re-initialization)
     eps_motor                     : integration constant for motor commands
     eps_decay                     : decay constant for motor commands
                                     (tendency towards zero)
     eps_learn                     : integration constant for feedforward learning
  *  delayToVocalTract             : delay (in seconds) for signals to VocalTract
     WeightFeedForward             : weight of feedforward command to total motor command
     WeightFeedBack                : weight of feedback command to total motor command
     WeightLearn                   : weight of feedback command to learning of
                                     total motor command
     WeightFeedBack_sound          : weight of auditory feedback to total feedback command
     WeightFeedBack_somatosensory  : weight of somatosensory feedback to total
                                     feedback command
     WeightLearn_sound             : weight of auditory feedback to total learning command
     WeightLearn_somatosensory     : weight of somatosensory feedback to total
                                     learning command
     WeightsFromTargets            : weights for target signals
     ErrorNoise_sound            : additive noise which simulates degradation of transmission of auditory error cell information
     ErrorNoise_somatosensory      : additive noise which simulates degradation of transmission of somatosensory error cell information
     ErrorNoise_ffAmplitude        : additive noise which simulates degradation of transmission of the feedforward command

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function out=DIVA_MotorCortex(varargin)
0002 % DIVA_MotorCortex Motor cortex model
0003 %
0004 % This model receives the forward and feedback motor commands and
0005 % sends control commands to the vocal tract
0006 %
0007 % DIVA_MotorCortex('init' [,SessionName]);          Initializes the module
0008 % DIVA_MotorCortex('save' [,SessionName] );         Saves state
0009 % DIVA_MotorCortex('exit');                         Exits the module (without saving)
0010 % DIVA_MotorCortex(PropertyName [,PropertyValue] )  Reads and writes internal
0011 %                                                   model properties
0012 %
0013 % DIVA_MotorCortex('target',idx,'error_sound',e1,'error_somatosensory',e2);
0014 % The motor target is represented as an index 'idx' into the a set
0015 % of learned weights ('WeightsFromTargets') representing the
0016 % learned forward commands. The auditory and somatosensory errors
0017 % are represented as vectors of AuditoryCortex and
0018 % SomatosensoryCortex activations respectively.  Corrective
0019 % movements are calculated from the auditory and somatosensory
0020 % error via explicit pseudoinverse of the ForwardModel.
0021 %
0022 % Current DIVA_MotorCortex properties are: (* requires re-initialization)
0023 %     eps_motor                     : integration constant for motor commands
0024 %     eps_decay                     : decay constant for motor commands
0025 %                                     (tendency towards zero)
0026 %     eps_learn                     : integration constant for feedforward learning
0027 %  *  delayToVocalTract             : delay (in seconds) for signals to VocalTract
0028 %     WeightFeedForward             : weight of feedforward command to total motor command
0029 %     WeightFeedBack                : weight of feedback command to total motor command
0030 %     WeightLearn                   : weight of feedback command to learning of
0031 %                                     total motor command
0032 %     WeightFeedBack_sound          : weight of auditory feedback to total feedback command
0033 %     WeightFeedBack_somatosensory  : weight of somatosensory feedback to total
0034 %                                     feedback command
0035 %     WeightLearn_sound             : weight of auditory feedback to total learning command
0036 %     WeightLearn_somatosensory     : weight of somatosensory feedback to total
0037 %                                     learning command
0038 %     WeightsFromTargets            : weights for target signals
0039 %     ErrorNoise_sound            : additive noise which simulates degradation of transmission of auditory error cell information
0040 %     ErrorNoise_somatosensory      : additive noise which simulates degradation of transmission of somatosensory error cell information
0041 %     ErrorNoise_ffAmplitude        : additive noise which simulates degradation of transmission of the feedforward command
0042 %
0043 
0044 % Dependencies:
0045 %
0046 
0047 % 2007-03-22: (JSB) Additive normal noise distortion added to .current.error_sound
0048 % and .current.error_somatosensory channels simulating degraded synaptic transmission
0049 % between calculation of auditory/somatosensory feedback corrective motor
0050 % commands and combination with complete motor command.  Done in motor space
0051 % to use standard (motor) units.  Also, in this space a single noise
0052 % parameter makes sense (can split later on for individual articulators)
0053 
0054 % TODO % Adaptive control of feedforward/feedback learning weights
0055   
0056   out=[];
0057   global DIVA_MotorCortex_data
0058 
0059   %%%%%%%%%%%%%%%% INITIALIZATION %%%%%%%%%
0060   %%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%
0061 
0062   somethingtoexecute=0;
0063   for indexargin=1:2:nargin,
0064     switch(varargin{indexargin}),
0065      case 'init',
0066       SessionFolder=strcat(DIVA('SessionFolder'),filesep);
0067       if nargin<indexargin+1 || isempty(varargin{indexargin+1}),
0068         initfile='';
0069       else,
0070         initfile=[SessionFolder,'Session_',varargin{indexargin+1},filesep,mfilename,'.mat'];
0071       end
0072       if isempty(initfile) || isempty(dir(initfile)),
0073         disp([mfilename, ' : Defining new session...']);
0074         DIVA_MotorCortex_data.params = struct(...
0075             'nMotor',2*DIVA('VocalTract','nArtic'),...  % # of neurons for motor representation
0076             'eps_motor',.25,...          % integration constant for motor commands
0077             'eps_decay',.95,...          % decay constant for motor commands (tendency towards zero)
0078             'delayToVocalTract',.005,...
0079             'WeightFeedForward',0.9,...  % Weight of feedforward command to total motor command 
0080             'WeightFeedBack',0.1,...     % Weight of feedback command to total motor command 
0081             'WeightFeedBack_sound',0.8,... % Weight of auditory feedback to feedback command (used for total motor command)
0082             'WeightFeedBack_somatosensory',.0,... % Weight of somatosensory feedback to feedback command (used for total motor command)
0083             'WeightLearn',0.7,...          % Weight of feedback command to learning of motor command
0084             'WeightLearn_sound',0.6,...    % Weight of auditory feedback to feedback command (used for learning)
0085             'WeightLearn_somatosensory',0,... % Weight of somatosensory feedback to feedback command (used for learning) 
0086             'ErrorNoise_sound', [0 0], ... % mean, std of additive noise to auditory error
0087             'ErrorNoise_somatosensory', [0 0], ... % mean, std of additive noise to somatosensory error
0088             'ErrorNoise_ffAmplitude', [0 0], ... % mean, std of additive noise to feedforward command amplitude
0089             'ErrorNoise_ffTiming', [0,0], ... % mean and std of additive noise to feedforward command timint
0090             'WeightsFromTargets',[],...    % Motor command weights
0091             'InverseParameters',struct(... % Parameters needed for explicit pseudoinverse
0092                 'DELTA', 5,...
0093                 'ALPHA', 0.5,...
0094                 'BETA', 0.05,...
0095                 'LAMBDA',0),...
0096             'plotf',0);
0097       else,
0098         data=load(initfile,'-mat');
0099         DIVA_MotorCortex_data.params=data.params;
0100       end
0101 
0102       DIVA_MotorCortex_data.params.TimeStep=DIVA('TimeStep');
0103       DIVA_MotorCortex_data.params.default_motorSound = ...
0104           (0.5*ones(DIVA_MotorCortex_data.params.nMotor,1));
0105       % Default motor representation when defining a new target
0106 
0107       DIVA_MotorCortex_data.params.default_motorSilence = ...
0108           (0.5*ones(DIVA_MotorCortex_data.params.nMotor,1));
0109       % Motor representation associated with relaxed vocal tract configuration
0110 
0111       DIVA_MotorCortex_data.params.motorAmplitude = DIVA('VocalTract','Amplitude');
0112       % Motor representation index for amplitude control
0113 
0114       DIVA_MotorCortex_data.params.MaedaSpread = DIVA('VocalTract','MaedaSpread');
0115       DIVA_MotorCortex_data.params.delayFromSomatosensoryCortex=...
0116           DIVA('SomatosensoryCortex','delayToMotorCortex');
0117       DIVA_MotorCortex_data.params.delayFromAuditoryCortex=...
0118           DIVA('AuditoryCortex','delayToMotorCortex');
0119       DIVA_MotorCortex_data.params.delayToerror_sound=...
0120           DIVA_MotorCortex_data.params.delayToVocalTract+...
0121           DIVA('VocalTract','delayToSoundChannel')+...
0122           0*DIVA('SoundChannel','delayToCochlea')+...
0123           DIVA('Cochlea','delayToAuditoryCortex')+...
0124           DIVA('AuditoryCortex','delayToMotorCortex');
0125       DIVA_MotorCortex_data.params.delayToerror_somatosensory=...
0126           DIVA_MotorCortex_data.params.delayToVocalTract+...
0127           DIVA('VocalTract','delayToSensoryChannel')+...
0128           0*DIVA('SensoryChannel','delayToSensory')+...
0129           DIVA('Sensory','delayToSomatosensoryCortex')+...
0130           DIVA('SomatosensoryCortex','delayToMotorCortex');
0131       DIVA_MotorCortex_data.params.current.motor=...
0132           DIVA_MotorCortex_data.params.default_motorSilence;
0133       DIVA_MotorCortex_data.params.current.error_sound=[];
0134       DIVA_MotorCortex_data.params.current.error_somatosensory=[];
0135       DIVA_MotorCortex_data.params.current.target=[];
0136       % temporary variables used to calculate true WeightsFromTargets
0137       DIVA_MotorCortex_data.params.current.motorupdate_a=0;
0138       DIVA_MotorCortex_data.params.current.motorupdate_s=0;
0139 
0140       % Channels
0141       out={'error_sound','error_somatosensory','target'};
0142 
0143      case 'save',
0144       SessionFolder=strcat(DIVA('SessionFolder'),filesep);
0145       if nargin<indexargin+1,
0146         initfile=[SessionFolder,'Session_','default',filesep,mfilename,'.mat'];
0147       else,
0148         initfile=[SessionFolder,'Session_',varargin{indexargin+1},filesep,mfilename,'.mat'];
0149       end
0150       params=DIVA_MotorCortex_data.params;
0151       save(initfile,'params');
0152 
0153      case 'exit',
0154       clear DIVA_MotorCortex_data
0155 
0156      case 'disp',
0157       disp(DIVA_MotorCortex_data.params);
0158       out=fieldnames(DIVA_MotorCortex_data.params);
0159 
0160       %%%%%%%%%%%%%%%% ACTION %%%%%%%%%%%%%%%%%
0161       %%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%
0162 
0163      case 'error_sound'
0164       % current sound error projection
0165       
0166       DIVA_MotorCortex_data.params.current.error_sound = varargin{indexargin+1};
0167       somethingtoexecute=1;
0168       if ~nargout,
0169         DIVA('GUI','other_weights','error_sound');
0170         DIVA('ModelStatePlot','MotorCortex','error_sound');
0171       end
0172 
0173      case 'error_somatosensory'
0174       % current somatosensory error projection
0175       DIVA_MotorCortex_data.params.current.error_somatosensory = varargin{indexargin+1};
0176       somethingtoexecute=1;
0177       if ~nargout,
0178         DIVA('GUI','other_weights','error_somatosensory');
0179         DIVA('ModelStatePlot','MotorCortex','error_somatosensory');
0180       end
0181 
0182      case 'target'
0183       % current target projection
0184       DIVA_MotorCortex_data.params.current.target=varargin{indexargin+1};
0185       somethingtoexecute=1;
0186       if ~nargout,
0187         DIVA('ModelStatePlot','MotorCortex','target');
0188       end
0189 
0190      otherwise,
0191       if isfield(DIVA_MotorCortex_data.params,varargin{indexargin}),
0192         if indexargin==nargin,
0193           out=DIVA_MotorCortex_data.params.(varargin{indexargin});
0194         else,
0195           if(strmatch('errornoise',lower(varargin{indexargin}))),
0196             if(length(varargin{indexargin+1})==1)
0197               DIVA_MotorCortex_data.params.(varargin{indexargin}) = ...
0198                 [0 varargin{indexargin+1}];
0199             else
0200               DIVA_MotorCortex_data.params.(varargin{indexargin}) = ...
0201                 varargin{indexargin+1};
0202             end
0203           else
0204             DIVA_MotorCortex_data.params.(varargin{indexargin})=varargin{indexargin+1};
0205           end
0206         end
0207       else,
0208         warning('DIVA_MotorCortex: wrong argument');
0209       end
0210     end
0211   end
0212 
0213   %---------------------------EXECUTE---------------------------------------%
0214 
0215 
0216   if somethingtoexecute,
0217     ntimepoints=DIVA('AuditoryCortexCategorical','ntimepoints');
0218     if(DIVA_MotorCortex_data.params.WeightLearn > 0), % Skip if simply production
0219       %----------------------COMPUTE FEEDBACK COMPONENTS----------------------%
0220       if ~isempty(DIVA_MotorCortex_data.params.current.error_sound) && ...
0221             DIVA_MotorCortex_data.params.WeightFeedBack_sound>0,
0222         %-----------------------Auditory Error Feedback-----------------------%
0223         % PERFORM Auditory to Motor Transformation
0224         % explicit pseudo-inverse implementation
0225         originalmotorcommand=DIVA('VocalTract','motor',[],...
0226                                   -DIVA_MotorCortex_data.params.delayToerror_sound+...
0227                                   DIVA_MotorCortex_data.params.delayToVocalTract+...
0228                                   DIVA_MotorCortex_data.params.TimeStep*...
0229                                   (0:size(DIVA_MotorCortex_data.params.current.error_sound,2)-1));
0230 
0231         originaltarget=DIVA('AuditoryCortex','target',[],...
0232                             -DIVA_MotorCortex_data.params.delayFromAuditoryCortex+...
0233                             DIVA_MotorCortex_data.params.TimeStep*...
0234                             (0:size(DIVA_MotorCortex_data.params.current.error_sound,2)-1));
0235 
0236         originalsound=DIVA('AuditoryCortex','sound',[],...
0237                            -DIVA_MotorCortex_data.params.delayFromAuditoryCortex+...
0238                            DIVA_MotorCortex_data.params.TimeStep*...
0239                            (0:size(DIVA_MotorCortex_data.params.current.error_sound,2)-1));
0240 
0241         errorsound    = DIVA_MotorCortex_data.params.current.error_sound;
0242         nMotor        = DIVA_MotorCortex_data.params.nMotor;
0243         nArtic        = DIVA('VocalTract','nArtic');
0244         nFormants     = DIVA('AuditoryCortex','nFormants');
0245 
0246         N=size(DIVA_MotorCortex_data.params.current.error_sound,2); %length of error sound
0247 
0248         tmp=DIVA('VocalTract','motor',originalmotorcommand);
0249         artic=tmp{2}(1:nArtic,:);
0250         
0251         % Compute Auditory Error to Motor Corrective Movement
0252         motor = calculateInverse(originalmotorcommand,originalsound,errorsound,nFormants);
0253         % Additive error representing degraded synaptic transmission
0254         motor = motor + (DIVA_MotorCortex_data.params.ErrorNoise_sound(1) + ...
0255                          DIVA_MotorCortex_data.params.ErrorNoise_sound(2) * ...
0256                          randn(size(motor)));
0257         DIVA_MotorCortex_data.params.current.error_sound = motor;
0258         CommandFeedBack_sound=DIVA_MotorCortex_data.params.current.error_sound;
0259       else
0260         CommandFeedBack_sound = 0;
0261       end
0262 
0263       %---------------------Somatosensory Error Feedback---------------------%
0264 
0265       % PERFORM Somatosensory to Motor Transformation
0266       if ~isempty(DIVA_MotorCortex_data.params.current.error_somatosensory) && ...
0267             DIVA_MotorCortex_data.params.WeightFeedBack_somatosensory > 0,
0268         % explicit pseudo-inverse implementation
0269         originalmotorcommand = ...
0270             DIVA('VocalTract','motor',[],...
0271                  -DIVA_MotorCortex_data.params.delayToerror_somatosensory+...
0272                  DIVA_MotorCortex_data.params.delayToVocalTract+...
0273                  DIVA_MotorCortex_data.params.TimeStep*...
0274                  (0:size(DIVA_MotorCortex_data.params.current.error_somatosensory,2)-1));
0275 
0276         originaltarget = ...
0277             DIVA('SomatosensoryCortex','target',[],...
0278                  -DIVA_MotorCortex_data.params.delayFromSomatosensoryCortex+...
0279                  DIVA_MotorCortex_data.params.TimeStep*...
0280                  (0:size(DIVA_MotorCortex_data.params.current.error_somatosensory,2)-1));
0281 
0282         originalsomato = ...
0283             DIVA('SomatosensoryCortex','somatosensory',[],...
0284                  -DIVA_MotorCortex_data.params.delayFromSomatosensoryCortex+...
0285                  DIVA_MotorCortex_data.params.TimeStep*...
0286                  (0:size(DIVA_MotorCortex_data.params.current.error_somatosensory,2)-1));
0287 
0288         nArtic        = DIVA('VocalTract','nArtic');
0289         nMotor        = DIVA_MotorCortex_data.params.nMotor;
0290         nSomato       = DIVA('Sensory','nSensory');
0291         errorsomato   = DIVA_MotorCortex_data.params.current.error_somatosensory;
0292 
0293         N = size(DIVA_MotorCortex_data.params.current.error_somatosensory,2);
0294 
0295         % Compute Somatosensory Error to Motor Corrective Movement
0296         motor = calculateInverse(originalmotorcommand,originalsomato,errorsomato,nSomato);
0297         % Additive error representing degraded synaptic transmission
0298         motor = motor + (DIVA_MotorCortex_data.params.ErrorNoise_somatosensory(1) + ...
0299                          DIVA_MotorCortex_data.params.ErrorNoise_somatosensory(2) * ...
0300                          randn(size(motor)));
0301         
0302         DIVA_MotorCortex_data.params.current.error_somatosensory=motor;
0303         CommandFeedBack_somatosensory=DIVA_MotorCortex_data.params.current.error_somatosensory;
0304       else
0305         CommandFeedBack_somatosensory = 0;
0306       end
0307 
0308       %-------------------------Combined Error Feedback--------------------------%
0309 
0310       % Combine Auditory and Somatosensory corrective motor commands
0311       CommandFeedBack = ...
0312           (DIVA_MotorCortex_data.params.WeightFeedBack_sound * CommandFeedBack_sound) + ...
0313           (DIVA_MotorCortex_data.params.WeightFeedBack_somatosensory * ...
0314            CommandFeedBack_somatosensory);
0315 
0316     else, % There is no learning going on
0317       CommandFeedBack=0;
0318     end
0319 
0320     %-------------------------Prepare Motor Movement w.r.t. Motor targets------%
0321 
0322     if ~isempty(DIVA_MotorCortex_data.params.current.target),
0323       % initializes target if it does not exist
0324       idx=union(floor(DIVA_MotorCortex_data.params.current.target),...
0325                 ceil(DIVA_MotorCortex_data.params.current.target));
0326 
0327       % Make room at end of WeightsFromTargets if current utterance is not represented yet
0328       if max(idx)+ntimepoints>size(DIVA_MotorCortex_data.params.WeightsFromTargets,2),
0329         idxnew=size(DIVA_MotorCortex_data.params.WeightsFromTargets,2)+...
0330                1:max(idx)+ntimepoints;
0331 
0332         DIVA_MotorCortex_data.params.WeightsFromTargets(:,idxnew) = ...
0333             DIVA_MotorCortex_data.params.default_motorSound(:,ones(1,length(idxnew)));
0334       end
0335 
0336       % Determine current Motor Target region
0337       % HERE IS WHERE WE ADD temporal NOISE for FEEDFORWARD CMD
0338       %   - Represents demylinization
0339       if length(idx)>1,
0340         DIVA_MotorCortex_data.params.current.targetmotor = ...
0341             fastinterp1(idx,DIVA_MotorCortex_data.params.WeightsFromTargets(:,idx),...
0342                         DIVA_MotorCortex_data.params.current.target);
0343       else,
0344         DIVA_MotorCortex_data.params.current.targetmotor = ...
0345             DIVA_MotorCortex_data.params.WeightsFromTargets(:,idx*ones(1,size(DIVA_MotorCortex_data.params.current.target,2)));
0346       end
0347       if nargout>0,
0348         tempcurrentmotor = DIVA_MotorCortex_data.params.current.motor;
0349         DIVA_MotorCortex_data.params.current.motor = ...
0350             DIVA_MotorCortex_data.params.default_motorSilence;
0351       end
0352 
0353       %-------------------------Feedforward AND total Command-------------------------%
0354 
0355       for n1=1:size(DIVA_MotorCortex_data.params.current.target,2),
0356         % computes feedforward component
0357         CommandFeedForward = ...
0358             DIVA_MotorCortex_data.params.current.targetmotor(:,n1) - ...
0359             DIVA_MotorCortex_data.params.current.motor;
0360         % Additive noise simulating degradation in synaptic transmission of feedforward command
0361         CommandFeedForward = CommandFeedForward + ...
0362                              (DIVA_MotorCortex_data.params.ErrorNoise_ffAmplitude(1) + ...
0363                               DIVA_MotorCortex_data.params.ErrorNoise_ffAmplitude(2) * ...
0364                               randn(size(CommandFeedForward)));          
0365 
0366         % computes motor command from FeedForward and FeedBack commands
0367         Command = DIVA_MotorCortex_data.params.WeightFeedBack*...
0368                   CommandFeedBack(:,min(n1,size(CommandFeedBack,2))) + ...
0369                   DIVA_MotorCortex_data.params.WeightFeedForward*CommandFeedForward;
0370 
0371         % Calculate current motor command hard-limited to [0,1]
0372         DIVA_MotorCortex_data.params.current.motor = ...
0373             max(0,min(1,DIVA_MotorCortex_data.params.default_motorSilence + ...
0374                       DIVA_MotorCortex_data.params.eps_decay*...
0375                       (DIVA_MotorCortex_data.params.current.motor - ...
0376                        DIVA_MotorCortex_data.params.default_motorSilence) + ...
0377                       DIVA_MotorCortex_data.params.eps_motor * Command));
0378         out(:,n1)=(DIVA_MotorCortex_data.params.current.motor);
0379       end
0380 
0381       %---------------------------Project to Vocal Tract---------------------------%
0382 
0383       if ~nargout,
0384         DIVA('VocalTract','motor',out,DIVA_MotorCortex_data.params.delayToVocalTract);
0385       else,
0386         DIVA_MotorCortex_data.params.current.motor=tempcurrentmotor;
0387       end
0388     end
0389 
0390     %-----------------------------------------------------------------------------%
0391 
0392     % Update Learned Weights
0393 
0394     if DIVA_MotorCortex_data.params.WeightLearn > 0,
0395       % learning from auditory error
0396       if ~isempty(DIVA_MotorCortex_data.params.current.error_sound) && ...
0397             DIVA_MotorCortex_data.params.WeightLearn_sound > 0,
0398 
0399         % Find relevant target indicies
0400         targettolearn = DIVA('MotorCortex','target',[],...
0401                              -DIVA_MotorCortex_data.params.delayToerror_sound + ...
0402                              DIVA_MotorCortex_data.params.TimeStep*...
0403                              (0:size(CommandFeedBack_sound,2)));
0404 
0405         % Sometimes in blockmode the tail target index is nonzero, errant behavior with
0406         % no known source yet, fix to zero...2006-10-06, JB
0407         if(targettolearn(end)<targettolearn(end-1)),
0408           targettolearn(end)=0;
0409         end
0410 
0411         if ~all(targettolearn(1:end-1)>0),
0412           disp('DIVA_MotorCortex: warning, receiving sound error signal without a motor cause');
0413         else,
0414           idxvalid = 1:length(targettolearn)-1;
0415           idx = floor(targettolearn(idxvalid(1))):floor(targettolearn(idxvalid(end)));
0416           idx = idx(find(idx>0));
0417 
0418           % Temporary weight update, need to find average update over all instances
0419           % of target indicies per training trial
0420           % For instance, target index sequence might be [1 1.3 1.6 1.9 2.0,...]
0421           % The round() command above creates a sequence [1 1 2 2 2,...], resulting in
0422           % over training of index 2 compared to index 1.  The imaginary part of
0423           % motorupdate_* counts the number of consecutive input indicies for use in an
0424           % averaging procedure
0425           if(~DIVA('BlockMode')),
0426             DIVA_MotorCortex_data.params.current.motorupdate_a=...
0427                 DIVA_MotorCortex_data.params.current.motorupdate_a+...
0428                 DIVA_MotorCortex_data.params.WeightLearn * ...
0429                 DIVA_MotorCortex_data.params.WeightLearn_sound * ...
0430                 CommandFeedBack_sound + sqrt(-1);
0431 
0432             % Update Motor Weights
0433             if diff(floor(targettolearn)),
0434               %idx = union(floor(targettolearn),ceil(targettolearn));
0435               idx = min(floor(targettolearn(find(targettolearn>0)))):max(ceil(targettolearn(find(targettolearn>0))));
0436               idx = idx(find(idx>0));
0437               if(diff(floor(targettolearn))<0)
0438                 idx = idx;%max(round(targettolearn))
0439               else
0440                 idx = idx(find(idx<floor(targettolearn(end))));
0441               end
0442               DIVA_MotorCortex_data.params.WeightsFromTargets(:,idx)=...
0443                   DIVA_MotorCortex_data.params.WeightsFromTargets(:,idx)+...
0444                   repmat(real(DIVA_MotorCortex_data.params.current.motorupdate_a)./...
0445                          imag(DIVA_MotorCortex_data.params.current.motorupdate_a),...
0446                          1,length(idx));
0447               DIVA_MotorCortex_data.params.current.motorupdate_a=0;
0448             end
0449           else
0450             idx=unique(floor(targettolearn(find(targettolearn>0))));
0451             blockBound = diff(floor(targettolearn));
0452             for n=1:length(idx),
0453               if(blockBound(max(find(floor(targettolearn)==idx(n))))>0)
0454                 targetIdx = ...
0455                     idx(n):idx(n)+blockBound(max(find(floor(targettolearn)==idx(n))))-1;
0456               else
0457                 targetIdx = idx(n):idx(n)+1;
0458               end
0459               DIVA_MotorCortex_data.params.WeightsFromTargets(:,targetIdx) = ...
0460                   DIVA_MotorCortex_data.params.WeightsFromTargets(:,targetIdx) + ...
0461                   DIVA_MotorCortex_data.params.WeightLearn * ...
0462                   DIVA_MotorCortex_data.params.WeightLearn_sound * ...
0463                   repmat(...
0464                       sum(CommandFeedBack_sound(:,find(floor(targettolearn)==idx(n))),2) / ...
0465                       length(find(floor(targettolearn)==idx(n))),...
0466                       1,length(targetIdx));
0467             end
0468           end
0469         end
0470       end
0471 
0472       %----------------------------------------------------------------------------%
0473 
0474       % learning from somatosensory error
0475       if ~isempty(DIVA_MotorCortex_data.params.current.error_somatosensory) & ...
0476             DIVA_MotorCortex_data.params.WeightLearn_somatosensory,
0477         % Find relevant target indicies
0478         targettolearn = ...
0479             DIVA('MotorCortex','target',[],...
0480                  -DIVA_MotorCortex_data.params.delayToerror_somatosensory + ...
0481                  DIVA_MotorCortex_data.params.TimeStep*...
0482                  (0:size(CommandFeedBack_somatosensory,2)));
0483         
0484         % Sometimes in blockmode the tail target index is nonzero, errant behavior with
0485         % no known source yet, fix to zero...2006-10-06, JB
0486         if(targettolearn(end)<targettolearn(end-1)),
0487           targettolearn(end)=0;
0488         end
0489         
0490         if ~all(targettolearn(1:end-1)>0),
0491           disp(['DIVA_MotorCortex: warning, receiving somatosensory error '...
0492                 'signal without a motor cause']);
0493         else,
0494           idxvalid=1:length(targettolearn)-1;
0495           idx = floor(targettolearn(idxvalid(1))):floor(targettolearn(idxvalid(end)));
0496           idx = idx(find(idx>0));
0497 
0498           % See explanation for motorupdate_* above
0499           if(~DIVA('BlockMode')),
0500             DIVA_MotorCortex_data.params.current.motorupdate_s=...
0501                 DIVA_MotorCortex_data.params.current.motorupdate_s+...
0502                 DIVA_MotorCortex_data.params.WeightLearn * ...
0503                 DIVA_MotorCortex_data.params.WeightLearn_somatosensory * ...
0504                 CommandFeedBack_somatosensory + sqrt(-1);
0505 
0506             % Update Motor Weights
0507             if(diff(floor(targettolearn))),
0508               idx = min(floor(targettolearn(find(targettolearn>0)))):max(ceil(targettolearn(find(targettolearn>0))));
0509               idx = idx(find(idx>0));
0510               if(diff(floor(targettolearn))<0)
0511                 idx = idx;
0512               else
0513                 idx = idx(find(idx<floor(targettolearn(end))));
0514               end
0515               DIVA_MotorCortex_data.params.WeightsFromTargets(:,idx)=...
0516                   DIVA_MotorCortex_data.params.WeightsFromTargets(:,idx)+...
0517                   repmat(real(DIVA_MotorCortex_data.params.current.motorupdate_s)./...
0518                          imag(DIVA_MotorCortex_data.params.current.motorupdate_s),...
0519                          1,length(idx));
0520               DIVA_MotorCortex_data.params.current.motorupdate_s=0;
0521             end
0522           else
0523             idx=unique(floor(targettolearn(find(targettolearn>0))));
0524             blockBound = diff(floor(targettolearn));
0525             for n=1:length(idx),
0526               if(blockBound(max(find(floor(targettolearn)==idx(n))))>0)                  
0527                 targetIdx = ...
0528                     idx(n):idx(n)+blockBound(max(find(floor(targettolearn)==idx(n))))-1;
0529               else
0530                 targetIdx = idx(n):idx(n)+1;
0531               end
0532               DIVA_MotorCortex_data.params.WeightsFromTargets(:,targetIdx) = ...
0533                   DIVA_MotorCortex_data.params.WeightsFromTargets(:,targetIdx) + ...
0534                   DIVA_MotorCortex_data.params.WeightLearn * ...
0535                   DIVA_MotorCortex_data.params.WeightLearn_somatosensory * ...
0536                   repmat(...
0537                       sum(CommandFeedBack_somatosensory(:,find(floor(targettolearn)==idx(n))),2) / ...
0538                       length(find(floor(targettolearn)==idx(n))),...
0539                       1,length(targetIdx));
0540             end
0541           end
0542         end
0543       end
0544     end
0545     DIVA_MotorCortex_data.params.current.error_sound=[];
0546     DIVA_MotorCortex_data.params.current.error_somatosensory=[];
0547     DIVA_MotorCortex_data.params.current.target=[];
0548 
0549   end
0550

Generated on Tue 27-Mar-2007 12:06:24 by m2html © 2003