// link: eigen real complex vector c_vector i_vector poly #include #include "real.h" #include "complex.h" #include "vector.h" #include "c_vector.h" #include "i_vector.h" #include "poly.h" /* This program finds eigenvalues and, if desired, eigenvector components of a real square matrix of size n by n. First the matrix is transformed so that it consists of one or more companion matrices in diagonal position. Then each companion matrix is transformed so that the eigenvalues are along the diagonal, with each set of k multiple eigenvalues having k-1 ones appearing just above them. If an accuracy check is passed, then eigenvalues and eigenvectors are displayed, otherwise precision is increased and the process repeated. When eigenvectors are desired, the transforming matrix Q is kept track of, and its final form gives the eigenvector components. */ void diagonal_test(); void diagonalize_companion(); void find_companion(); string solution_string(); string Y_col_string(int); string Y_col_string_real(int); string Y_col_string_imag(int); enum eigen_type{group_member, group_end, list_end, eigenvector, near_eigenvector}; int d, distinct_count, eigenvectors_wanted, n, n1, num_blocks, test_trouble = FALSE, transform_trouble = FALSE; real delta; matrix A, A0; cmatrix B, I, Q, Y; smatrix Ae; cvector eigenvalue; ivector companion_bounds, eigen_mult, v_type; imatrix row, kind; int main() { string msg1 = "\n\ Program to find the eigenvalues and eigenvectors of a real square matrix A\ \n\n"; cout << msg1; set_precision(30); int_entry("Enter the number of rows of A ", n, 1, 20, "", "20 rows is max\n"); n1 = n+1; A = matrix(n,n); Q = cmatrix(n,n); int i, j; I = cmatrix(n,n); for (i=0; i max_eigen_mult) max_eigen_mult = h; if (h == 1) r = r_max; else if (h == 2) r = sqrt(r_max); else r = r_max ^ (one / real(h)); i = row(k,0); eigenvalue(k) = B(i,i) % r;} // Check for overlapping eigenvalues; sets may have to be combined. int k1, repeat; do { repeat = FALSE; for (k=0; k 1) { if (test_failure > 50) test_failure = 50; test_failure *= max_eigen_mult;} return;} if (eigenvectors_wanted == FALSE) return; // construct eigenvectors and near eigenvectors int i1, i2, j1, l, last_group; Y = cmatrix(n,n); vector X(n); cvector Y1(n); for (k=0; ki1; i--) { l = row(k1,i-1); X(l) = (X(j) + r_max) / r; j = l;} if (last_group) break; i = ++i2;}} for (i=0; i r) { r = r1; j = i;}} z1 = Y(j,j1); Y(j,j1) = one; if (z1 == zero) { test_trouble = TRUE; return;} for (i=0; i r) { r = r1; j = i;}} z1 = Y(j,j1); Y(j,j1) = one; if (z1 == zero) { test_trouble = TRUE; return;} for (i=0; i= delta) { test_trouble = TRUE; return;} for (i=0; i 1) for (k=1; k be1) { // transform to move pivot element for (k=0; kblock_start; k--) { s = k-1; for (j=0; jblock_start; j--) A(i,j) = A(i,j-1); A(i,block_start) = temp;} if (eigenvectors_wanted) { for (i=0; iblock_start; j--) { Q(i,j).x = Q(i,j-1).x;} Q(i,block_start).x = temp;}} for (i=0; iblock_start; j--) A(j,i) = A(j-1,i); A(block_start,i) = temp;} block_end = block_start;} else { // companion block constructed block_end++; break;}}} companion_bounds(++num_blocks) = block_end; if (block_end == n) break; else block_start = block_end;} } string solution_string() { // Sort eigenvalues by real part or, if real parts equal, by imaginary part int i, j, k, repeat, t, w; do { repeat = FALSE; for (i=1; i lengthr) lengthr = j; j = eigenvalue(i).y.str(1,d).len(); if (j > lengthi) lengthi = j; } if (lengthr > fieldr) fieldr = lengthr; if (lengthi > fieldi) fieldi = lengthi; int total_length = 2 + 3 + fieldr + 2 + fieldi + 2; string out, null; out = string("\n") + null.setw(total_length/2 - 5) + string("Distinct Eigenvalues\n"); int frontsp_r, backsp_r, frontsp_i, backsp_i; frontsp_r = (fieldr - 9)/2; backsp_r = fieldr - frontsp_r - 9; frontsp_i = (fieldi - 14)/2; backsp_i = fieldi - frontsp_i - 14; out += null.setw(fieldr + fieldi + 11) + string("Apparent\n"); out += string("No. ") + null.setw(frontsp_r) + string("Real Part"); out += null.setw(backsp_r + 2 + frontsp_i) + string("Imaginary Part"); out += null.setw(backsp_i) + string(" multiplicity\n"); if (lengthr < fieldr) { frontsp_r = (fieldr - lengthr)/2; backsp_r = fieldr - frontsp_r - lengthr;} else {frontsp_r = 0; backsp_r = 0;} if (lengthi < fieldi) { frontsp_i = (fieldi - lengthi)/2; backsp_i = fieldi - frontsp_i - lengthi;} else {frontsp_i = 0; backsp_i = 0;} w = 2; string::left_adjustment(); for (i=0; i fieldwidth) fieldwidth = printwidth; frontspace = (fieldwidth - 9) / 2; backspace = fieldwidth - 9 - frontspace; string Y_col, null; Y_col = null.setw(3+frontspace) ; frontspace = (fieldwidth - printwidth) / 2; backspace = fieldwidth - frontspace - printwidth; for (i=0; i fieldwidth) fieldwidth = printwidth; frontspace = (fieldwidth - 9) / 2; backspace = fieldwidth - 9 - frontspace; string Y_col, null; Y_col = null.setw(3+frontspace) ; frontspace = (fieldwidth - printwidth) / 2; backspace = fieldwidth - frontspace - printwidth; for (i=0; i fieldwidth) fieldwidth = printwidth; frontspace = (fieldwidth - 9) / 2; backspace = fieldwidth - 9 - frontspace; string Y_col, null; Y_col = string("Component") + null.setw(3+frontspace) + string("Real Part"); Y_col += null.setw(backspace+3+frontspace) + string("Imag Part\n"); frontspace = (fieldwidth - printwidth) / 2; backspace = fieldwidth - frontspace - printwidth; for (i=0; i