Saltar al contenido

Cómo encontrar los vectores propios comunes de dos matrices con valores propios distintos

Hemos buscando en el mundo online para regalarte la solución a tu problema, si continúas con inquietudes puedes dejar tu pregunta y responderemos con gusto, porque estamos para servirte.

Solución:

No creo que haya una función incorporada en Matlab para calcular valores propios comunes de dos matrices. Simplemente describiré la forma de fuerza bruta y lo haré en Matlab para resaltar algunos de sus métodos relacionados con el vector propio. Supondremos que las matrices A y B son cuadradas y diagonalizables.

Esquema de pasos:

  1. Obtenga autovectores / valores para A y B respectivamente.

  2. Agrupe los vectores propios resultantes por sus espacios propios.

  3. Compruebe la intersección de los autoespacios comprobando la dependencia lineal entre los autovectores de A y B, un par de autoespacios a la vez.

¡Matlab proporciona métodos para completar (eficientemente) cada paso! Excepto, por supuesto, que el paso 3 implica verificar la dependencia lineal muchas veces, lo que a su vez significa que es probable que estemos haciendo cálculos innecesarios. Sin mencionar que para encontrar vectores propios comunes puede que no sea necesario encontrar todos los vectores propios. Así que esto no pretende ser una receta numérica general.

Cómo obtener autovectores / valores

La sintaxis es

[V,D] = eig(A)

dónde D(i), V(:,i) son los pares propios correspondientes.

Solo tenga cuidado con los errores numéricos. En otras palabras, si marca

tol=sum(abs(A*V(:,i)-D(i)*V(:,i)));

toleps debiera ser true para algunos pequeños n para una matriz A más pequeña, pero probablemente no sea true para 0 o 1.

Ejemplo:

>> A = gallery('lehmer',4);
>> [V,D] = eig(A);
>> sum(abs(A*V(:,1)-D(1)*V(:,1)))> sum(abs(A*V(:,1)-D(1)*V(:,1)))<10*eps
ans =
  logical
   1

Cómo agrupar los vectores propios por sus espacios propios

En Matlab, los valores propios no se ordenan automáticamente en la salida de [V,D] = eig(A). Entonces necesitas hacer eso.

  • Obtenga entradas diagonales de la matriz: diag(D)

  • Ordene y realice un seguimiento de la permutación necesaria para la clasificación: [d,I]=sort(diag(D))

  • Identificar elementos repetidos en d: [~,ia,~]=unique(d,'stable')

ia(i) te dice el índice inicial del iel eigenspace. Entonces puedes esperar d(ia(i):ia(i+1)-1) ser valores propios idnticos y, por tanto, los vectores propios pertenecientes a la iel eigenspace son las columnas W(:,ia(i):ia(i+1)-1) dónde W=V(:,I). Por supuesto, para el último, el índice es ia(end):end

El último paso se responde aquí en true generalidad. Aquí, unique es suficiente al menos para pequeños A.

(Siéntase libre de hacer una pregunta separada sobre cómo hacer todo este paso de "mezclar columnas de una matriz en base a otra matriz diagonal" de manera eficiente. Probablemente existen otros métodos eficientes que usan funciones integradas de Matlab).

Por ejemplo,

>> A=[1,2,0;1,2,2;3,6,1];
>> [V,D] = eig(A),
V =
         0         0    0.7071
    1.0000   -0.7071         0
         0    0.7071   -0.7071
D =
     3     0     0
     0     5     0
     0     0     3
>> [d,I]=sort(diag(D));
>> W=V(:,I),
W =
         0    0.7071         0
    1.0000         0   -0.7071
         0   -0.7071    0.7071
>> [~,ia,~]=unique(d,'stable'),
ia =
     1
     3

lo cual tiene sentido porque el primer espacio propio es el que tiene el valor propio 3 que comprende el intervalo de la columna 1 y 2 de W, y de manera similar para el segundo espacio.

Cómo obtener una intersección lineal de (el lapso de) dos conjuntos

Para completar la tarea de encontrar vectores propios comunes, haga lo anterior para ambos A y B. A continuación, para cada par de espacios propios, verifica la dependencia lineal. Si hay dependencia lineal, la intersección lineal es un respuesta.

Hay varias formas de verificar la dependencia lineal. Uno es utilizar las herramientas de otras personas. Ejemplo: https://www.mathworks.com/matlabcentral/fileexchange/32060-intersection-of-linear-subspaces

Uno es obtener el RREF de la matriz formada concatenando los vectores de columna en forma de columna.

Digamos que hizo el cálculo en el paso 2 y llegó a V1, D1, d1, W1, ia1 por A y V2, D2, d2, W2, ia2 por B. Necesitas hacer

for i=1:numel(ia1)
    for j=1:numel(ia2)
         check_linear_dependency(col1,col2);
    end
end

dónde col1 es W1(:,ia1(i):ia1(i+1)-1) como se mencionó en el paso 2 pero con la advertencia para el último espacio y de manera similar para col2 y por check_linear_dependency nos referimos a los siguientes. Primero obtenemos RREF:

[R,p] = rref([col1,col2]);

Usted está buscando, primero, rank([col1,col2]). Si ha calculado rref de todos modos, ya tienes el rango. Puede consultar la documentación de Matlab para obtener más detalles. Deberá perfilar su código para seleccionar el método más eficiente. Me abstendré de estimar-estimar lo que Matlab hace en rank(). Aunque si haciendo rank() implica hacer el trabajo en rref puede hacer un bien separar pregunta.

En los casos en que rank([col1,col2]) es true, algunas filas no tienen 1 a la izquierda y creo que p le ayudará a rastrear qué columnas dependen de qué otras columnas. Y puedes construir la intersección desde aquí. Como de costumbre, esté alerta a los errores numéricos que se interponen en el camino de == declaraciones. Estamos llegando al punto de una pregunta diferente, es decir. cómo obtener una intersección lineal de rref() en Matlab, así que lo voy a dejar aquí.

Hay otra forma más de usar el teorema fundamental del álgebra lineal (* suspiro ante ese desafortunado nombre):

null( [null(col1.').' ; null(col2.').'] )

La fórmula que obtuve de aquí. Creo que ftla es la razón por la que debería funcionar. Si ese no es el motivo o si quiere estar seguro de que la fórmula funciona (lo que probablemente debería), pregunte a un separar pregunta. Solo tenga en cuenta que las preguntas puramente matemáticas deben ir en un sitio de stackexchange diferente.


¡Ahora supongo que hemos terminado!


EDITAR 1:

Seamos más claros sobre cómo ia funciona con un ejemplo. Digamos que nombramos todo con un final 1 por A y 2 por B. Nosotros necesitamos

for i=1:numel(ia1)
    for j=1:numel(ia2)
        if i==numel(ia1)
            col1 = W1(:,ia1(end):end);
        else
            col1 = W1(:,ia1(i):ia1(i+1)-1);
        end
        if j==numel(ia2)
            col2 = W2(:,ia2(j):ia2(j+1)-1);
        else
            col2 = W2(:,ia2(end):end);
        end
        check_linear_dependency(col1,col2);
    end
end

EDITAR 2:

Debo mencionar la observación de que los vectores propios comunes deben ser los del espacio nulo del conmutador. Por lo tanto, tal vez null(A*B-B*A) produce el mismo resultado.

Pero aún esté alerta a los errores numéricos. Con el método de fuerza bruta, comenzamos con pares propios con baja tol (vea la definición en las secciones anteriores) y así ya verificamos la parte "eigen" en los autovectores. Con null(A*B-B*A), también debería hacerse lo mismo.

Por supuesto, con varios métodos a mano, es una buena idea comparar los resultados entre métodos.

Sospecho que se trata de un asunto bastante delicado.

En primer lugar, matemáticamente, A y B son simultáneamente diagonalizables si se conmutan, es decir, si

A*B - B*A == 0 (often A*B-B*A is written [A,B])
(for if A*X = X*a and B*X = X*b with a, b diagonal then
A = X*a*inv(X), B = X*b*inv(X) 
[A,B] = X*[a,b]*inv(X) = 0 since a and b, being diagonal, commute)

Entonces, diría que lo primero que debe verificar es que su A y B se conmuten, y aquí está el primer problema incómodo: desde [A,B] como es poco probable que el cálculo sea todo ceros debido a un error de redondeo, deberá decidir si [A,B] ser distinto de cero se debe solo a un error de redondeo o si, en realidad, A y B no se desplazan.

Ahora suponga que x es un vector propio de A, con valor propio e. Luego

A*B*x = B*A*x = B*e*x = e*B*x

Y entonces tenemos, matemáticamente, dos posibilidades: o Bx es 0, o Bx es también un autovector de A con autovalor e.

Un buen caso es cuando todos los elementos de a son diferentes, es decir, cuando cada espacio propio de A es unidimensional. En ese caso: si AX = Xa para la diagonal a, entonces BX = Xb para la diagonal b (que deberá calcular). Si diagonaliza A, y todos los valores propios son suficientemente diferentes, entonces puede asumir que cada espacio propio es de dimensión 1, pero ¿qué significa "suficientemente"? Otra pregunta delicada, ay. Si dos autovalores calculados son muy cercanos, ¿son los autovalores diferentes o es el error de redondeo de la diferencia? De todos modos, para calcular los autovalores de b para cada autovector x de A, calcule Bx. Si || Bx || es lo suficientemente pequeño en comparación con || x || entonces el valor propio de B es 0, de lo contrario es

x'*B*x/(x'*x) 

En el caso general, algunos de los espacios propios pueden tener una dimensión mayor que 1. Los espacios propios unidimensionales pueden tratarse como se indicó anteriormente, pero se requieren más cálculos para los de dimensiones superiores.

Suponga que m autovectores x[1].. X[m] de A corresponden al valor propio e. Dado que A y B se desplazan, es fácil ver que B mapea el espacio abarcado por las x a sí mismo. Sea C la matriz mxm

C[i,j] = x[j]'*B*x[i]

Entonces C es simétrica y entonces podemos diagonalizarla, es decir, encontrar la V ortogonal y la diagonal c con

C = V'*c*V

Si definimos

y[l] = Sum k  l=1..m

luego un poco de álgebra muestra que y[l] es un autovector de B, con autovalor c[l]. Además, dado que cada x[i] es un vector propio de A con el mismo valor propio e, cada y[l] es también un autovector de A con autovector e.

Entonces, en general, creo que un método sería:

  1. Calcular [A,B] y si realmente no es 0, ríndete
  2. Diagonalice A y ordene los autovalores para que sean crecientes (¡y ordene los autovectores!)
  3. Identifique los espacios propios de A. Para los espacios unidimensionales, el vector propio correspondiente de A es un vector propio de B, y todo lo que necesita calcular es el valor propio de B. Para los espacios de dimensión superior, proceda como en el párrafo anterior.

Una manera relativamente cara (en esfuerzo computacional) pero razonablemente confiable de probar si el conmutador es cero sería calcular el svd del conmutador y tomar el valor singular más grande, digamos c, y también tomar el valor singular más grande (o el valor absoluto más grande valor de los valores propios) a de A y b de B. A menos que c sea mucho más pequeño (por ejemplo, 1e-10 veces) el menor de ayb, debe concluir que el conmutador no es cero.

Aquí tienes las comentarios y calificaciones

Si estás de acuerdo, tienes el poder dejar una crónica acerca de qué le añadirías a este ensayo.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Respuestas a preguntas comunes sobre programacion y tecnología