({{, (RefLink[SystemModelLinearize, paclet:ref/SystemModelLinearize])[model] 
gives a linearized (RefLink[StateSpaceModel, paclet:ref/StateSpaceModel]) for model at an equilibrium. }, {, (RefLink[SystemModelLinearize, paclet:ref/SystemModelLinearize])[model,op]
linearizes at the operating point op.}})

OpenersNotesSection(Spacer1)Details and Options

(RefLink[SystemModelLinearize, paclet:ref/SystemModelLinearize]) gives a linear approximation of model near an operating point.

A linear model is typically used for control design, optimization and frequency analysis.

A system with equations 0==f(x'(t),x(t),u(t)) and output equations y(t)==g(x(t),u(t)) is linearized at an operating point (Subscript[x, 0]) and (Subscript[u, 0]) that should satisfy f(0,(Subscript[x, 0]),(Subscript[u, 0]))==0.

The returned linear (RefLink[StateSpaceModel, paclet:ref/StateSpaceModel]) has state (OverTilde[x])(t)==x(t)-(Subscript[x, 0]), input (OverTilde[u])(t)==u(t)-(Subscript[u, 0]) and output (OverTilde[y])(t)==(Subscript[y, lin])(t)-g((Subscript[x, 0]),(Subscript[u, 0])), with state equations e.(OverTilde[x])'(t)==a.(OverTilde[x])(t)+b.(OverTilde[u])(t) and output equation (OverTilde[y])(t)==c.(OverTilde[x])(t)+d.(OverTilde[u])(t). The matrices are given by a==((∂f(x',x,u))/(∂x)), b==((∂f(x',x,u))/(∂u)), c==((∂g(x,u))/(∂x)), d==((∂g(x,u))/(∂u)) and e==-((∂f(x',x,u))/(∂x')), all evaluated at x'==0, x==(Subscript[x, 0]) and u==(Subscript[u, 0]).

(RefLink[SystemModelLinearize, paclet:ref/SystemModelLinearize])[model] is equivalent to (RefLink[SystemModelLinearize, paclet:ref/SystemModelLinearize])[model,"EquilibriumValues"].

Specifications for op use the following values for the operating point:

The simulation sim can be obtained using (RefLink[SystemModelSimulate, paclet:ref/SystemModelSimulate])[model,(RefLink[All, paclet:ref/All]),…].

(RefLink[SystemModelLinearize, paclet:ref/SystemModelLinearize]) linearizes a system of DAEs symbolically, or first reduces it to a system of ODEs and linearizes the resulting ODEs numerically.

The following options can be given:

The option (RefLink[Method, paclet:ref/Method]) has the following possible settings:

OpenersPrimaryExamplesSection(Spacer1)Examples  (45)

OpenersExampleSection0(Spacer1)Basic Examples  (3)

Linearize a DC-motor model around an equilibrium:

SystemModelLinearize[]

Linearize a mixing tank model around equilibrium with given state and input constraints:

SystemModelLinearize[,{{{"H",0.75}},{{"u1",5.23}}}]

Linearize one of the included (WebLink[introductory hierarchical, http://reference.wolfram.com/system-modeler/libraries/IntroductoryExamples/IntroductoryExamples.Hierarchical.html]) examples:

model=Last@SystemModelExamples["Models","IntroductoryExamples.Hierarchical.*"]

SystemModelLinearize[model]

OpenersExampleSection1(Spacer1)Scope  (19)

OpenersExampleSubsection0(Spacer1)Model Types  (5)

Linearize a textual RLC circuit model:

SystemModelLinearize[]

Linearize an RLC circuit block diagram model:

SystemModelLinearize[]

Linearize an acausal RLC circuit:

SystemModelLinearize[]

Linearize a DAE model:

SystemModelLinearize[]

Linearize a DAE model symbolically:

SystemModelLinearize[,Method->{"SymbolicDerivative","SymbolicParameters"->{"R1","R2","L"}}]

OpenersExampleSubsection1(Spacer1)Limiting Cases  (3)

Linearize a model without inputs:

SystemModelLinearize[]

Linearize a model without states:

SystemModelLinearize[]

Linearize a model without outputs:

SystemModelLinearize[]

OpenersExampleSubsection2(Spacer1)Linearization Values  (5)

Linearize around an equilibrium:

SystemModelLinearize[,"EquilibriumValues"]

Linearize around initial values:

SystemModelLinearize[,"InitialValues"]

Linearize around equilibrium with given state and input constraints:

SystemModelLinearize[,{{{"H1",2.03},{"T1",45},{"T2",45}},{{"u1",5},{"u2",5}}},"EquilibriumValues"]

Linearize around equilibrium with state constraints:

SystemModelLinearize[,{{{"H1",5},{"T1",45},{"T2",45}},{}},"EquilibriumValues"]

Linearize around given partial states and inputs, using initial values for remaining values:

SystemModelLinearize[,{{{"H1",3.03},{"T1",45},{"T2",45}},{{"u1",5},{"u2",5}}},"InitialValues"]

OpenersExampleSubsection3(Spacer1)Operating Point  (6)

Linearize around an equilibrium:

SystemModelLinearize[,"EquilibriumValues"]

Linearize around initial values:

SystemModelLinearize[,"InitialValues"]

Linearize around equilibrium with given state and input constraints:

SystemModelLinearize[,{{{"H1",2.03},{"T1",45},{"T2",45}},{{"u1",5},{"u2",5}}},"EquilibriumValues"]

Linearize around initial values from a simulation:

sim=SystemModelSimulate[,All,{0,0}]

SystemModelLinearize[,{sim,"StartTime"}]

Linearize around final values from a simulation:

sim=SystemModelSimulate[,All]

SystemModelLinearize[,{sim,"StopTime"}]

Linearize around final values from a simulation run to steady state:

sim=SystemModelSimulate[,All,Method->{"StopAtSteadyState"->True}]

SystemModelLinearize[,{sim,"StopTime"}]

OpenersExampleSection2(Spacer1)Generalizations & Extensions  (1)

Hide labels in the resulting (RefLink[StateSpaceModel, paclet:ref/StateSpaceModel]):

SystemModelLinearize[,SystemsModelLabels->None]

OpenersExampleSection3(Spacer1)Options  (3)

OpenersExampleSubsection4(Spacer1)Method  (3)

The "SymbolicDerivative" method uses a fully specified operating point from a simulation:

sim=SystemModelSimulate[,All,{0,0}]

SystemModelLinearize[,sim,Method->"SymbolicDerivative"]

The "NumericDerivative" method uses an operating point specified by state and input values:

SystemModelLinearize[,{{{"capacitor.v",0.`},{"inductor.i",0.`}},{{"v",0.`}}},Method->"NumericDerivative"]

Linearizing symbolically allows keeping some parameters symbolic:

SystemModelLinearize[,Method->{"SymbolicDerivative","SymbolicParameters"->{"R","L","C"}}]

OpenersExampleSection4(Spacer1)Applications  (10)

OpenersExampleSubsection5(Spacer1)Analyzing Linearized System  (5)

Compare responses from a model and its linearization at an equilibrium point:

model=;

{(Subscript[x, 0]),(Subscript[u, 0]),(Subscript[y, 0])}=FindSystemModelEquilibrium[model];

Linearize around the equilibrium point:

ss=SystemModelLinearize[model,"EquilibriumValues"];

Compare the stationary output response with a nonlinear model:

{linY1,linY2}=OutputResponse[ss,{UnitStep[t],UnitStep[t]},{t,0,300}];

nonLin=SystemModelSimulate[model,{0,300},<|"InitialValues"->Rule@@@(Subscript[x, 0]),"Inputs"->{"u1"->Function[t,(Subscript[u, 0])[[1,2]]+UnitStep[t]],"u2"->Function[t,(Subscript[u, 0])[[2,2]]+UnitStep[t]]}|>];

Compare the y1 output:

Show[SystemModelPlot[nonLin,{"y1"}],Plot[Tooltip[(Subscript[y, 0])[[1,2]]+linY1,"linear y1"],{t,0,300}]]

Test the stability of a linearized system from eigenvalues of the system matrix:

ss=SystemModelLinearize[,"InitialValues"]

Since there is an eigenvalue with a positive real part, the system is unstable:

{a,b,c,d,e}=Normal[ss];

Re@Eigenvalues[a]

Plotting the output response also indicates an unstable system:

Plot[Evaluate[OutputResponse[ss,UnitStep[t],{t,1}]],{t,0,1}]

Test the stability of a linearized system from poles of the transfer function:

tf=TransferFunctionModel@SystemModelLinearize[];

Since there is a pole with a positive real part, the system is unstable:

TransferFunctionPoles[tf]

Do a frequency analysis using a linear model:

model=;

By plotting (Abs[H(i ω)]) for the linearized transfer function H(s):

ss=SystemModelLinearize[model];

BodePlot[ss,{0.5,3},PlotLayout->"Magnitude"]

Verify the result using (RefLink[Fourier, paclet:ref/Fourier]) on simulated data:

nonLin=SystemModelSimulate[model,{0,200},<|"Inputs"->{"u"->Function[t,UnitStep[t]-UnitStep[t-2]]}|>];

Compute (Abs[H(i ω)]) from Y(i ω)==H(i ω) U(i ω):

odata=Abs@Fourier@Table[nonLin[{"inertia3.w"},t][[1]],{t,0,200,0.25}];
idata=Abs@Fourier@Table[UnitStep[t]-UnitStep[t-2],{t,0,200,0.25}];

ListLogLinearPlot[odata[[1;;200]]/idata[[1;;200]],Joined->True,DataRange->{0,2Pi},PlotRange->{{0.5,3},{0,50}}]

Alternatively, the imaginary parts of the eigenvalues give the resonance peaks:

{a,b,c,d}=Normal[ss];

Im[Eigenvalues[a]]

Linearization takes place at time 0:

model=;

Linearize with the switch connecting at time 0:

model2=SystemModel[model,{"t"->0}];

rlc=SystemModelLinearize[model2]

If the switch is not connected at time 0, the result is different:

model3=SystemModel[model2,{"t"->1}];

rl=SystemModelLinearize[model3]

OpenersExampleSubsection6(Spacer1)Controller Design for Linearized System  (5)

Design a PID controller using a linearized model:

tf=TransferFunctionModel@SystemModelLinearize[];

Define a PID controller and closed-loop transfer function:

pidTf=TransferFunctionModel[kp (1+1/(τi \[FormalS])+τd \[FormalS]),\[FormalS]];

cltf=SystemsModelFeedbackConnect[SystemsModelSeriesConnect[pidTf,tf]];

Select PID parameters for appropriate step response:

Manipulate[
Plot[OutputResponse[cltf/.{kp->gain,τi->iTime,τd->dTime},UnitStep[t],{t,20}]//Evaluate,{t,0,20},PlotStyle->Thick,GridLines->Automatic,Frame->True,PlotRange->{0,1.2}],
{{gain,1,"(Subscript[k, p])"},0.01,10},{{dTime,0.01,"(Subscript[τ, d])"},0.01,10},{{iTime,1.9,"(Subscript[τ, i])"},0.01,10},SaveDefinitions->True]

Design a lead-based controller for a DC motor based on its linearization:

tf=TransferFunctionModel@SystemModelLinearize[];

Define a PI-lead controller transfer function:

piLeadTf=TransferFunctionModel[kp (1+1/τi \[FormalS](τd \[FormalS]+1)/(α τd \[FormalS]+1)),\[FormalS]];

Open-loop transfer function:

optf=SystemsModelSeriesConnect[piLeadTf,tf];

Select controller parameters:

Manipulate[BodePlot[newOptf=optf/.{kp->Kp,τi->Τi,τd->Τd,α->Α},StabilityMargins->True,PlotLayout->"List"],
{{Kp,4.5,"(Subscript[k, p])"},0.01,10},{{Τi,2,"τi"},0.01,10},{{Τd,0.01,"τd"},0.01,10},{{Α,0.07,"α"},0.01,0.9},SaveDefinitions->True]

Use selected parameters and close the loop with the PI-lead controller:

cltf=SystemsModelFeedbackConnect[SystemsModelSeriesConnect[newOptf,tf]];

Plot[OutputResponse[cltf,UnitStep[t],{t,20}]//Evaluate,{t,0,20},PlotStyle->Thick,GridLines->Automatic,Frame->True,PlotRange->All]

Design a controller using pole placement:

ss=SystemModelLinearize[];

Place the closed-loop poles:

k=StateFeedbackGains[ss,{-0.251,-0.222,-0.222}]

Compute the closed-loop state-space model:

clss=SystemsModelStateFeedbackConnect[ss,k];

Show the step response:

Plot[OutputResponse[clss,{UnitStep[t],UnitStep[t]},{t,100}]//Evaluate,{t,0,100},PlotRange->All]

Design an LQ controller:

ss=SystemModelLinearize[];

Define state and input weight matrices:

{q1,q2}={DiagonalMatrix[{1,6 (10^(-4)),6 (10^(-4))}],DiagonalMatrix[{0.0002,0.0002}]};

Define LQ controller gain:

k=LQRegulatorGains[ss,{q1,q2}]

Closed-loop state-space model:

clss=SystemsModelStateFeedbackConnect[ss,k];

Closed-loop step response:

Plot[OutputResponse[clss,{UnitStep[t],UnitStep[t]},{t,100}]//Evaluate,{t,0,100},PlotRange->All]

Design a state estimator:

model=;

ss=SystemModelLinearize[model];

Compute estimator gains and the estimator state-space model:

l=EstimatorGains[ss,{-0.6020,-0.5856,-0.5697}]

{a,b,c,d}=Normal[ss];

ssobsv=StateSpaceModel[{a-l.c,ArrayFlatten[{{b-l.d,l}}],IdentityMatrix[3]}];

The state and output response to a unit step on the inputs:

sresp=StateResponse[ss,{UnitStep[t],UnitStep[t]},{t,200}];
y=OutputResponse[ss,{UnitStep[t],UnitStep[t]},{t,200}];

Observer state response:

oresp=OutputResponse[ssobsv,{UnitStep[t],UnitStep[t],y[[1]],y[[2]]},{t,200}];

Compare each state and its estimate:

states=model["StateVariables"];

Table[Plot[{sresp[[i]],oresp[[i]]},{t,0,200},PlotLabel->states[[i]]],{i,3}]

OpenersExampleSection5(Spacer1)Properties & Relations  (8)

Linearize around initial values using properties from (RefLink[SystemModel, paclet:ref/SystemModel]):

model=;

ival=model["GroupedInitialValues"]

Compare results:

SystemModelLinearize[model,ival,"InitialValues"]==SystemModelLinearize[model,"InitialValues"]

Linearize around equilibrium using (RefLink[FindSystemModelEquilibrium, paclet:ref/FindSystemModelEquilibrium]):

model=;

eqval=FindSystemModelEquilibrium[model];

Compare results:

SystemModelLinearize[model,eqval]==SystemModelLinearize[model,"EquilibriumValues"]

Compare responses from a model and its linearization at an equilibrium point:

model=;

{(Subscript[x, 0]),(Subscript[u, 0]),(Subscript[y, 0])}=FindSystemModelEquilibrium[model,{"H"==0.85,"Tu"==38,"Tx"==38}]

Linearize around the equilibrium point:

ss=SystemModelLinearize[model,{{{"H",0.85},{"Tu",38},{"Tx",38}},{}},"EquilibriumValues"]

Compare the stationary output response with a nonlinear model:

{linY1,linY2}=OutputResponse[ss,{UnitStep[t],UnitStep[t]},{t,0,300}];

nonLin=SystemModelSimulate[model,{0,300},<|"InitialValues"->Rule@@@(Subscript[x, 0]),"Inputs"->{"u1"->Function[t,(Subscript[u, 0])[[1,2]]+UnitStep[t]],"u2"->Function[t,(Subscript[u, 0])[[2,2]]+UnitStep[t]]}|>];

Compare the first output:

Show[SystemModelPlot[nonLin,{"y1"}],Plot[Evaluate@Tooltip[(Subscript[y, 0])[[1,2]]+linY1,"linear y1"],{t,0,300}]]

Compare responses from a model and its linearization at a non-equilibrium point:

model=;

(Subscript[x, 0])={{"H",0.85},{"Tu",38},{"Tx",38}}

(Subscript[u, 0])={{"u1",5.23},{"u2",3.08}}

Linearize around the given point:

ss=SystemModelLinearize[model,{(Subscript[x, 0]),(Subscript[u, 0])},"InitialValues"];

Compare the stationary output response with a nonlinear model:

{linY1,linY2}=OutputResponse[ss,{UnitStep[t],UnitStep[t]},{t,0,300}];

nonLin=SystemModelSimulate[model,{0,300},<|"InitialValues"->Rule@@@(Subscript[x, 0]),"Inputs"->{"u1"->Function[t,(Subscript[u, 0])[[1,2]]+UnitStep[t]],"u2"->Function[t,(Subscript[u, 0])[[2,2]]+UnitStep[t]]}|>];

Get the output equations:

eqs=model["SystemEquations",t]/.model["ParameterValues"]

(Subscript[g, out])=Cases[eqs,(QuantityVariable["y1",_]|QuantityVariable["y2",_])[t]==rhs__:>rhs];

Compute the stationary output:

{(Subscript[y, 2,0]),(Subscript[y, 1,0])}=(Subscript[g, out])/.(Function[{var,val},QuantityVariable[var,_][t]->val]@@@(Subscript[x, 0]));

Compare the first output:

Show[Plot[Evaluate@Tooltip[(Subscript[y, 1,0])+linY1,"linear y1"],{t,0,300}],SystemModelPlot[nonLin,{"y1"}]]

Use (RefLink[TransferFunctionModel, paclet:ref/TransferFunctionModel]) to convert to a transfer function representation:

SystemModelLinearize[]

TransferFunctionModel[%]

Use (RefLink[ToDiscreteTimeModel, paclet:ref/ToDiscreteTimeModel]) to discretize a linearized model:

SystemModelLinearize[]

Discretize using sample time 0.10:

ToDiscreteTimeModel[%,0.10,z]

The linearized state-space model is not unique:

({{model Linearize1}, {  extends DocumentationExamples.Icons.Textual;}, {  parameter Real A = 0.02;}, {  parameter Real B = 1;}, {  Modelica.Blocks.Interfaces.RealInput u(start = 0);}, {  Modelica.Blocks.Interfaces.RealOutput y(start = 0);}, {  Real x1(start = 0) "State variable 1";}, {  Real x2(start = 0) "State variable 2";}, {equation}, {  der(x1) = (-x1) + x2 ^ 2 * A * u;}, {  der(x2) = x1 + B * x2 + u;}, {  y = x2;}, {end Linearize1;}})

ss1=SystemModelLinearize["DocumentationExamples.Basic.Linearize1"]

Change the order in which the variables x1 and x2 are declared:

({{model Linearize2}, {  extends DocumentationExamples.Icons.Textual;}, {  parameter Real A = 0.02;}, {  parameter Real B = 1;}, {  Modelica.Blocks.Interfaces.RealInput u(start = 0);}, {  Modelica.Blocks.Interfaces.RealOutput y(start = 0);}, {  Real x2(start = 0) "State variable 2";}, {  Real x1(start = 0) "State variable 1";}, {equation}, {  der(x1) = (-x1) + x2 ^ 2 * A * u;}, {  der(x2) = x1 + B * x2 + u;}, {  y = x2;}, {end Linearize2;}})

ss2=SystemModelLinearize["DocumentationExamples.Basic.Linearize2"]

The models are equivalent and have identical transfer functions:

TransferFunctionModel[ss1]==TransferFunctionModel[ss2]

(RefLink[StateSpaceModel, paclet:ref/StateSpaceModel]) can linearize systems of ordinary differential equations:

eqs={-(M+m)x''[t]-m l Sin[θ[t]] ((θ'[t])^2)+m l Cos[θ[t]] θ''[t]==k i[t] +bc x'[t],-m x''[t] Cos[θ[t]]+m l θ''[t]==m g Sin[θ[t]]- bp  θ'[t],0==(vin[t] - R i[t] - L i'[t]+k x'[t])};

StateSpaceModel[eqs,{{i[t],0},{θ[t],0},{θ'[t],0},{x'[t],0},{x[t],0}},{{vin[t],0}},{x[t], θ[t]},t]

Using approximate numeric parameter values:

%/.{R->13,L->1,k->-932.282,m->0.277,g->9.81,bp->0.0025,l->0.0415,M->339512,bc->0.204}

Using (RefLink[SystemModeler, paclet:ref/SystemModeler]) to linearize a model of the same system:

SystemModelLinearize[,"InitialValues"]

OpenersExampleSection6(Spacer1)Possible Issues  (1)

Some models cannot be linearized symbolically:

SystemModelLinearize["DocumentationExamples.Modeling.ElectricCircuit.CircuitWithEvent",Method->"SymbolicDerivative"]

SystemModelLinearize["DocumentationExamples.Basic.StateOut",Method->"SymbolicDerivative"]

SystemModelLinearize["DocumentationExamples.Basic.InOutNoState",Method->"SymbolicDerivative"]

Use "NumericDerivative" to linearize numerically:

SystemModelLinearize["DocumentationExamples.Modeling.ElectricCircuit.CircuitWithEvent",Method->"NumericDerivative"]

({{DocumentationFooterIconsRelatedFunction.png, ({{See Also}, {(RefLink[StateSpaceModel, paclet:ref/StateSpaceModel])  ▪  (RefLink[SystemModel, paclet:ref/SystemModel])  ▪  (RefLink[FindSystemModelEquilibrium, paclet:ref/FindSystemModelEquilibrium])  ▪  (RefLink[SystemModelSimulate, paclet:ref/SystemModelSimulate])  ▪  (RefLink[SystemModelExamples, paclet:ref/SystemModelExamples])}})}})

({{DocumentationFooterIconsRelatedGuide.png, ({{Related Guides}, {▪(RefLinkPlain[System Model Analytics & Design, paclet:guide/SystemModelAnalyticsDesign])}, {▪(RefLinkPlain[System Modeling Overview, paclet:guide/SystemModelingOverview])}, {▪(RefLinkPlain[Basic Modeling, paclet:guide/Modeling])}, {▪(RefLinkPlain[Control Systems, paclet:guide/ControlSystems])}})}})

({{(Spacer1), ({{(Spacer1)Related Links}, {(Spacer1)▪(WebLink[(Spacer1)Wolfram SystemModeler Documentation, http://reference.wolfram.com/system-modeler/])}})}})