Matrizes de cofator

18

A matriz de cofator é a transposição da matriz adjuvante . Os elementos desta matriz são os cofatores da matriz original.

O cofator insira a descrição da imagem aqui(isto é, o elemento da matriz de cofator na linha ie coluna j) é o determinante da submatriz formada pela exclusão da i-ésima coluna e-ésima coluna da matriz original, multiplicada por (-1) ^ (i + j).

Por exemplo, para a matriz

insira a descrição da imagem aqui

O elemento da matriz de cofator na linha 1 e coluna 2 é:

insira a descrição da imagem aqui

Você pode encontrar informações sobre qual é o determinante de uma matriz e como calculá-las aqui .

Desafio

Seu objetivo é produzir a matriz de cofator de uma matriz de entrada.

Nota : Built-ins que avaliam matrizes de cofator ou matrizes adjugadas ou determinantes ou algo semelhante são permitidos .

Entrada

A matriz pode ser inserida como um argumento de linha de comando, como um parâmetro de função, STDINou de qualquer maneira que seja mais apropriada para o idioma usado.

A matriz será formatada como uma lista de listas, cada sublist correspondente a uma linha, que contém fatores ordenados da esquerda para a direita. As linhas são ordenadas de cima para baixo na lista.

Por exemplo, a matriz

a b
c d

será representado por [[a,b],[c,d]].

Você pode substituir os colchetes e vírgulas por outra coisa se ela se encaixar no seu idioma e for sensata (por exemplo ((a;b);(c;d)))

Matrizes conterão apenas números inteiros (que podem ser negativos) .

As matrizes sempre serão quadradas (ou seja, o mesmo número de linhas e colunas).

Você pode assumir que a entrada estará sempre correta (ou seja, nenhum problema de formatação, nada além de números inteiros, nenhuma matriz vazia).

Resultado

A matriz de cofator resultante pode ser gerada STDOUT, retornada de uma função, gravada em um arquivo ou qualquer coisa semelhante que naturalmente se adapte ao idioma que você usa.

A matriz do cofator deve ser formatada exatamente da mesma maneira que as matrizes de entrada são fornecidas, por exemplo [[d,-c],[-b,a]]. Se você ler uma sequência, deverá retornar / produzir uma sequência na qual a matriz está formatada exatamente como na entrada. Se você usar algo como, por exemplo, uma lista de listas como entrada, também deverá retornar uma lista de listas.

Casos de teste

  • Entrada: [[1]]

Resultado: [[1]]

  • Entrada: [[1,2],[3,4]]

Resultado: [[4,-3],[-2,1]]

  • Entrada: [[-3,2,-5],[-1,0,-2],[3,-4,1]]

Resultado: [[-8,-5,4],[18,12,-6],[-4,-1,2]]

  • Entrada: [[3,-2,7,5,0],[1,-1,42,12,-10],[7,7,7,7,7],[1,2,3,4,5],[-3,14,-1,5,-9]]

Resultado:

[[9044,-13580,-9709,23982,-9737],[-1981,1330,3689,-3444,406],[14727,7113,2715,-9792,414],[-28448,-2674,-707,16989,14840],[-2149,2569,-2380,5649,-3689]]

Pontuação

Isso é então a resposta mais curta em bytes vence.

Fatalizar
fonte
2
Não tenho certeza de como interpretar a matriz de cofator deve ser formatada da mesma maneira que as matrizes de entrada são fornecidas para envios de funções que obtêm entrada de argumentos e retornam um valor. Lemos / retornamos matrizes reais ou suas representações de string?
Dennis
1
Resumindo: se você ler uma string, deverá retornar / produzir uma string na qual a matriz esteja formatada exatamente como na entrada. Se você usar algo como, por exemplo, uma lista de listas, também deverá retornar uma lista de listas.
Fatalize
Uma matriz 1x1 realmente tem uma matriz de cofator?
Liam
Seu penúltimo caso de teste também parece ser a matriz adjunta (a transposição do que deveria ser), a menos que eu esteja enganado.
Liam
@ICanHazHats Correto, eu corrigi, obrigado.
Fatalize

Respostas:

1

J, 29 bytes

3 :'<.0.5+|:(-/ .**%.)1e_9+y'

O mesmo truque epsilon / inverso / determinante. Da direita para esquerda:

  • 1e_9+ adiciona um epsilon,
  • (-/ .**%.)é determinante ( -/ .*) vezes inverso ( %.),
  • |: transpõe,
  • <.0.5+ rodadas.
Lynn
fonte
5

Matlab, 42 33 bytes

Usando uma função anônima:

@(A)round(inv(A+eps)'*det(A+eps))

Entrada e saída são matrizes (matrizes numéricas 2D).

epsé adicionado caso a matriz seja singular. É "removido" usando round(o resultado verdadeiro é garantido como um número inteiro).

Exemplo:

>> @(A)round(inv(A+eps)'*det(A+eps))
ans = 
    @(A)round(inv(A+eps)'*det(A+eps))
>> ans([-3,2,-5; -1,0,-2; 3,-4,1])
ans =
-8    -5     4
18    12    -6
-4    -1     2

Exemplo com matriz singular:

>> @(A)round(inv(A+eps)'*det(A+eps))
ans = 
    @(A)round(inv(A+eps)*det(A+eps)')
>> ans([1,0 ; 0,0])
ans =
     0     0
     0     1

Ou experimente online no Octave.

Luis Mendo
fonte
2
No entanto, tenho uma preocupação de que não falei no desafio: esta resposta assume que a matriz de entrada é invertível. O uso do seu código no say [1,0 ; 0,0]gera um erro quando deve ser gerado.[0,0 ; 0,1]
Fatalize
1
Como você está retornando de uma função, não acho que você precise mat2str: "a matriz de cofatores resultante pode ser ... retornada de uma função"
FryAmTheEggman
1
@FryAmTheEggman Thanks! Mas " A matriz do cofator deve ser formatada exatamente da mesma maneira que as matrizes de entrada são fornecidas ". É por isso que eu acho que precisomat2str
Luis Mendo
1
@Fatalize Sim, é isso. epsé cerca de 1e-16. Portanto, torna a matriz não singular (mas muito mal condicionada). O resultado não é exatamente inteiro; então fix(arredondar para zero) corrige isso. Isso funciona, desde que o erro não exceda .5. Receio que não haja garantias. Para números inteiros muito grandes, pode falhar. Eu disse que era um truque sujo :-P
Luis Mendo
1
@Fatalize para maior clareza, você poderia dizer se mat2stré necessário aqui? Para mim, parece que, uma vez que essa é uma função, a entrada é realmente a matriz não formatada. Por exemplo, se você tentar f=..., f(f(...))isso não funcionará, mas a remoção mat2strfaz com que funcione bem.
FryAmTheEggman
4

Mathematica, 27 35 bytes

Thread[Det[#+x]Inverse[#+x]]/.x->0&
alefalpha
fonte
Isso funciona para matrizes não invertíveis, por exemplo [[1,0],[0,0]]?
Fatalize
@FryAmTheEggman Isso parece não funcionar.
LegionMammal978
3

R, 121 94 bytes

function(A)t(outer(1:(n=NROW(A)),1:n,Vectorize(function(i,j)(-1)^(i+j)*det(A[-i,-j,drop=F]))))

Essa é uma função absurdamente longa que aceita um objeto de classe matrixe retorna outro objeto. Para chamá-lo, atribua-o a uma variável.

Ungolfed:

cofactor <- function(A) {
    # Get the number of rows (and columns, since A is guaranteed to
    # be square) of the input matrix A
    n <- NROW(A)

    # Define a function that accepts two indices i,j and returns the
    # i,j cofactor
    C <- function(i, j) {
        # Since R loves to drop things into lower dimensions whenever
        # possible, ensure that the minor obtained by column deletion
        # is still a matrix object by adding the drop = FALSE option
        a <- A[-i, -j, drop = FALSE]

        (-1)^(i+j) * det(a)
    }

    # Obtain the adjugate matrix by vectorizing the function C over
    # the indices of A
    adj <- outer(1:n, 1:n, Vectorize(C))

    # Transpose to obtain the cofactor matrix
    t(adj)
}
Alex A.
fonte
80 bytes usando em mapplyvez de outereVectorize
Giuseppe
2

GAP , 246 bytes

Você pode dizer que essa é uma boa codificação pelos for-loops triplos aninhados.

É bem direto. O GAP realmente não tem as mesmas ferramentas para lidar com matrizes que outras linguagens orientadas à matemática. A única coisa realmente usada aqui é o operador determinante incorporado.

f:=function(M)local A,B,i,j,v;A:=StructuralCopy(M);if not Size(M)=1 then for i in [1..Size(M)] do for j in [1..Size(M)] do B:=StructuralCopy(M);for v in B do Remove(v,j);od;Remove(B,i);A[i][j]:= (-1)^(i+j)*DeterminantMat(B);od;od;fi;Print(A);end;

ungolfed:

f:=function(M)
    local A,B,i,j,v;
    A:=StructuralCopy(M);
    if not Size(M)=1 then
        for i in [1..Size(M)] do
            for j in [1..Size(M)] do
                B:=StructuralCopy(M);
                for v in B do
                    Remove(v,j);
                od;
                Remove(B,i);
                 A[i][j]:= (-1)^(i+j)*DeterminantMat(B);
            od;
        od;
    fi;
    Print(A);
end;
Liam
fonte
1

Verbosidade v2 , 196 bytes

IncludeTypePackage<Matrix>
IncludeTypePackage<OutputSystem>
print=OutputSystem:NewOutput<DEFAULT>
input=Matrix:Adjugate<ARGV0>
input=Matrix:Transpose<input>
OutputSystem:DisplayAsText<print;input>

Experimente online!

NB: Atualmente, não funciona no TIO, aguardando uma atração. Deve funcionar offline

Recebe entrada no formulário ((a b)(c d))para representar

[umabcd]

Apesar de ter um construído para o coadjuvante, a verbosidade do Verbosity ainda o prejudica. Bastante básico como ele funciona, apenas transpõe o adjunto da entrada.

caird coinheringaahing
fonte