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.


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.

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.


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&

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)
}

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;

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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.