⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jacobinomax.m

📁 jacobi algorithm matlab code
💻 M
字号:
%%%%%%%%%%%%%%%%%%%JACOBI ALGORITHM WITHOUT SORTING%%%%%%%%%%%%%%%%%%%%%%%

%%INPUT
%%randMatrix is the matrix we wish to diagonalize. It's only random for the
% first interation
%%k is our current iteration
%%A is the matrix previous to randMatrix 

%%OUTPUT
%%D is the more diagonal matrix
%%bk is the off(D)
%%k is the number of iterations

function [D, bk, k, originalMatrix] = jacobiNoMax(randMatrix, k, A)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%Creating the random symmetric matrix [START]%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    if (size(randMatrix)==[0,0])
        
        %randMatrix is our random 5 x 5 symmetric matrix and is initialized
        %to be completely filled with 0's
        randMatrix = zeros(5,5);
        
        %If the row is equal to the column then we are on the diagonal
        %and thus the values needn't be mirrored. If we are not on
        %the diagonal, then we need to mirror the random value on the
        %other side of the diagonal to create a symmetric matrix. When 
        %a random value is stored in randMatrix(row, column), it is also 
        %stored in (column, row), thus "mirroring" the value. 
        %
        %We will loop through the x portion of the randMatrix:
        %      | x 0 0 0 0 |
        %      | x x 0 0 0 |
        %      | x x x 0 0 |
        %      | x x x x 0 |
        %      | x x x x x |
        %and mirror the off-diagonal elements. The diagonal elements will a
        %sense be "mirrored" too, but mirrored with its own position. 
        %Ex: row=2, column=2, randNumber is some random value
        %    then randMatrix (row, col) = randNumber;
        %         randMatrix (col, row) = randNumber;
        %    is   randMatrix (2,2) = randNumber;
        %         randMatrix (2,2) = randNumber;
        
        for (row = 1:5)
            for (col = 1:row)
                  %randNumber is a random number on the interval [0,10]  
                  randNumber = floor(rand*10);
                  %change the value at randMatrix(row, col) to the random number
                  randMatrix (row, col) = randNumber;
                  %mirror the value at randMatrix(col, row)
                  randMatrix (col, row) = randNumber;
            end
        end
    end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%Creating the random symmetric matrix randMatrix [END]%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

originalMatrix = randMatrix;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%Randomly selecting an off-diagonal entry and the 2 x 2 matrix%%%%%%%% 
%%%%%%containing that entry [START]%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    
    %B will our 2 x 2 matrix
    B = zeros(2,2);
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %%%%ONLY PORTION DIFFERENT FROM JACOBI ALGORITHM WITH SORTING%%%%%%%%%    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%    
  
    %Instead of looking for the off-diagonal entry with the largest
    %magnitude. We instead randomly choose an off diagonal entry.
    maxRow = 0;
    maxCol = 0;
    
    %Since our modified rand() will generate random numbers from 0 to 5,
    %we need to loop until neither numbers are 0 because matlab begins
    %indexing at 1 instead of 0 like most other languages and until the
    %two numbers are not equal, because we wish for an off-diagonal entry
    %rather than a diagonal entry.
    %%
    while (maxRow == 0)||(maxCol == 0)||(maxRow == maxCol)
        maxRow = abs(floor(rand()*10)-4);
        maxCol = abs(floor(rand()*10)-4);
    end
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    %So we've found the entry. Now we need to use it to find a 2 x 2
    %symmetric matrix that we can diagonalize. The matrix basically follows
    %this formula which should hold true any n x n symmetric matrix where 
    %n >=3:
    %B = | randMatrix(maxRow, maxRow)  randMatrix(maxRow, maxCol) |
    %    | randMatrix(maxRow, maxCol)  randMatrix(maxCol, maxCol) | 
    B(1,2) = randMatrix(maxRow, maxCol);
    B(2,1) = randMatrix(maxRow, maxCol);
    B(1,1) = randMatrix(maxRow, maxRow);
    B(2,2) = randMatrix(maxCol, maxCol);
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%Randomly selecting an off-diagonal entry and the 2 x 2 matrix%%%%%%%% 
%%%%%%containing that entry [END]%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%Diagonalizing 2 x 2 symmetric matrix B [START]%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    % a, b, d will be used the calculation of the eigenvalues where:
    % B = |a b |
    %     |b d |
    a = B(1,1);
    b = B(1,2);
    d = B(2,2);
    I = [1 0; 0 1];
    
    %In order to diagonalize the matrix, we set the det(B-(mu*I)) equal to 
    %0 and solve for mu:
    %    0 = det | a - mu  b    |
    %            | b       d-mu |
    %   0 = (a-mu)*(d-mu) - b^2
    %   0 = mu^2 - (d+a)mu + (ad-b^2)
    %   In this form, we can use the quadatric formula to solve for mu:
    %       mu+ = myPlus  = ((d+a) + sqrt((d-a)^2 + 4*b^2))/2
    %       mu- = muMinus =((d+a) - sqrt((d-a)^2 + 4*b^2))/2
    %But we also need to check if b is equal to 0, because if it is then
    %this matrix is already diagonalized. We can eliminate needless
    %calculations and avoid incidents that will cause our matrix to be 
    %filled with NaN (not a number) values. ie divide by zero or squareroot
    %of a negative number.
    if (b ~= 0)
        muPlus = ((d+a) + sqrt((d-a).^2 + 4.*b.^2))./2;
        muMinus = ((d+a) - sqrt((d-a).^2 + 4.*b.^2))./2;
        %Now we plug in the eigenvalues where u1 and u2 are the results of that
        %plugging in, though it's not really necessary that we calculate the
        %u2
        u1 = B - (muPlus*I);
        if (u1 == NaN)
            u1 = B - (muMinus*I);
        end
        u2 = B - (muMinus*I);

        %u1R1 is the first column of our soon to be normalized matrix u. u1R1
        %is obtained from the first row of the u1 with the appropriate sign
        %flipping. Ex:  u1 = |a b|
        %                    |c d|
        %               u1R1 = |-b|
        %                      | a|
        %but technically we could skip the skip of actually looking for the
        %eigenvalues is the sum of the first row is equal to the sum of the
        %second. Ex:    | 2 1 | = 3
        %               | 1 2 | = 3
        %We can assume that |1| to be our u1R1.
        %                   |1|
        u1R1 = [-u1(1,2) u1(1,1)]';
        if (sum(B(1,:))==sum(B(2,:)))
            u1R1 = [1 1]';
        end

        %u2R1 is the second column of matrix u and is obtained from u1R1 again
        %with the appropriate flipping. 
        %           Ex: u1R1 = |a|
        %                      |b|
        %               u1R2 = |-b|
        %                      | a|
        u2R1 = [-u1R1(2) u1R1(1)]';

        %u1Length is the 1/||u1R1||. The length for u2R1 is the same as u1R1 so
        %there is no need to calculate it again.
        u1Length = 1/(sqrt(u1R1(1)^2 + u1R1(2)^2));

        %The first column of matrix u is u1R1 and the second is u2R1. u is
        %normalized because its components are both normalized.
         u = u1Length*[u1R1 u2R1];


        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        %%%%%%%%%%%%%%%%%%%Creating the Givens Matrix [START]%%%%%%%%%%%%%%%%%%
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            %%G will be our Givens matrix, first filled with 0's 
            G = zeros(5,5);

            %We place entries from the u into G that correspond to the entries
            %that were taken from the original matrix randMatrix
            G(maxRow, maxCol) = u(1,2);
            G(maxCol, maxRow) = u(2,1);
            G(maxRow, maxRow) = u(1,1);
            G(maxCol, maxCol) = u(2,2);

            %We loop through G placing 1's on the diagonal where the value
            %is 0.
            for row=1:5
                for col=1:5
                    if (row==col)
                        if (G(row,col)==0)
                            G(row,col)=1;
                        end
                    end
                end
            end
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        %%%%%%%%%%%%%%%%%%%Creating the Givens Matrix [END]%%%%%%%%%%%%%%%%%%%%
        %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

        %D is our final more-diagonal matrix that we return
        D = G'*randMatrix*G;
    else
        D = randMatrix;
    end
    %bk is the value of the OFF(D), where OFF(x) is the sum of the square of 
    %each off-diagonal elements of x 
    bk = 0;
    for (row = 2:5)
            for (col = 1:row-1)
                bk = bk + 2*(D(row, col))^2;
            end
    end

    %increment k
    k=k+1;
    
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%Diagonalizing 2 x 2 symmetric matrix B [END]%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -