# findDecoupledBlocks

Search for decoupled blocks in systems of equations

## Syntax

``````[eqsBlocks,varsBlocks] = findDecoupledBlocks(eqs,vars)``````

## Description

example

``````[eqsBlocks,varsBlocks] = findDecoupledBlocks(eqs,vars)``` identifies subsets (blocks) of equations that can be used to define subsets of variables. The number of variables `vars` must coincide with the number of equations `eqs`.The ith block is the set of equations determining the variables in `vars(varsBlocks{i})`. The variables in `vars([varsBlocks{1},…,varsBlocks{i-1}])` are determined recursively by the previous blocks of equations. After you solve the first block of equations for the first block of variables, the second block of equations, given by `eqs(eqsBlocks{2})`, defines a decoupled subset of equations containing only the subset of variables given by the second block of variables, `vars(varsBlock{2})`, plus the variables from the first block (these variables are known at this time). Thus, if a nontrivial block decomposition is possible, you can split the solution process for a large system of equations involving many variables into several steps, where each step involves a smaller subsystem.The number of blocks `length(eqsBlocks)` coincides with `length(varsBlocks)`. If ```length(eqsBlocks) = length(varsBlocks) = 1```, then a nontrivial block decomposition of the equations is not possible.```

## Examples

collapse all

Compute a block lower triangular decomposition (BLT decomposition) of a symbolic system of differential algebraic equations (DAEs).

Create the following system of four differential algebraic equations. Here, the symbolic function calls `x1(t)`, `x2(t)`, `x3(t)`, and `x4(t)` represent the state variables of the system. The system also contains symbolic parameters `c1`, `c2`, `c3`, `c4`, and functions `f(t,x,y)` and `g(t,x,y)`.

```syms x1(t) x2(t) x3(t) x4(t) syms c1 c2 c3 c4 syms f(t,x,y) g(t,x,y) eqs = [c1*diff(x1(t),t)+c2*diff(x3(t),t)==c3*f(t,x1(t),x3(t));... c2*diff(x1(t),t)+c1*diff(x3(t),t)==c4*g(t,x3(t),x4(t));... x1(t)==g(t,x1(t),x3(t));... x2(t)==f(t,x3(t),x4(t))]; vars = [x1(t),x2(t),x3(t),x4(t)];```

Use `findDecoupledBlocks` to find the block structure of the system.

`[eqsBlocks,varsBlocks] = findDecoupledBlocks(eqs,vars)`
```eqsBlocks=1×3 cell array {[1 3]} {} {} ```
```varsBlocks=1×3 cell array {[1 3]} {} {} ```

The first block contains two equations in two variables.

`eqs(eqsBlocks{1})`
```ans =  ```
`vars(varsBlocks{1})`
`ans = $\left(\begin{array}{cc}{x}_{1}\left(t\right)& {x}_{3}\left(t\right)\end{array}\right)$`

After you solve this block for the variables `x1(t)`, `x3(t)`, you can solve the next block of equations. This block consists of one equation.

`eqs(eqsBlocks{2})`
```ans =  ```

The block involves one variable.

`vars(varsBlocks{2})`
`ans = ${x}_{4}\left(t\right)$`

After you solve the equation from block 2 for the variable `x4(t)`, the remaining block of equations, `eqs(eqsBlocks{3})`, defines the remaining variable, `vars(varsBlocks{3})`.

`eqs(eqsBlocks{3})`
`ans = ${x}_{2}\left(t\right)=f\left(t,{x}_{3}\left(t\right),{x}_{4}\left(t\right)\right)$`
`vars(varsBlocks{3})`
`ans = ${x}_{2}\left(t\right)$`

Find the permutations that convert the system to a block lower triangular form.

`eqsPerm = [eqsBlocks{:}]`
```eqsPerm = 1×4 1 3 2 4 ```
`varsPerm = [varsBlocks{:}]`
```varsPerm = 1×4 1 3 4 2 ```

Convert the system to a block lower triangular system of equations.

`eqs = eqs(eqsPerm)`
```eqs =  ```
`vars = vars(varsPerm)`
`vars = $\left(\begin{array}{cccc}{x}_{1}\left(t\right)& {x}_{3}\left(t\right)& {x}_{4}\left(t\right)& {x}_{2}\left(t\right)\end{array}\right)$`

Find the incidence matrix of the resulting system. The incidence matrix shows that the system of permuted equations has three diagonal blocks of size `2`-by-`2`, `1`-by-`1`, and `1`-by-`1`.

`incidenceMatrix(eqs, vars)`
```ans = 4×4 1 1 0 0 1 1 0 0 1 1 1 0 0 1 1 1 ```

Find blocks of equations in a linear algebraic system, and then solve the system by sequentially solving each block of equations starting from the first one.

Create the following system of linear algebraic equations.

```syms x1 x2 x3 x4 x5 x6 c1 c2 c3 eqs = [c1*x1 + x3 + x5 == c1 + c2 + 1;... x1 + x3 + x4 + 2*x6 == 4 + c2;... x1 + 2*x3 + c3*x5 == 1 + 2*c2 + c3;... x2 + x3 + x4 + x5 == 2 + c2;... x1 - c2*x3 + x5 == 2 - c2^2;... x1 - x3 + x4 - x6 == 1 - c2]; vars = [x1,x2,x3,x4,x5,x6];```

Use `findDecoupledBlocks` to convert the system to a lower triangular form. For this system, `findDecoupledBlocks` identifies three blocks of equations and corresponding variables.

`[eqsBlocks,varsBlocks] = findDecoupledBlocks(eqs,vars)`
```eqsBlocks=1×3 cell array {[1 3 5]} {[2 6]} {} ```
```varsBlocks=1×3 cell array {[1 3 5]} {[4 6]} {} ```

Identify the variables in the first block. This block consists of three equations in three variables.

`vars(varsBlocks{1})`
`ans = $\left(\begin{array}{ccc}{x}_{1}& {x}_{3}& {x}_{5}\end{array}\right)$`

Solve the first block of equations for the first block of variables assigning the solutions to the corresponding variables.

`[x1,x3,x5] = solve(eqs(eqsBlocks{1}),vars(varsBlocks{1}))`
`x1 = $1$`
`x3 = ${c}_{2}$`
`x5 = $1$`

Identify the variables in the second block. This block consists of two equations in two variables.

`vars(varsBlocks{2})`
`ans = $\left(\begin{array}{cc}{x}_{4}& {x}_{6}\end{array}\right)$`

Solve this block of equations assigning the solutions to the corresponding variables.

`[x4,x6] = solve(eqs(eqsBlocks{2}),vars(varsBlocks{2}))`
```x4 =  $\frac{{x}_{3}}{3}-{x}_{1}-\frac{{c}_{2}}{3}+2$```
```x6 =  $\frac{2 {c}_{2}}{3}-\frac{2 {x}_{3}}{3}+1$```

Use `subs` to evaluate the result for the already known values of variables `x1`, `x3`, and `x5`.

`x4 = subs(x4)`
`x4 = $1$`
`x6 = subs(x6)`
`x6 = $1$`

Identify the variables in the third block. This block consists of one equation in one variable.

`vars(varsBlocks{3})`
`ans = ${x}_{2}$`

Solve this equation assigning the solution to `x2`.

`x2 = solve(eqs(eqsBlocks{3}),vars(varsBlocks{3}))`
`x2 = ${c}_{2}-{x}_{3}-{x}_{4}-{x}_{5}+2$`

Use `subs` to evaluate the result for the already known values of all other variables of this system.

`x2 = subs(x2)`
`x2 = $0$`

Alternatively, you can rewrite this example using the `for`-loop. This approach lets you use the example for larger systems of equations.

```syms x1 x2 x3 x4 x5 x6 c1 c2 c3 eqs = [c1*x1 + x3 + x5 == c1 + c2 + 1;... x1 + x3 + x4 + 2*x6 == 4 + c2;... x1 + 2*x3 + c3*x5 == 1 + 2*c2 + c3;... x2 + x3 + x4 + x5 == 2 + c2;... x1 - c2*x3 + x5 == 2 - c2^2 x1 - x3 + x4 - x6 == 1 - c2]; vars = [x1,x2,x3,x4,x5,x6]; [eqsBlocks,varsBlocks] = findDecoupledBlocks(eqs,vars); vars_sol = vars; for i = 1:numel(eqsBlocks) sol = solve(eqs(eqsBlocks{i}),vars(varsBlocks{i})); vars_sol_per_block = subs(vars(varsBlocks{i}),sol); for k=1:i-1 vars_sol_per_block = subs(vars_sol_per_block,vars(varsBlocks{k}),... vars_sol(varsBlocks{k})); end vars_sol(varsBlocks{i}) = vars_sol_per_block end```
`vars_sol = $\left(\begin{array}{cccccc}1& {x}_{2}& {c}_{2}& {x}_{4}& 1& {x}_{6}\end{array}\right)$`
`vars_sol = $\left(\begin{array}{cccccc}1& {x}_{2}& {c}_{2}& 1& 1& 1\end{array}\right)$`
`vars_sol = $\left(\begin{array}{cccccc}1& 0& {c}_{2}& 1& 1& 1\end{array}\right)$`

## Input Arguments

collapse all

System of equations, specified as a vector of symbolic equations or expressions.

Variables, specified as a vector of symbolic variables, functions, or function calls, such as `x(t)`.

Example: `[x(t),y(t)]` or `[x(t);y(t)]`

## Output Arguments

collapse all

Indices defining blocks of equations, returned as a cell array. Each block of indices is a row vector of double-precision integer numbers. The ith block of equations consists of the equations `eqs(eqsBlocks{i})` and involves only the variables in `vars(varsBlocks{1:i})`.

Indices defining blocks of variables, returned as a cell array. Each block of indices is a row vector of double-precision integer numbers. The ith block of equations consists of the equations `eqs(eqsBlocks{i})` and involves only the variables in `vars(varsBlocks{1:i})`.

## Tips

• The implemented algorithm requires that for each variable in `vars` there must be at least one matching equation in `eqs` involving this variable. The same equation cannot also be matched to another variable. If the system does not satisfy this condition, then `findDecoupledBlocks` throws an error. In particular, `findDecoupledBlocks` requires that ```length(eqs) = length(vars)```.

• Applying the permutations `e = [eqsBlocks{:}]` to the vector `eqs` and `v = [varsBlocks{:}]` to the vector `vars` produces an incidence matrix ```incidenceMatrix(eqs(e), vars(v))``` that has a block lower triangular sparsity pattern.

## Version History

Introduced in R2014b