This example shows how to model a scalar gain *K* with
a bilinear dependence on two scheduling variables, *α* and *V*,
as follows:

For this example, *α* is an angle of
incidence that ranges from 0 to 15 degrees, and *V* is
a speed that ranges from 300 to 600 m/s. The coefficients *K*_{0},...,*K*_{3} are
the tunable parameters of this variable gain.

Create a grid of design points, (*α*,*V*),
that are linearly spaced in *α* and *V*.
These design points are where you will tune the gain surface coefficients.

[alpha,V] = ndgrid(0:5:15,300:100:600);

These arrays, `alpha` and `V`,
represent the independent variation of the two scheduling variables,
each across its full range.

When you tune the gain surface coefficients with `systune`,
you might obtain better solver performance by normalizing the scheduling
variables to fall within the interval [–1,1]. Scale the *α* and *V* grid
to fall within this range.

alphaN = alpha/15;
VN = (V-450)/150;

Create the tunable gain surface sampled at the grid of
(*α*_{N},*V*_{N})
values:

In this expansion, the basis functions are:

Specify the values of the basis functions over the (*α*_{N},*V*_{N}).

F1 = alphaN;
F2 = VN;
F3 = alphaN.*VN;
K = gainsurf('K',1,F1,F2,F3)

K =
4x4 array of generalized matrices with 1 rows, 1 columns, and the following blocks:
K_0: Scalar parameter, 1 occurrences.
K_1: Scalar parameter, 1 occurrences.
K_2: Scalar parameter, 1 occurrences.
K_3: Scalar parameter, 1 occurrences.
Type "double(K)" to see the current value, "get(K)" to see all properties, and "K.Blocks" to interact with the blocks.

`K` is an array of generalized matrices. Each
element in `K` corresponds to *K*(*α*_{N},*V*_{N})
for a particular (*α*_{N},*V*_{N})
pair, and depends on the tunable coefficients `K_0`,...,`K_3`.

Associate the independent variable values with the corresponding
values of `K`.

K.SamplingGrid = struct('alpha',alpha,'V',V);

The `SamplingGrid` property keeps track
of the scheduling variable values associated with each entry in `K`.
This association is convenient for tracing results back to independent
variable values. For instance, you can use `view(K)` to
inspect the tuned values of the gain surface after tuning. When you
do so, `view` takes the axis range and labels from
the entries in `SamplingGrid`. For this example,
instead of tuning, manually set the values of the tunable blocks to
non-zero values. View the resulting gain surface as a function of
the scheduling variables.

values = struct('K_0',1,'K_1',-1,'K_2',0.1,'K_3',-0.2);
Ktuned = setBlockValue(K,values);
view(Ktuned)

The variable names and values that you specified in the `SamplingGrid` property
are used to scale and label the axes.

You can use `K` as a tunable gain to
build a control system with gain-scheduled tunable components. For
example, use `K` to create a gain-scheduled low-pass
filter.

F = tf(K,[1 K]);

You can use gain surfaces as arguments to model creation commands
like `tf` the same way you would use numeric arguments.
The resulting filter is a generalized state-space (`genss`)
model array that depends on the four coefficients of the gain surface.

Use model interconnection commands (such as `connect` and `feedback`)
to combine `F` with an array of plant models sampled
at the same values of *α* and *V*.
You can then use `systune` to tune the gain-scheduled
controller to meet your design requirements. Because you normalized
the scheduling variables to model the tunable gain, you must adjust
the coefficient values in the implementation of your tuned controller.