Identify a multilinear time-invariant (MTI) state-space model from measured data.
Source: src/mlgreyest.m
mlgreyest(data,r,structuralRestrictions,mtiBase,options)
fits a discrete-time explicit multilinear time-invariant (eMTI)
model
to measured data. The model parameters are stored in structure matrices , and in the parameter matrices .
The identification result is returned as an mss object where the
mtiTensor is a CPNTensor. If the
model base
is not passed explicitly to mlgreyest, the default
mtiBase of the returned model is the monomial base
().
In an mss, the CPNTensor is stored as
one structure matrix
is
and one parameter matrix
is
for the whole model, such that
.
Calling mlgreyest without any Name-Value options (default) will identify values
for
and/or
from measured states.
State-trajectory mode (default). data.y
is the measured state trajectory, so the model order equals the
number of measured channels and the initial state is
data.y(1,:). Only a state equation is identified.
Focus selects whether the freely simulated trajectory
("simulation") or the one-step-ahead prediction from the
measured states ("prediction") is fitted.
Output-identification mode
(idFromOutputs=true). data.y are
output measurements and the state is hidden: it is simulated forward
from InitialState, whose length defines the state
dimension. A state equation and an output equation are
identified. Only the nonlinear methods support this mode, and only
Focus="simulation" β without measured states there is
nothing to predict from, so a different Focus is overridden
with a warning.
Two different things are accepted in the third position as
structuralRestrictions.
A numeric or logical matrix is a completely known structure matrix . Only the parameters in are then computed.
A CPNTensor
restricts the nonlinear, output-identification path per element (only
for the identification of a literal-base model). Its six split channels
are read as follows:
| Channel of the restriction tensor | Effect on that entry |
|---|---|
structureMatrixTrue |
free, bounded to |
structureMatrixFalse |
free, bounded to |
structureMatrixContinuous |
free, bounded to
[options.lowerBoundS, options.upperBoundS] |
| structure entry in no channel | fixed at (literal base neutral element) |
parameterMatrixOne / MinusOne /
Continuous |
free, bounded to [lowerBoundPhi, upperBoundPhi] |
| parameter entry in no channel | fixed at |
| Syntax |
|---|
[sys,J] = mlgreyest(data,r) returns a monomial
base mss with identified
values for
and
from measured states using an ALS algorithm. r defines the
number of columns of
and
. |
[sys,J] = mlgreyest(data,[],structuralRestrictions)
with structuralRestrictions provided as a numeric / logical
structureMatrix returns a monomial base mss with
structuralRestrictions
and identified values for
from measured states. |
[sys,J] = mlgreyest(data,r,[],mtiBase) returns an
mss in the specified
mtiBase with identified values for
and
from measured states using an ALS algorithm. |
[sys,J] = mlgreyest(data,r,[],mtiBase,'Method',"lsqnonlin")
returns an mss in the
specified mtiBase with identified values for
and
from measured states using lsqnonlin. |
[sys,J] = mlgreyest(data,r,[],mtiBase,'Method',"lsqnonlin",'idFromOutputs',true,'InitialState',x0,...)
returns anmss in the
specified mtiBase with identified values for
and
from measured outputs and an initial state x0 using
lsqnonlin. |
[sys,J,x0Est] = mlgreyest(data,[],structuralRestrictions,true,'Method',"lsqnonlin",'idFromOutputs',true,'InitialState',x0,'estimateInitialState',true,...)
returns a literal base mss
in the specified mtiBase which together with
x0Est approximates the input-output given by
data. The identified values for
and
lie within the bounds provided through the CPNTensor provided as
structuralRestrictions. |
dataiddatadata.u holds the inputs, data.y the measured
states (default) or the measured outputs
(options.idFromOutputs=true). The ALS requires more than
2*r samples.rscalar,
[rStateEq rOutputEq], or []structuralRestrictions[] (default), numeric/logical
matrix, or CPNTensorCPNTensor
requires mtiBase = true,
options.idFromOutputs = true and a nonlinear
options.Method.mtiBaselogicalfalse0 selects the monomial
base, 1 the literal base.optionsSolver
| Option | Type | Default | Description |
|---|---|---|---|
Method |
string | "als" |
"als", or the nonlinear solvers
"lsqnonlin" or "fmincon". ALS is
state-trajectory only. |
Focus |
string | "simulation" |
"simulation" or "prediction"; overridden
to "simulation" in output mode. |
Display |
string | "off" |
"on"/"off" for ALS; any
optimoptions value ("iter",
"final", β¦) for the nonlinear methods. |
Nonnegative |
logical | false |
only relevant in combination with Method="als":
identification returns nonnegative
and
. |
UseParallel |
logical | false |
Nonlinear solvers only. |
Initialization and stopping
| Option | Type | Default | Description |
|---|---|---|---|
Initialize |
string / CPNTensor |
"random" |
"random", "zero", only in combination with
nonlinear solvers: "ga", or a CPNTensor. |
MaxIterations |
double | 400 |
ALS sweeps, or nonlinear solver iterations. |
AlsTolerance |
double | 0.1 |
ALS: stop once the cost drops below it. |
MaxInitialization |
int16 | 5 |
ALS: how often a stalled random start may be redrawn. |
ToleranceInitialization |
double | 0.5 |
ALS: restart a stalled run only while the cost is still above this. |
MaxFunctionEvaluations |
double | 100000 |
Nonlinear solvers only. |
OptimalityTolerance |
double | 1e-6 |
Nonlinear solvers only. |
Bounds (nonlinear methods)
| Option | Type | Default | Description |
|---|---|---|---|
lowerBoundS / upperBoundS |
double | -1 / 1 |
Bounds on the structure matrix entries. |
lowerBoundPhi / upperBoundPhi |
double | -10 / 10 |
Bounds on the parameter entries. |
Output identification (Nonlinear solvers only)
| Option | Type | Default | Description |
|---|---|---|---|
idFromOutputs |
logical | false |
true: data.y are outputs, the state is
hidden. |
InitialState |
double | [] |
Initial state x0; its length defines the state
dimension. |
estimateInitialState |
logical | false |
true: fit x0 jointly,
InitialState being only its guess. |
columnIndexStateEq |
double | [] |
Structure-matrix columns of the state equation. |
columnIndexOutputEq |
double | [] |
Structure-matrix columns of the output equation. |
sysmssr, because trivialReduction
is called internally after the identification.Jvector (ALS) or
scalar (nonlinear)J(end) is the final one
and plot(J) shows the convergence; the nonlinear methods
return the solverβs final cost.x0Estcolumn vector or
[]estimateInitialState=true it is the value the solver found;
otherwise it echoes InitialState, and in state-trajectory
mode the first measured sample.The examples below generate their own data with msim, so they can be run
as they stand (the iddata constructor needs the System
Identification Toolbox).
% a rank-2 monomial model, 2 states and 1 input
S = [0.6 0.2; % x1
0.3 0.9; % x2
0.4 0.1]; % u1
P = [0.5 0.2; % x1(k+1)
0.1 0.4]; % x2(k+1)
sys0 = mss(S,P,[1 2],3,1,[1 2],[],'mtiBase',false);
t = (0:59)';
u = 0.5 + 0.4*sin(t/3);
[~,~,x] = sys0.msim(u,t,[0.3 0.6]);
data = iddata(x,u,1); % measured STATE trajectory
[sys,J] = mlgreyest(data,2,[],false,'Method',"als",'Display',"off");
fprintf('final cost %.3e\n', J(end));Add 'Nonnegative',true to keep every identified value
non-negative (each subproblem is then solved with
lsqnonneg), or 'Focus',"prediction" to fit the
one-step-ahead prediction instead of the free simulation.
sys = mlgreyest(data,[],S); % S from the example above[sys,J] = mlgreyest(data,2,[],true,'Method',"als",'Initialize',"random");% state equation on columns 1-2, output equation on columns 3-4
S = [ 1.0 0.0 0.6 1.0 ; % x1
0.0 1.0 1.0 0.0 ; % x2
0.4 -0.3 0.0 0.2 ]; % u1
P = [ 0.7 0.2 0 0 ; % x1(k+1)
0.3 0.5 0 0 ; % x2(k+1)
0 0 1.5 0.5 ; % y1
0 0 0.8 1.2 ]; % y2
sys0 = mss(S,P,[1 2],3,1,[1 2],[3 4],'mtiBase',true);
t = (0:59)';
u = 0.5 + 0.4*sin(t/3);
x0 = [0.3; 0.6];
y = sys0.msim(u,t,x0');
data = iddata(y,u,1); % measured OUTPUTS, state hidden
[sys,J,x0Est] = mlgreyest(data,[2 2],[],true, ...
'Method',"lsqnonlin",'idFromOutputs',true,'InitialState',x0, ...
'Display',"off",'MaxIterations',80,'MaxFunctionEvaluations',5000);r = [2 2] requests disjoint column blocks. Use a scalar
r to let both equations share the same columns, or name the
columns explicitly:
[sys,J] = mlgreyest(data,[],[],true, ...
'Method',"lsqnonlin",'idFromOutputs',true,'InitialState',x0, ...
'columnIndexStateEq',[1 2],'columnIndexOutputEq',[2 3 4]); % may overlaprestriction = sys0.mtiTensor; % same size as the model to be identified
[sys,J,x0Est] = mlgreyest(data,[],restriction,true, ...
'Method',"lsqnonlin",'idFromOutputs',true,'InitialState',x0, ...
'Focus',"simulation",'Display',"off",'MaxFunctionEvaluations',20000);The tensor is also the warm start, so a restriction tensor that already carries good values converges in very few iterations.
To warm-start from different values on the same
free-variable layout, pass a second tensor of the same size as
Initialize:
perturbedTensor = copy(sys0.mtiTensor);
perturbedTensor.structureMatrixContinuous(perturbedTensor.structureMatrixContinuous>0)=0.8;
[sys,J] = mlgreyest(data,[],restriction,true, ...
'Method',"lsqnonlin",'idFromOutputs',true,'InitialState',x0, ...
'Initialize',perturbedTensor, 'Display', 'iter');βA CPNTensor Initialize inherits every
restriction of the restriction tensorβ It supplies only values;
which entries are free is decided by the CPNTensor
structural restrictions, which it therefore
requires.
guess = [0.4; 0.4]; % only a guess now
[sys,J,x0Est] = mlgreyest(data,[],restriction,true, ...
'Method',"lsqnonlin",'idFromOutputs',true,'InitialState',guess, ...
'estimateInitialState',true,'MaxFunctionEvaluations',20000);The initial state becomes an extra block of optimization variables,
bounded to
,
and is returned as x0Est.
x0 is generally not identifiable
by itself. With a hidden state and factors that are affine in
,
the model admits an affine state reparameterization: only the
inputβoutput map is pinned down, so a jointly estimated
x0Est need not approach the true initial state even when
the fit is excellent. Judge the result by the output fit, not by
x0Est β unless the restrictions remove the symmetry.r, because trivialReduction merges
duplicate monomial columns and drops unused ones.mss β the identified
model classmsim β simulate
the resultCPNTensor β the
tensor representation and the restriction formatMyToolbox Documentation | Generated automatically by CI/CD pipeline