How to use a matrix as input for NLARX

Based on the text (see below in italic) for NLARX I would like to use a matrix to provide the u en y (input/output).
Comma-Separated Matrix Pair
Specify data as a comma-separated pair of real-valued matrices that contain input and output time-domain signal values. When you specify matrix-based data, the software assumes a sample time of 1 second. You can change the sample time after estimation by setting the property sys.Ts.
  • For SISO systems, specify data as a pair of Ns-element numeric column vectors that contain uniformly sampled input and output time-domain signal values. Here, Ns is the number of samples.
  • For MIMO systems, specify u,y as an input/output matrix pair with the following dimensions:
  • u — Ns-by-Nu, where Nu is the number of inputs.
  • y — Ns-by-Ny, where Ny is the number of outputs.
For multiexperiment data, specify data as a pair of Ne-by-1 cell arrays of matrices, where Ne is the number of experiments. The sample times of all the experiments must match.Single Matrix
Specify data as a single real-valued matrix with Ny+Nu columns that contain the output signal values followed by the input signal values. Note that this order is the opposite of the order used for the comma-separated matrix pair form of data. When you specify matrix-based data, the software assumes a sample time of 1 second. You can change the sample time after estimation by setting the property sys.Ts.
Also I want the matrix built up such that each line has a many inputs/outputs as the orders given in teh NLARX.
So in principal I have a x amount of meausurements (number of lines in the matrix) and the number input and output(columns) is equal to the orders
I have written a small code to test this but I get an error message.
Code:
Input_A = (1:5); Output_B = (5:-1:1);
Data = [Output_B Input_A];
Total_Data = [Data; Data];
for counter = 1:50
Total_Data = [Total_Data; Data];
end
sys_1 = nlarx(Total_Data,[5 5 1]);
Error:
>> sys_1 = nlarx(Total_Data,[5 5 0]);
Error using nlarx (line 409)
The number of inputs and outputs of the model must match that of the data.

 Accepted Answer

I think this line in the Comma-Separated Matrix Pair description is the issue: "specify data as a pair of Ns-element numeric column vectors"
You have specified your Input_A and Output_B as row vectors. I think if you make them column vectors, the error is resolved.
Input_A = (1:5)'; % Transpose so this is a column vector
Output_B = (5:-1:1)'; % Transpose so this is a column vector
Data = [Output_B Input_A];
Total_Data = [Data; Data];
for counter = 1:50
Total_Data = [Total_Data; Data];
end
sys_1 = nlarx(Total_Data,[5 5 1])
sys_1 = Nonlinear ARX model with 1 output and 1 input Inputs: u1 Outputs: y1 Regressors: Linear regressors in variables y1, u1 Output function: Wavelet network with 11 units Sample time: 1 seconds Status: Estimated using NLARX on time domain data "Total_Data". Fit to estimation data: 100% (prediction focus) FPE: 9.651e-21, MSE: 8.348e-21 More information in model's "Report" property.

11 Comments

Thank you Cris for your answer,
What I see now is that is that the Total_Data is sequentlial. So I get 5*50 data points.
If I then use:
figure(); compare(Total_Data, sys_1, 2);
I get a graph with 250+ datapoints.
But what I am looking for is: that I have 50 (or any other number) of different measurements.
Each measurement consist of 5 input and 5 output (or any other number).
Then I want to train the NLARX with 50 different measurements.
That is why I was looking at:
For multiexperiment data, specify data as a pair of Ne-by-1 cell arrays of matrices, where Ne is the number of experiments. The sample times of all the experiments must match.Single Matrix
Can you help me with this?
Many thanks.
Leon
I thought the based on the Single Matrix is should look something like:
Sample 1, y1(t-1), y1(t-2), y1(t-3) y1(t-4), y1(t-5), u1(t-1), u1(t-2), u1(t-3), u1(t-4), u1(t-5)
Sample 2, y1(t-1), y1(t-2), y1(t-3) y1(t-4), y1(t-5), u1(t-1), u1(t-2), u1(t-3), u1(t-4), u1(t-5)
Sample 3, y1(t-1), y1(t-2), y1(t-3) y1(t-4), y1(t-5), u1(t-1), u1(t-2), u1(t-3), u1(t-4), u1(t-5)
Sample 4, y1(t-1), y1(t-2), y1(t-3) y1(t-4), y1(t-5), u1(t-1), u1(t-2), u1(t-3), u1(t-4), u1(t-5)
etc.
My read of the documentation is that you need to create 2 cell arrays, one for inputs, and one for outputs. Each cell should contain the corresponsing matrix of samples.
I did have to reduce the orders to avoid getting an error, likely because each experiement only contains 5 data points.
Input_A = (1:5)'; % Transpose so this is a column vector
Output_B = (5:-1:1)'; % Transpose so this is a column vector
% Add each experiment to a row in the corresponding cell array
for counter = 1:50
Output_Data{counter,1} = Output_B;
Input_Data{counter,1} = Input_A;
end
% Call nlarx with a pair of Ne-by-1 cell arrays of matrices
sys_2 = nlarx(Output_Data, Input_Data,[2 2 1])
sys_2 = Nonlinear ARX model with 1 output and 1 input Inputs: u1 Outputs: y1 Regressors: Linear regressors in variables y1, u1 Output function: Wavelet network with 1 units Sample time: 1 seconds Status: Estimated using NLARX on time domain data "Output_Data". Fit to estimation data: [100 100 100 100 100 100 100 100 100 100....% (prediction focus) FPE: 0, MSE: [0 0 0 0 0 0 0 0 0 0... More information in model's "Report" property.
Hello Cris,
Again thanks for your answer.
However I get an error message when I try to run your code on my computer:
>> sys_2 = nlarx(Output_Data, Input_Data,[2 2 1]);
Error using nlarx (line 148)
The first input argument of the "nlarx" command must be an IDDATA object.
Could it be something with the version I am using?:
System Identification Toolbox Version 9.13 (R2020b)
I believe this is because you are using an older version of MATLAB. At the bottom of the nlarx doc page, you can see in the Version History that the ability to use matrices was added in R2022b (see here).
You appear to be using R2020b.
In R2020b, the Data input must be an iddata object (see here).
Hello Cris,
Thanks for al support I will see how I can resolve this. Most likely updating Matlab.
Best wishes
Leon
If you have access to MATLAB Online, you might try your code there. It is always running the latest version of MATLAB.
Hello Cris,
Thanks for your suggestion with MATLAB Online. I downloaded a trial version for 2023a to test the program.
I still have a challenge, when I put order at 5 (equal to the number of input and output).
I get the following error:
>> sys_2 = nlarx(Output_Data, Input_Data,[5 5 1]);
Error using nlarx
The regressor set is empty. Model cannot be estimated.
In your example you use 2 as order.
The reason way I want to have the order equal to the number of input/ouput because I have X amount of samples/experiments with 5 inputs and 5 outputs. The end of each input/output might be a little bit different/unique for each sample/experiment. By having the order equal to the input/ouput should overcome this.
The idea that this way the NLARX/sys is trained with each unique sample/experiment. Taken in account the small differences at the end of each experiment.
Do you have any suggestion or other technique I can use ?
Thanks again for your support
Best wishes
Leon
Hi Leon,
What is the datatype of Output_Data, Input_Data input arguments? Are they double matrices? What are their sizes (number of rows and columns)?
Rajiv
Hello Rajiv,
Each sample has 15 inputs and 15 outputs. The data are real numbers.
The input and output are rows of each 15 items.
The big issue is that the end of the each output is a little different for each sample.
Therefore I had the idea the run each individual sample through teh NLARX to train.
Hope this info helps, if you have any questions please let me know
Best wishes
Leon
15 inputs and 15 output channels can be difficult to model using a single system. I would suggest looking closely at the dynamics to see if some channels can be removed (using PLCA, PLS etc). Another thing to try would be to create a separate model for each output.
That said, the easiest way to crate regressors would be using commands such as linearRegressor, polynomialRegressor, etc.
Example:
uvars = "u"+(1:15);
yvars = "y"+(1:15);
R1 = linearRegressor([uvars, yvars],1:3)
R2 = polynomialRegressor(uvars,1:2:7,2,false,true)
R3 = polynomialRegressor(yvars(1:4),1:3,3)
etc.
model = idnlarx(yvars,uvars,[R1;R2;R3],idSigmoidNetwork)
model2 = nlarx(udata, ydata, model)
If you want to use an order matrix to generate the (linear) regressors, please look at the right syntax to use on the idnlarx, or nlarx reference page. Basically, order matrix has the form N = [na nb nk], where na is Ny-by-Ny matrix, and nb/nk are Ny-by-Nu matrices (where Ny denotes the number of outputs, and Nu denotes the number of inputs).
If you run into any errors, please post reproduction steps.
Rajiv

Sign in to comment.

More Answers (0)

Products

Release

R2020b

Tags

Asked:

on 3 Apr 2023

Commented:

on 10 Apr 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!