Determinanti


# Codice Python per metodo di Laplace ed eliminazione di Gauss
# (non ottimizzato)

import numpy as np
from itertools import permutations

def minor(m,i,j):
    return np.delete(np.delete(m,i,axis=0),j,axis=1)

def laplace(m,j=0):
    print("Calcolo determinante minore:\n",m,"\n")
    if len(m)==1:
        return m[0,0]
    res=0
    for i in range(0,len(m)):
        res+= (m[i,j]*pow(-1,i+j)*laplace(minor(m,i,j)))
    return res


def gauss(m):
    print("Matrice=")
    print(m)
    if len(m)==1:
        return m[0,0]
    res=1
    n=m.copy()
    # Cerca entrate non nulle in prima colonna
    i=np.nonzero(n[:,0])[0]
    # Ogni entrata =0 -> colonna di 0 -> det=0
    if len(i)==0:
        return 0
    # Prima riga con entrata non nulla nella prima colonna
    i=min(i)
    # Scambio righe
    if i>0:
        print("Scambio riga ",i+1," e riga ",1,"\n")
        n[[i,0]]=n[[0,i]]
        print(n,"\n")
        res*=-1
        print("Ris. parziale= ",res,"\n")
    # Riduzione
    for j in range(1,len(n)):
        print("Riduzione riga ",j+1,"\n")
        n[j,:] -=  n[j,0]/n[0,0]*n[0,:]
        print(n,"\n")
    # Ricorsione
    print("Aggiornamento risultato\n")
    res*=n[0,0]
    print("Ris. parziale= ",res,"\n")
    print("Sottomatrice...\n")
    return res*gauss(minor(n,0,0))


def segno_permutazione(s0):
    s=list(s0)
    N = len(s)
    res=1
    for i in range(N-1):
        for j in range(i+1, N):
            if s[i] > s[j]:
                s[i], s[j] = s[j], s[i]
                res *= -1
    return res




def detpermutazione(m):
    res=0
    n=len(m)
    for s in permutations(range(n)):
        tmp=1
        sgn=segno_permutazione(s)
        print("Permutazione=",s," Segno=",sgn,"\n")
        for i in range(n):
            tmp *= m[i,s[i]]
        res += sgn*tmp
    return res


# Esempi
m=np.matrix(np.random.randint(0,high=10,size=(6,6)))*1.
laplace(m)
gauss(m)
detpermutazione(m)
np.linalg.det(m)