# Implement Hardware-Efficient Real Partial-Systolic Q-less QR Decomposition

This example shows how to implement a hardware-efficient Q-less QR decomposition using the Real Partial-Systolic Q-less QR Decomposition block.

### Economy Size Q-less QR Decomposition

The Real Partial-Systolic Q-less QR Decomposition block performs the first step of solving the matrix equation A'AX = B which transforms A in-place to upper-triangular R, then solves the transformed system R'RX = B, where R'R = A'A.

### Define Matrix Dimensions

Specify the number of rows and columns in matrix A.

```m = 5; % Number of rows in matrix A n = 3; % Number of columns in matrix A ```

### Generate Matrix A

Use the helper function `realUniformRandomArray` to generate a random matrix A such that the elements of A are between -1 and +1, and A is full rank.

```rng('default') A = fixed.example.realUniformRandomArray(-1,1,m,n); ```

### Select Fixed-Point Data Types

Use the helper function `qlessqrFixedpointTypes` to select fixed-point data types for matrix A that guarantee no overflow will occur in the transformation of A in-place to R.

```max_abs_A = 1; % Upper bound on max(abs(A(:)) precisionBits = 24; % Number of bits of precision T = fixed.qlessqrFixedpointTypes(m,max_abs_A,precisionBits); A = cast(A,'like',T.A); ```

### Open the Model

```model = 'RealPartialSystolicQlessQRModel'; open_system(model); ``` ### AMBA AXI Handshaking Process

The Data Handler subsystem in this model takes real matrix A as input. It sends rows of A to the QR Decomposition block using the AMBA AXI handshake protocol. The `validIn` signal indicates when data is available. The `ready` signal indicates that the block can accept the data. Transfer of data occurs only when both the `validIn` and `ready` signals are high. You can set delay for the feeding in rows of A in the Data Handler to emulate the processing time of the upstream block. `validOut` signal of the Data Handler remain high when `rowDelay` is set to `0` because this indicates the Data Handler always has data available.

### Set Variables in the Model Workspace

Use the helper function `setModelWorkspace` to add the variables defined above to the model workspace. These variables correspond to the block parameters for the Real Partial-Systolic Q-less QR Decomposition block.

```numSamples = 1; % Number of sample matrices rowDelay = 1; % Delay of clock cycles between feeding in rows of A fixed.example.setModelWorkspace(model,'A',A,'m',m,'n',n,... 'numSamples',numSamples,'rowDelay',rowDelay); ```

### Simulate the Model

```out = sim(model); ```

### Construct the Solution from the Output Data

The Real Partial-Systolic QR Decomposition block outputs matrix R at each time step. When a valid result matrix is output, the block sets `validOut` to true.

```R = out.R; ```

R is an upper-triangular matrix.

```R ```
```R = 1.5379 0.0432 -0.1395 0 1.5978 0.4742 0 0 1.5192 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 28 FractionLength: 24 ```
```isequal(R,triu(R)) ```
```ans = logical 1 ```

### Verify the Accuracy of the Output

To evaluate the accuracy of the Real Partial-Systolic Q-less QR Decomposition block, compute the relative error.

```relative_error = norm(double(R'*R - A'*A))/norm(double(A'*A)) ```
```relative_error = 8.2641e-07 ```

Suppress mlint warnings.

```%#ok<*NOPTS> ```