--- rpl/src/algebre_lineaire3.c 2010/07/14 14:19:32 1.10 +++ rpl/src/algebre_lineaire3.c 2010/08/06 15:26:42 1.11 @@ -1,1701 +1,1701 @@ -/* -================================================================================ - RPL/2 (R) version 4.0.18 - Copyright (C) 1989-2010 Dr. BERTRAND Joël - - This file is part of RPL/2. - - RPL/2 is free software; you can redistribute it and/or modify it - under the terms of the CeCILL V2 License as published by the french - CEA, CNRS and INRIA. - - RPL/2 is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License - for more details. - - You should have received a copy of the CeCILL License - along with RPL/2. If not, write to info@cecill.info. -================================================================================ -*/ - - -#include "rpl.conv.h" - - -/* -================================================================================ - Fonction réalisation la factorisation de Schur d'une matrice carrée -================================================================================ - Entrées : struct_matrice --------------------------------------------------------------------------------- - Sorties : décomposition de Schur de la matrice d'entrée et drapeau d'erreur. - La matrice en entrée est écrasée. La matrice de sortie est - la forme de Schur. - La routine renvoie aussi une matrice de complexes correspondant - aux vecteurs de Schur. Cette matrice est allouée par - la routine et vaut NULL sinon. --------------------------------------------------------------------------------- - Effets de bord : néant -================================================================================ -*/ - -void -factorisation_schur(struct_processus *s_etat_processus, - struct_matrice *s_matrice, struct_matrice **s_schur) -{ - complex16 *w; - - integer4 info; - integer4 lwork; - integer4 nombre_colonnes_a; - integer4 nombre_lignes_a; - integer4 sdim; - - real8 *rwork; - real8 *wi; - real8 *wr; - - unsigned char calcul_vecteurs_schur; - unsigned char tri_vecteurs_schur; - - unsigned long i; - unsigned long j; - unsigned long k; - unsigned long taille_matrice_f77; - - void *matrice_a_f77; - void *matrice_vs_f77; - void *tampon; - void *work; - - nombre_lignes_a = (integer4) (*s_matrice).nombre_lignes; - nombre_colonnes_a = (integer4) (*s_matrice).nombre_colonnes; - taille_matrice_f77 = nombre_lignes_a * nombre_colonnes_a; - - calcul_vecteurs_schur = 'V'; - tri_vecteurs_schur = 'N'; - - switch((*s_matrice).type) - { - case 'I' : - { - /* Conversion de la matrice en matrice réelle */ - - for(i = 0; i < (unsigned long) nombre_lignes_a; i++) - { - tampon = (*s_matrice).tableau[i]; - - if ((((real8 **) (*s_matrice).tableau)[i] = (real8 *) - malloc(nombre_colonnes_a * sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = - d_es_allocation_memoire; - return; - } - - for(j = 0; j < (unsigned long) nombre_colonnes_a; j++) - { - ((real8 **) (*s_matrice).tableau)[i][j] = - ((integer8 *) tampon)[j]; - } - - free(tampon); - } - - (*s_matrice).type = 'R'; - } - - case 'R' : - { - if ((matrice_a_f77 = (void *) malloc(taille_matrice_f77 * - sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - if ((matrice_vs_f77 = (void *) malloc(taille_matrice_f77 * - sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) - { - for(j = 0; j < (*s_matrice).nombre_lignes; j++) - { - ((real8 *) matrice_a_f77)[k++] = ((real8 **) - (*s_matrice).tableau)[j][i]; - } - } - - if ((wr = (real8 *) malloc(nombre_lignes_a * sizeof(real8))) - == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - if ((wi = (real8 *) malloc(nombre_lignes_a * sizeof(real8))) - == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - lwork = -1; - - if ((work = (real8 *) malloc(sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - dgees_(&calcul_vecteurs_schur, &tri_vecteurs_schur, - NULL, &nombre_lignes_a, matrice_a_f77, - &nombre_colonnes_a, &sdim, wr, wi, - matrice_vs_f77, &nombre_colonnes_a, - work, &lwork, NULL, &info, 1, 1); - - lwork = ((real8 *) work)[0]; - free(work); - - if ((work = (real8 *) malloc(lwork * sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - dgees_(&calcul_vecteurs_schur, &tri_vecteurs_schur, - NULL, &nombre_lignes_a, matrice_a_f77, - &nombre_colonnes_a, &sdim, wr, wi, - matrice_vs_f77, &nombre_colonnes_a, - work, &lwork, NULL, &info, 1, 1); - - free(work); - free(wr); - free(wi); - - if (info != 0) - { - if (info > 0) - { - (*s_etat_processus).exception = d_ep_decomposition_QR; - } - else - { - (*s_etat_processus).erreur_execution = - d_ex_routines_mathematiques; - } - - free(matrice_a_f77); - free(matrice_vs_f77); - return; - } - - for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) - { - for(j = 0; j < (*s_matrice).nombre_lignes; j++) - { - ((real8 **) (*s_matrice).tableau)[j][i] = - ((real8 *) matrice_a_f77)[k++]; - } - } - - (**s_schur).nombre_colonnes = (*s_matrice).nombre_colonnes; - (**s_schur).nombre_lignes = (*s_matrice).nombre_lignes; - (**s_schur).type = 'R'; - - if (((**s_schur).tableau = malloc((**s_schur) - .nombre_lignes * sizeof(real8 *))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - for(i = 0; i < (**s_schur).nombre_lignes; i++) - { - if ((((real8 **) (**s_schur).tableau)[i] = (real8 *) - malloc((**s_schur).nombre_colonnes * - sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = - d_es_allocation_memoire; - return; - } - } - - for(k = 0, i = 0; i < (**s_schur).nombre_colonnes; i++) - { - for(j = 0; j < (**s_schur).nombre_lignes; j++) - { - ((real8 **) (**s_schur).tableau)[j][i] = ((real8 *) - matrice_vs_f77)[k++]; - } - } - - free(matrice_a_f77); - free(matrice_vs_f77); - - break; - } - - case 'C' : - { - if ((matrice_a_f77 = (void *) malloc(taille_matrice_f77 * - sizeof(complex16))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - if ((matrice_vs_f77 = (void *) malloc(taille_matrice_f77 * - sizeof(complex16))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) - { - for(j = 0; j < (*s_matrice).nombre_lignes; j++) - { - ((complex16 *) matrice_a_f77)[k].partie_reelle = - ((complex16 **) (*s_matrice).tableau)[j][i] - .partie_reelle; - ((complex16 *) matrice_a_f77)[k++].partie_imaginaire = - ((complex16 **) (*s_matrice).tableau)[j][i] - .partie_imaginaire; - } - } - - if ((w = (complex16 *) malloc(nombre_lignes_a * sizeof(complex16))) - == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - lwork = -1; - - if ((work = (complex16 *) malloc(sizeof(complex16))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - if ((rwork = (real8 *) malloc(nombre_lignes_a * sizeof(real8))) - == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - zgees_(&calcul_vecteurs_schur, &tri_vecteurs_schur, - NULL, &nombre_lignes_a, matrice_a_f77, - &nombre_colonnes_a, &sdim, w, - matrice_vs_f77, &nombre_colonnes_a, - work, &lwork, rwork, NULL, &info, 1, 1); - - lwork = ((complex16 *) work)[0].partie_reelle; - free(work); - - if ((work = (complex16 *) malloc(lwork * sizeof(complex16))) - == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - zgees_(&calcul_vecteurs_schur, &tri_vecteurs_schur, - NULL, &nombre_lignes_a, matrice_a_f77, - &nombre_colonnes_a, &sdim, w, - matrice_vs_f77, &nombre_colonnes_a, - work, &lwork, rwork, NULL, &info, 1, 1); - - free(work); - free(rwork); - free(w); - - if (info != 0) - { - if (info > 0) - { - (*s_etat_processus).exception = d_ep_decomposition_QR; - } - else - { - (*s_etat_processus).erreur_execution = - d_ex_routines_mathematiques; - } - - free(matrice_a_f77); - free(matrice_vs_f77); - return; - } - - for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) - { - for(j = 0; j < (*s_matrice).nombre_lignes; j++) - { - ((complex16 **) (*s_matrice).tableau)[j][i] - .partie_reelle = ((complex16 *) matrice_a_f77)[k] - .partie_reelle; - ((complex16 **) (*s_matrice).tableau)[j][i] - .partie_imaginaire = ((complex16 *) matrice_a_f77) - [k++].partie_imaginaire; - } - } - - (**s_schur).nombre_colonnes = (*s_matrice).nombre_colonnes; - (**s_schur).nombre_lignes = (*s_matrice).nombre_lignes; - (**s_schur).type = 'C'; - - if (((**s_schur).tableau = malloc((**s_schur) - .nombre_lignes * sizeof(complex16 *))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - for(i = 0; i < (**s_schur).nombre_lignes; i++) - { - if ((((complex16 **) (**s_schur).tableau)[i] = (complex16 *) - malloc((**s_schur).nombre_colonnes * - sizeof(complex16))) == NULL) - { - (*s_etat_processus).erreur_systeme = - d_es_allocation_memoire; - return; - } - } - - for(k = 0, i = 0; i < (**s_schur).nombre_colonnes; i++) - { - for(j = 0; j < (**s_schur).nombre_lignes; j++) - { - ((complex16 **) (**s_schur).tableau)[j][i].partie_reelle = - ((complex16 *) matrice_vs_f77)[k].partie_reelle; - ((complex16 **) (**s_schur).tableau)[j][i] - .partie_imaginaire = ((complex16 *) matrice_vs_f77) - [k++].partie_imaginaire; - } - } - - free(matrice_a_f77); - free(matrice_vs_f77); - - break; - } - } - - return; -} - - -/* -================================================================================ - Fonction réalisation la factorisation LQ d'une matrice quelconque -================================================================================ - Entrées : struct_matrice --------------------------------------------------------------------------------- - Sorties : décomposition de LQ de la matrice d'entrée. Le tableau tau - est initialisé par la fonction --------------------------------------------------------------------------------- - Effets de bord : néant -================================================================================ -*/ - -void -factorisation_lq(struct_processus *s_etat_processus, struct_matrice *s_matrice, - void **tau) -{ - integer4 nombre_colonnes_a; - integer4 nombre_lignes_a; - integer4 erreur; - - unsigned long i; - unsigned long j; - unsigned long k; - unsigned long taille_matrice_f77; - - void *matrice_a_f77; - void *tampon; - void *work; - - nombre_lignes_a = (integer4) (*s_matrice).nombre_lignes; - nombre_colonnes_a = (integer4) (*s_matrice).nombre_colonnes; - taille_matrice_f77 = nombre_lignes_a * nombre_colonnes_a; - - switch((*s_matrice).type) - { - case 'I' : - { - /* Conversion de la matrice en matrice réelle */ - - for(i = 0; i < (unsigned long) nombre_lignes_a; i++) - { - tampon = (*s_matrice).tableau[i]; - - if ((((real8 **) (*s_matrice).tableau)[i] = (real8 *) - malloc(nombre_colonnes_a * sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = - d_es_allocation_memoire; - return; - } - - for(j = 0; j < (unsigned long) nombre_colonnes_a; j++) - { - ((real8 **) (*s_matrice).tableau)[i][j] = - ((integer8 *) tampon)[j]; - } - - free(tampon); - } - - (*s_matrice).type = 'R'; - } - - case 'R' : - { - if ((matrice_a_f77 = (void *) malloc(taille_matrice_f77 * - sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - if (((*tau) = malloc(((nombre_colonnes_a < nombre_lignes_a) - ? nombre_colonnes_a : nombre_lignes_a) * sizeof(real8))) - == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - if ((work = malloc(nombre_lignes_a * sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) - { - for(j = 0; j < (*s_matrice).nombre_lignes; j++) - { - ((real8 *) matrice_a_f77)[k++] = ((real8 **) - (*s_matrice).tableau)[j][i]; - } - } - - dgelq2_(&nombre_lignes_a, &nombre_colonnes_a, matrice_a_f77, - &nombre_lignes_a, (*((real8 **) tau)), work, &erreur); - - if (erreur != 0) - { - // L'erreur ne peut être que négative. - - (*s_etat_processus).erreur_execution = - d_ex_routines_mathematiques; - free(work); - free(matrice_a_f77); - return; - } - - for(k = 0, i = 0; i < (unsigned long) nombre_colonnes_a; i++) - { - for(j = 0; j < (unsigned long) nombre_lignes_a; j++) - { - ((real8 **) (*s_matrice).tableau)[j][i] = ((real8 *) - matrice_a_f77)[k++]; - } - } - - free(work); - free(matrice_a_f77); - - break; - } - - case 'C' : - { - if ((matrice_a_f77 = (void *) malloc(taille_matrice_f77 * - sizeof(complex16))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - if (((*tau) = malloc(((nombre_colonnes_a < nombre_lignes_a) - ? nombre_colonnes_a : nombre_lignes_a) * - sizeof(complex16))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - if ((work = malloc(nombre_lignes_a * sizeof(complex16))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) - { - for(j = 0; j < (*s_matrice).nombre_lignes; j++) - { - ((complex16 *) matrice_a_f77)[k].partie_reelle = - ((complex16 **) (*s_matrice).tableau)[j][i] - .partie_reelle; - ((complex16 *) matrice_a_f77)[k++].partie_imaginaire = - ((complex16 **) (*s_matrice).tableau)[j][i] - .partie_imaginaire; - } - } - - zgelq2_(&nombre_lignes_a, &nombre_colonnes_a, matrice_a_f77, - &nombre_lignes_a, (*((complex16 **) tau)), work, &erreur); - - if (erreur != 0) - { - // L'erreur ne peut être que négative. - - (*s_etat_processus).erreur_execution = - d_ex_routines_mathematiques; - free(work); - free(matrice_a_f77); - return; - } - - for(k = 0, i = 0; i < (unsigned long) nombre_colonnes_a; i++) - { - for(j = 0; j < (unsigned long) nombre_lignes_a; j++) - { - ((complex16 **) (*s_matrice).tableau)[j][i].partie_reelle = - ((complex16 *) matrice_a_f77)[k].partie_reelle; - ((complex16 **) (*s_matrice).tableau)[j][i] - .partie_imaginaire = ((complex16 *) matrice_a_f77) - [k++].partie_imaginaire; - } - } - - free(work); - free(matrice_a_f77); - - break; - } - } - - return; -} - - -/* -================================================================================ - Fonction réalisation la factorisation QR d'une matrice quelconque -================================================================================ - Entrées : struct_matrice --------------------------------------------------------------------------------- - Sorties : décomposition de QR de la matrice d'entrée. Le tableau tau - est initialisé par la fonction --------------------------------------------------------------------------------- - Effets de bord : néant -================================================================================ -*/ - -void -factorisation_qr(struct_processus *s_etat_processus, struct_matrice *s_matrice, - void **tau) -{ - integer4 lwork; - integer4 nombre_colonnes_a; - integer4 nombre_lignes_a; - integer4 erreur; - integer4 *pivot; - - real8 *rwork; - - unsigned long i; - unsigned long j; - unsigned long k; - unsigned long taille_matrice_f77; - - void *matrice_a_f77; - void *registre; - void *tampon; - void *work; - - nombre_lignes_a = (integer4) (*s_matrice).nombre_lignes; - nombre_colonnes_a = (integer4) (*s_matrice).nombre_colonnes; - taille_matrice_f77 = nombre_lignes_a * nombre_colonnes_a; - - switch((*s_matrice).type) - { - case 'I' : - { - /* Conversion de la matrice en matrice réelle */ - - for(i = 0; i < (unsigned long) nombre_lignes_a; i++) - { - tampon = (*s_matrice).tableau[i]; - - if ((((real8 **) (*s_matrice).tableau)[i] = (real8 *) - malloc(nombre_colonnes_a * sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = - d_es_allocation_memoire; - return; - } - - for(j = 0; j < (unsigned long) nombre_colonnes_a; j++) - { - ((real8 **) (*s_matrice).tableau)[i][j] = - ((integer8 *) tampon)[j]; - } - - free(tampon); - } - - (*s_matrice).type = 'R'; - } - - case 'R' : - { - if ((matrice_a_f77 = (void *) malloc(taille_matrice_f77 * - sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - if (((*tau) = malloc(((nombre_colonnes_a < nombre_lignes_a) - ? nombre_colonnes_a : nombre_lignes_a) * sizeof(real8))) - == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) - { - for(j = 0; j < (*s_matrice).nombre_lignes; j++) - { - ((real8 *) matrice_a_f77)[k++] = ((real8 **) - (*s_matrice).tableau)[j][i]; - } - } - - if ((pivot = malloc(nombre_colonnes_a * sizeof(integer4))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - for(i = 0; i < (unsigned long) nombre_colonnes_a; pivot[i++] = 0); - - lwork = -1; - - if ((work = malloc(sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - // Calcul de la taille de l'espace - - dgeqp3_(&nombre_lignes_a, &nombre_colonnes_a, matrice_a_f77, - &nombre_lignes_a, pivot, (*((real8 **) tau)), - work, &lwork, &erreur); - - lwork = ((real8 *) work)[0]; - - free(work); - - if ((work = malloc(lwork * sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - // Calcul de la permutation - - if ((registre = (void *) malloc(taille_matrice_f77 * - sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - memcpy(registre, matrice_a_f77, taille_matrice_f77 * sizeof(real8)); - - dgeqp3_(&nombre_lignes_a, &nombre_colonnes_a, registre, - &nombre_lignes_a, pivot, (*((real8 **) tau)), - work, &lwork, &erreur); - - free(registre); - - if (erreur != 0) - { - // L'erreur ne peut être que négative. - - (*s_etat_processus).erreur_execution = - d_ex_routines_mathematiques; - free(work); - free(matrice_a_f77); - free(tau); - return; - } - - // La permutation doit maintenant être unitaire - - dgeqp3_(&nombre_lignes_a, &nombre_colonnes_a, matrice_a_f77, - &nombre_lignes_a, pivot, (*((real8 **) tau)), - work, &lwork, &erreur); - - if (erreur != 0) - { - // L'erreur ne peut être que négative. - - (*s_etat_processus).erreur_execution = - d_ex_routines_mathematiques; - free(work); - free(matrice_a_f77); - free(tau); - return; - } - - for(i = 0; i < (unsigned long) nombre_colonnes_a; i++) - { - if ((i + 1) != (unsigned long) pivot[i]) - { - (*s_etat_processus).erreur_execution = - d_ex_routines_mathematiques; - - free(pivot); - free(work); - free(matrice_a_f77); - free(tau); - - return; - } - } - - free(pivot); - - for(k = 0, i = 0; i < (unsigned long) nombre_colonnes_a; i++) - { - for(j = 0; j < (unsigned long) nombre_lignes_a; j++) - { - ((real8 **) (*s_matrice).tableau)[j][i] = ((real8 *) - matrice_a_f77)[k++]; - } - } - - free(work); - free(matrice_a_f77); - - break; - } - - case 'C' : - { - if ((matrice_a_f77 = (void *) malloc(taille_matrice_f77 * - sizeof(complex16))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - if (((*tau) = malloc(((nombre_colonnes_a < nombre_lignes_a) - ? nombre_colonnes_a : nombre_lignes_a) * sizeof(complex16))) - == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) - { - for(j = 0; j < (*s_matrice).nombre_lignes; j++) - { - ((complex16 *) matrice_a_f77)[k].partie_reelle = - ((complex16 **) (*s_matrice).tableau)[j][i] - .partie_reelle; - ((complex16 *) matrice_a_f77)[k++].partie_imaginaire = - ((complex16 **) (*s_matrice).tableau)[j][i] - .partie_imaginaire; - } - } - - if ((pivot = malloc(nombre_colonnes_a * sizeof(integer4))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - if ((rwork = malloc(2 * nombre_colonnes_a * sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - for(i = 0; i < (unsigned long) nombre_colonnes_a; pivot[i++] = 0); - - lwork = -1; - - if ((work = malloc(sizeof(complex16))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - // Calcul de la taille de l'espace - - zgeqp3_(&nombre_lignes_a, &nombre_colonnes_a, matrice_a_f77, - &nombre_lignes_a, pivot, (*((complex16 **) tau)), - work, &lwork, rwork, &erreur); - - if (erreur != 0) - { - // L'erreur ne peut être que négative. - - (*s_etat_processus).erreur_execution = - d_ex_routines_mathematiques; - - free(work); - free(rwork); - free(pivot); - free(matrice_a_f77); - free(tau); - return; - } - - lwork = ((complex16 *) work)[0].partie_reelle; - - free(work); - - if ((work = malloc(lwork * sizeof(complex16))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - // Calcul de la permutation - - if ((registre = (void *) malloc(taille_matrice_f77 * - sizeof(complex16))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - memcpy(registre, matrice_a_f77, - taille_matrice_f77 * sizeof(complex16)); - - zgeqp3_(&nombre_lignes_a, &nombre_colonnes_a, registre, - &nombre_lignes_a, pivot, (*((complex16 **) tau)), - work, &lwork, rwork, &erreur); - - free(registre); - - if (erreur != 0) - { - // L'erreur ne peut être que négative. - - (*s_etat_processus).erreur_execution = - d_ex_routines_mathematiques; - - free(work); - free(rwork); - free(pivot); - free(matrice_a_f77); - free(tau); - return; - } - - // La permutation doit maintenant être unitaire - - zgeqp3_(&nombre_lignes_a, &nombre_colonnes_a, matrice_a_f77, - &nombre_lignes_a, pivot, (*((complex16 **) tau)), - work, &lwork, rwork, &erreur); - - if (erreur != 0) - { - // L'erreur ne peut être que négative. - - (*s_etat_processus).erreur_execution = - d_ex_routines_mathematiques; - - free(work); - free(rwork); - free(pivot); - free(matrice_a_f77); - free(tau); - return; - } - - free(rwork); - - for(i = 0; i < (unsigned long) nombre_colonnes_a; i++) - { - if ((i + 1) != (unsigned long) pivot[i]) - { - (*s_etat_processus).erreur_execution = - d_ex_routines_mathematiques; - - free(pivot); - free(work); - free(matrice_a_f77); - free(tau); - - return; - } - } - - free(pivot); - - for(k = 0, i = 0; i < (unsigned long) nombre_colonnes_a; i++) - { - for(j = 0; j < (unsigned long) nombre_lignes_a; j++) - { - ((complex16 **) (*s_matrice).tableau)[j][i].partie_reelle = - ((complex16 *) matrice_a_f77)[k].partie_reelle; - ((complex16 **) (*s_matrice).tableau)[j][i] - .partie_imaginaire = ((complex16 *) - matrice_a_f77)[k++].partie_imaginaire; - } - } - - free(work); - free(matrice_a_f77); - - break; - } - } - - return; -} - - -/* -================================================================================ - Fonctions calculant le déterminant ou le rang d'une matrice quelconque -================================================================================ - Entrées : struct_matrice --------------------------------------------------------------------------------- - Sorties : déterminant --------------------------------------------------------------------------------- - Effets de bord : néant -================================================================================ -*/ - - -static integer4 -calcul_rang(struct_processus *s_etat_processus, void *matrice_f77, - integer4 nombre_lignes_a, integer4 nombre_colonnes_a, - integer4 *pivot, integer4 dimension_vecteur_pivot, unsigned char type) -{ - integer4 erreur; - integer4 *iwork; - integer4 *jpvt; - integer4 lwork; - integer4 longueur; - integer4 nombre_colonnes_b; - integer4 nombre_lignes_b; - integer4 ordre; - integer4 rang; - - real8 anorme; - real8 rcond; - real8 *rwork; - - unsigned char norme; - - unsigned long i; - - void *matrice_b; - void *matrice_c; - void *work; - -#undef NORME_I -#ifdef NORME_I - norme = 'I'; - - if ((work = malloc(nombre_lignes_a * sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(-1); - } -#else - norme = '1'; - work = NULL; -#endif - - longueur = 1; - - if (type == 'R') - { - anorme = dlange_(&norme, &nombre_lignes_a, &nombre_colonnes_a, - matrice_f77, &nombre_lignes_a, work, longueur); - -#ifndef NORME_I - free(work); -#endif - - if ((matrice_c = malloc(nombre_lignes_a * nombre_colonnes_a * - sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(-1); - } - - memcpy(matrice_c, matrice_f77, nombre_lignes_a * nombre_colonnes_a * - sizeof(real8)); - - dgetrf_(&nombre_lignes_a, &nombre_colonnes_a, matrice_f77, - &nombre_lignes_a, pivot, &erreur); - - if (erreur < 0) - { - (*s_etat_processus).erreur_execution = - d_ex_routines_mathematiques; - - free(matrice_f77); - return(-1); - } - - if ((iwork = malloc(nombre_colonnes_a * sizeof(integer4))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(-1); - } - - if ((work = malloc(4 * nombre_colonnes_a * sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(-1); - } - - ordre = (nombre_lignes_a > nombre_colonnes_a) - ? nombre_colonnes_a : nombre_lignes_a; - - dgecon_(&norme, &ordre, matrice_f77, - &nombre_lignes_a, &anorme, &rcond, work, iwork, &erreur, - longueur); - - free(work); - free(iwork); - - if (erreur < 0) - { - (*s_etat_processus).erreur_execution = - d_ex_routines_mathematiques; - - free(matrice_f77); - return(-1); - } - - if ((jpvt = malloc(nombre_colonnes_a * sizeof(integer4))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(-1); - } - - for(i = 0; i < (unsigned long) nombre_colonnes_a; i++) - { - ((integer4 *) jpvt)[i] = 0; - } - - lwork = -1; - - if ((work = malloc(sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(-1); - } - - nombre_colonnes_b = 1; - nombre_lignes_b = (nombre_lignes_a > nombre_colonnes_a) - ? nombre_lignes_a : nombre_colonnes_a; - - if ((matrice_b = malloc(nombre_lignes_b * sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(-1); - } - - for(i = 0; i < (unsigned long) nombre_lignes_b; i++) - { - ((real8 *) matrice_b)[i] = 0; - } - - dgelsy_(&nombre_lignes_a, &nombre_colonnes_a, - &nombre_colonnes_b, matrice_c, &nombre_lignes_a, - matrice_b, &nombre_lignes_b, jpvt, &rcond, &rang, - work, &lwork, &erreur); - - lwork = ((real8 *) work)[0]; - free(work); - - if ((work = malloc(lwork * sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(-1); - } - - dgelsy_(&nombre_lignes_a, &nombre_colonnes_a, - &nombre_colonnes_b, matrice_c, &nombre_lignes_a, - matrice_b, &nombre_lignes_b, jpvt, &rcond, &rang, - work, &lwork, &erreur); - - free(matrice_b); - free(matrice_c); - free(work); - free(jpvt); - - if (erreur < 0) - { - (*s_etat_processus).erreur_execution = - d_ex_routines_mathematiques; - - free(matrice_f77); - return(-1); - } - } - else - { - anorme = zlange_(&norme, &nombre_lignes_a, &nombre_colonnes_a, - matrice_f77, &nombre_lignes_a, work, longueur); - -#ifndef NORME_I - free(work); -#endif - - if ((matrice_c = malloc(nombre_lignes_a * nombre_colonnes_a * - sizeof(complex16))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(-1); - } - - memcpy(matrice_c, matrice_f77, nombre_lignes_a * nombre_colonnes_a * - sizeof(complex16)); - - zgetrf_(&nombre_lignes_a, &nombre_colonnes_a, matrice_f77, - &nombre_lignes_a, pivot, &erreur); - - if (erreur < 0) - { - (*s_etat_processus).erreur_execution = - d_ex_routines_mathematiques; - - free(matrice_f77); - return(-1); - } - - if ((rwork = malloc(2 * nombre_colonnes_a * sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(-1); - } - - if ((work = malloc(2 * nombre_colonnes_a * sizeof(complex16))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(-1); - } - - ordre = (nombre_lignes_a > nombre_colonnes_a) - ? nombre_colonnes_a : nombre_lignes_a; - - zgecon_(&norme, &ordre, matrice_f77, - &nombre_lignes_a, &anorme, &rcond, work, rwork, &erreur, - longueur); - - free(work); - - if (erreur < 0) - { - (*s_etat_processus).erreur_execution = - d_ex_routines_mathematiques; - - free(matrice_f77); - return(-1); - } - - if ((jpvt = malloc(nombre_colonnes_a * sizeof(integer4))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(-1); - } - - for(i = 0; i < (unsigned long) nombre_colonnes_a; i++) - { - ((integer4 *) jpvt)[i] = 0; - } - - lwork = -1; - - if ((work = malloc(sizeof(complex16))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(-1); - } - - nombre_colonnes_b = 1; - nombre_lignes_b = (nombre_lignes_a > nombre_colonnes_a) - ? nombre_lignes_a : nombre_colonnes_a; - - if ((matrice_b = malloc(nombre_lignes_b * sizeof(complex16))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(-1); - } - - for(i = 0; i < (unsigned long) nombre_lignes_b; i++) - { - ((complex16 *) matrice_b)[i].partie_reelle = 0; - ((complex16 *) matrice_b)[i].partie_imaginaire = 0; - } - - zgelsy_(&nombre_lignes_a, &nombre_colonnes_a, - &nombre_colonnes_b, matrice_c, &nombre_lignes_a, - matrice_b, &nombre_lignes_b, jpvt, &rcond, &rang, - work, &lwork, rwork, &erreur); - - lwork = ((complex16 *) work)[0].partie_reelle; - free(work); - - if ((work = malloc(lwork * sizeof(complex16))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return(-1); - } - - zgelsy_(&nombre_lignes_a, &nombre_colonnes_a, - &nombre_colonnes_b, matrice_c, &nombre_lignes_a, - matrice_b, &nombre_lignes_b, jpvt, &rcond, &rang, - work, &lwork, rwork, &erreur); - - free(rwork); - free(matrice_b); - free(matrice_c); - free(work); - free(jpvt); - - if (erreur < 0) - { - (*s_etat_processus).erreur_execution = - d_ex_routines_mathematiques; - - free(matrice_f77); - return(-1); - } - } - - return(rang); -} - - -void -determinant(struct_processus *s_etat_processus, struct_matrice *s_matrice, - void *valeur) -{ - complex16 *vecteur_complexe; - - integer4 dimension_vecteur_pivot; - integer4 nombre_colonnes_a; - integer4 nombre_lignes_a; - integer4 *pivot; - integer4 rang; - - integer8 signe; - - real8 *vecteur_reel; - - unsigned long i; - unsigned long j; - unsigned long k; - unsigned long taille_matrice_f77; - - void *matrice_f77; - - nombre_lignes_a = (integer4) (*s_matrice).nombre_lignes; - nombre_colonnes_a = (integer4) (*s_matrice).nombre_colonnes; - dimension_vecteur_pivot = (nombre_lignes_a < nombre_colonnes_a) - ? nombre_lignes_a : nombre_colonnes_a; - taille_matrice_f77 = nombre_lignes_a * nombre_colonnes_a; - - switch((*s_matrice).type) - { - case 'I' : - { - if ((matrice_f77 = (void *) malloc(taille_matrice_f77 * - sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) - { - for(j = 0; j < (*s_matrice).nombre_lignes; j++) - { - ((real8 *) matrice_f77)[k++] = ((integer8 **) - (*s_matrice).tableau)[j][i]; - } - } - - if ((pivot = (integer4 *) malloc(dimension_vecteur_pivot * - sizeof(integer4))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - if ((rang = calcul_rang(s_etat_processus, matrice_f77, - nombre_lignes_a, nombre_colonnes_a, pivot, - dimension_vecteur_pivot, 'R')) < 0) - { - return; - } - - if (rang < nombre_lignes_a) - { - (*((real8 *) valeur)) = 0; - } - else - { - if ((vecteur_reel = malloc((*s_matrice).nombre_colonnes * - sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = - d_es_allocation_memoire; - return; - } - - signe = 1; - - for(i = 0; i < (*s_matrice).nombre_colonnes; i++) - { - if ((unsigned long) pivot[i] != (i + 1)) - { - signe = (signe == 1) ? -1 : 1; - } - - vecteur_reel[i] = ((real8 *) matrice_f77) - [(i * nombre_colonnes_a) + i]; - } - - for(i = 1; i < (*s_matrice).nombre_colonnes; i++) - { - vecteur_reel[0] *= vecteur_reel[i]; - } - - (*((real8 *) valeur)) = vecteur_reel[0] * signe; - - free(vecteur_reel); - } - - free(matrice_f77); - free(pivot); - - break; - } - - case 'R' : - { - if ((matrice_f77 = (void *) malloc(taille_matrice_f77 * - sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) - { - for(j = 0; j < (*s_matrice).nombre_lignes; j++) - { - ((real8 *) matrice_f77)[k++] = ((real8 **) - (*s_matrice).tableau)[j][i]; - } - } - - if ((pivot = (integer4 *) malloc(dimension_vecteur_pivot * - sizeof(integer4))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - if ((rang = calcul_rang(s_etat_processus, matrice_f77, - nombre_lignes_a, nombre_colonnes_a, pivot, - dimension_vecteur_pivot, 'R')) < 0) - { - return; - } - - if (rang < nombre_lignes_a) - { - (*((real8 *) valeur)) = 0; - } - else - { - if ((vecteur_reel = malloc((*s_matrice).nombre_colonnes * - sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = - d_es_allocation_memoire; - return; - } - - signe = 1; - - for(i = 0; i < (*s_matrice).nombre_colonnes; i++) - { - if ((unsigned long) pivot[i] != (i + 1)) - { - signe = (signe == 1) ? -1 : 1; - } - - vecteur_reel[i] = ((real8 *) matrice_f77) - [(i * nombre_colonnes_a) + i]; - } - - for(i = 1; i < (*s_matrice).nombre_colonnes; i++) - { - vecteur_reel[0] *= vecteur_reel[i]; - } - - (*((real8 *) valeur)) = vecteur_reel[0] * signe; - - free(vecteur_reel); - } - - free(matrice_f77); - free(pivot); - - break; - } - - case 'C' : - { - if ((matrice_f77 = (void *) malloc(taille_matrice_f77 * - sizeof(complex16))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) - { - for(j = 0; j < (*s_matrice).nombre_lignes; j++) - { - ((complex16 *) matrice_f77)[k++] = ((complex16 **) - (*s_matrice).tableau)[j][i]; - } - } - - if ((pivot = (integer4 *) malloc(dimension_vecteur_pivot * - sizeof(integer4))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - if ((rang = calcul_rang(s_etat_processus, matrice_f77, - nombre_lignes_a, nombre_colonnes_a, pivot, - dimension_vecteur_pivot, 'C')) < 0) - { - return; - } - - if (rang < nombre_lignes_a) - { - (*((complex16 *) valeur)).partie_reelle = 0; - (*((complex16 *) valeur)).partie_imaginaire = 0; - } - else - { - if ((vecteur_complexe = malloc((*s_matrice).nombre_colonnes * - sizeof(complex16))) == NULL) - { - (*s_etat_processus).erreur_systeme = - d_es_allocation_memoire; - return; - } - - signe = 1; - - for(i = 0; i < (*s_matrice).nombre_colonnes; i++) - { - if ((unsigned long) pivot[i] != (i + 1)) - { - signe = (signe == 1) ? -1 : 1; - } - - vecteur_complexe[i] = ((complex16 *) matrice_f77) - [(i * nombre_colonnes_a) + i]; - } - - for(i = 1; i < (*s_matrice).nombre_colonnes; i++) - { - f77multiplicationcc_(&(vecteur_complexe[0]), - &(vecteur_complexe[i]), &(vecteur_complexe[0])); - } - - f77multiplicationci_(&(vecteur_complexe[0]), &signe, - ((complex16 *) valeur)); - - free(vecteur_complexe); - } - - free(matrice_f77); - free(pivot); - - break; - } - } - - return; -} - - -void -rang(struct_processus *s_etat_processus, struct_matrice *s_matrice, - integer8 *valeur) -{ - integer4 dimension_vecteur_pivot; - integer4 nombre_lignes_a; - integer4 nombre_colonnes_a; - integer4 *pivot; - integer4 rang; - integer4 taille_matrice_f77; - - unsigned long i; - unsigned long j; - unsigned long k; - - void *matrice_f77; - - nombre_lignes_a = (integer4) (*s_matrice).nombre_lignes; - nombre_colonnes_a = (integer4) (*s_matrice).nombre_colonnes; - dimension_vecteur_pivot = (nombre_lignes_a < nombre_colonnes_a) - ? nombre_lignes_a : nombre_colonnes_a; - taille_matrice_f77 = nombre_lignes_a * nombre_colonnes_a; - - if ((pivot = (integer4 *) malloc(dimension_vecteur_pivot * - sizeof(integer4))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - switch((*s_matrice).type) - { - case 'I' : - { - if ((matrice_f77 = (void *) malloc(taille_matrice_f77 * - sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) - { - for(j = 0; j < (*s_matrice).nombre_lignes; j++) - { - ((real8 *) matrice_f77)[k++] = ((integer8 **) - (*s_matrice).tableau)[j][i]; - } - } - - if ((rang = calcul_rang(s_etat_processus, matrice_f77, - nombre_lignes_a, nombre_colonnes_a, pivot, - dimension_vecteur_pivot, 'R')) < 0) - { - free(pivot); - free(matrice_f77); - return; - } - - free(matrice_f77); - (*valeur) = rang; - break; - } - - case 'R' : - { - if ((matrice_f77 = (void *) malloc(taille_matrice_f77 * - sizeof(real8))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) - { - for(j = 0; j < (*s_matrice).nombre_lignes; j++) - { - ((real8 *) matrice_f77)[k++] = ((real8 **) - (*s_matrice).tableau)[j][i]; - } - } - - if ((rang = calcul_rang(s_etat_processus, matrice_f77, - nombre_lignes_a, nombre_colonnes_a, pivot, - dimension_vecteur_pivot, 'R')) < 0) - { - free(pivot); - free(matrice_f77); - return; - } - - free(matrice_f77); - (*valeur) = rang; - break; - } - - case 'C' : - { - if ((matrice_f77 = (void *) malloc(taille_matrice_f77 * - sizeof(complex16))) == NULL) - { - (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; - return; - } - - for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) - { - for(j = 0; j < (*s_matrice).nombre_lignes; j++) - { - ((complex16 *) matrice_f77)[k++] = ((complex16 **) - (*s_matrice).tableau)[j][i]; - } - } - - if ((rang = calcul_rang(s_etat_processus, matrice_f77, - nombre_lignes_a, nombre_colonnes_a, pivot, - dimension_vecteur_pivot, 'C')) < 0) - { - free(pivot); - free(matrice_f77); - return; - } - - free(matrice_f77); - (*valeur) = rang; - break; - } - } - - free(pivot); - - return; -} - -// vim: ts=4 +/* +================================================================================ + RPL/2 (R) version 4.0.18 + Copyright (C) 1989-2010 Dr. BERTRAND Joël + + This file is part of RPL/2. + + RPL/2 is free software; you can redistribute it and/or modify it + under the terms of the CeCILL V2 License as published by the french + CEA, CNRS and INRIA. + + RPL/2 is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License + for more details. + + You should have received a copy of the CeCILL License + along with RPL/2. If not, write to info@cecill.info. +================================================================================ +*/ + + +#include "rpl-conv.h" + + +/* +================================================================================ + Fonction réalisation la factorisation de Schur d'une matrice carrée +================================================================================ + Entrées : struct_matrice +-------------------------------------------------------------------------------- + Sorties : décomposition de Schur de la matrice d'entrée et drapeau d'erreur. + La matrice en entrée est écrasée. La matrice de sortie est + la forme de Schur. + La routine renvoie aussi une matrice de complexes correspondant + aux vecteurs de Schur. Cette matrice est allouée par + la routine et vaut NULL sinon. +-------------------------------------------------------------------------------- + Effets de bord : néant +================================================================================ +*/ + +void +factorisation_schur(struct_processus *s_etat_processus, + struct_matrice *s_matrice, struct_matrice **s_schur) +{ + complex16 *w; + + integer4 info; + integer4 lwork; + integer4 nombre_colonnes_a; + integer4 nombre_lignes_a; + integer4 sdim; + + real8 *rwork; + real8 *wi; + real8 *wr; + + unsigned char calcul_vecteurs_schur; + unsigned char tri_vecteurs_schur; + + unsigned long i; + unsigned long j; + unsigned long k; + unsigned long taille_matrice_f77; + + void *matrice_a_f77; + void *matrice_vs_f77; + void *tampon; + void *work; + + nombre_lignes_a = (integer4) (*s_matrice).nombre_lignes; + nombre_colonnes_a = (integer4) (*s_matrice).nombre_colonnes; + taille_matrice_f77 = nombre_lignes_a * nombre_colonnes_a; + + calcul_vecteurs_schur = 'V'; + tri_vecteurs_schur = 'N'; + + switch((*s_matrice).type) + { + case 'I' : + { + /* Conversion de la matrice en matrice réelle */ + + for(i = 0; i < (unsigned long) nombre_lignes_a; i++) + { + tampon = (*s_matrice).tableau[i]; + + if ((((real8 **) (*s_matrice).tableau)[i] = (real8 *) + malloc(nombre_colonnes_a * sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + for(j = 0; j < (unsigned long) nombre_colonnes_a; j++) + { + ((real8 **) (*s_matrice).tableau)[i][j] = + ((integer8 *) tampon)[j]; + } + + free(tampon); + } + + (*s_matrice).type = 'R'; + } + + case 'R' : + { + if ((matrice_a_f77 = (void *) malloc(taille_matrice_f77 * + sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if ((matrice_vs_f77 = (void *) malloc(taille_matrice_f77 * + sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) + { + for(j = 0; j < (*s_matrice).nombre_lignes; j++) + { + ((real8 *) matrice_a_f77)[k++] = ((real8 **) + (*s_matrice).tableau)[j][i]; + } + } + + if ((wr = (real8 *) malloc(nombre_lignes_a * sizeof(real8))) + == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if ((wi = (real8 *) malloc(nombre_lignes_a * sizeof(real8))) + == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + lwork = -1; + + if ((work = (real8 *) malloc(sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + dgees_(&calcul_vecteurs_schur, &tri_vecteurs_schur, + NULL, &nombre_lignes_a, matrice_a_f77, + &nombre_colonnes_a, &sdim, wr, wi, + matrice_vs_f77, &nombre_colonnes_a, + work, &lwork, NULL, &info, 1, 1); + + lwork = ((real8 *) work)[0]; + free(work); + + if ((work = (real8 *) malloc(lwork * sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + dgees_(&calcul_vecteurs_schur, &tri_vecteurs_schur, + NULL, &nombre_lignes_a, matrice_a_f77, + &nombre_colonnes_a, &sdim, wr, wi, + matrice_vs_f77, &nombre_colonnes_a, + work, &lwork, NULL, &info, 1, 1); + + free(work); + free(wr); + free(wi); + + if (info != 0) + { + if (info > 0) + { + (*s_etat_processus).exception = d_ep_decomposition_QR; + } + else + { + (*s_etat_processus).erreur_execution = + d_ex_routines_mathematiques; + } + + free(matrice_a_f77); + free(matrice_vs_f77); + return; + } + + for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) + { + for(j = 0; j < (*s_matrice).nombre_lignes; j++) + { + ((real8 **) (*s_matrice).tableau)[j][i] = + ((real8 *) matrice_a_f77)[k++]; + } + } + + (**s_schur).nombre_colonnes = (*s_matrice).nombre_colonnes; + (**s_schur).nombre_lignes = (*s_matrice).nombre_lignes; + (**s_schur).type = 'R'; + + if (((**s_schur).tableau = malloc((**s_schur) + .nombre_lignes * sizeof(real8 *))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + for(i = 0; i < (**s_schur).nombre_lignes; i++) + { + if ((((real8 **) (**s_schur).tableau)[i] = (real8 *) + malloc((**s_schur).nombre_colonnes * + sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + } + + for(k = 0, i = 0; i < (**s_schur).nombre_colonnes; i++) + { + for(j = 0; j < (**s_schur).nombre_lignes; j++) + { + ((real8 **) (**s_schur).tableau)[j][i] = ((real8 *) + matrice_vs_f77)[k++]; + } + } + + free(matrice_a_f77); + free(matrice_vs_f77); + + break; + } + + case 'C' : + { + if ((matrice_a_f77 = (void *) malloc(taille_matrice_f77 * + sizeof(complex16))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if ((matrice_vs_f77 = (void *) malloc(taille_matrice_f77 * + sizeof(complex16))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) + { + for(j = 0; j < (*s_matrice).nombre_lignes; j++) + { + ((complex16 *) matrice_a_f77)[k].partie_reelle = + ((complex16 **) (*s_matrice).tableau)[j][i] + .partie_reelle; + ((complex16 *) matrice_a_f77)[k++].partie_imaginaire = + ((complex16 **) (*s_matrice).tableau)[j][i] + .partie_imaginaire; + } + } + + if ((w = (complex16 *) malloc(nombre_lignes_a * sizeof(complex16))) + == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + lwork = -1; + + if ((work = (complex16 *) malloc(sizeof(complex16))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if ((rwork = (real8 *) malloc(nombre_lignes_a * sizeof(real8))) + == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + zgees_(&calcul_vecteurs_schur, &tri_vecteurs_schur, + NULL, &nombre_lignes_a, matrice_a_f77, + &nombre_colonnes_a, &sdim, w, + matrice_vs_f77, &nombre_colonnes_a, + work, &lwork, rwork, NULL, &info, 1, 1); + + lwork = ((complex16 *) work)[0].partie_reelle; + free(work); + + if ((work = (complex16 *) malloc(lwork * sizeof(complex16))) + == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + zgees_(&calcul_vecteurs_schur, &tri_vecteurs_schur, + NULL, &nombre_lignes_a, matrice_a_f77, + &nombre_colonnes_a, &sdim, w, + matrice_vs_f77, &nombre_colonnes_a, + work, &lwork, rwork, NULL, &info, 1, 1); + + free(work); + free(rwork); + free(w); + + if (info != 0) + { + if (info > 0) + { + (*s_etat_processus).exception = d_ep_decomposition_QR; + } + else + { + (*s_etat_processus).erreur_execution = + d_ex_routines_mathematiques; + } + + free(matrice_a_f77); + free(matrice_vs_f77); + return; + } + + for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) + { + for(j = 0; j < (*s_matrice).nombre_lignes; j++) + { + ((complex16 **) (*s_matrice).tableau)[j][i] + .partie_reelle = ((complex16 *) matrice_a_f77)[k] + .partie_reelle; + ((complex16 **) (*s_matrice).tableau)[j][i] + .partie_imaginaire = ((complex16 *) matrice_a_f77) + [k++].partie_imaginaire; + } + } + + (**s_schur).nombre_colonnes = (*s_matrice).nombre_colonnes; + (**s_schur).nombre_lignes = (*s_matrice).nombre_lignes; + (**s_schur).type = 'C'; + + if (((**s_schur).tableau = malloc((**s_schur) + .nombre_lignes * sizeof(complex16 *))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + for(i = 0; i < (**s_schur).nombre_lignes; i++) + { + if ((((complex16 **) (**s_schur).tableau)[i] = (complex16 *) + malloc((**s_schur).nombre_colonnes * + sizeof(complex16))) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + } + + for(k = 0, i = 0; i < (**s_schur).nombre_colonnes; i++) + { + for(j = 0; j < (**s_schur).nombre_lignes; j++) + { + ((complex16 **) (**s_schur).tableau)[j][i].partie_reelle = + ((complex16 *) matrice_vs_f77)[k].partie_reelle; + ((complex16 **) (**s_schur).tableau)[j][i] + .partie_imaginaire = ((complex16 *) matrice_vs_f77) + [k++].partie_imaginaire; + } + } + + free(matrice_a_f77); + free(matrice_vs_f77); + + break; + } + } + + return; +} + + +/* +================================================================================ + Fonction réalisation la factorisation LQ d'une matrice quelconque +================================================================================ + Entrées : struct_matrice +-------------------------------------------------------------------------------- + Sorties : décomposition de LQ de la matrice d'entrée. Le tableau tau + est initialisé par la fonction +-------------------------------------------------------------------------------- + Effets de bord : néant +================================================================================ +*/ + +void +factorisation_lq(struct_processus *s_etat_processus, struct_matrice *s_matrice, + void **tau) +{ + integer4 nombre_colonnes_a; + integer4 nombre_lignes_a; + integer4 erreur; + + unsigned long i; + unsigned long j; + unsigned long k; + unsigned long taille_matrice_f77; + + void *matrice_a_f77; + void *tampon; + void *work; + + nombre_lignes_a = (integer4) (*s_matrice).nombre_lignes; + nombre_colonnes_a = (integer4) (*s_matrice).nombre_colonnes; + taille_matrice_f77 = nombre_lignes_a * nombre_colonnes_a; + + switch((*s_matrice).type) + { + case 'I' : + { + /* Conversion de la matrice en matrice réelle */ + + for(i = 0; i < (unsigned long) nombre_lignes_a; i++) + { + tampon = (*s_matrice).tableau[i]; + + if ((((real8 **) (*s_matrice).tableau)[i] = (real8 *) + malloc(nombre_colonnes_a * sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + for(j = 0; j < (unsigned long) nombre_colonnes_a; j++) + { + ((real8 **) (*s_matrice).tableau)[i][j] = + ((integer8 *) tampon)[j]; + } + + free(tampon); + } + + (*s_matrice).type = 'R'; + } + + case 'R' : + { + if ((matrice_a_f77 = (void *) malloc(taille_matrice_f77 * + sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if (((*tau) = malloc(((nombre_colonnes_a < nombre_lignes_a) + ? nombre_colonnes_a : nombre_lignes_a) * sizeof(real8))) + == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if ((work = malloc(nombre_lignes_a * sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) + { + for(j = 0; j < (*s_matrice).nombre_lignes; j++) + { + ((real8 *) matrice_a_f77)[k++] = ((real8 **) + (*s_matrice).tableau)[j][i]; + } + } + + dgelq2_(&nombre_lignes_a, &nombre_colonnes_a, matrice_a_f77, + &nombre_lignes_a, (*((real8 **) tau)), work, &erreur); + + if (erreur != 0) + { + // L'erreur ne peut être que négative. + + (*s_etat_processus).erreur_execution = + d_ex_routines_mathematiques; + free(work); + free(matrice_a_f77); + return; + } + + for(k = 0, i = 0; i < (unsigned long) nombre_colonnes_a; i++) + { + for(j = 0; j < (unsigned long) nombre_lignes_a; j++) + { + ((real8 **) (*s_matrice).tableau)[j][i] = ((real8 *) + matrice_a_f77)[k++]; + } + } + + free(work); + free(matrice_a_f77); + + break; + } + + case 'C' : + { + if ((matrice_a_f77 = (void *) malloc(taille_matrice_f77 * + sizeof(complex16))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if (((*tau) = malloc(((nombre_colonnes_a < nombre_lignes_a) + ? nombre_colonnes_a : nombre_lignes_a) * + sizeof(complex16))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if ((work = malloc(nombre_lignes_a * sizeof(complex16))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) + { + for(j = 0; j < (*s_matrice).nombre_lignes; j++) + { + ((complex16 *) matrice_a_f77)[k].partie_reelle = + ((complex16 **) (*s_matrice).tableau)[j][i] + .partie_reelle; + ((complex16 *) matrice_a_f77)[k++].partie_imaginaire = + ((complex16 **) (*s_matrice).tableau)[j][i] + .partie_imaginaire; + } + } + + zgelq2_(&nombre_lignes_a, &nombre_colonnes_a, matrice_a_f77, + &nombre_lignes_a, (*((complex16 **) tau)), work, &erreur); + + if (erreur != 0) + { + // L'erreur ne peut être que négative. + + (*s_etat_processus).erreur_execution = + d_ex_routines_mathematiques; + free(work); + free(matrice_a_f77); + return; + } + + for(k = 0, i = 0; i < (unsigned long) nombre_colonnes_a; i++) + { + for(j = 0; j < (unsigned long) nombre_lignes_a; j++) + { + ((complex16 **) (*s_matrice).tableau)[j][i].partie_reelle = + ((complex16 *) matrice_a_f77)[k].partie_reelle; + ((complex16 **) (*s_matrice).tableau)[j][i] + .partie_imaginaire = ((complex16 *) matrice_a_f77) + [k++].partie_imaginaire; + } + } + + free(work); + free(matrice_a_f77); + + break; + } + } + + return; +} + + +/* +================================================================================ + Fonction réalisation la factorisation QR d'une matrice quelconque +================================================================================ + Entrées : struct_matrice +-------------------------------------------------------------------------------- + Sorties : décomposition de QR de la matrice d'entrée. Le tableau tau + est initialisé par la fonction +-------------------------------------------------------------------------------- + Effets de bord : néant +================================================================================ +*/ + +void +factorisation_qr(struct_processus *s_etat_processus, struct_matrice *s_matrice, + void **tau) +{ + integer4 lwork; + integer4 nombre_colonnes_a; + integer4 nombre_lignes_a; + integer4 erreur; + integer4 *pivot; + + real8 *rwork; + + unsigned long i; + unsigned long j; + unsigned long k; + unsigned long taille_matrice_f77; + + void *matrice_a_f77; + void *registre; + void *tampon; + void *work; + + nombre_lignes_a = (integer4) (*s_matrice).nombre_lignes; + nombre_colonnes_a = (integer4) (*s_matrice).nombre_colonnes; + taille_matrice_f77 = nombre_lignes_a * nombre_colonnes_a; + + switch((*s_matrice).type) + { + case 'I' : + { + /* Conversion de la matrice en matrice réelle */ + + for(i = 0; i < (unsigned long) nombre_lignes_a; i++) + { + tampon = (*s_matrice).tableau[i]; + + if ((((real8 **) (*s_matrice).tableau)[i] = (real8 *) + malloc(nombre_colonnes_a * sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + for(j = 0; j < (unsigned long) nombre_colonnes_a; j++) + { + ((real8 **) (*s_matrice).tableau)[i][j] = + ((integer8 *) tampon)[j]; + } + + free(tampon); + } + + (*s_matrice).type = 'R'; + } + + case 'R' : + { + if ((matrice_a_f77 = (void *) malloc(taille_matrice_f77 * + sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if (((*tau) = malloc(((nombre_colonnes_a < nombre_lignes_a) + ? nombre_colonnes_a : nombre_lignes_a) * sizeof(real8))) + == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) + { + for(j = 0; j < (*s_matrice).nombre_lignes; j++) + { + ((real8 *) matrice_a_f77)[k++] = ((real8 **) + (*s_matrice).tableau)[j][i]; + } + } + + if ((pivot = malloc(nombre_colonnes_a * sizeof(integer4))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + for(i = 0; i < (unsigned long) nombre_colonnes_a; pivot[i++] = 0); + + lwork = -1; + + if ((work = malloc(sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + // Calcul de la taille de l'espace + + dgeqp3_(&nombre_lignes_a, &nombre_colonnes_a, matrice_a_f77, + &nombre_lignes_a, pivot, (*((real8 **) tau)), + work, &lwork, &erreur); + + lwork = ((real8 *) work)[0]; + + free(work); + + if ((work = malloc(lwork * sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + // Calcul de la permutation + + if ((registre = (void *) malloc(taille_matrice_f77 * + sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + memcpy(registre, matrice_a_f77, taille_matrice_f77 * sizeof(real8)); + + dgeqp3_(&nombre_lignes_a, &nombre_colonnes_a, registre, + &nombre_lignes_a, pivot, (*((real8 **) tau)), + work, &lwork, &erreur); + + free(registre); + + if (erreur != 0) + { + // L'erreur ne peut être que négative. + + (*s_etat_processus).erreur_execution = + d_ex_routines_mathematiques; + free(work); + free(matrice_a_f77); + free(tau); + return; + } + + // La permutation doit maintenant être unitaire + + dgeqp3_(&nombre_lignes_a, &nombre_colonnes_a, matrice_a_f77, + &nombre_lignes_a, pivot, (*((real8 **) tau)), + work, &lwork, &erreur); + + if (erreur != 0) + { + // L'erreur ne peut être que négative. + + (*s_etat_processus).erreur_execution = + d_ex_routines_mathematiques; + free(work); + free(matrice_a_f77); + free(tau); + return; + } + + for(i = 0; i < (unsigned long) nombre_colonnes_a; i++) + { + if ((i + 1) != (unsigned long) pivot[i]) + { + (*s_etat_processus).erreur_execution = + d_ex_routines_mathematiques; + + free(pivot); + free(work); + free(matrice_a_f77); + free(tau); + + return; + } + } + + free(pivot); + + for(k = 0, i = 0; i < (unsigned long) nombre_colonnes_a; i++) + { + for(j = 0; j < (unsigned long) nombre_lignes_a; j++) + { + ((real8 **) (*s_matrice).tableau)[j][i] = ((real8 *) + matrice_a_f77)[k++]; + } + } + + free(work); + free(matrice_a_f77); + + break; + } + + case 'C' : + { + if ((matrice_a_f77 = (void *) malloc(taille_matrice_f77 * + sizeof(complex16))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if (((*tau) = malloc(((nombre_colonnes_a < nombre_lignes_a) + ? nombre_colonnes_a : nombre_lignes_a) * sizeof(complex16))) + == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) + { + for(j = 0; j < (*s_matrice).nombre_lignes; j++) + { + ((complex16 *) matrice_a_f77)[k].partie_reelle = + ((complex16 **) (*s_matrice).tableau)[j][i] + .partie_reelle; + ((complex16 *) matrice_a_f77)[k++].partie_imaginaire = + ((complex16 **) (*s_matrice).tableau)[j][i] + .partie_imaginaire; + } + } + + if ((pivot = malloc(nombre_colonnes_a * sizeof(integer4))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if ((rwork = malloc(2 * nombre_colonnes_a * sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + for(i = 0; i < (unsigned long) nombre_colonnes_a; pivot[i++] = 0); + + lwork = -1; + + if ((work = malloc(sizeof(complex16))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + // Calcul de la taille de l'espace + + zgeqp3_(&nombre_lignes_a, &nombre_colonnes_a, matrice_a_f77, + &nombre_lignes_a, pivot, (*((complex16 **) tau)), + work, &lwork, rwork, &erreur); + + if (erreur != 0) + { + // L'erreur ne peut être que négative. + + (*s_etat_processus).erreur_execution = + d_ex_routines_mathematiques; + + free(work); + free(rwork); + free(pivot); + free(matrice_a_f77); + free(tau); + return; + } + + lwork = ((complex16 *) work)[0].partie_reelle; + + free(work); + + if ((work = malloc(lwork * sizeof(complex16))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + // Calcul de la permutation + + if ((registre = (void *) malloc(taille_matrice_f77 * + sizeof(complex16))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + memcpy(registre, matrice_a_f77, + taille_matrice_f77 * sizeof(complex16)); + + zgeqp3_(&nombre_lignes_a, &nombre_colonnes_a, registre, + &nombre_lignes_a, pivot, (*((complex16 **) tau)), + work, &lwork, rwork, &erreur); + + free(registre); + + if (erreur != 0) + { + // L'erreur ne peut être que négative. + + (*s_etat_processus).erreur_execution = + d_ex_routines_mathematiques; + + free(work); + free(rwork); + free(pivot); + free(matrice_a_f77); + free(tau); + return; + } + + // La permutation doit maintenant être unitaire + + zgeqp3_(&nombre_lignes_a, &nombre_colonnes_a, matrice_a_f77, + &nombre_lignes_a, pivot, (*((complex16 **) tau)), + work, &lwork, rwork, &erreur); + + if (erreur != 0) + { + // L'erreur ne peut être que négative. + + (*s_etat_processus).erreur_execution = + d_ex_routines_mathematiques; + + free(work); + free(rwork); + free(pivot); + free(matrice_a_f77); + free(tau); + return; + } + + free(rwork); + + for(i = 0; i < (unsigned long) nombre_colonnes_a; i++) + { + if ((i + 1) != (unsigned long) pivot[i]) + { + (*s_etat_processus).erreur_execution = + d_ex_routines_mathematiques; + + free(pivot); + free(work); + free(matrice_a_f77); + free(tau); + + return; + } + } + + free(pivot); + + for(k = 0, i = 0; i < (unsigned long) nombre_colonnes_a; i++) + { + for(j = 0; j < (unsigned long) nombre_lignes_a; j++) + { + ((complex16 **) (*s_matrice).tableau)[j][i].partie_reelle = + ((complex16 *) matrice_a_f77)[k].partie_reelle; + ((complex16 **) (*s_matrice).tableau)[j][i] + .partie_imaginaire = ((complex16 *) + matrice_a_f77)[k++].partie_imaginaire; + } + } + + free(work); + free(matrice_a_f77); + + break; + } + } + + return; +} + + +/* +================================================================================ + Fonctions calculant le déterminant ou le rang d'une matrice quelconque +================================================================================ + Entrées : struct_matrice +-------------------------------------------------------------------------------- + Sorties : déterminant +-------------------------------------------------------------------------------- + Effets de bord : néant +================================================================================ +*/ + + +static integer4 +calcul_rang(struct_processus *s_etat_processus, void *matrice_f77, + integer4 nombre_lignes_a, integer4 nombre_colonnes_a, + integer4 *pivot, integer4 dimension_vecteur_pivot, unsigned char type) +{ + integer4 erreur; + integer4 *iwork; + integer4 *jpvt; + integer4 lwork; + integer4 longueur; + integer4 nombre_colonnes_b; + integer4 nombre_lignes_b; + integer4 ordre; + integer4 rang; + + real8 anorme; + real8 rcond; + real8 *rwork; + + unsigned char norme; + + unsigned long i; + + void *matrice_b; + void *matrice_c; + void *work; + +#undef NORME_I +#ifdef NORME_I + norme = 'I'; + + if ((work = malloc(nombre_lignes_a * sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(-1); + } +#else + norme = '1'; + work = NULL; +#endif + + longueur = 1; + + if (type == 'R') + { + anorme = dlange_(&norme, &nombre_lignes_a, &nombre_colonnes_a, + matrice_f77, &nombre_lignes_a, work, longueur); + +#ifndef NORME_I + free(work); +#endif + + if ((matrice_c = malloc(nombre_lignes_a * nombre_colonnes_a * + sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(-1); + } + + memcpy(matrice_c, matrice_f77, nombre_lignes_a * nombre_colonnes_a * + sizeof(real8)); + + dgetrf_(&nombre_lignes_a, &nombre_colonnes_a, matrice_f77, + &nombre_lignes_a, pivot, &erreur); + + if (erreur < 0) + { + (*s_etat_processus).erreur_execution = + d_ex_routines_mathematiques; + + free(matrice_f77); + return(-1); + } + + if ((iwork = malloc(nombre_colonnes_a * sizeof(integer4))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(-1); + } + + if ((work = malloc(4 * nombre_colonnes_a * sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(-1); + } + + ordre = (nombre_lignes_a > nombre_colonnes_a) + ? nombre_colonnes_a : nombre_lignes_a; + + dgecon_(&norme, &ordre, matrice_f77, + &nombre_lignes_a, &anorme, &rcond, work, iwork, &erreur, + longueur); + + free(work); + free(iwork); + + if (erreur < 0) + { + (*s_etat_processus).erreur_execution = + d_ex_routines_mathematiques; + + free(matrice_f77); + return(-1); + } + + if ((jpvt = malloc(nombre_colonnes_a * sizeof(integer4))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(-1); + } + + for(i = 0; i < (unsigned long) nombre_colonnes_a; i++) + { + ((integer4 *) jpvt)[i] = 0; + } + + lwork = -1; + + if ((work = malloc(sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(-1); + } + + nombre_colonnes_b = 1; + nombre_lignes_b = (nombre_lignes_a > nombre_colonnes_a) + ? nombre_lignes_a : nombre_colonnes_a; + + if ((matrice_b = malloc(nombre_lignes_b * sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(-1); + } + + for(i = 0; i < (unsigned long) nombre_lignes_b; i++) + { + ((real8 *) matrice_b)[i] = 0; + } + + dgelsy_(&nombre_lignes_a, &nombre_colonnes_a, + &nombre_colonnes_b, matrice_c, &nombre_lignes_a, + matrice_b, &nombre_lignes_b, jpvt, &rcond, &rang, + work, &lwork, &erreur); + + lwork = ((real8 *) work)[0]; + free(work); + + if ((work = malloc(lwork * sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(-1); + } + + dgelsy_(&nombre_lignes_a, &nombre_colonnes_a, + &nombre_colonnes_b, matrice_c, &nombre_lignes_a, + matrice_b, &nombre_lignes_b, jpvt, &rcond, &rang, + work, &lwork, &erreur); + + free(matrice_b); + free(matrice_c); + free(work); + free(jpvt); + + if (erreur < 0) + { + (*s_etat_processus).erreur_execution = + d_ex_routines_mathematiques; + + free(matrice_f77); + return(-1); + } + } + else + { + anorme = zlange_(&norme, &nombre_lignes_a, &nombre_colonnes_a, + matrice_f77, &nombre_lignes_a, work, longueur); + +#ifndef NORME_I + free(work); +#endif + + if ((matrice_c = malloc(nombre_lignes_a * nombre_colonnes_a * + sizeof(complex16))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(-1); + } + + memcpy(matrice_c, matrice_f77, nombre_lignes_a * nombre_colonnes_a * + sizeof(complex16)); + + zgetrf_(&nombre_lignes_a, &nombre_colonnes_a, matrice_f77, + &nombre_lignes_a, pivot, &erreur); + + if (erreur < 0) + { + (*s_etat_processus).erreur_execution = + d_ex_routines_mathematiques; + + free(matrice_f77); + return(-1); + } + + if ((rwork = malloc(2 * nombre_colonnes_a * sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(-1); + } + + if ((work = malloc(2 * nombre_colonnes_a * sizeof(complex16))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(-1); + } + + ordre = (nombre_lignes_a > nombre_colonnes_a) + ? nombre_colonnes_a : nombre_lignes_a; + + zgecon_(&norme, &ordre, matrice_f77, + &nombre_lignes_a, &anorme, &rcond, work, rwork, &erreur, + longueur); + + free(work); + + if (erreur < 0) + { + (*s_etat_processus).erreur_execution = + d_ex_routines_mathematiques; + + free(matrice_f77); + return(-1); + } + + if ((jpvt = malloc(nombre_colonnes_a * sizeof(integer4))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(-1); + } + + for(i = 0; i < (unsigned long) nombre_colonnes_a; i++) + { + ((integer4 *) jpvt)[i] = 0; + } + + lwork = -1; + + if ((work = malloc(sizeof(complex16))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(-1); + } + + nombre_colonnes_b = 1; + nombre_lignes_b = (nombre_lignes_a > nombre_colonnes_a) + ? nombre_lignes_a : nombre_colonnes_a; + + if ((matrice_b = malloc(nombre_lignes_b * sizeof(complex16))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(-1); + } + + for(i = 0; i < (unsigned long) nombre_lignes_b; i++) + { + ((complex16 *) matrice_b)[i].partie_reelle = 0; + ((complex16 *) matrice_b)[i].partie_imaginaire = 0; + } + + zgelsy_(&nombre_lignes_a, &nombre_colonnes_a, + &nombre_colonnes_b, matrice_c, &nombre_lignes_a, + matrice_b, &nombre_lignes_b, jpvt, &rcond, &rang, + work, &lwork, rwork, &erreur); + + lwork = ((complex16 *) work)[0].partie_reelle; + free(work); + + if ((work = malloc(lwork * sizeof(complex16))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return(-1); + } + + zgelsy_(&nombre_lignes_a, &nombre_colonnes_a, + &nombre_colonnes_b, matrice_c, &nombre_lignes_a, + matrice_b, &nombre_lignes_b, jpvt, &rcond, &rang, + work, &lwork, rwork, &erreur); + + free(rwork); + free(matrice_b); + free(matrice_c); + free(work); + free(jpvt); + + if (erreur < 0) + { + (*s_etat_processus).erreur_execution = + d_ex_routines_mathematiques; + + free(matrice_f77); + return(-1); + } + } + + return(rang); +} + + +void +determinant(struct_processus *s_etat_processus, struct_matrice *s_matrice, + void *valeur) +{ + complex16 *vecteur_complexe; + + integer4 dimension_vecteur_pivot; + integer4 nombre_colonnes_a; + integer4 nombre_lignes_a; + integer4 *pivot; + integer4 rang; + + integer8 signe; + + real8 *vecteur_reel; + + unsigned long i; + unsigned long j; + unsigned long k; + unsigned long taille_matrice_f77; + + void *matrice_f77; + + nombre_lignes_a = (integer4) (*s_matrice).nombre_lignes; + nombre_colonnes_a = (integer4) (*s_matrice).nombre_colonnes; + dimension_vecteur_pivot = (nombre_lignes_a < nombre_colonnes_a) + ? nombre_lignes_a : nombre_colonnes_a; + taille_matrice_f77 = nombre_lignes_a * nombre_colonnes_a; + + switch((*s_matrice).type) + { + case 'I' : + { + if ((matrice_f77 = (void *) malloc(taille_matrice_f77 * + sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) + { + for(j = 0; j < (*s_matrice).nombre_lignes; j++) + { + ((real8 *) matrice_f77)[k++] = ((integer8 **) + (*s_matrice).tableau)[j][i]; + } + } + + if ((pivot = (integer4 *) malloc(dimension_vecteur_pivot * + sizeof(integer4))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if ((rang = calcul_rang(s_etat_processus, matrice_f77, + nombre_lignes_a, nombre_colonnes_a, pivot, + dimension_vecteur_pivot, 'R')) < 0) + { + return; + } + + if (rang < nombre_lignes_a) + { + (*((real8 *) valeur)) = 0; + } + else + { + if ((vecteur_reel = malloc((*s_matrice).nombre_colonnes * + sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + signe = 1; + + for(i = 0; i < (*s_matrice).nombre_colonnes; i++) + { + if ((unsigned long) pivot[i] != (i + 1)) + { + signe = (signe == 1) ? -1 : 1; + } + + vecteur_reel[i] = ((real8 *) matrice_f77) + [(i * nombre_colonnes_a) + i]; + } + + for(i = 1; i < (*s_matrice).nombre_colonnes; i++) + { + vecteur_reel[0] *= vecteur_reel[i]; + } + + (*((real8 *) valeur)) = vecteur_reel[0] * signe; + + free(vecteur_reel); + } + + free(matrice_f77); + free(pivot); + + break; + } + + case 'R' : + { + if ((matrice_f77 = (void *) malloc(taille_matrice_f77 * + sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) + { + for(j = 0; j < (*s_matrice).nombre_lignes; j++) + { + ((real8 *) matrice_f77)[k++] = ((real8 **) + (*s_matrice).tableau)[j][i]; + } + } + + if ((pivot = (integer4 *) malloc(dimension_vecteur_pivot * + sizeof(integer4))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if ((rang = calcul_rang(s_etat_processus, matrice_f77, + nombre_lignes_a, nombre_colonnes_a, pivot, + dimension_vecteur_pivot, 'R')) < 0) + { + return; + } + + if (rang < nombre_lignes_a) + { + (*((real8 *) valeur)) = 0; + } + else + { + if ((vecteur_reel = malloc((*s_matrice).nombre_colonnes * + sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + signe = 1; + + for(i = 0; i < (*s_matrice).nombre_colonnes; i++) + { + if ((unsigned long) pivot[i] != (i + 1)) + { + signe = (signe == 1) ? -1 : 1; + } + + vecteur_reel[i] = ((real8 *) matrice_f77) + [(i * nombre_colonnes_a) + i]; + } + + for(i = 1; i < (*s_matrice).nombre_colonnes; i++) + { + vecteur_reel[0] *= vecteur_reel[i]; + } + + (*((real8 *) valeur)) = vecteur_reel[0] * signe; + + free(vecteur_reel); + } + + free(matrice_f77); + free(pivot); + + break; + } + + case 'C' : + { + if ((matrice_f77 = (void *) malloc(taille_matrice_f77 * + sizeof(complex16))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) + { + for(j = 0; j < (*s_matrice).nombre_lignes; j++) + { + ((complex16 *) matrice_f77)[k++] = ((complex16 **) + (*s_matrice).tableau)[j][i]; + } + } + + if ((pivot = (integer4 *) malloc(dimension_vecteur_pivot * + sizeof(integer4))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + if ((rang = calcul_rang(s_etat_processus, matrice_f77, + nombre_lignes_a, nombre_colonnes_a, pivot, + dimension_vecteur_pivot, 'C')) < 0) + { + return; + } + + if (rang < nombre_lignes_a) + { + (*((complex16 *) valeur)).partie_reelle = 0; + (*((complex16 *) valeur)).partie_imaginaire = 0; + } + else + { + if ((vecteur_complexe = malloc((*s_matrice).nombre_colonnes * + sizeof(complex16))) == NULL) + { + (*s_etat_processus).erreur_systeme = + d_es_allocation_memoire; + return; + } + + signe = 1; + + for(i = 0; i < (*s_matrice).nombre_colonnes; i++) + { + if ((unsigned long) pivot[i] != (i + 1)) + { + signe = (signe == 1) ? -1 : 1; + } + + vecteur_complexe[i] = ((complex16 *) matrice_f77) + [(i * nombre_colonnes_a) + i]; + } + + for(i = 1; i < (*s_matrice).nombre_colonnes; i++) + { + f77multiplicationcc_(&(vecteur_complexe[0]), + &(vecteur_complexe[i]), &(vecteur_complexe[0])); + } + + f77multiplicationci_(&(vecteur_complexe[0]), &signe, + ((complex16 *) valeur)); + + free(vecteur_complexe); + } + + free(matrice_f77); + free(pivot); + + break; + } + } + + return; +} + + +void +rang(struct_processus *s_etat_processus, struct_matrice *s_matrice, + integer8 *valeur) +{ + integer4 dimension_vecteur_pivot; + integer4 nombre_lignes_a; + integer4 nombre_colonnes_a; + integer4 *pivot; + integer4 rang; + integer4 taille_matrice_f77; + + unsigned long i; + unsigned long j; + unsigned long k; + + void *matrice_f77; + + nombre_lignes_a = (integer4) (*s_matrice).nombre_lignes; + nombre_colonnes_a = (integer4) (*s_matrice).nombre_colonnes; + dimension_vecteur_pivot = (nombre_lignes_a < nombre_colonnes_a) + ? nombre_lignes_a : nombre_colonnes_a; + taille_matrice_f77 = nombre_lignes_a * nombre_colonnes_a; + + if ((pivot = (integer4 *) malloc(dimension_vecteur_pivot * + sizeof(integer4))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + switch((*s_matrice).type) + { + case 'I' : + { + if ((matrice_f77 = (void *) malloc(taille_matrice_f77 * + sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) + { + for(j = 0; j < (*s_matrice).nombre_lignes; j++) + { + ((real8 *) matrice_f77)[k++] = ((integer8 **) + (*s_matrice).tableau)[j][i]; + } + } + + if ((rang = calcul_rang(s_etat_processus, matrice_f77, + nombre_lignes_a, nombre_colonnes_a, pivot, + dimension_vecteur_pivot, 'R')) < 0) + { + free(pivot); + free(matrice_f77); + return; + } + + free(matrice_f77); + (*valeur) = rang; + break; + } + + case 'R' : + { + if ((matrice_f77 = (void *) malloc(taille_matrice_f77 * + sizeof(real8))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) + { + for(j = 0; j < (*s_matrice).nombre_lignes; j++) + { + ((real8 *) matrice_f77)[k++] = ((real8 **) + (*s_matrice).tableau)[j][i]; + } + } + + if ((rang = calcul_rang(s_etat_processus, matrice_f77, + nombre_lignes_a, nombre_colonnes_a, pivot, + dimension_vecteur_pivot, 'R')) < 0) + { + free(pivot); + free(matrice_f77); + return; + } + + free(matrice_f77); + (*valeur) = rang; + break; + } + + case 'C' : + { + if ((matrice_f77 = (void *) malloc(taille_matrice_f77 * + sizeof(complex16))) == NULL) + { + (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; + return; + } + + for(k = 0, i = 0; i < (*s_matrice).nombre_colonnes; i++) + { + for(j = 0; j < (*s_matrice).nombre_lignes; j++) + { + ((complex16 *) matrice_f77)[k++] = ((complex16 **) + (*s_matrice).tableau)[j][i]; + } + } + + if ((rang = calcul_rang(s_etat_processus, matrice_f77, + nombre_lignes_a, nombre_colonnes_a, pivot, + dimension_vecteur_pivot, 'C')) < 0) + { + free(pivot); + free(matrice_f77); + return; + } + + free(matrice_f77); + (*valeur) = rang; + break; + } + } + + free(pivot); + + return; +} + +// vim: ts=4