Cálculo del espacio nulo de una matriz.

Estoy intentando resolver un conjunto de ecuaciones de la forma Ax = 0. Se conoce una matriz de 6×6 y he escrito el siguiente código usando SVD para obtener el vector x que funciona en cierta medida. La respuesta es aproximadamente correcta pero no lo suficientemente buena como para ser útil para mí. ¿Cómo puedo mejorar la precisión del cálculo? Bajar eps por debajo de 1.e-4 hace que la función falle.

from numpy.linalg import * from numpy import * A = matrix([[0.624010149127497 ,0.020915658603923 ,0.838082638087629 ,62.0778180312547 ,-0.336 ,0], [0.669649399820597 ,0.344105317421833 ,0.0543868015800246 ,49.0194290212841 ,-0.267 ,0], [0.473153758252885 ,0.366893577716959 ,0.924972565581684 ,186.071352614705 ,-1 ,0], [0.0759305208803158 ,0.356365401030535 ,0.126682113674883 ,175.292109352674 ,0 ,-5.201], [0.91160934274653 ,0.32447818779582 ,0.741382053883291 ,0.11536775372698 ,0 ,-0.034], [0.480860406786873 ,0.903499596111067 ,0.542581424762866 ,32.782593418975 ,0 ,-1]]) def null(A, eps=1e-3): u,s,vh = svd(A,full_matrices=1,compute_uv=1) null_space = compress(s <= eps, vh, axis=0) return null_space.T NS = null(A) print "Null space equals ",NS,"\n" print dot(A,NS) 

A es rango completo — entonces x es 0

Dado que parece que necesitas una solución de mínimos cuadrados, es decir, min ||A*x|| st ||x|| = 1 min ||A*x|| st ||x|| = 1 min ||A*x|| st ||x|| = 1 , haga la SVD de manera que [USV] = svd(A) y la última columna de V (suponiendo que las columnas estén ordenadas en orden decreciente de valores singulares) sea x .

Es decir,

 U = -0.23024 -0.23241 0.28225 -0.59968 -0.04403 -0.67213 -0.1818 -0.16426 0.18132 0.39639 0.83929 -0.21343 -0.69008 -0.59685 -0.18202 0.10908 -0.20664 0.28255 -0.65033 0.73984 -0.066702 -0.12447 0.088364 0.0442 -0.00045131 -0.043887 0.71552 -0.32745 0.1436 0.59855 -0.12164 0.11611 0.5813 0.59046 -0.47173 -0.25029 S = 269.62 0 0 0 0 0 0 4.1038 0 0 0 0 0 0 1.656 0 0 0 0 0 0 0.6416 0 0 0 0 0 0 0.49215 0 0 0 0 0 0 0.00027528 V = -0.002597 -0.11341 0.68728 -0.12654 0.70622 0.0050325 -0.0024567 0.018021 0.4439 0.85217 -0.27644 0.0028357 -0.0036713 -0.1539 0.55281 -0.4961 -0.6516 0.00013067 -0.9999 -0.011204 -0.0068651 0.0013713 0.0014128 0.0052698 0.0030264 0.17515 0.02341 -0.020917 -0.0054032 0.98402 0.012996 -0.96557 -0.15623 0.10603 0.014754 0.17788 

Asi que,

 x = 0.0050325 0.0028357 0.00013067 0.0052698 0.98402 0.17788 

Y, ||A*x|| = 0.00027528 ||A*x|| = 0.00027528 diferencia de su solución anterior para x donde ||A*x_old|| = 0.079442 ||A*x_old|| = 0.079442

Atención: Puede haber confusión con la SVD en python vs. matlab-syntax (?): En python, numpy.linalg.svd (A) devuelve las matrices u, s, v de manera que u * s * v = A (estrictamente: punto (u, punto (diag (s), v) = A, porque s es un vector y no una matriz 2D en números).

La respuesta más alta es correcta en ese sentido, por lo general, usted escribe u * s * vh = A y vh se devuelve, y esta respuesta explica v Y NO vh.

Para resumir, si tiene matrices u, s, v de manera que u * s * v = A, entonces las últimas filas de v, no las últimas columnas de v, describen el espacio nulo.

Edición: [para personas como yo:] cada una de las últimas filas es un vector v0 tal que A * v0 = 0 (si el valor singular correspondiente es 0)