2010-03-18 16 views
35

Me gustaría calcular la mathematical rank de una matriz usando scipy. La función más obvia numpy.rank calcula la dimensión de una matriz (es decir, los escalares tienen la dimensión 0, los vectores 1, las matrices 2, etc. ...). Soy consciente de que el módulo numpy.linalg.lstsq tiene esta capacidad, pero me preguntaba si una operación tan fundamental está incorporada en alguna clase de matriz.Calcula la puntuación de matriz usando scipy

Aquí es un ejemplo explícito:

from numpy import matrix, rank 
A = matrix([[1,3,7],[2,8,3],[7,8,1]]) 
print rank(A) 

Esto da 2 la dimensión, donde estoy buscando una respuesta de 3.

+0

Comprobé el rango usando Mathematica - de hecho es 3. La función a la que llama en Python es incorrecta o la está utilizando mal. – duffymo

+3

El uso es correcto; esto es lo que me desconcertó en primer lugar. En la publicación, explico qué es lo que hace rank: calcula la dimensionalidad de la matriz. Una matriz de "rango 3" sería una lista de listas de listas. – Hooked

+0

Tenga en cuenta que el término "rango" es algo ambiguo. Para un tensor, el rango le indica el número de índices (por ejemplo, un escalar es un tensor de rango 0, un rango de vector 1 y un rango de matriz 2). Para el álgebra lineal también existe la definición que cita más arriba. Desde el docstring, está claro que Numpy usa el primero. –

Respuesta

50

Numpy proporciona numpy.linalg.matrix_rank():

>>> import numpy 
>>> numpy.__version__ 
'1.5.1' 
>>> A = numpy.matrix([[1,3,7],[2,8,3],[7,8,1]]) 
>>> numpy.linalg.matrix_rank(A) 
3 
+1

¿Cómo puedo encontrar el rango de ** entero ** matrices ** módulo n **? En Mathematica existe esta función MatrixRank [..., Módulo -> n], pero ¿cómo puedo realizar esta función en Python? –

1

No conozco a Numpy en particular, pero es poco probable que sea una operación integrada en una matriz; implica cálculos numéricos bastante intensos (y preocupaciones relacionadas con el error de redondeo de punto flotante, etc.) y selecciones de umbral que pueden o no ser apropiadas en un contexto dado, y la selección del algoritmo es importante para calcularlo con precisión y rapidez.

Las cosas que se integran en las clases básicas tienden a ser cosas que se pueden realizar de una manera única y directa, como las multiplicaciones de matrices en el más complejo.

+0

Este es un buen punto, una matriz numéricamente inestable podría causar que el rango cambie debido a errores de redondeo. Sin embargo, este es un problema conocido y me preguntaba si las librerías scipy/numpy tienen una función directa. Si la respuesta es no, está bien también, siempre puedo elegir una SVD. – Hooked

+1

No son solo numéricamente inestables. ¿Qué tal {{1.0, 3.0}, {1.0/3.0, 1.0}}? La división no puede producir una respuesta exacta, por lo que debe ser contado como rango 1 o rango 2? –

1

Las funciones de álgebra lineal generalmente se agrupan en numpy.linalg. (También están disponibles en scipy.linalg, que tiene más funciones). Esto permite el polimorfismo: las funciones pueden aceptar cualquiera de los tipos que maneja SciPy.

Por lo tanto, sí, la función numpy.linalg.lstsq hace lo que está preguntando. ¿Por qué es eso insuficiente?

+2

Hace lo que le pido, pero hace mucho más innecesariamente, y con una gran cantidad de equipaje. Lo mismo podría haberse logrado con una descomposición de LU y luego un ordenamiento de filas. La intención de la pregunta, si esto no estaba claro, era si existía una función cuyo único propósito era calcular el rango. Es decir. tomar en matrx, escupir un int. – Hooked

2

Esta respuesta no está actualizada.

La respuesta es no; actualmente no hay ninguna función dedicada al cálculo del rango de matriz de una matriz/matriz en scipy. Se ha discutido agregar uno antes, pero si va a suceder, todavía no lo creo.

+1

Dicho sea de paso, http://mail.scipy.org/pipermail/numpy-discussion/2008-February/031214.html es la primera publicación de una breve discusión de grupos de noticias sobre esto. –

+5

Hoy en día, hay 'numpy.linalg.matrix_rank()'. Ver mi respuesta – Simon

12

Proporcionar un fragmento de código aproximado para las personas que necesitan hacerlo en la práctica. Siéntase libre de mejorar.

u, s, v = np.linalg.svd(A) 
rank = np.sum(s > 1e-10) 
5

Si numpy no ofrece una instalación de rango, ¿por qué no escribe su propio?

Una manera eficiente de calcular el rango es a través de la Descomposición de valores singulares: el rango de la matriz es igual al número de valores singulares distintos de cero.

def rank(A, eps=1e-12): 
    u, s, vh = numpy.linalg.svd(A) 
    return len([x for x in s if abs(x) > eps]) 

en cuenta que eps depende de la aplicación - la mayoría estaría de acuerdo en que 1e-12 corresponde a cero, pero puede ser testigo de inestabilidad numérica incluso para eps = 1e-9.

Usando su ejemplo, la respuesta es tres. Si cambia la segunda fila a [2, 6, 14] (linealmente dependiente de la fila uno), la respuesta es dos (el valor propio "cero" es 4.9960E-16)

1

scipy ahora contiene un eficiente interpolative method para estimar el rango de una matriz/LinearOperator usando métodos aleatorios, que a menudo puede ser lo suficientemente precisa:

>>> from numpy import matrix 
>>> A = matrix([[1,3,7],[2,8,3],[7,8,1]], dtype=float) # doesn't accept int 

>>> import scipy.linalg.interpolative as sli 
>>> sli.estimate_rank(A, eps=1e-10) 
3 
Cuestiones relacionadas