# lolimotDemo5 Demo 5: Dynamic process of first order with 2 inputs and 2 outputs

    LoLiMoT - Nonlinear System Identification Toolbox
    Torsten Fischer, 20-October-2011
    Institute of Mechanics & Automatic Control, University of Siegen, Germany
    Copyright (c) 2012 by Prof. Dr.-Ing. Oliver Nelles

    % Initialise object
    LMN= lolimot;                   % Generate an empty net and data set structure

    % Create training data
    u1 = randn(300,1);
    u2 = sin(linspace(0,2*pi,300))';
    y1 = zeros(300,1);
    y2 = zeros(300,1);
    for k = 2:300
        y1(k) = atan(u1(k-1)) + atan(u2(k-1)) + 0.9*y1(k-1);
        y2(k) = u1(k-1).^2 + u1(k-1)*u2(k-1) + 0.7*y1(k-1) + 0.8*y2(k-1);
    end

    % Assign training data
    LMN.input = [u1 u2];
    LMN.output = [y1 y2];

    % Specify delays
    LMN.xInputDelay{1} = [1]; LMN.xInputDelay{2} = [1];        % Delayed inputs
    LMN.xOutputDelay{1} = [1]; LMN.xOutputDelay{2} = [1];      % Delayed outputs
    LMN.zInputDelay{1} = [1]; LMN.zInputDelay{2} = [1];        % Delayed inputs
    LMN.zOutputDelay{1} = [1]; LMN.zOutputDelay{2} = [1];      % Delayed outputs

    LMN.maxNumberOfLM = 10;         % Termination criterion for maximal number of LLMs
    LMN.minError = 0.02;            % Termination criterion for minimal error
    LMN.kStepPrediction = inf;      % Simulation not one-step-ahead prediction
    LMN.history.displayMode = true; % display information

    % Train net
    LMN = LMN.train;

    % Generalization
    u1G = randn(270,1);
    u2G = sin(linspace(0,2*pi,length(u1G)))';
    y1G = zeros(length(u1G),1);
    y2G = zeros(length(u1G),1);
    for k = 2:length(y1G)
        y1G(k) = atan(u1G(k-1)) + atan(u2G(k-1)) + 0.9*y1G(k-1);
        y2G(k) = u1G(k-1).^2 + u1G(k-1)*u2G(k-1) + 0.7*y1G(k-1) + 0.8*y2G(k-1);
    end
    uG = [u1G u2G];
    yG = [y1G y2G];

    % Simulate net
    yGModel = calculateModelOutput(LMN, uG, yG);
    JG = calcGlobalLossFunction(LMN ,yG, yGModel);

    figure
    subplot(1,2,1)
    LMN.plotModel([],1)
    subplot(1,2,2)
    LMN.plotModel([],2)

    Initial net has 1 local linear model(s): J = 0.104233.

    1. Iteration. Number of local linear models = 1. Checking for split of model 1 ...
       Testing split in dimension 1 with ratio 0.50: J = 0.073329.
       Testing split in dimension 2 with ratio 0.50: J = 0.080388.
       Testing split in dimension 3 with ratio 0.50: J = 0.088554.
       Testing split in dimension 4 with ratio 0.50: J = 0.088307.
    -> Splitting in dimension 1 with ratio 0.50: J = 0.073329 and penalty = 0.075400.

    2. Iteration. Number of local linear models = 2. Checking for split of model 2 ...
       Testing split in dimension 1 with ratio 0.50: J = 0.061569.
       Testing split in dimension 2 with ratio 0.50: J = 0.060225.
       Testing split in dimension 3 with ratio 0.50: J = 0.066203.
       Testing split in dimension 4 with ratio 0.50: J = 0.065393.
    -> Splitting in dimension 2 with ratio 0.50: J = 0.060225 and penalty = 0.062457.

    3. Iteration. Number of local linear models = 3. Checking for split of model 3 ...
       Testing split in dimension 1 with ratio 0.50: J = 0.056366.
       Testing split in dimension 2 with ratio 0.50: J = 0.054148.
       Testing split in dimension 3 with ratio 0.50: J = 0.056575.
       Testing split in dimension 4 with ratio 0.50: J = 0.056377.
    -> Splitting in dimension 2 with ratio 0.50: J = 0.054148 and penalty = 0.056579.

    4. Iteration. Number of local linear models = 4. Checking for split of model 4 ...
       Testing split in dimension 1 with ratio 0.50: J = 0.046467.
       Testing split in dimension 2 with ratio 0.50: J = 0.044515.
       Testing split in dimension 3 with ratio 0.50: J = 0.051451.
       Testing split in dimension 4 with ratio 0.50: J = 0.051450.
    -> Splitting in dimension 2 with ratio 0.50: J = 0.044515 and penalty = 0.046912.

    5. Iteration. Number of local linear models = 5. Checking for split of model 7 ...
       Testing split in dimension 1 with ratio 0.50: J = 0.043700.
       Testing split in dimension 2 with ratio 0.50: J = 0.042060.
       Testing split in dimension 3 with ratio 0.50: J = 0.043298.
       Testing split in dimension 4 with ratio 0.50: J = 0.042997.
    -> Splitting in dimension 2 with ratio 0.50: J = 0.042060 and penalty = 0.044637.

    6. Iteration. Number of local linear models = 6. Checking for split of model 8 ...
       Testing split in dimension 1 with ratio 0.50: J = 0.039049.
       Testing split in dimension 2 with ratio 0.50: J = 0.041475.
       Split in dimension 3 with ratio 0.50 is forbidden!
       Split in dimension 4 with ratio 0.50 is forbidden!
    -> Splitting in dimension 1 with ratio 0.50: J = 0.039049 and penalty = 0.041853.

    7. Iteration. Number of local linear models = 7. Checking for split of model 5 ...
       Testing split in dimension 1 with ratio 0.50: J = 0.036524.
       Testing split in dimension 2 with ratio 0.50: J = 0.036195.
       Testing split in dimension 3 with ratio 0.50: J = 0.037480.
       Testing split in dimension 4 with ratio 0.50: J = 0.037357.
    -> Splitting in dimension 2 with ratio 0.50: J = 0.036195 and penalty = 0.039142.

    8. Iteration. Number of local linear models = 8. Checking for split of model 6 ...
       Testing split in dimension 1 with ratio 0.50: J = 0.031300.
       Testing split in dimension 2 with ratio 0.50: J = 0.034120.
       Testing split in dimension 3 with ratio 0.50: J = 0.035770.
       Testing split in dimension 4 with ratio 0.50: J = 0.035936.
    -> Splitting in dimension 1 with ratio 0.50: J = 0.031300 and penalty = 0.034182.

    9. Iteration. Number of local linear models = 9. Checking for split of model 15 ...
       Testing split in dimension 1 with ratio 0.50: J = 0.028970.
       Testing split in dimension 2 with ratio 0.50: J = 0.031549.
       Split in dimension 3 with ratio 0.50 is forbidden!
       Split in dimension 4 with ratio 0.50 is forbidden!
    -> Splitting in dimension 1 with ratio 0.50: J = 0.028970 and penalty = 0.031911.

    Maximum number of local models reached.

    Final net has 10 local models and 100 parameters: J = 0.028970

    Net 10 with 10 LMs and 100 parameters is suggested as the model with the best complexity trade-off.