/* ================================================================================ RPL/2 (R) version 4.1.11 Copyright (C) 1989-2012 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 'lu' ================================================================================ Entrées : pointeur sur une structure struct_processus -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_lu(struct_processus *s_etat_processus) { struct_matrice *s_matrice; struct_objet *s_objet_argument; struct_objet *s_objet_copie; struct_objet *s_objet_resultat_1; struct_objet *s_objet_resultat_2; struct_objet *s_objet_resultat_3; unsigned long i; unsigned long j; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n LU "); if ((*s_etat_processus).langue == 'F') { printf("(décomposition LU)\n\n"); } else { printf("(LU decomposition)\n\n"); } printf(" 1: %s, %s\n", d_MIN, d_MRL); printf("-> 3: %s\n", d_MIN); printf(" 2: %s\n", d_MRL); printf(" 1: %s\n\n", d_MRL); printf(" 1: %s\n", d_MCX); printf("-> 3: %s\n", d_MIN); printf(" 2: %s\n", d_MCX); printf(" 1: %s\n", d_MCX); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 1) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } /* -------------------------------------------------------------------------------- Résultat sous la forme de matrices réelles -------------------------------------------------------------------------------- */ if (((*s_objet_argument).type == MIN) || ((*s_objet_argument).type == MRL)) { if ((*((struct_matrice *) (*s_objet_argument).objet)).nombre_lignes != (*((struct_matrice *) (*s_objet_argument).objet)) .nombre_colonnes) { liberation(s_etat_processus, s_objet_argument); (*s_etat_processus).erreur_execution = d_ex_dimensions_invalides; return; } if ((s_objet_copie = copie_objet(s_etat_processus, s_objet_argument, 'Q')) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } liberation(s_etat_processus, s_objet_argument); s_objet_argument = s_objet_copie; if ((s_matrice = malloc(sizeof(struct_matrice))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } factorisation_lu(s_etat_processus, (*s_objet_argument).objet, &s_matrice); (*s_objet_copie).type = MRL; if (((*s_etat_processus).exception != d_ep) || ((*s_etat_processus).erreur_execution != d_ex)) { // S'il y a une erreur autre qu'une erreur système, le tableau // de la structure matrice n'a pas encore été alloué. free(s_matrice); liberation(s_etat_processus, s_objet_argument); return; } if ((*s_etat_processus).erreur_systeme != d_es) { return; } if ((s_objet_resultat_1 = allocation(s_etat_processus, NON)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } (*s_objet_resultat_1).objet = s_matrice; (*s_objet_resultat_1).type = MIN; if ((s_objet_resultat_2 = allocation(s_etat_processus, MRL)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if ((s_objet_resultat_3 = allocation(s_etat_processus, MRL)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } /* L */ (*((struct_matrice *) (*s_objet_resultat_3).objet)).nombre_lignes = (*((struct_matrice *) (*s_objet_argument).objet)) .nombre_lignes; (*((struct_matrice *) (*s_objet_resultat_3).objet)).nombre_colonnes = (*((struct_matrice *) (*s_objet_argument).objet)) .nombre_colonnes; if (((*((struct_matrice *) (*s_objet_resultat_3).objet)).tableau = malloc((*((struct_matrice *) (*s_objet_resultat_3) .objet)).nombre_lignes * sizeof(real8 *))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } for(i = 0; i < (*((struct_matrice *) (*s_objet_resultat_3).objet)) .nombre_lignes; i++) { if ((((real8 **) (*((struct_matrice *) (*s_objet_resultat_3).objet)) .tableau)[i] = malloc((*((struct_matrice *) (*s_objet_resultat_3).objet)).nombre_colonnes * sizeof(real8))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } /* * Si la décomposition comporte plus de lignes que de colonnes, * L est une matrice trapézoïdale. */ for(j = 0; j < (*((struct_matrice *) (*s_objet_resultat_3).objet)) .nombre_colonnes; j++) { if (i == j) { ((real8 **) (*((struct_matrice *) (*s_objet_resultat_3) .objet)).tableau)[i][j] = 1; } else if (i > j) { ((real8 **) (*((struct_matrice *) (*s_objet_resultat_3) .objet)).tableau)[i][j] = ((real8 **) (*((struct_matrice *) (*s_objet_argument) .objet)).tableau)[i][j]; } else { ((real8 **) (*((struct_matrice *) (*s_objet_resultat_3) .objet)).tableau)[i][j] = 0; } } } /* U */ (*((struct_matrice *) (*s_objet_resultat_2).objet)).nombre_lignes = (*((struct_matrice *) (*s_objet_argument).objet)) .nombre_lignes; (*((struct_matrice *) (*s_objet_resultat_2).objet)).nombre_colonnes = (*((struct_matrice *) (*s_objet_argument).objet)) .nombre_colonnes; if (((*((struct_matrice *) (*s_objet_resultat_2).objet)).tableau = malloc((*((struct_matrice *) (*s_objet_resultat_2) .objet)).nombre_lignes * sizeof(real8 *))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } for(i = 0; i < (*((struct_matrice *) (*s_objet_resultat_2).objet)) .nombre_lignes; i++) { if ((((real8 **) (*((struct_matrice *) (*s_objet_resultat_2).objet)) .tableau)[i] = malloc((*((struct_matrice *) (*s_objet_resultat_2).objet)).nombre_colonnes * sizeof(real8))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } /* * Si la décomposition comporte plus de colonnes que de lignes, * U est une matrice trapézoïdale. */ for(j = 0; j < (*((struct_matrice *) (*s_objet_resultat_2).objet)) .nombre_colonnes; j++) { if (i <= j) { ((real8 **) (*((struct_matrice *) (*s_objet_resultat_2) .objet)).tableau)[i][j] = ((real8 **) (*((struct_matrice *) (*s_objet_argument) .objet)).tableau)[i][j]; } else { ((real8 **) (*((struct_matrice *) (*s_objet_resultat_2) .objet)).tableau)[i][j] = 0; } } } } /* -------------------------------------------------------------------------------- Résultat sous la forme de matrices complexes -------------------------------------------------------------------------------- */ else if ((*s_objet_argument).type == MCX) { if ((*((struct_matrice *) (*s_objet_argument).objet)).nombre_lignes != (*((struct_matrice *) (*s_objet_argument).objet)) .nombre_colonnes) { liberation(s_etat_processus, s_objet_argument); (*s_etat_processus).erreur_execution = d_ex_dimensions_invalides; return; } if ((s_objet_copie = copie_objet(s_etat_processus, s_objet_argument, 'Q')) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } liberation(s_etat_processus, s_objet_argument); s_objet_argument = s_objet_copie; if ((s_matrice = malloc(sizeof(struct_matrice))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } factorisation_lu(s_etat_processus, (*s_objet_argument).objet, &s_matrice); if (((*s_etat_processus).exception != d_ep) || ((*s_etat_processus).erreur_execution != d_ex)) { // S'il y a une erreur autre qu'une erreur système, le tableau // de la structure matrice n'a pas encore été alloué. free(s_matrice); liberation(s_etat_processus, s_objet_argument); return; } if ((*s_etat_processus).erreur_systeme != d_es) { return; } if ((s_objet_resultat_1 = allocation(s_etat_processus, NON)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } (*s_objet_resultat_1).objet = s_matrice; (*s_objet_resultat_1).type = MIN; if ((s_objet_resultat_2 = allocation(s_etat_processus, MCX)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if ((s_objet_resultat_3 = allocation(s_etat_processus, MCX)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } /* L */ (*((struct_matrice *) (*s_objet_resultat_3).objet)).nombre_lignes = (*((struct_matrice *) (*s_objet_argument).objet)) .nombre_lignes; (*((struct_matrice *) (*s_objet_resultat_3).objet)).nombre_colonnes = (*((struct_matrice *) (*s_objet_argument).objet)) .nombre_colonnes; if (((*((struct_matrice *) (*s_objet_resultat_3).objet)).tableau = malloc((*((struct_matrice *) (*s_objet_resultat_3) .objet)).nombre_lignes * sizeof(complex16 *))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } for(i = 0; i < (*((struct_matrice *) (*s_objet_resultat_3).objet)) .nombre_lignes; i++) { if ((((complex16 **) (*((struct_matrice *) (*s_objet_resultat_3).objet)) .tableau)[i] = malloc((*((struct_matrice *) (*s_objet_resultat_3).objet)).nombre_colonnes * sizeof(complex16))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } /* * Si la décomposition comporte plus de lignes que de colonnes, * L est une matrice trapézoïdale. */ for(j = 0; j < (*((struct_matrice *) (*s_objet_resultat_3).objet)) .nombre_colonnes; j++) { if (i == j) { ((complex16 **) (*((struct_matrice *) (*s_objet_resultat_3) .objet)).tableau)[i][j].partie_reelle = 1; ((complex16 **) (*((struct_matrice *) (*s_objet_resultat_3) .objet)).tableau)[i][j].partie_imaginaire = 0; } else if (i > j) { ((complex16 **) (*((struct_matrice *) (*s_objet_resultat_3) .objet)).tableau)[i][j] = ((complex16 **) (*((struct_matrice *) (*s_objet_argument) .objet)).tableau)[i][j]; } else { ((complex16 **) (*((struct_matrice *) (*s_objet_resultat_3) .objet)).tableau)[i][j].partie_reelle = 0; ((complex16 **) (*((struct_matrice *) (*s_objet_resultat_3) .objet)).tableau)[i][j].partie_imaginaire = 0; } } } /* U */ (*((struct_matrice *) (*s_objet_resultat_2).objet)).nombre_lignes = (*((struct_matrice *) (*s_objet_argument).objet)) .nombre_lignes; (*((struct_matrice *) (*s_objet_resultat_2).objet)).nombre_colonnes = (*((struct_matrice *) (*s_objet_argument).objet)) .nombre_colonnes; if (((*((struct_matrice *) (*s_objet_resultat_2).objet)).tableau = malloc((*((struct_matrice *) (*s_objet_resultat_2) .objet)).nombre_lignes * sizeof(complex16 *))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } for(i = 0; i < (*((struct_matrice *) (*s_objet_resultat_2).objet)) .nombre_lignes; i++) { if ((((complex16 **) (*((struct_matrice *) (*s_objet_resultat_2).objet)) .tableau)[i] = malloc((*((struct_matrice *) (*s_objet_resultat_2).objet)).nombre_colonnes * sizeof(complex16))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } /* * Si la décomposition comporte plus de colonnes que de lignes, * U est une matrice trapézoïdale. */ for(j = 0; j < (*((struct_matrice *) (*s_objet_resultat_2).objet)) .nombre_colonnes; j++) { if (i <= j) { ((complex16 **) (*((struct_matrice *) (*s_objet_resultat_2) .objet)).tableau)[i][j] = ((complex16 **) (*((struct_matrice *) (*s_objet_argument) .objet)).tableau)[i][j]; } else { ((complex16 **) (*((struct_matrice *) (*s_objet_resultat_2) .objet)).tableau)[i][j].partie_reelle = 0; ((complex16 **) (*((struct_matrice *) (*s_objet_resultat_2) .objet)).tableau)[i][j].partie_imaginaire = 0; } } } } /* -------------------------------------------------------------------------------- Type d'argument invalide -------------------------------------------------------------------------------- */ else { liberation(s_etat_processus, s_objet_argument); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } liberation(s_etat_processus, s_objet_argument); if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_resultat_1) == d_erreur) { return; } if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_resultat_3) == d_erreur) { return; } if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet_resultat_2) == d_erreur) { return; } return; } /* ================================================================================ Fonction 'lchol' ================================================================================ Entrées : pointeur sur une structure struct_processus -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_lchol(struct_processus *s_etat_processus) { struct_objet *s_copie_objet; struct_objet *s_objet; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n LCHOL "); if ((*s_etat_processus).langue == 'F') { printf("(décomposition de Cholevski à gauche)\n\n"); } else { printf("(left Cholevski decomposition)\n\n"); } printf(" 1: %s, %s\n", d_MIN, d_MRL); printf("-> 1: %s\n\n", d_MRL); printf(" 1: %s\n", d_MCX); printf("-> 1: %s\n", d_MCX); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 1) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } /* -------------------------------------------------------------------------------- Résultat sous la forme de matrices réelles -------------------------------------------------------------------------------- */ if (((*s_objet).type == MIN) || ((*s_objet).type == MRL)) { if ((*((struct_matrice *) (*s_objet).objet)).nombre_lignes != (*((struct_matrice *) (*s_objet).objet)).nombre_colonnes) { liberation(s_etat_processus, s_objet); (*s_etat_processus).erreur_execution = d_ex_dimensions_invalides; return; } if ((s_copie_objet = copie_objet(s_etat_processus, s_objet, 'Q')) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } liberation(s_etat_processus, s_objet); s_objet = s_copie_objet; factorisation_cholesky(s_etat_processus, (*s_objet).objet, 'L'); (*s_objet).type = MRL; if ((*s_etat_processus).erreur_systeme != d_es) { return; } if (((*s_etat_processus).exception != d_ep) || ((*s_etat_processus).erreur_execution != d_ex)) { if ((*s_etat_processus).exception == d_ep_domaine_definition) { (*s_etat_processus).exception = d_ep_matrice_non_definie_positive; } liberation(s_etat_processus, s_objet); return; } } /* -------------------------------------------------------------------------------- Résultat sous la forme de matrices complexes -------------------------------------------------------------------------------- */ else if ((*s_objet).type == MCX) { if ((*((struct_matrice *) (*s_objet).objet)).nombre_lignes != (*((struct_matrice *) (*s_objet).objet)).nombre_colonnes) { liberation(s_etat_processus, s_objet); (*s_etat_processus).erreur_execution = d_ex_dimensions_invalides; return; } if ((s_copie_objet = copie_objet(s_etat_processus, s_objet, 'Q')) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } liberation(s_etat_processus, s_objet); s_objet = s_copie_objet; factorisation_cholesky(s_etat_processus, (*s_objet).objet, 'L'); if ((*s_etat_processus).erreur_systeme != d_es) { return; } if (((*s_etat_processus).exception != d_ep) || ((*s_etat_processus).erreur_execution != d_ex)) { if ((*s_etat_processus).exception == d_ep_domaine_definition) { (*s_etat_processus).exception = d_ep_matrice_non_definie_positive; } liberation(s_etat_processus, s_objet); return; } } /* -------------------------------------------------------------------------------- Type d'argument invalide -------------------------------------------------------------------------------- */ else { liberation(s_etat_processus, s_objet); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } if (empilement(s_etat_processus, &((*s_etat_processus).l_base_pile), s_objet) == d_erreur) { return; } return; } /* ================================================================================ Fonction 'lock' ================================================================================ Entrées : pointeur sur une structure struct_processus -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void instruction_lock(struct_processus *s_etat_processus) { file *descripteur; struct flock lock; struct_descripteur_fichier *fichier; struct_objet *s_objet_argument_1; struct_objet *s_objet_argument_2; unsigned char *chaine; (*s_etat_processus).erreur_execution = d_ex; if ((*s_etat_processus).affichage_arguments == 'Y') { printf("\n LOCK "); if ((*s_etat_processus).langue == 'F') { printf("(verrouillage d'un fichier)\n\n"); } else { printf("(file lock)\n\n"); } printf(" 2: %s\n", d_FCH); printf(" 1: %s (READ/WRITE/NONE)\n", d_CHN); return; } else if ((*s_etat_processus).test_instruction == 'Y') { (*s_etat_processus).nombre_arguments = -1; return; } if (test_cfsf(s_etat_processus, 31) == d_vrai) { if (empilement_pile_last(s_etat_processus, 2) == d_erreur) { return; } } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument_1) == d_erreur) { (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile), &s_objet_argument_2) == d_erreur) { liberation(s_etat_processus, s_objet_argument_1); (*s_etat_processus).erreur_execution = d_ex_manque_argument; return; } if (((*s_objet_argument_2).type == FCH) && ((*s_objet_argument_1).type == CHN)) { lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; lock.l_pid = getpid(); if ((chaine = conversion_majuscule((unsigned char *) (*s_objet_argument_1).objet)) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return; } if (strcmp(chaine, "READ") == 0) { lock.l_type = F_WRLCK; } else if (strcmp(chaine, "WRITE") == 0) { lock.l_type = F_RDLCK; } else if (strcmp(chaine, "NONE") == 0) { lock.l_type = F_UNLCK; } else { free(chaine); liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); (*s_etat_processus).erreur_execution = d_ex_verrou_indefini; return; } free(chaine); if ((fichier = descripteur_fichier(s_etat_processus, (struct_fichier *) (*s_objet_argument_2).objet)) == NULL) { return; } descripteur = (*fichier).descripteur_c; if (fcntl(fileno(descripteur), F_SETLK, &lock) == -1) { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); (*s_etat_processus).erreur_execution = d_ex_fichier_verrouille; return; } } else { liberation(s_etat_processus, s_objet_argument_1); liberation(s_etat_processus, s_objet_argument_2); (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument; return; } return; } // vim: ts=4