1
resposta

Erro de precisão ao resolver sistemas lineares com muitas equações

import numpy as np
from numpy import linalg as LA

A = np.random.rand(1,144)
A = A.reshape(12,12)
b = np.array(range(1,13))
x = LA.solve(A,b)
np.dot(A,x) == b

O código acima gera uma matriz 12 x 12 com elementos aleatórios, e um vetor 1 x 12 da forma [1,2,3,4,5,6,7,8,9,10,11,12]. Para encontrar o vetor x que soluciona o sistema A.x = b, teoricamente deve-se utilizar a função LA.solve(A,b) do Numpy. No entanto, ao comparar o produto dot(A,x) com b, não importa quais números aleatórios são gerados em A, dá False (apesar de aproximados). Para a aplicação que estou usando é estritamente necessário que os resultados sejam minimamente precisos (x precisa atender a uma certa simetria), o que faz com que esse procedimento, via função LA.solve não seja interessante para mim. Alguém tem alguma sugestão de uma função para resolver sistemas lineares com muitas equações? (12 equações ainda é um número beem pequeno para as minhas necessidades)

1 resposta

Oii Marcel, como você está?

Peço desculpas pela demora em obter um retorno.

Números de ponto flutuante são uma aproximação, então é comum que dê uma discrepância na comparação — mesmo que mínima, fazendo assim com que os números sejam avaliados como diferentes. Então é necessário atribuir um valor de tolerância para que esses valores sejam considerados como iguais.

A documentação do Numpy recomenda que ao utilizarmos a função solve devemos verificar o sucesso através da função allclose, que irá retornar se as matrizes são iguais a depender de uma faixa de tolerância, que por padrão é 1e-05 (10 elevado a -05 potência, que equivale em torno de 0.000009999999999999999). Sendo assim, para o seu caso, utilizando essa função podemos verificar que os valores estão dentro da faixa aceitável, mas fique tranquilo, você pode alterar essa faixa de tolerância:

import numpy as np
from numpy import linalg as LA

A = np.random.rand(1,144)
A = A.reshape(12,12)
b = np.array(range(1,13))
x = LA.solve(A,b)

np.allclose(np.dot(A, x), b)

Resultado: True

Todavia, se precisar de uma precisão muito certeira, recomendo que trabalhe com arredondamentos, seja do número de casas decimais ou arredondando para o inteiro mais próximo, dessa forma terá um resultado mais preciso.

Qualquer dúvida fico à disposição.

Grande abraço e bons estudos!