> restart:
> # QR ALGORITHM 9.6
> #
> # To obtain the eigenvalues of a symmetric, tridiagonal n by n matrix
> #
> #          a(1)   b(2)
> #          b(2)   a(2)   b(3)
> #             .      .      .
> #               .      .      .
> #                 .      .      .
> #                 b(n-1)  a(n-1)  b(n)
> #                            b(n)   a(n)
> #
> # INPUT:   n: A(1),...,A(n) (diagonal of A): B(2),...,B(n)
> #          (off-diagonal of A): maximum number of iterations M, 
> #          tolerance TOL.
> #
> # OUTPUT:  Eigenvalues of A or recommended splitting of A, or a 
> #          message that the maximum number of iterations was 
> #          exceeded.
> print(`This is the QR Method.`):
> OK := FALSE:
> print(`Choice of input method`):
> print(`1. input from keyboard - not recommended for large matrices`):
> print(`2. input from a text file`):
> print(`Please enter 1 or 2.`):
> FLAG := scanf(`%d`)[1]: print(`Your response is`): print(FLAG):
> if FLAG = 2 then
>    print(`The tridiagonal symmetric array A will be input from `):
>    print(`a text file in the order:`):
>    print(` (diagonal): A(1), A(2), ..., A(n),`):
>    print(` (subdiagonal): B(2), B(3), ..., B(n).`):
>    print(`Place as many entries as desired on each line, but separate `):
>    print(`entries with at least one blank.`):
>    print(`Has the input file been created? - enter 1 for yes or 2 for no.`):
>    AA := scanf(`%d`)[1]: print(`Your response is `): print(AA):
>    if AA = 1 then
>       print(`Input the file name in the form - drive:\\name.ext`):
>       print(`for example:  A:\\DATA.DTA`):
>       NAME := scanf(`%s`)[1]: print(`Input file name is `): print(NAME):
>       INP := fopen(NAME,READ,TEXT):
>       OK := FALSE:
>       while OK = FALSE do
>          print(`Input the dimension n.`):
>          N := scanf(`%d`)[1]: print(`Dimension n = `): print(N):
>          if N > 1 then
>             for I1 from 1 to N do
>                A[I1-1] := fscanf(INP, `%f`)[1]:
>             od:
>             for I1 from 2 to N do
>                B[I1-1] := fscanf(INP, `%f`)[1]:
>             od:
>             OK := TRUE:
>             fclose(INP):
>          else print(`The number must be a positive integer.`):
>          fi:
>       od:  
>    else 
>       print(`The program will end so the input file can be created.`):
>    fi:
> else
>    OK := FALSE:
>    while OK = FALSE do
>       print(`Input the dimension n - an integer.`):
>       N := scanf(`%d`)[1]: print(`n = `): print(N):
>       if N > 0 then
>          print(`The tridiagonal symmetric array A will be input in the order `):
>          print(` (diagonal): A(1), A(2), ..., A(n),`):
>          print(` (subdiagonal): B(2), B(3), ..., B(n).`):          
>          for I1 from 1 to N do
>             print(`Input diagonal entry A(I) for I = `):  print(I1): 
>             A[I1-1] := scanf( `%f`)[1]: print(`Data is `): print(A[I1-1]):
>          od:
>          for I1 from 2 to N do
>             print(`Input subdiagonal entry B[I] for I = `): print(I1):
>             B[I1-1] := scanf(`%f`)[1]: print(`Data is `): print(B[I1-1]):
>          od:
>          OK := TRUE:
>       else print(`The number must be a positive integer.`):
>       fi:
>    od:
> fi:
> if OK = TRUE then
>    OK := FALSE:
>    while OK = FALSE do
>       print(`Input the tolerance.`):
>       TOL := scanf(`%f`)[1]: print(`Tolerance = `): print(TOL):
>       if TOL > 0 then
>          OK := TRUE:
>       else
>          print(`Tolerance must be a positive real number.`):
>       fi:
>    od:
> fi:
> if OK = TRUE then
>    OK := FALSE:
>    while OK = FALSE do
>       print(`Input the maximum number of iterations.`):
>       L := scanf(`%d`)[1]: print(`Maximun number of iterations = `): print(L):
>       if L > 0 then
>          OK := TRUE:
>       else
>          print(`The number must be a positive integer.`):
>       fi:
>    od:
> fi:
> if OK = TRUE then
>    OUP := default:
>    fprintf(OUP, `The original matrix :\n`):
>       fprintf(OUP, `Diagonal:\n`):
>       for I1 from 1 to N do
>          fprintf(OUP, ` %11.8f`, A[I1-1]):
>       od:
>       fprintf(OUP, `\nOff diagonal:\n`):
>       for I1 from 2 to N do
>          fprintf(OUP, ` %11.8f`, B[I1-1]):
>       od:
>       fprintf(OUP, `\n`):
> fi:
> if OK = TRUE then
>    print(`Choice of output method:`):
>    print(`1. Output to screen`):
>    print(`2. Output to text file`):
>    print(`Please enter 1 or 2.`):
>    FLAG := scanf(`%d`)[1]:  print(`Your response is `): print(FLAG):
>    if FLAG = 2 then
>       print(`Input the file name in the form - drive:\\name.ext`):
>       print(`for example  A:\\OUTPUT.DTA`):
>       NAME := scanf(`%s`)[1]: print(`Output file is `):print(NAME):
>       OUP := fopen(NAME,WRITE,TEXT):
>    else
>       OUP := default:
>    fi:
>    fprintf(OUP, `QR METHOD\n\n`):
> # STEP 1 
>    SHIFT := 0:
>    K := 1:
> # STEP 2 
>    while K <= L and OK = TRUE do
>       fprintf(OUP, `Iteration number %d N = %d\n`, K, N):
>       fprintf(OUP, `The array A is now as follows:\n`):
>       fprintf(OUP, `Diagonal:\n`):
>       for I1 from 1 to N do
>          fprintf(OUP, ` %11.8f`, A[I1-1]):
>       od:
>       fprintf(OUP, `\nOff diagonal:\n`):
>       for I1 from 2 to N do
>          fprintf(OUP, ` %11.8f`, B[I1-1]):
>       od:
>       fprintf(OUP, `\n \n`):
> # Steps 3-7 test for success  
> # STEP 3  
>       if abs(B[N-1]) <= TOL then
>          A[N-1] := A[N-1] + SHIFT:
>          fprintf(OUP, `Eigenvalue = %12.8f\n`, A[N-1]):
>          N := N-1:
>       fi:
> # STEP 4
>       if abs(B[1]) <= TOL then
>          A[0] := A[0]+SHIFT:
>          fprintf(OUP, `Eigenvalue = %12.8f\n`, A[0]):
>          N := N-1:
>          A[0] := A[1]:
>          for J from 2 to N do
>             A[J-1] := A[J]:
>             B[J-1] := B[J]:
>          od:
>       fi:
> # STEP 5  
>       if N = 0 then
>          OK := FALSE:
>       fi:
> # STEP 6
>       if N = 1 then
>          A[0] := A[0] + SHIFT:
>          fprintf(OUP,`Eigenvalue = %12.8f\n`, A[0]):
>          OK := FALSE:
>       fi:
> # STEP 7  
>       if OK = TRUE then
>          M := N-1:
>          if M >= 2 then
>             for I1 from 2 to M do
>                if abs(B[I1-1]) <= TOL then
>                   OK := FALSE:
>                   J := I1:
>                fi:
>             od:
>             if OK = FALSE then
>                fprintf(OUP, `Split the matrix into\n`):
>                for I1 from 1 to J-1 do
>                   fprintf(OUP,`%11.8f`,A[I1-1]):
>                od:
>                fprintf(OUP,`\n`):
>                for I1 from 2 to J-1 do
>                   fprintf(OUP,`%11.8f`,B[I1-1]):
>                od:
>                fprintf(OUP,`\n and \n`):
>                for I1 from J to N do
>                   fprintf(OUP,`%11.8f`,A[I1-1]):
>                od:
>                fprintf(OUP,`\n`):
>                for I1 from J+1 to N do
>                   fprintf(OUP,`%11.8f`,B[I1-1]):
>                od:
>                fprintf(OUP,`\n`):
>             fi:
>          fi:
>       fi:
>       if OK = TRUE then
> # STEP 8 
> # compute shift 
>          B1 := -(A[N-1]+A[N-2]):
>          C1 := A[N-1]*A[N-2]-B[N-1]*B[N-1]:
>          D1 := B1*B1-4*C1:
>          if D1 < 0 then
>             fprintf(OUP, `Problem with complex roots, D1 = %.8e\n`, D1):
>             OK := FALSE:
>          else
>             D1 := sqrt(D1):
> #  STEP 9
>             if B1 > 0 then
>                X1 := -2*C1/(B1+D1):
>                X2 := -(B1+D1)/2:
>             else
>                X1 := (D1-B1)/2:
>                X2 := 2*C1/(D1-B1):
>             fi:
> # if N = 2 then the 2 eigenvalues have been computed 
> #  STEP 10  
>             if N = 2 then
>                X1 := X1+SHIFT:
>                X2 := X2+SHIFT:
>                fprintf(OUP, `The last two eigenvalues are: %12.8f%11.8f\n`,X1, X2):
>                OK := FALSE:
>             else
> # STEP 11 
>                if abs(A[N-1]-X1) > abs(A[N-1]-X2) then
>                   X1 := X2:
>                fi:
> # STEP 12 
> # accumulate shift 
>                SHIFT := SHIFT+X1:
> # STEP 13
> # perform shift 
>                for I1 from 1 to N do
>                   DI[I1-1] := A[I1-1]-X1:
>                od:
> # STEP 14 and 15 compute R(K) 
> # STEP 14 
>                X[0] := DI[0]:
>                Y[0] := B[1]:
> # STEP 15 
>                for J from 2 to N do
>                   Z[J-2] := sqrt((X[J-2]*X[J-2])+(B[J-1]*B[J-1])):
>                   C[J-1] := X[J-2]/Z[J-2]:
>                   S[J-1] := B[J-1]/Z[J-2]:
>                   Q[J-2] := C[J-1]*Y[J-2]+S[J-1]*DI[J-1]:
>                   X[J-1] := C[J-1]*DI[J-1]-S[J-1]*Y[J-2]:
>                   if J <> N then
>                      R[J-2] := S[J-1]*B[J]:
>                      Y[J-1] := C[J-1]*B[J]:
>                   fi:
>                od:
>                M := N-1:
>                MM := N-2:
> # Steps 16-18 compute A(K+1) 
> # STEP 16 
>                Z[N-1] := X[N-1]:
>                A[0] := C[1]*Z[0]+S[1]*Q[0]:
>                B[1] := S[1]*Z[1]:
> # STEP 17 
>                if N > 2 then
>                   for J from 2 to M do
>                      A[J-1] := C[J]*C[J-1]*Z[J-1]+S[J]*Q[J-1]:
>                      B[J] := S[J]*Z[J]:
>                   od:
>                fi:
> # STEP 18 
>                A[N-1] := C[N-1]*Z[N-1]:
>             fi:
>          fi:
>       fi:
> # STEP 19 
>       K := K+1:
>    od:
> # STEP 20 
>    if OK = TRUE and K > L then
>       fprintf(OUP, `Maximum Number of Iterations Exceeded.\n`):
>    fi:
> # the process is complete 
>    if OUP <> default then
>       fclose(OUP):
>       print(`Output file `,NAME,` created successfully`):
>    fi:
> fi:
