Integer type:  int32  int64  nag_int  show int32  show int32  show int64  show int64  show nag_int  show nag_int

Chapter Contents
Chapter Introduction
NAG Toolbox

# NAG Toolbox: nag_lapack_dgebal (f08nh)

## Purpose

nag_lapack_dgebal (f08nh) balances a real general matrix in order to improve the accuracy of computed eigenvalues and/or eigenvectors.

## Syntax

[a, ilo, ihi, scale, info] = f08nh(job, a, 'n', n)
[a, ilo, ihi, scale, info] = nag_lapack_dgebal(job, a, 'n', n)

## Description

nag_lapack_dgebal (f08nh) balances a real general matrix A$A$. The term ‘balancing’ covers two steps, each of which involves a similarity transformation of A$A$. The function can perform either or both of these steps.
1. The function first attempts to permute A$A$ to block upper triangular form by a similarity transformation:
PAPT = A =
 A11 ′ A12 ′ A13 ′ 0 A22 ′ A23 ′ 0 0 A33 ′
$PAPT = A′ = A11′ A12′ A13′ 0 A22′ A23′ 0 0 A33′$
where P$P$ is a permutation matrix, and A11${A}_{11}^{\prime }$ and A33${A}_{33}^{\prime }$ are upper triangular. Then the diagonal elements of A11${A}_{11}^{\prime }$ and A33${A}_{33}^{\prime }$ are eigenvalues of A$A$. The rest of the eigenvalues of A$A$ are the eigenvalues of the central diagonal block A22${A}_{22}^{\prime }$, in rows and columns ilo${i}_{\mathrm{lo}}$ to ihi${i}_{\mathrm{hi}}$. Subsequent operations to compute the eigenvalues of A$A$ (or its Schur factorization) need only be applied to these rows and columns; this can save a significant amount of work if ilo > 1${i}_{\mathrm{lo}}>1$ and ihi < n${i}_{\mathrm{hi}}. If no suitable permutation exists (as is often the case), the function sets ilo = 1${i}_{\mathrm{lo}}=1$ and ihi = n${i}_{\mathrm{hi}}=n$, and A22${A}_{22}^{\prime }$ is the whole of A$A$.
2. The function applies a diagonal similarity transformation to A${A}^{\prime }$, to make the rows and columns of A22${A}_{22}^{\prime }$ as close in norm as possible:
A ′ ′ = DAD − 1 =
 I 0 0 0 D22 0 0 0 I
 A11 ′ A12 ′ A13 ′ 0 A22 ′ A23 ′ 0 0 A33 ′
 I 0 0 0 D22 − 1 0 0 0 I
.
$A′′ = DA′D-1 = I 0 0 0 D22 0 0 0 I A11′ A12′ A13′ 0 A22′ A23′ 0 0 A33′ I 0 0 0 D22-1 0 0 0 I .$
This scaling can reduce the norm of the matrix (i.e., A22 < A22$‖{A}_{22}^{\prime \prime }‖<‖{A}_{22}^{\prime }‖$) and hence reduce the effect of rounding errors on the accuracy of computed eigenvalues and eigenvectors.

## References

Golub G H and Van Loan C F (1996) Matrix Computations (3rd Edition) Johns Hopkins University Press, Baltimore

## Parameters

### Compulsory Input Parameters

1:     job – string (length ≥ 1)
Indicates whether A$A$ is to be permuted and/or scaled (or neither).
job = 'N'${\mathbf{job}}=\text{'N'}$
A$A$ is neither permuted nor scaled (but values are assigned to ilo, ihi and scale).
job = 'P'${\mathbf{job}}=\text{'P'}$
A$A$ is permuted but not scaled.
job = 'S'${\mathbf{job}}=\text{'S'}$
A$A$ is scaled but not permuted.
job = 'B'${\mathbf{job}}=\text{'B'}$
A$A$ is both permuted and scaled.
Constraint: job = 'N'${\mathbf{job}}=\text{'N'}$, 'P'$\text{'P'}$, 'S'$\text{'S'}$ or 'B'$\text{'B'}$.
2:     a(lda, : $:$) – double array
The first dimension of the array a must be at least max (1,n)$\mathrm{max}\phantom{\rule{0.125em}{0ex}}\left(1,{\mathbf{n}}\right)$
The second dimension of the array must be at least max (1,n)$\mathrm{max}\phantom{\rule{0.125em}{0ex}}\left(1,{\mathbf{n}}\right)$
The n$n$ by n$n$ matrix A$A$.

### Optional Input Parameters

1:     n – int64int32nag_int scalar
Default: The first dimension of the array a The second dimension of the array a.
n$n$, the order of the matrix A$A$.
Constraint: n0${\mathbf{n}}\ge 0$.

lda

### Output Parameters

1:     a(lda, : $:$) – double array
The first dimension of the array a will be max (1,n)$\mathrm{max}\phantom{\rule{0.125em}{0ex}}\left(1,{\mathbf{n}}\right)$
The second dimension of the array will be max (1,n)$\mathrm{max}\phantom{\rule{0.125em}{0ex}}\left(1,{\mathbf{n}}\right)$
ldamax (1,n)$\mathit{lda}\ge \mathrm{max}\phantom{\rule{0.125em}{0ex}}\left(1,{\mathbf{n}}\right)$.
a stores the balanced matrix. If job = 'N'${\mathbf{job}}=\text{'N'}$, a is not referenced.
2:     ilo – int64int32nag_int scalar
3:     ihi – int64int32nag_int scalar
The values ilo${i}_{\mathrm{lo}}$ and ihi${i}_{\mathrm{hi}}$ such that on exit a(i,j)${\mathbf{a}}\left(i,j\right)$ is zero if i > j$i>j$ and 1j < ilo$1\le j<{i}_{\mathrm{lo}}$ or ihi < in${i}_{\mathrm{hi}}.
If job = 'N'${\mathbf{job}}=\text{'N'}$ or 'S'$\text{'S'}$, ilo = 1${i}_{\mathrm{lo}}=1$ and ihi = n${i}_{\mathrm{hi}}=n$.
4:     scale(n) – double array
Details of the permutations and scaling factors applied to A$A$. More precisely, if pj${p}_{j}$ is the index of the row and column interchanged with row and column j$j$ and dj${d}_{j}$ is the scaling factor used to balance row and column j$j$ then
scale(j) =
 { pj, j = 1,2, … ,ilo − 1 dj, j = ilo,ilo + 1, … ,ihi  and pj, j = ihi + 1,ihi + 2, … ,n.
$scalej = { pj, j=1,2,…,ilo-1 dj, j=ilo,ilo+1,…,ihi and pj, j=ihi+1,ihi+2,…,n.$
The order in which the interchanges are made is n$n$ to ihi + 1${i}_{\mathrm{hi}}+1$ then 1$1$ to ilo1${i}_{\mathrm{lo}}-1$.
5:     info – int64int32nag_int scalar
info = 0${\mathbf{info}}=0$ unless the function detects an error (see Section [Error Indicators and Warnings]).

## Error Indicators and Warnings

info = i${\mathbf{info}}=-i$
If info = i${\mathbf{info}}=-i$, parameter i$i$ had an illegal value on entry. The parameters are numbered as follows:
1: job, 2: n, 3: a, 4: lda, 5: ilo, 6: ihi, 7: scale, 8: info.
It is possible that info refers to a parameter that is omitted from the MATLAB interface. This usually indicates that an error in one of the other input parameters has caused an incorrect value to be inferred.

## Accuracy

The errors are negligible.

If the matrix A$A$ is balanced by nag_lapack_dgebal (f08nh), then any eigenvectors computed subsequently are eigenvectors of the matrix A${A}^{\prime \prime }$ (see Section [Description]) and hence nag_lapack_dgebak (f08nj) must then be called to transform them back to eigenvectors of A$A$.
If the Schur vectors of A$A$ are required, then this function must not be called with job = 'S'${\mathbf{job}}=\text{'S'}$ or 'B'$\text{'B'}$, because then the balancing transformation is not orthogonal. If this function is called with job = 'P'${\mathbf{job}}=\text{'P'}$, then any Schur vectors computed subsequently are Schur vectors of the matrix A${A}^{\prime \prime }$, and nag_lapack_dgebak (f08nj) must be called (with side = 'R'${\mathbf{side}}=\text{'R'}$) to transform them back to Schur vectors of A$A$.
The total number of floating point operations is approximately proportional to n2${n}^{2}$.
The complex analogue of this function is nag_lapack_zgebal (f08nv).

## Example

```function nag_lapack_dgebal_example
a = [5.14, 0.91, 0, -32.8;
0.91, 0.2, 0, 34.5;
1.9, 0.8, -0.4, -3;
-0.33, 0.35, 0, 0.66];
% Balance a
[a, ilo, ihi, scale, info] = nag_lapack_dgebal('Both', a);
% Reduce a to upper Hessenberg form
[a, tau, info] = nag_lapack_dgehrd(ilo, ihi, a);
% Copy a to h and vr
h = a;
vr = a;
% Form q explicitly, storing results in vr
[vr, info] = nag_lapack_dorghr(int64(1), int64(4), vr, tau);
% Calculate the eigenvalues and Schur factorisation of a
[h, wr, wi, vr, info] = nag_lapack_dhseqr('Schur Form', 'Vectors', ilo, ihi, h, vr);

if (info > 0 )
fprintf('\nFailed to converge.\n');
else
fprintf('\nEigenvalues:\n');
fprintf('   %+9.6f\n',complex(wr,wi));
% Calculate the eigenvectors of a, storing the result in vr
[select, vl, vr, m, info] = ...
nag_lapack_dtrevc('Right', 'Backtransform', false, h, zeros(1), vr, int64(4));
[vr, info] = nag_lapack_dgebak('Both', 'Right', ilo, ihi, scale, vr);
fprintf('\nEigenvectors:\n');
fprintf('   %+9.6f  %+9.6f  %+9.6f  %+9.6f\n',transpose(vr));
end
```
```

Eigenvalues:
-0.400000
-4.020781
+3.013557
+7.007224

Eigenvectors:
+0.000000  -1.964025  -1.168843  -3.814926
+0.000000  +4.000000  -1.981233  +0.687332
+1.000000  -0.215709  -1.000000  -1.000000
+0.000000  -0.437561  -0.130744  +0.236244

```
```function f08nh_example
a = [5.14, 0.91, 0, -32.8;
0.91, 0.2, 0, 34.5;
1.9, 0.8, -0.4, -3;
-0.33, 0.35, 0, 0.66];
% Balance a
[a, ilo, ihi, scale, info] = f08nh('Both', a);
% Reduce a to upper Hessenberg form
[a, tau, info] = f08ne(ilo, ihi, a);
% Copy a to h and vr
h = a;
vr = a;
% Form q explicitly, storing results in vr
[vr, info] = f08nf(int64(1), int64(4), vr, tau);
% Calculate the eigenvalues and Schur factorisation of a
[h, wr, wi, vr, info] = f08pe('Schur Form', 'Vectors', ilo, ihi, h, vr);

if (info > 0 )
fprintf('\nFailed to converge.\n');
else
fprintf('\nEigenvalues:\n');
fprintf('   %+9.6f\n',complex(wr,wi));
% Calculate the eigenvectors of a, storing the result in vr
[select, vl, vr, m, info] = ...
f08qk('Right', 'Backtransform', false, h, zeros(1), vr, int64(4));
[vr, info] = f08nj('Both', 'Right', ilo, ihi, scale, vr);
fprintf('\nEigenvectors:\n');
fprintf('   %+9.6f  %+9.6f  %+9.6f  %+9.6f\n',transpose(vr));
end
```
```

Eigenvalues:
-0.400000
-4.020781
+3.013557
+7.007224

Eigenvectors:
+0.000000  -1.964025  -1.168843  -3.814926
+0.000000  +4.000000  -1.981233  +0.687332
+1.000000  -0.215709  -1.000000  -1.000000
+0.000000  -0.437561  -0.130744  +0.236244

```