ORTH

 


   more...

Orthogonalizes the columns of a matrix.

Function Return Value

Orthogonal matrix Q from the decomposition A=QR. If A is rank-3, Q is rank-3. (Output)

Required Argument

A — Matrix A to be decomposed. Must be an array of rank-2 or rank-3 (box data) of type real, double, complex, or double complex. (Input)

Optional Arguments, Packaged Options

R — Upper-triangular or upper trapezoidal matrix R, from the QR decomposition. If this optional argument is present, the decomposition is complete. If A is rank-3, R is rank-3. (Output)

The option and derived type names are given in the following tables:

Option Name for ORTH

Option Value

Skip_error_processing

5

 

Name of Unallocated Option Array to Use for Setting Options

Use

Derived Type

?_orth_options(:)

Use when setting options for calls hereafter.

?_options

?_orth_options_once(:)

Use when setting options for next call only.

?_options

For a description on how to use these options, see Matrix Optional Data Changes.

FORTRAN 90 Interface

ORTH (A [])

Description

Orthogonalizes the columns of a matrix. The decomposition A = QR is computed using a forward and backward sweep of the Modified Gram-Schmidt algorithm.

Examples

Example 1: (Operator_ex19.f90)

 

use linear_operators

use lin_sol_tri_int

use rand_int

use Numerical_Libraries

 

implicit none

 

! This is the equivalent of Example 3 (using operators) for LIN_SOL_TRI.

 

integer i, nopt

integer, parameter :: n=128, k=n/4, ncoda=1, lda=2

real(kind(1e0)), parameter :: s_one=1e0, s_zero=0e0

real(kind(1e0)) A(lda,n), EVAL(k)

type(s_options) :: iopt(2)

real(kind(1e0)) d(n), b(n), d_t(2*n,k), c_t(2*n,k), perf_ratio, &

b_t(2*n,k), y_t(2*n,k), eval_t(k), res(n,k)

logical small

 

! This flag is used to get the k largest eigenvalues.

small = .false.

 

! Generate the main diagonal and the co-diagonal of the

! tridiagonal matrix.

b=rand(b); d=rand(d)

A(1,1:)=b; A(2,1:)=d

 

! Use Numerical Libraries routine for the calculation of k

! largest eigenvalues.

CALL EVASB (N, K, A, LDA, NCODA, SMALL, EVAL)

EVAL_T = EVAL

 

! Use IMSL Fortran Numerical Librarytridiagonal solver for inverse iteration

! calculation of eigenvectors.

factorization_choice: do nopt=0,1

 

! Create k tridiagonal problems, one for each inverse

! iteration system.

b_t(1:n,1:k) = spread(b,DIM=2,NCOPIES=k)

c_t(1:n,1:k) = EOSHIFT(b_t(1:n,1:k),SHIFT=1,DIM=1)

d_t(1:n,1:k) = spread(d,DIM=2,NCOPIES=k) - &

spread(EVAL_T,DIM=1,NCOPIES=n)

 

! Start the right-hand side at random values, scaled downward

! to account for the expected 'blowup' in the solution.

y_t=rand(y_t)

 

! Do two iterations for the eigenvectors.

do i=1, 2

y_t(1:n,1:k) = y_t(1:n,1:k)*epsilon(s_one)

call lin_sol_tri(c_t, d_t, b_t, y_t, &

iopt=iopt)

iopt(nopt+1) = s_lin_sol_tri_solve_only

end do

 

! Orthogonalize the eigenvectors. (This is the most

! intensive part of the computing.)

y_t(1:n,1:k) = ORTH(y_t(1:n,1:k))

 

 

! See if the performance ratio is smaller than the value one.

! If it is not the code will re-solve the systems using Gaussian

! Elimination. This is an exceptional event. It is a necessary

! complication for achieving reliable results.

 

res(1:n,1:k) = spread(d,DIM=2,NCOPIES=k)*y_t(1:n,1:k) + &

spread(b,DIM=2,NCOPIES=k)* &

EOSHIFT(y_t(1:n,1:k),SHIFT=-1,DIM=1) + &

EOSHIFT(spread(b,DIM=2,NCOPIES=k)*y_t(1:n,1:k),SHIFT=1) &

- y_t(1:n,1:k)*spread(EVAL_T(1:k),DIM=1,NCOPIES=n)

 

! If the factorization method is Cyclic Reduction and perf_ratio is

! larger than one, re-solve using Gaussian Elimination. If the

! method is already Gaussian Elimination, the loop exits

! and perf_ratio is checked at the end.

perf_ratio = norm(res(1:n,1:k),1) / &

norm(EVAL_T(1:k),1) / &

epsilon(s_one) / (5*n)

if (perf_ratio <= s_one) exit factorization_choice

iopt(nopt+1) = s_lin_sol_tri_use_Gauss_elim

 

end do factorization_choice

 

if (perf_ratio <= s_one) then

write (*,*) 'Example 3 for LIN_SOL_TRI (operators) is correct.'

end if

 

end

Parallel Example

 

use linear_operators

use mpi_setup_int

 

integer, parameter :: N=32, nr=4

real (kind(1.e0)) A(N,N,nr), Q(N,N,nr)

! Setup for MPI

mp_nprocs = mp_setup()

 

if (mp_rank == 0) then

A = rand(A)

end if

 

Q = orth(A)

 

mp_nprocs = mp_setup ('Final')

 

end