Pergunta

Eu tenho esta linha de código em MATLAB, escrito por outra pessoa:

c=a.'/b

Eu preciso traduzi-lo em Python. A, B, e C são todas as matrizes. As dimensões que estou usando atualmente para testar o código são:

A: 18x1,
b: 25x18,

que me dá c com dimensões 1x25.

As matrizes não são quadrados, mas eu não gostaria que o código para falhar se eles eram. Alguém pode explicar exatamente o que esta linha está fazendo (matematicamente), e como fazê-lo em Python? (Isto é, o equivalente para o interno em função mrdivide em MATLAB se ela existir em Python?)

Foi útil?

Solução

A linha

c = a.' / b

calcula a solução da equação c b = a T de c . não Numpy não tem um operador que faz isso diretamente. Em vez disso você deve resolver b T c T = a para c T e transposição o resultado:

c = numpy.linalg.lstsq(b.T, a.T)[0].T

Outras dicas

O símbolo / é o operador de divisão direito matriz no MATLAB, que chama a função mrdivide . A partir da documentação, matriz de divisão direita está relacionada com a matriz divisão esquerda em da seguinte maneira:

B/A = (A'\B')'

Se A é uma matriz quadrada, B/A é aproximadamente igual ao B*inv(A) (embora seja calculado de forma diferente, mais robusto). Caso contrário, x = B/A é a solução, no sentido dos mínimos quadrados para o sistema de sub ou sobre-determinado de equações x*A = B. Mais detalhes sobre os algoritmos utilizados para resolver o sistema de equações é dada aqui . Normalmente pacotes como LAPACK ou BLAS são usados ??sob o capô.

O NumPy pacote para Python contém uma rotina de lstsq para o cálculo da solução de mínimos quadrados para um sistema de equações. Esta rotina irá provavelmente dar-lhe resultados comparáveis ??aos usando a função mrdivide em MATLAB, mas é improvável que seja exata . Quaisquer diferenças nos algoritmos subjacentes utilizados por cada função irá provavelmente resultar em respostas que diferem ligeiramente uns dos outros (isto é, uma pode devolver um valor de 1,0, enquanto que o outro pode devolver um valor de 0,999). O tamanho relativo deste erro pode acabar por ser maior, dependendo pesadamente no sistema específico de equações que você está resolvendo.

Para uso lstsq, você pode ter que ajustar o seu problema ligeiramente. Parece que você quer resolver uma equação do formulário cB = a , onde B é 25-por-18, a é 1- por-18, e c é um by-25. Aplicando um transposição para ambos os lados dá-lhe a equação B T c T = a T , que é uma forma mais convencional (isto é, Ax = b ). Os argumentos para lstsq deve ser (nesta ordem) B T (um 18-por-25 de matriz) e a T (uma matriz de 18 elementos). lstsq deve retornar uma matriz de 25 elementos ( c T ).

Nota: enquanto NumPy não faz qualquer distinção entre um 1-por-N ou matriz N-por-1, MATLAB certamente faz, e vai gritar com você, se você não usar o correto.

em Matlab, meios A.' de transposição da matriz A. Então, matematicamente, o que é conseguido no código é A T / B.


Como ir sobre a implementação de divisão matriz em Python (ou qualquer língua) (Nota: Vamos passar por cima de uma simples divisão do A/B forma, pois o seu exemplo, você precisa fazer uma T em primeiro lugar e, em seguida, a T / B ao lado, e é muito fácil de fazer a operação de transposição em Python | deixou-as-a-exercício:) |)

Você tem uma equação matricial C * B = A (Você quer encontrar C como A / B)

divisão correta (/) é a seguinte:

C* (B*B T ) = A*B T

C, em seguida, isolado por inversão (B*B T )

i.,

C = A*B T * (B*B T )' ----- [1]

Portanto, para implementar divisão matriz em Python (ou qualquer língua), obtenha as seguintes três métodos.

  • A multiplicação de matrizes
  • Matrix transposição
  • matriz inversa

Em seguida, aplicá-las de forma iterativa para alcançar divisão como em [1].

Apenas, você precisa fazer um T / B, portanto, a sua operação final depois de implementar os três métodos básicos deve ser:

A T *B T * (B*B T ) '

Nota: Não se esqueça as regras básicas de precedência do operador:)

[editado] Como Suvesh apontou, eu estava completamente errado antes. no entanto, numpy ainda pode facilmente fazer o procedimento que ele dá em seu post:

A = numpy.matrix(numpy.random.random((18, 1))) # as noted by others, your dimensions are off
B = numpy.matrix(numpy.random.random((25, 18)))
C = A.T * B.T * (B * B.T).I

Você também pode abordar esta usando o pseudo-inversa de B seguida, postar multiplicando esse resultado com A. Tente usar numpy.linalg.pinv em seguida, combinar isso com matriz multiplicação via numpy.dot :

c = numpy.dot(a, numpy.linalg.pinv(b))
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top