## Uncertain Matrices

Uncertain matrices (class `umat`) are built from doubles and uncertain elements, using traditional MATLAB® matrix building syntax. Uncertain matrices can be added, subtracted, multiplied, inverted, transposed, etc., resulting in uncertain matrices. The rows and columns of an uncertain matrix are referenced in the same manner that MATLAB references rows and columns of an array, using parenthesis, and integer indices. The `NominalValue` of a uncertain matrix is the result obtained when all uncertain elements are replaced with their own `NominalValue`. The uncertain elements making up a `umat` are accessible through the `Uncertainty` gateway, and the properties of each element within a `umat` can be changed directly. The properties are:

Properties

Meaning

Class

`NominalValue`

Nominal value of element

`double`

`Uncertainty`

Uncertain blocks in the matrix, stored as a structure whose fields are named after the uncertain blocks, and contain the uncertain elements, such as `ureal`.

`struct`

`SamplingGrid`

Sampling grid, for `umat` arrays, stored as a structure whose fields are named after the sampling variables, and contain the sample values associated with the corresponding model in the array.

`struct`

`Name`

`umat` name. When you convert a static control design block such as `ureal` to an uncertain matrix using `umat(blk)`, the `Name` property of the block is preserved.

`char`

Using `usubs`, specific values may be substituted for any of the uncertain elements within a `umat`. The command `usample` generates a random sample of the uncertain matrix, substituting random samples (within their ranges) for each of the uncertain elements.

The command `wcnorm` computes tight bounds on the worst-case (maximum over the uncertain elements' ranges) norm of the uncertain matrix.

Standard MATLAB numerical matrices (i.e., `double`) naturally can be viewed as uncertain matrices without any uncertainty.

### Create and Manipulate Uncertain Matrices

You create uncertain matrices (`umat` objects) by creating uncertain parameters and using them to build matrices. You can then use uncertain matrices to build uncertain state-space models. This example shows how to create an uncertain matrix, access and change its uncertain parameters, extract elements, and perform matrix arithmetic.

For example, create two uncertain real parameters, and use them to create a 3-by-2 uncertain matrix.

```a = ureal('a',3); b = ureal('b',10,'Percentage',20); M = [-a, 1/b; b, a+1/b; 1, 3]```
```M = Uncertain matrix with 3 rows and 2 columns. The uncertainty consists of the following blocks: a: Uncertain real, nominal = 3, variability = [-1,1], 2 occurrences b: Uncertain real, nominal = 10, variability = [-20,20]%, 3 occurrences Type "M.NominalValue" to see the nominal value, "get(M)" to see all properties, and "M.Uncertainty" to interact with the uncertain elements. ```

Examine and Modify `umat` Properties

`M` is a `umat` object. Examine its properties using `get`.

`get(M)`
``` NominalValue: [3x2 double] Uncertainty: [1x1 struct] SamplingGrid: [1x1 struct] Name: '' ```

The nominal value of `M` is the matrix obtained by replacing all the uncertain elements with their nominal values.

`M.NominalValue`
```ans = 3×2 -3.0000 0.1000 10.0000 3.1000 1.0000 3.0000 ```

The `Uncertainty` property is a structure containing the uncertain elements (the Control Design Blocks (Control System Toolbox)) of `M`.

`M.Uncertainty`
```ans = struct with fields: a: [1x1 ureal] b: [1x1 ureal] ```
`M.Uncertainty.a`
```ans = Uncertain real parameter "a" with nominal value 3 and variability [-1,1]. ```

Use the `Uncertainty` property for direct access to the uncertain elements. For example, check the `Range` of the uncertain element `a` within `M`.

`M.Uncertainty.a.Range`
```ans = 1×2 2 4 ```

The range is `[2,4]` because you created the `ureal` parameter `a` with a nominal value 3 and the default uncertainty of +/- 1. Change the range to `[2.5,5]`.

`M.Uncertainty.a.Range = [2.5,5]`
```M = Uncertain matrix with 3 rows and 2 columns. The uncertainty consists of the following blocks: a: Uncertain real, nominal = 3, variability = [-0.5,2], 2 occurrences b: Uncertain real, nominal = 10, variability = [-20,20]%, 3 occurrences Type "M.NominalValue" to see the nominal value, "get(M)" to see all properties, and "M.Uncertainty" to interact with the uncertain elements. ```

This change to `a` only takes place within `M`. Verify that the variable `a` in the MATLAB workspace still has the original range.

`a.Range`
```ans = 1×2 2 4 ```

You cannot combine elements that have a common internal name, but different properties. So, for example, entering `M.Uncertainty.a - a` would generate an error, because the `realp` parameter `a` in the workspace has different properties from the element `a` in `M`.

Row and Column Referencing

You can use standard row-column referencing to extract elements from a `umat`. For example, extract a 2-by-2 selection from `M` consisting of its second and third rows.

`Msub = M(2:3,:)`
```Msub = Uncertain matrix with 2 rows and 2 columns. The uncertainty consists of the following blocks: a: Uncertain real, nominal = 3, variability = [-0.5,2], 1 occurrences b: Uncertain real, nominal = 10, variability = [-20,20]%, 2 occurrences Type "Msub.NominalValue" to see the nominal value, "get(Msub)" to see all properties, and "Msub.Uncertainty" to interact with the uncertain elements. ```

You can use single indexing only if the `umat` is a single column or row. Make a single-column selection from `M` and use single-index references to access elements of it.

```Msing = M([2 1 2 3],2); Msing(2)```
```ans = Uncertain matrix with 1 rows and 1 columns. The uncertainty consists of the following blocks: b: Uncertain real, nominal = 10, variability = [-20,20]%, 1 occurrences Type "ans.NominalValue" to see the nominal value, "get(ans)" to see all properties, and "ans.Uncertainty" to interact with the uncertain elements. ```

You can use indexing to change the value of any element of a `umat`. For example, set the (3,2) entry of `M` to an uncertain parameter `c`.

```c = ureal('c',3,'Percentage',40); M(3,2) = c```
```M = Uncertain matrix with 3 rows and 2 columns. The uncertainty consists of the following blocks: a: Uncertain real, nominal = 3, variability = [-0.5,2], 2 occurrences b: Uncertain real, nominal = 10, variability = [-20,20]%, 2 occurrences c: Uncertain real, nominal = 3, variability = [-40,40]%, 1 occurrences Type "M.NominalValue" to see the nominal value, "get(M)" to see all properties, and "M.Uncertainty" to interact with the uncertain elements. ```

M now has three uncertain blocks.

Matrix Operations on `umat` Objects

You can perform many matrix operations on a `umat` object, such as matrix-multiply, transpose, and inverse. You can also combine uncertain matrices with numeric matrices that do not have uncertainty.

For example, premultiply `M` by a `1-by-3` numeric matrix, resulting in a 1-by-2 `umat`.

`M1 = [2 3 1]*M;`

Verify that the first entry of `M1` is as expected, `-2*a + 3*b + 1`.

`d = M1(1) - (-2*M.Uncertainty.a + 3*M.Uncertainty.b + 1)`
```d = Uncertain matrix with 1 rows, 1 columns, and no uncertain blocks. Type "d.NominalValue" to see the nominal value, "get(d)" to see all properties, and "d.Uncertainty" to interact with the uncertain elements. ```

Transpose `M`, form a product, and invert it. As expected, the product of a matrix and its inverse is the identity matrix. You can verify this by sampling the result.

```H = M.'*M; K = inv(H); usample(K*H,3)```
```ans = ans(:,:,1) = 1.0000 0.0000 -0.0000 1.0000 ans(:,:,2) = 1.0000 0.0000 -0.0000 1.0000 ans(:,:,3) = 1.0000 0.0000 -0.0000 1.0000 ```

Lifting a Double Matrix to `umat`

You can convert a numeric matrix to a `umat` object with no uncertain elements. Use the `umat` command to lift a double matrix to the `umat` class. For example:

```Md = [1 2 3;4 5 6]; M = umat(Md)```
```M = Uncertain matrix with 2 rows, 3 columns, and no uncertain blocks. Type "M.NominalValue" to see the nominal value, "get(M)" to see all properties, and "M.Uncertainty" to interact with the uncertain elements. ```

You can also convert higher-dimension numeric matrices to `umat`. When you do so, the software interprets the third dimension and beyond as array dimensions. For example, convert a random three-dimensional numeric array to `umat`.

```Md = randn(4,5,6); M = umat(Md)```
```M = 6x1 array of uncertain matrices with 4 rows, 5 columns, and no uncertain blocks. Type "M.NominalValue" to see the nominal value, "get(M)" to see all properties, and "M.Uncertainty" to interact with the uncertain elements. ```

The result is a one-dimensional array of uncertain matrices, rather than a three-dimensional uncertain array. Similarly, a four-dimensional numeric array converts to a two-dimensional array of `umat` objects.

```Md = randn(4,5,6,7); M = umat(Md)```
```M = 6x7 array of uncertain matrices with 4 rows, 5 columns, and no uncertain blocks. Type "M.NominalValue" to see the nominal value, "get(M)" to see all properties, and "M.Uncertainty" to interact with the uncertain elements. ``` 