Forma reduzida de Row-Echelon de uma matriz

8

O objetivo deste desafio é criar um programa que absorva uma matriz e produza sua forma reduzida de escalão de linha.

Uma matriz está na forma de escalão de linha reduzido se atender a todas as seguintes condições:

  1. Se houver uma linha em que cada entrada seja zero, essa linha ficará abaixo de qualquer outra linha que contenha uma entrada diferente de zero.
  2. A entrada diferente de zero à esquerda de uma linha é igual a 1.
  3. A entrada diferente de zero à esquerda de uma linha é a única entrada diferente de zero em sua coluna.
  4. Considere quaisquer duas entradas diferentes que não sejam zero à esquerda, uma localizada na linha i, coluna j e a outra localizada na linha s, coluna t. Se s>ientão t>j.

Fonte

O processo geral para transformar a matriz é:

  1. Lide com cada linha i de 1 a n por sua vez, e trabalhe nas colunas j de 1 a m pulando qualquer coluna de todas as zero entradas.
  2. Encontre a próxima coluna j com uma entrada diferente de zero.
  3. Troque linhas, se necessário, para que o elemento dinâmico A (i, j) seja diferente de zero.
  4. Torne o pivô igual a 1, dividindo cada elemento na linha de pivô pelo valor do pivô.
  5. Torne todos os elementos acima e abaixo do pivô iguais a 0, subtraindo um múltiplo adequado da linha do pivô.
  6. Repita para todas as linhas.

Se você quiser ler mais sobre esse tipo de matriz, consulte o artigo da Wikipedia sobre ele e uma ferramenta e artigo (etapas acima) que mostram as etapas para transformar a matriz.

Quanto ao desafio real, aqui está:

A entrada pode ser dada da maneira que você desejar através do STDIN ou equivalente, apenas explique-o na sua resposta. A saída será a forma reduzida de escalão de linha da entrada da mesma forma que a entrada por STDOUT ou equivalente. Brechas padrão não são permitidos e bibliotecas ou funções que fazem esta tarefa externas também não são permitidos ( TI-BASIC's rref(comando, por exemplo). Você pode escrever um programa ou função completo. Este é o código de golfe, o menor BYTES vence. Boa sorte!

Exemplo de entrada: [[2,1,1,14][-1,-3,2,-2][4,-6,3,-5]]

Saída de exemplo: [[1,0,0,1][0,1,0,5][0,0,1,7]]

GamrCorps
fonte
5
Você precisa dar algumas explicações sobre o processo de redução aqui, para que essa questão ainda faça sentido quando esses links ficarem ruins.
Sparr
Adicionada uma explicação. Espero que seja detalhado o suficiente.
GamrCorps
É permitido usar `ref ()` `, solucionadores de equações lineares ou quaisquer outros componentes internos que quase resolvam o problema?
lirtosiast
Enquanto há um passo mais complexo que apenas algo como method(ref(matrix)), então eu diria que ir em frente
GamrCorps

Respostas:

2

R, 232 bytes

function(M){p=1;R=nrow(M);C=ncol(M);for(r in 1:R){if(C<=p)break;i=r;while(M[i,p]==0){i=i+1;if(R==i){i=r;p=p+1;if(C==p)return(M)}};t=M[i,];M[i,]=M[r,];M[r,]=t;M[r,]=M[r,]/M[r,p];for(i in 1:R)if(i!=r)M[i,]=M[i,]-M[r,]*M[i,p];p=p+1};M}

Esta é apenas uma implementação do algoritmo de eliminação gaussiano usual.

Ungolfed:

rref <- function(M) {
    p <- 1
    R <- nrow(M)
    C <- ncol(M)
    for (r in 1:R) {
        if (C <= p)
            break
        i <- r
        while (M[i, p] == 0) {
            i <- i + 1
            if (R == i) {
                i <- r
                p <- p + 1
                if (C == p)
                    return(M)
            }
        }
        t <- M[i, ]
        M[i, ] <- M[r, ]
        M[r, ] <- t
        M[r, ] <- M[r, ] / M[r, p]
        for (i in 1:R)
            if (i != r)
                M[i, ] <- M[i, ] - M[r, ] * M[i, p]
        p <- p + 1
    }
    M
}
Alex A.
fonte
Eu acho que você pode ser capaz de fugir com M[c(i,r),]=M[c(r,i),]em vez det=M[i,];M[i,]=M[r,];M[r,]=t
MickyT