Esercizio sagemath per la costruzione di applicazioni lineari

Pubblicità

Rahab97

Utente Attivo
Messaggi
213
Reazioni
19
Punteggio
37
Salve ragazzi avrei bisogno di aiuto con un esercizio su sagemath. Spero si possa condividere il codice senza troppi problemi. Avrei un paio di domande a riguardo.
Premetto che, sono sicuro al 100% non sia ottimizzato ma non mi interessa ai fini della risoluzione.
Premetto pure che il codice che inserirò dopo è perfettamente funzionante.
La prima domanda è perché
Codice:
random_matrix(SR,n,m)
mi genera matrici casuali, con soli numeri interi compresi tra -2 e 2? Avrei bisogno di una matrice con un range più grande e che includa frazioni, numeri irrazionali, immaginari ecc.
Per la seconda domanda devo inserirvi codice e traccia quindi la metto a fine codice
Devo scrivere un codice che accetta in input un'applicazione 𝑓:ℝ^𝑚→ℝ^𝑛 con m>n e dopo aver verificato sia surgettiva deve costruirmi 𝑔:ℝ^𝑛→ℝ^𝑚 tale che 𝑓∘𝑔 sia la funzione identità.
Ho scritto un codice che genera delle applicazioni lineari (ripeto, non è ottimizzato sicuramente) in base a varie necessità:
Probabilmente la prima parte di codice è inutile però non si sa mai.
Codice:
reset()
show('''Scegli, indicando la lettera (in maiuscolo), come vuoi fornire o generare
l'applicazione lineare tra le seguenti possibilita:''')
show('''A) Vuoi inserire manualmente la relazione funzionale?
B) Vuoi fornire due basi di due spazi vettoriali V e W, di dimensione prefissata (m>n), e una matrice?
C) Vuoi che l'applicazione lineare sia generata casualmente a partire da una matrice casuale (mxn, m>n)?
D) Vuoi fornire solo la matrice di dimensioni note?''')
I=input()
var('A,B,C,D,Y,N')
W = None
if I==str(A):
    while True:
        m = int(input('Inserisci la dimensione del dominio: '))
        n = int(input('Inserisci la dimensione del codominio: '))
        if m>n:  
            # Definizione delle variabili
            alfabeto = 'abcdefghijklmnopqrstuvwxyz'
            variabili = [var(alfabeto[i]) for i in range(m)]
   
            # Visualizzazione delle variabili
            show('Le variabili utilizzabili sono le seguenti: ',variabili)
            show('Il numero di "relazioni" necessarie fornire è ' +str(n))

            # Input delle relazioni come una stringa separata da virgole e verifica della lunghezza
            while True:
                relazione_input = input("Inserisci la relazione funzionale per intero separata da virgole (ad esempio 2*a,b,c+a): ")
                # Divisione della relazione basata sulla virgola e formattazione della lista relazioni
                relazioni = relazione_input.split(',')
                #Verifica che
                if len(relazioni) != n:
                    print(f"Il numero di relazioni fornite non corrisponde alla dimensione del codominio ({n}). Riprova.")
                else:
                    break
            # Creazione dell'applicazione lineare
            f = lambda x: [eval(relazione, {alfabeto[i]: x[i] for i in range(m)}) for relazione in relazioni]
            show(f(variabili))
            f=linear_transformation(SR^m,SR^n,f)
            show(f)
            break
        else:
            print('La dimensione del dominio è minore di quella del codominio. Riprova.')
   
elif I==str(B):
     while True:
        #chiede e verifica che le dimensioni rispettino la condizione m>n
        m=int(input('Scegli la dimensione del dominio '))
        n=int(input('Scegli la dimensione del codominio '))
        if m>n:
            baseV=[]
            baseW=[]
            A=[]
           
            #Acquisisce i vettori della base di V assicurandosi che abbiano lunghezza adeguata
            for j in range(m):
                while True:
                    vettore = input(f"Inserisci il vettore {j+1} della base di V come lista di numeri separati da virgola: ")
                    vettore = [eval(x) for x in vettore.split(',')]
                    if len(vettore) != m:
                        print(f"Il vettore deve avere lunghezza {m}. Riprova.")
                    else:
                        baseV.append(vettore)
                        break
                       
            #Acquisisce i vettori della base di V assicurandosi che abbiano lunghezza adeguata          
            for j in range(n):
                while True:
                    vettore = input(f"Inserisci il vettore {j+1} della base di W come lista di numeri separati da virgola: ")
                    vettore = [eval(x) for x in vettore.split(',')]
                    if len(vettore) != n:
                        print(f"Il vettore deve avere lunghezza {n}. Riprova.")
                    else:
                        baseW.append(vettore)
                        break
            show('Vuoi che almeno la matrice sia casuale? ')
            I= input('Y/N ')
            if I==str(Y):
                #Genera una matrice casuale di dimensione n x m
                A = random_matrix(SR, n, m)
                show('La matrice generata casualmente è A= ',A)
                show('Il rango di A è ' +str(rank(A)))      
           
            else:
                #Acquisisce i vettori riga che formano la matrice A assicurandosi che abbiano lunghezza adeguata          
                for j in range(n):
                    while True:
                        riga = input(f"Inserisci la riga {j+1} della matrice come lista di numeri separati da virgola (lunghezza {m}): ")
                        riga = [eval(x) for x in riga.split(',')]
                        if len(riga) != m:
                            print(f"La riga della matrice deve avere lunghezza {m}. Riprova.")
                        else:
                            A.append(riga)
                            break
                                       
                 
                   
            #Genera e mostra V,W e A e definisce l'applicazione lineare
            A=matrix(A)
            V = VectorSpace(SR, m).subspace_with_basis(baseV)
            W = VectorSpace(SR, n).subspace_with_basis(baseW)
            show('V= ',V)
            show('W=',W)
            show('A=',A)
            f=linear_transformation(V,W,A,side='right')  
            show(f)
            break
        else:
            print('La dimensione del dominio è minore di quella del codominio. Riprova.')

elif I==str(C):
    while True:
        m = ZZ.random_element(1, 10)  # Genera un numero casuale tra 1 e 10
        n = ZZ.random_element(1, 10)  # Genera un altro numero casuale tra 1 e 10      
        if m > n:
            break
    show('La dimensione di V è m = '+ str(m), ', La dimensione di W è n = ' + str(n))
   
    #Genera una matrice casuale di dimensione n x m
    A = random_matrix(SR, n, m)
    show('La matrice generata casualmente è A= ',A)
    show('Il rango di A è ' +str(rank(A)))
    f=linear_transformation(A,side='right')
    show(f)  

elif I==str(D):
    A=[]
    while True:
            m=int(input('Scegli la dimensione del dominio (colonne) '))
            n=int(input('Scegli la dimensione del codominio (righe) '))
            if m>n:
                #Acquisisce i vettori riga che formano la matrice A assicurandosi che abbiano lunghezza adeguata          
                for j in range(n):
                    while True:
                        riga = input(f"Inserisci la riga {j+1} della matrice come lista di numeri separati da virgola (lunghezza {m}): ")
                        riga = [eval(x) for x in riga.split(',')]
                        if len(riga) != m:
                            print(f"La riga della matrice deve avere lunghezza {m}. Riprova.")
                        else:
                            A.append(riga)
                            break
                A=matrix(SR,A)
                show('A=',A)
                f=linear_transformation(A,side='right')
                show(f)
                break
            else:
                print('La dimensione del dominio è minore di quella del codominio. Riprova.')

Dopodiché ho scritto il codice per risolvere il secondo punto.
Codice:
if f.is_surjective():
    # Se W (e quindi V) non è definito, costruisce la matrice associata a f e g tramite la pseudoinversa
    if W is None:
        A = f.matrix()
        g = linear_transformation(A.pseudoinverse())
 
    # Altrimenti direttamente g  
    else:      
        g = linear_transformation(A.pseudoinverse(),side='right')
       
    #verifica che la composizione di f e g coincide con l'identità
    if (f * g).is_identity() == True:
        show('''la composizione di f con g coincide con l'applicazione identica''')
        show("f:  ", f)
        show("g:  ", g)
        show("fog: ",f*g)
     
    else:
        show('''la composizione di f con g non coincide con l'applicazione identica''')
        show("f:  ", f)
        show("g:  ", g)
       
else:
        show('f non è surgettiva')

Il problema è che ho usato il concetto di pseudoinversa, quando invece vorrei farne a meno ma non ho assolutamente idea di come, eventualmente ragionando con le matrici, poter trovare una matrice B tale che $A*B=I$. Inizialmente avevo creato una matrice fatta di sole variabili ma chiaramente non riusciva a risolvermi il sistema lineare associato a causa dei numerosi parametri liberi. Poi ho cercato allora di creare un codice che sostituisse parzialmente tali variabili con numeri casuali ma poi non trovava alcuna soluzione.
La seconda domanda è: avete qualche idea alternativa, più semplice (anche più articolata) che eviti il concetto di pseudoinversa per risolvere questo punto?

Vi ringrazio in anticipo per il vostro aiuto! e vi chiedo scusa per il testo lunghissimo! Se devo modificare qualcosa ditemelo pure e procedo.
 
La prima domanda è perché
Codice:
random_matrix(SR,n,m)
mi genera matrici casuali, con soli numeri interi compresi tra -2 e 2?
guarda l'help online: https://doc.sagemath.org/html/en/re...pecial.html#sage.matrix.special.random_matrix
ad un certo punto dice
The distribution keyword set to uniform will limit values between -2 and 2.
purtroppo non conosco il sw e non so aiutarti oltre, ma penso che devi cambiare opportunamente o i paramteri della funzione in input (l'assenza di alcuni di essi imposta automaticamente dei valori predefiniti) oppure devi fare delle operazioni preliminari per estendere l'intervallo di numeri casuali
però come includere numeri immaginari non saprei, tra l'altro se dai un range di reali non non credo che uno randomizzatore crei dei bumer complessi, sempre che non ci siano librerie fatte apposta
 
guarda l'help online: https://doc.sagemath.org/html/en/re...pecial.html#sage.matrix.special.random_matrix
ad un certo punto dice
The distribution keyword set to uniform will limit values between -2 and 2.
purtroppo non conosco il sw e non so aiutarti oltre, ma penso che devi cambiare opportunamente o i paramteri della funzione in input (l'assenza di alcuni di essi imposta automaticamnete dei valori predefiniti) oppure devi fare delle operazioni preliminari per estendere l'intervallo di numeri casuali
però come includere numeri immaginari non saprei, tra l'altro se dai un range di reali non non credo che uno randomizzatore crei delgi immaginari, sempre che non ci siano librerie fatte apposta
e si ci ho già dato uno sguardo però non ho trovato risposte soddisfacenti. Poi non so se sono stato superficiale nella lettura.
Inoltre posso stabilire un intervallo solo se lavoro in \ZZ con, ad esempio, random_matrix(ZZ, 3, 3, x=-100, y=100).
Però dato che lavoro con l'anello simbolico SR (ma comunque non funziona nemmeno con Q, R o C) mi va in errore.
Vorrei evitare di creare funzioni e chiedere di raccattare numeri irrazionali, frazioni ecc. "casualmente" da un elenco stabilito da me.
Per quanto riguarda i reali, se sfrutto RR, in generale, mi crea numeri orripilanti scritti in forma decimale e non frazionaria o altro

Grazie per la risposta!
 
Pubblicità
Pubblicità
Indietro
Top