Bonjour,

Je requiers votre aide aujourd'hui car j'ai réalisé un algorithme pour résoudre un système d'équation basé sur le pivot de Gauss. Mon problème est qu'il ralentit arrivé à 40% (voir l'émission du signal "progressChanged()" pour l'avancement). Ma matrice "matCopy" fait environ 1600 lignes et 1600 colonnes. Donc certes c'est long mais pourquoi ça ralentit à 40%??? Entre 0 et 40%, on avance d' 1% par secondes mais à 40% on est à 1% toutes les 5-10 sec. Sur quoi est-ce que je peux jouer pour l'accélérer un peu?

Voici le code:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
MyThread::results MyThread::solve(QVector<QVariant>& boundariesCdt, QVector<double>& forces)
{
    results result; //Variable qui va contenir les résultats
 
    //On copie la matrice de rigidité dans une autre matrice que l'on pourrat modifier
    matCopy.setSize(mat.rowCount(),mat.columnCount());
    for(int i=0;i<mat.rowCount();i++)
    {
        for(int j=0;j<mat.columnCount();j++)
        {
            matCopy(i,j) = mat(i,j);
        }
    }
 
    //On copie les forces dans resultat.displacements (sera transformé par le pivot de gauss pour la résolution)
    for(int j=0;j<forces.size();j++)
    {
        result.displacements.push_back(forces.at(j));
    }
 
    //Comme certaines réactions aux connecteurs sont inconnues mais on connait les déplacement, on ne peut pas appliquer le pivot de
    //Gauss à certaines lignes. La seule solution est de la résoudre à part et d'appliquer le pivot aux lignes où le membre de droite
    //est connu. Une fois qu'on aura calculé les déplacements, il suffira de résoudre les équations mises à part
    //pour les efforts aux connecteurs.
 
    for(int j=0;j<boundariesCdt.size();j++)
    {
        if(boundariesCdt.at(j)!=QVariant()) //Si le déplacement (ou la rotation) vaut une valeur, on modifie la matrice.
            //Sinon on ne fait rien.
        {
            if(j<6) //Si on est dans les 6 premières lignes de la matrice (le noeud 1)
            {
                for(int i=0; i<matCopy.columnCount();i++)
                {
                    if(i==j) //si i=j alors on incrit un 1, sinon un 0. Permet de faire une équation xi*1=0
                    {
                        matCopy(j,i) = 1;
                    }
                    else
                    {
                        matCopy(j,i) = 0;
                    }
                }
                result.displacements[j] = boundariesCdt[j].toDouble();
            }
            else //Si on est dans les 6 dernières lignes de la matrice (le dernier noeud)
            {
                for(int i=0; i<matCopy.columnCount();i++)
                {
                    if(i==matCopy.rowCount()-12+j)//si i=n-12+j alors on incrit un 1, sinon un 0. Permet de faire une équation xi*1=0
                    {
                        matCopy(matCopy.rowCount()-12+j,i) = 1;
                    }
                    else
                    {
                        matCopy(matCopy.rowCount()-12+j,i) = 0;
                    }
                }
                result.displacements[result.displacements.size()-12+j] = boundariesCdt[j].toDouble();
            }
        }
    }
 
    //###############################################################################################################################
    //Pivot de Gauss appliqué à "matCopy" et "result.displacement"
    int r = 0;
    int k = 0;
    double maxPivot = 0;
 
    for(double j=0; j<matCopy.columnCount();j++)
    {
        emit progressChanged(floor(100*j/(matCopy.columnCount()-1)));
        maxPivot = 0; //On met "maxPivot" à une valeur minimale
 
        //On cherche le coef max de la colonne j et on le stocke dans "maxPivot". L'indice de la ligne du pivot est k.
        for(int i=r;i<matCopy.rowCount();i++)
        {
            if(matCopy(i,j)*matCopy(i,j)>maxPivot*maxPivot)
            {
                maxPivot = matCopy(i,j);
                k = i;
            }
        }
 
        if(matCopy(k,j)!=0)//Si le pivot est non nul, on procède aux opérations. Sinon, cela veut dire que toute la colonne est nulle
        {
            //############ On divise la ligne par le pivot (1 en début de ligne) ##############################
            for(int i = 0; i<matCopy.columnCount();i++)
            {
                matCopy(k,i) /= maxPivot;
            }
            result.displacements[k] /= maxPivot;
 
            double  coef = 0;
 
            //############ Echange des lignes r et k ##############################
            for(int i = 0; i<matCopy.columnCount();i++)
            {
                coef = matCopy(k,i);
                matCopy(k,i) = matCopy(r,i); //On modifie la ligne k
                matCopy(r,i) = coef; //On modifie la ligne r
            }
            coef = forces[r];
            result.displacements[r] = result.displacements[k];
            result.displacements[k] = coef;
 
            for(int i=0; i<matCopy.rowCount();i++)
            {
                if(i!=r)
                {
                    double coefLigne = matCopy(i,j);
 
                    for(int l=0;l<matCopy.columnCount();l++)
                    {
                        matCopy(i,l) -= matCopy(r,l)*coefLigne; // [Li] = [Li] - [Lr]*coefLigne
                    }
 
                    result.displacements[i] -= result.displacements[r]*coefLigne;
                }
            }
            r++;
        }
    }
    //###############################################################################################################################
    //Maintenant on va calculer les efforts aux connecteurs
    for(int i=0;i<mat.rowCount();i++)
    {
        result.reactionLoads.push_back(0);
 
        for(int j=0;j<mat.columnCount();j++)
        {
            result.reactionLoads[i] += mat(i,j)*result.displacements[j];
        }
    }
 
    //"forces"              est un tableau contenant toutes les solutions des déplacements
    //"connectorReaction"   est un tableau contenant toutes les solutions des efforts
 
    return result;
}
Cordialement