How to change the sampling period of discrete time model?

Mathematica Version 14.0 on Win 10.

This is a problem I am having with a much more complicated notebook. I crafted the simple example below for this question.

If I begin with an expression in the s-domain, create a continuous time model, and then convert that to a discrete time model using ToDiscreteTimeModel, and specify a symbolic parameter T for the sampling period. Then T appears in the model expression and as the subscript on the model icon. I can then evaluate this model at different sampling periods by using Replace with a Rule for T.

However, if I begin with an expression in the z-domain and create a discrete time model using TransferFunctionModel, with the option SamplingPeriod->T, then T does not appear in the model expression, but does appear as the subscript of the model icon. In this case, using Replace with a Rule for T, assigning a value to T, the model icon subscript changes, but it does not affect the behavior of the model.

The code below attempts to obtain the OutputResponse of the second case for different sampling periods, but changing the value of T has no effect.

There must be something I don't understand or some way in which I am thinking incorrectly.

(*start in the s-domain*)

gs = 10/(s + 10);

(*build a continuous time transfer function*)

gst = TransferFunctionModel[gs, s];

(*convert to discrete and the sampling period T appears in the \
expression*)

gstz = ToDiscreteTimeModel[gst, T, z]

(*start in the z-domain*)

gz = z/(z - 1);

(*build a discrete transfer function*)
(*T does not appear in the expression. It only appears in the \
subscript*)

gzt = TransferFunctionModel[gz, z, SamplingPeriod -> T]

(*apply a rule to define the sampling period and the subscript \
changes*)

gzt /. T -> .1

OutputResponse[gzt /. T -> .1, {1, 1, 1, 1, 1}]

(*{{1,2,3,4,5}}*)

(*change to a different sampling period and the output does not \
change*)

OutputResponse[gzt /. T -> .01, {1, 1, 1, 1, 1}]

(*{{1,2,3,4,5}}*)


As you have observed TransferFunctionModel[expr, z, SamplingPeriod -> T] does not do any approximation of the expr. That is handled by ToDiscreteTimeModel. This is as designed.

It appears that there is no effect, because OutputResponse gives the values at the sampling instants.

Thus they both have the same values at sampling instants.

or1 = OutputResponse[gzt /. T -> .1, {1, 1, 1, 1, 1}];
or2 = OutputResponse[gzt /. T -> .01, {1, 1, 1, 1, 1}];

{ListStepPlot[or1, DataRange -> {0, (5 - 1)}, AxesLabel -> {k}],
ListStepPlot[or2, DataRange -> {0, (5 - 1)}, AxesLabel -> {k}]}


But the actual time responses are different.

{ListStepPlot[or1, DataRange -> {0, (5 - 1) 0.1}, AxesLabel -> {t}],
ListStepPlot[or2, DataRange -> {0, (5 - 1) 0.01}, AxesLabel -> {t}]}


You can combine the above two plots to see the difference, or get the explicit values first and then plot them.

sampInstants[T_, n_] := NestList[# + T &, 0, n - 1]

Join[Thread[{sampInstants[0.1, 5], #}] & /@ or1,
Thread[{sampInstants[0.01, 5], #}] & /@ or2];
ListStepPlot[%, AxesLabel -> {t}]


• Thank you very much @Suba Thomas. As I suspected, my thinking was incorrect, or at least incomplete. I became confused when trying to design a discrete controller for a plant described in continuous time. How to model the dependence on SamplingPeriod? Now I think it's clear: ToDiscreteTimeModel preserves time dependence because it came from a continuous time description, but a purely discrete time model cares only about samples. I think the Control System tools are absolutely brilliant! I am going to attach more as another answer. Best, --David Commented Apr 9 at 19:46

Thank you, @Suba Thomas, for the answer above. I believe it led me to a proper understanding of the issue. I up-voted and accepted that answer. This “answer” is an addendum to my comment above. I am posting it so that, if my understanding is faulty, it can be corrected. And if correct, this follow up may be of use to others.

My question came about when designing a discrete controller for a plant described in continuous time. I was having trouble picturing how to use the Mathematica control system tools to simulate the effect of the sampling period on the response of the controlled system.

The plant, being modeled by a transfer function in continuous time, has a response which is time-dependent. When converted to a discrete time model by ToDiscreteTimeModel, the sampling period is built in to the model to preserve that dependency.

The controller, modeled in discrete time, has no explicit time dependence. It acts purely on a stream of samples to produce an output which is a stream of samples. The time dependence is implied by the generation of the samples and the interpretation of the output.

When the system transfer function is created by connecting the discrete transfer function of the controller and plant, and then applying a negative feedback connection, the result a discrete transfer function which acts on an input stream of samples to produce an output stream of samples. BUT – it retains the time dependence of the plant by allowing specification of the sampling interval. (I do that by applying a rule.)

To make use of this hybrid transfer function, it is necessary to provide an input stream of samples with values at the desired sampling period, and tell the function what the sampling period is so that the time-dependent response of the plant model will be correct. The output is a stream of samples at the design sample period.

The code below is an example. It describes a continuous time plant in the s-domain, and converts it to a discrete time model with SamplingPeriod given symbolically by T. It then connects it with a discrete time controller to form a system transfer function. The output response to a discrete step input is evaluated at several sampling intervals.

(*the plant is described in the continuous time domain*)

gps = 40/(s (s + 40));

(*in discrete time, it is sampled at interval T.
The discrete transfer function includes T because the plant response \
is time dependent*)

gpz = ToDiscreteTimeModel[TransferFunctionModel[gps, s], T, z]

(*the controller is a discrete time object, it knows nothing about \
the SamplingPeriod. It only responds to samples*)

gcz = TransferFunctionModel[(k (z - 0.72))/(z + 0.4), z,
SamplingPeriod -> T]

(* the cascade system does consider SamplingPeriod because the plant \
does*)

openLoop = SystemsModelSeriesConnect[gcz, gpz]

closedLoop = SystemsModelFeedbackConnect[openLoop]

(*model both plant and controller by telling the plant component what \
the samping period is and keeping track of the time axis when \
presenting samples as input*)

output[time_, samplePeriod_] := Module[{r},
r = Table[1, {t, 0, time, samplePeriod}];
OutputResponse[closedLoop /. k -> 150 /. T -> samplePeriod, r][[1]]]

duration = 0.5;

spList = {.05, .01, .005, .001};

outputs = output[duration, #] & /@ spList;

ListStepPlot[outputs, DataRange -> {0, duration}, PlotRange -> All,
AxesLabel -> {t},
PlotLegends ->
Placed[LineLegend[spList, LegendLabel -> "Sampling Period"],
Center]]