Method of mss.
Linear state transformation of an eMTI model in CPN1 format.
Source: src/model/@mss/mss2mss.m
sys_t = mss2mss(sys, T) % transformation (scaling and/or permutation)
sys_t = mss2mss(sys, T, c) % transformation and absolute offset
sys_t = mss2mss(sys, [], c) % offset only
sys_t = mss2mss(sys, [], [], permutation) % permutation only
sys_t = mss2mss(sys, T, transformIndex=[1, 3]) % transformation
% of only rows 1 and 3
sys_t = mss2mss(sys, T, c, permutation, outputMtiBase=1) % scaling, offset,
% permutation and output in literal base (base change if input monomial)
sys_t = mss2mss(sys, outputMtiBase=0) % output in monomial basemss2mss applies an affine transformation to (some of)
the state variables and/or the inputs of an explicit MTI model in CPN1
format while preserving the modelβs output behaviour. It is commonly
used to normalize or rescale states and inputs, reorder variables, or
change the internal MTI base representation.
The transformation is defined as
or equivalently,
where are the transformed variables, are the original variables, is the transformation matrix, and is the offset vector.
Currently only affine transformations consisting of scaling, permutations, and offsets are supported, i.e.Β the transformation matrix must contain exactly one non-zero entry in each row and column.
For discrete-time systems (timeStepSize > 0), the
transformed dynamics become
while continuous-time systems (timeStepSize == 0) are
transformed as
The output equations (for both continuous-time and discrete-time systems) are transformed as
The offset term appears only in the discrete-time state equation because constant offsets vanish under differentiation in continuous time. When , both formulations reduce to pure scaling.
This function can be used together with normalize for
scaling states and inputs to prescribed ranges.
| Argument | Type | Description |
|---|---|---|
mtiSystem |
mss |
Required argument. eMTI model with CPN1 tensor. |
transformation |
double vector or matrix | Optional positional argument, defaults to [] (no
transformation). If not empty, may be a square matrix or a vector
interpreted as its diagonal. Must correspond to the variables specified
by transformIndex. Only scaling and permutations are
supported. A vector or diagonal matrix result in scaling. |
offset |
double vector | Optional positional argument, defaults to [] (no
offset). If not empty, must match the dimensions of
transformation. |
permutation |
integer vector | Optional positional argument, defaults to [] (no
permutation). If not empty, must match dimensions of
transformation. Defines the reordering of variables in the
sense newStates = oldStates(permutation). May be combined
with scaling, but cannot be used together with a non-diagonal
transformation matrix. |
transformIndex |
integer vector (name-value) | Optional name-value argument, defaults to stateIndex
(in given order) if the length of transformation is
nState; or to [stateIndex, inputIndex] (in
this order!) if the length of transformation is
nState + nInput. Indicates rows of the
structureMatrix to transform. |
outputMtiBase |
boolean or integer (name-value) | Optional name-value argument, defaults to [] (preserve
current base). Output MTI base: 0 = false =
monomial, 1 = true = literal. |
Notes:
Scaling is applied before permutation,
i.e.Β transformation, offset,
transformIndex must refer to the old ordering of states and
inputs. Caveat: if transformIndex is given (e.g.Β such that
only state3 and state1 are transformed),
permutation must refer to indices of states in
oldStates(transformIndex) rather than in
oldStates directly (e.g.Β if we want to flip
state3 and state1 in the above example,
permutation would need to be [2; 1] instead of
[3; 1] because transformIndex is
[1; 3]. Or equivalently,
permutation = [3; 2; 1] and
transformIndex = [1; 2; 3].
Permutation with the permutation argument or with a
non-diagonal transformation matrix is equivalent,
permutation is the first output of a find()
call on transformation in the latter case.
transformIndex explicitly refers to rows in
structureMatrix and not to elements in the state vector and
input vector. Use it in combination with stateIndex and
inputIndex if needed. E.g. to transform the 2nd and 3rd
state (as given in stateNames) and the 2nd input (in
inputNames),
transformIndex = [stateIndex([2,3]), inputIndex([2])].
| Argument | Type | Description |
|---|---|---|
mtiSystemTransformed |
mss |
Transformed MTI model. |
Scale the states of an MTI model using normalize and
mss2mss:
clc;
clear all;
% build multilinear model, 2 states, 1 input, 2 outputs (same as states)
structureMatrix = [[0.83, -0.1, 1, 0]; ... % state 1
[0, 0.53, 0, 1]; ... % state 2
[1, -0.1, 0, 0]]; % input
parameterMatrix = [[0, 0, 1, 0]; ... % output 1 (= state 1)
[0, 0, 0, 1]; ... % ouput 2 (= state 2)
[1.0080, 0, 0, 0]; ... % state derivative 1
[0, 1.50, 0, 0]]; % state derivative 2
u = [zeros(20, 1); ones(20, 1); -ones(20, 1)]; % input signal
t = 1:1:60; % time vector
Ts = 1; % sampling time (discrete)
stateIndex = [1, 2]; % rows in structureMatrix
inputIndex = [3]; % rows in structureMatrix
stateEquationIndex = [3, 4]; % rows in parameterMatrix
outputEquationIndex = [1, 2]; % rows in parameterMatrix
modelTensor = CPNTensor(structureMatrix, parameterMatrix);
obj = mss(modelTensor, stateIndex, inputIndex, Ts, stateEquationIndex, ...
outputEquationIndex); % build mti model object
obj.stateName = ["state1", "state2"]; % label states with names
obj.inputName = ["input1"]; % label inputs
obj.outputName = ["output1", "output2"]; % label outputs
% simulate MTI model
x0 = [0; 0]; % initial state
[y, ~, xsim] = msim(obj, u, t, x0); % simulated output & state
% scale state btw. lower and upper bound and compute transformation
[xsc, c, T] = normalize(xsim, "range", [0, 1]);
% transform the model
msys = mss2mss(obj, T, c);
% simulate the transformed model with scaled initial state
[ysc, ~, xsimsc] = msim(msys, u, t, xsc(1, :));
% plot results
figure() % plot original mti model
sgtitle('original MTI model')
subplot(3, 1, 1)
plot(u)
xlim([min(t), max(t)])
xlabel('time')
legend(obj.inputName)
subplot(3, 1, 2)
plot(xsim)
xlim([min(t), max(t)])
xlabel('time')
legend(obj.stateName)
subplot(3, 1, 3)
plot(y)
xlim([min(t), max(t)])
xlabel('time')
legend(obj.outputName)
figure() % plot scaled mti model
sgtitle('MTI model with scaled states')
subplot(3,1,1)
plot(u)
xlim([min(t), max(t)])
xlabel('time')
legend(msys.inputName)
subplot(3,1,2)
plot(xsimsc)
xlim([min(t), max(t)])
xlabel('time')
legend(msys.stateName)
subplot(3,1,3)
plot(ysc)
xlim([min(t), max(t)])
xlabel('time')
legend(msys.outputName)

Scale both states and inputs, and permute states 1 and 2, and ouput in literal base:
% use the same steps as above to build and simulate the original model
% add additional input scaling and state permutation
[xsc2, cx, Tx] = normalize(xsim, "range", [0, 1]);
[usc2, cu, Tu] = normalize(u, "range", [0, 1]);
T2 = [Tx, Tu];
c2 = [cx, cu];
permutation = [2, 1, 3];
% transform the model
msys2 = mss2mss(obj, T2, c2, permutation, outputMtiBase=1);
% simulate the transformed model with scaled and permuted initial state
[ysc2, tOut, xsimsc2] = ...
msim(msys2, usc2, t, xsc2(1, permutation(stateIndex)));
figure() % plot transformed model
sgtitle('MTI model, literal base, scaled input & states, permuted states')
subplot(3, 1, 1)
plot(usc2)
xlim([min(t), max(t)])
xlabel('time')
legend(msys2.inputName)
subplot(3, 1, 2)
plot(xsimsc2)
xlim([min(t), max(t)])
xlabel('time')
legend(msys2.stateName)
subplot(3, 1, 3)
plot(ysc2)
xlim([min(t), max(t)])
xlabel('time')
legend(msys2.outputName)
MyToolbox Documentation | Generated automatically by CI/CD pipeline