function[data,learning,success,error,modpred]= GeneralizationModel(T,x,g,tt,noise)
    % x(1): learning fast
    % x(2): retention fast
    % x(3): learning slow
    % x(4): retention slow
    
    w.fast = zeros(size(g,1),T.nTrials);                                    % weights fast process
    w.slow = zeros(size(g,1),T.nTrials);                                    % weights slow process
    error = zeros(T.nTrials,1);                                             % error per trial
    learning.total = zeros(T.nTrials-1,1);                                  % total learning 
    learning.fast = zeros(T.nTrials-1,1);                                   % fast learning 
    learning.slow = zeros(T.nTrials-1,1);                                   % slow learning 
    theta_actual  = zeros(T.nTrials-1,1);                                   % true movement angle
    data = zeros(T.nTrials-1,1);                                            % data: to create data with noise

    
    for t = 1:T.nTrials-1
        learning.fast(t) = w.fast(:,t)' * g(:,T.theta_planned(t));          % learning of the fast process corresponds to the weights * motor primitives of the planned theta
        learning.slow(t) = w.slow(:,t)' * g(:,T.theta_planned(t));          % same for slow learning
        learning.total(t) = learning.fast(t)+learning.slow(t);              % total is the sum of both;
        

        %disp(t);
        error(t) = T.Fext(t) - learning.total(t);
       
        
        if abs(error(t)) < 3                                               % making sure the error cannot run to extreme values
            
             theta_actual(t) =  wrapTo360(round(T.UpdateAngle(t)));
             % index of 0 is not possible
             if theta_actual(t) == 0
                 theta_actual(t) = 360;
             end
             if sum(T.trialtype(t) == tt.ff) == 1
                 % learning trials 
                 w.fast(:,t+1) = x(2)*w.fast(:,t)+ error(t)*x(1)*g(:,theta_actual(t))/(sum(g(:,theta_actual(t))));
                 w.slow(:,t+1) = x(4)*w.slow(:,t)+ error(t)*x(3)*g(:,theta_actual(t))/(sum(g(:,theta_actual(t))));
             else
                 % clamp trials
                 w.fast(:,t+1) = x(2)*w.fast(:,t);
                 w.slow(:,t+1) = x(4)*w.slow(:,t);
                 error(t) = 0;
             end
            % data: only used for recovery analysis to add noise to the
            % model predictions
            data(t) = learning.total(t)+noise*randn;
            success = 1;                     
        else 
            disp('theta actual outside bounderies');
            disp([max(abs(error)),x]);
            success = 0;
            break;
        end
        modpred.fast_t(t,:) = w.fast(:,t)' * g;
        modpred.slow_t(t,:) = w.slow(:,t)' * g;
        modpred.total_t(t,:) =w.fast(:,t)' * g+ w.slow(:,t)' * g;
    end
    