Determinante di una matrice.

di Anonimizzato13124 il
16 risposte
Buonasera a tutti , la mia curiosità mi ha spinto a cercare di costruire un programma che mi permette di clacolarmi uil determinante di una matrice NxN.
Adesso mi chiedo , visto l'evidente difficoltà a calcolarlo secondo calcoli manuali, è possibile costruire un algoritmo che riesca a fare ciò ?

16 Risposte

  • Tu con quale metodo hai provato?
  • Con dei for annidati, per le matrici 3x3 non trovo difficoltà appena aumento la dimensione non ci capisco piu niente.


    P.s il determinate si calcola solo sulle matrici quadrate , giustoo ??
  • Conosci il metodo dello "sviluppo di Laplace"? Utilizza quello ...
  • Non lo conosco , è facile da implementare?? avresti qualcosa?
  • Solo per le matrici quadrate giusto si puo calcolare il determinate?
  • daniele90 ha scritto:


    Buonasera a tutti , la mia curiosità mi ha spinto a cercare di costruire un programma che mi permette di clacolarmi uil determinante di una matrice NxN.
    Adesso mi chiedo , visto l'evidente difficoltà a calcolarlo secondo calcoli manuali, è possibile costruire un algoritmo che riesca a fare ciò ?
    Ci sono fior fiore di algoritmi, piu' o meno efficienti. Quello a mano e' il meno efficiente di tutti. Ha una complessita' stratosferica con n che diventa sempre piu' grande: O(n!) ('n' fattoriale) per quelli che conoscono la notazione relativa alla complessita' computazionale

    Assioma: se lo puoi fare a mano, allora lo puoi fare anche con uun algoritmo!!!

    Ma ti basta andare su wikipedia!

  • daniele90 ha scritto:


    non lo conosco , è facile da implementare?? avresti qualcosa?
    Prima di affrontare un programma devi conoscere bene il problema e gli algoritmi che servono.

    E' un approccio ricorsivo (e questo potrebbe essere anche un problema per lo stato attuale delle tue conoscenze).

    Dai un'occhiata a questo link

    http://www.wirgilio.it/blog/2009/06/15/teorema-di-laplace-in-c/
  • Lo sviluppo di Laplace a ingegneria meccanica è un must, ho provato ad implementare qualcosa, sembrava divertente Dà un paio di warning sulle allocazioni dinamiche, ma sembra funzionare (provato fino alle 4x4), volevo una parere dagli esperti. (L'ho scritto in linguaggio C con Code::Blocks)



    
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    
    int determinante(int**, int);
    int **sottomatrice(int**, int, int);
    void StampaMatrice(int**, int);
    
    
    int **sottomatrice(int **m, int N, int k) //sottomatrice che si ottiene eliminando la prima riga e la colonna k dalla matrice m
    {
        int **sm, i, j;
        if((sm=(int**)malloc((N-1)*sizeof(int*)))==NULL){printf("impossibile allocare le righe"); return(-1);}
        for (i=0;i<N-1;i++){
            if((sm[i]=(int*)malloc((N-1)*sizeof(int)))==NULL){printf("impossibile allocare le colonne"); return(-1);}
        }
        for (i=0; i<N-1; i++){
                    for (j=0; i<N-1; j++){
                    if (j==k){
                        while (j<N-1){
                        sm[i][j]=m[i+1][j+1];
                        j++;
                        }
                        break;
                    }
                    sm[i][j]=m[i+1][j];
            }
        }
        return(sm);
        free(sm);
    }
    
    
    int determinante(int **mat, int N)
    {
        int det,j;
        det=0;
        if (N==2){
            det=mat[0][0]*mat[1][1]-mat[0][1]*mat[1][0];
        }
        else
        for (j=0; j<N; j++){
            det+=pow((double)(-1),(double)(j))*mat[0][j]*determinante(sottomatrice(mat, N, j), N-1);
        }
        return(det);
    }
    
    
    void StampaMatrice(int**mat, int N)
    {
        int i,j;
        for (i=0; i<N; i++){
            for (j=0; j<N; j++){
                printf("   %d   ",mat[i][j]);
            }
            printf("\n\n");
        }
    }
    
    
    int main()
    {
        int determin, **matrix, N, i, j;
        printf("Inserisci la dimensione della matrice da leggere\n");
        scanf("%d",&N);
        if((matrix=(int**)malloc(N*sizeof(int*)))==NULL){ printf("Impossibile allocare le righe"); return(-1);}
        for (i=0;i<N; i++){
            if((matrix[i]=(int*)malloc(N*sizeof(int)))==NULL){ printf("Impossibile allocare le colonne"); return(-1);}
        }
        for (i=0; i<N; i++){
            for (j=0; j<N; j++){
                printf("Inserisci il valore m[%d][%d] della matrice\n",i,j);
                scanf("%d", &matrix[i][j]);
            }
    
        }
        printf("La matrice di cui si vuole calcolare il determinante e'\n\n");
        StampaMatrice(matrix, N);
        if (N==1) determin=matrix[0][0];
        else determin=determinante(matrix, N);
        printf("Il determinante vale %d\n",determin);
        system("pause");
        free(matrix);
        return(0);
    }
    
  • Ciao intanto ti ringrazio tantissimo per la risposta , provando il programma mi segnala i seguenti errori:
    1-if((sm=(int**)malloc((N-1)*sizeof(int*)))==NULL){printf("impossibile allocare le righe"); return(-1);}
    (invalid conversion from int to int**);
    2- due riga sotto stesso errore;
    3-det+=pow((double)(-1),(double)(j))*mat[0][j]*determinante(sottomatrice(mat, N, j), N-1);
    ( converting to int from double);

    Grazie ancora!!
  • In "int** sottomatrice(...)" devi ritornare un doppio puntatore( tu invece ritorni un valore).

    ad esempio puoi ritornare "NULL"

    ps: prima del secondo return di questa funzione dealloca le "righe"

    nn ho altri errori con C::B
  • Utilizza una exit e non un return
  • Ho modificato le righe che davano errore così (ho messo un casting)
     if((sm=(int**)malloc((N-1)*sizeof(int*)))==NULL){printf("impossibile allocare le righe"); return((int**)(-1));}
        for (i=0;i<N-1;i++){
            if((sm[i]=(int*)malloc((N-1)*sizeof(int)))==NULL){printf("impossibile allocare le colonne"); return((int**)(-1));}
        }

    Così il programma non dà errori nè warning da me su C::B (ho aggiunto anche una deallocazione delle colonne).
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    
    int determinante(int**, int);
    int **sottomatrice(int**, int, int);
    void StampaMatrice(int**, int);
    
    
    int **sottomatrice(int **m, int N, int k) //sottomatrice che si ottiene eliminando la prima riga e la colonna k dalla matrice m
    {
        int **sm, i, j;
        if((sm=(int**)malloc((N-1)*sizeof(int*)))==NULL){printf("impossibile allocare le righe"); return((int**)(-1));}
        for (i=0;i<N-1;i++){
            if((sm[i]=(int*)malloc((N-1)*sizeof(int)))==NULL){printf("impossibile allocare le colonne"); return((int**)(-1));}
        }
        for (i=0; i<N-1; i++){
                    for (j=0; i<N-1; j++){
                    if (j==k){
                        while (j<N-1){
                        sm[i][j]=m[i+1][j+1];
                        j++;
                        }
                        break;
                    }
                    sm[i][j]=m[i+1][j];
            }
        }
        return(sm);
        for (i=0;i<N;i++) free(sm[i]);
        free(sm);
    }
    
    
    int determinante(int **mat, int N)
    {
        int det,j;
        det=0;
        if (N==2){
            det=mat[0][0]*mat[1][1]-mat[0][1]*mat[1][0];
        }
        else
        for (j=0; j<N; j++){
            det+=pow((double)(-1),(double)(j))*mat[0][j]*determinante(sottomatrice(mat, N, j), N-1);
        }
        return(det);
    }
    
    
    void StampaMatrice(int**mat, int N)
    {
        int i,j;
        for (i=0; i<N; i++){
            for (j=0; j<N; j++){
                printf("   %d   ",mat[i][j]);
            }
            printf("\n\n");
        }
    }
    
    
    int main()
    {
        int determin, **matrix, N, i, j;
        printf("Inserisci la dimensione della matrice da leggere\n");
        scanf("%d",&N);
        if((matrix=(int**)malloc(N*sizeof(int*)))==NULL){ printf("Impossibile allocare le righe"); return(-1);}
        for (i=0;i<N; i++){
            if((matrix[i]=(int*)malloc(N*sizeof(int)))==NULL){ printf("Impossibile allocare le colonne"); return(-1);}
        }
        for (i=0; i<N; i++){
            for (j=0; j<N; j++){
                printf("Inserisci il valore m[%d][%d] della matrice\n",i,j);
                scanf("%d", &matrix[i][j]);
            }
    
        }
        printf("La matrice di cui si vuole calcolare il determinante e'\n\n");
        StampaMatrice(matrix, N);
        if (N==1) determin=matrix[0][0];
        else determin=determinante(matrix, N);
        printf("Il determinante vale %d\n",determin);
        system("pause");
        free(matrix);
        return(0);
    }
    Grazie a tutti, Oregon scusa ma la funzione exit non l'ho mai usata, il mio bagaglio di funzioni è piuttosto limitato
  • Beh, è meglio studiarla la exit piuttosto che restituire un -1 come doppio puntatore ...
  • Si, il -1 come doppio puntatore fa abbastanza schifo pure a me... mi guarderò exit... intanto non è che potresti farmi vedere l'allocazione di prima usando exit invece che return?
Devi accedere o registrarti per scrivere nel forum
16 risposte