IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

[Présentation bibliothèque] Nombres imaginaires


Sujet :

C++

  1. #1
    Membre régulier

    Inscrit en
    Juin 2008
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 49
    Points : 114
    Points
    114
    Par défaut [Présentation bibliothèque] Nombres imaginaires
    Bonsoir,

    Cela fait quelques temps que je travaille sur des simulations numériques utilisant à outrance des nombres complexes. Pour ce faire, j'utilise la classe std::complex<> de la SL bien qu'à mon goût elle ne soit pas optimale dans son design.
    Dans de nombreux calculs, je multiplie des nombres réels ou complexes par l'unité imaginaire i (sqrt(-1)). Le moyen le plus simple de faire cela est de définir une constante complexe valant i définie comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const std::complex<double> ii(0.,1.)
    et d'utiliser cette constante là où une multiplication par i est nécessaire.

    Cependant, ceci n'est pas du tout optimal puisque étant donné le type même de cette variable, le calcul du produit de i et d'un autre nombre complexe est inutilement coûteux. Alors que i*(a+ib) s'obtient facilement en deux opérations, la manière dont la classe std::complex<> est implémentée force le calcul de (0+i)*(a+ib) ce qui est nettement plus coûteux.

    J'ai cherché à améliorer cela dans mes calculs. La première manière d'y arriver est de récrire toutes mes équations séparément pour la partie réelle et la partie imaginaire, mais ce n'est pas très pratique et je préférais une solution plus "informatique". J'ai donc défini une classe Imaginary<> représentant un nombre purement imaginaire (i.e. a*i) et proposant toutes les opérations que std::complex<> offre. J'ai alors pu observer un gain assez spectaculaire dans mes simulations.

    Je vous présente donc mon code et je viens vous demander votre avis sur la manière dont ma classe et ses fonctions externes sont implémentées.

    L'utilisation de la classe est très simple. Pour l'unité imaginaire, on déclare simplement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const Imaginary<double> ii(1.)
    et tous les opérateurs réels - imaginaires et complexe - imaginaire sont implémentés. Vous pouvez trouver le code de cette classe en pièce jointe.

    L'exemple fournit avec est un cas typique d'utilisation. Il s'agit d'un code faisant évoluer une fonction d'onde dans un potentiel au moyen de l'équation de Schroedinger.
    En compilant avec g++ 4.6.1 sur mon core i7-2820QM et avec les options -O2 ou -O3, j'obtiens un temps d'exécution de la partie calculatoire de 11.85 secondes.
    Si j'utilise l'option -DUSE_IMAGINARY qui active l'utilisation de ma classe pour la variable ii au lieu de std::complex<>, j'obtiens un temps de
    4.84 secondes pour la même portion de code, soit un gain de 2.4 !
    J'obtiens les mêmes proportions si je fais itérer le code un plus grand nombre de fois pour éliminer les fluctuations.
    Le compilateur Intel me fournit approximativement les mêmes valeurs.

    Le code teste explicitement le gain dû à des multiplications par i, mais il y a aussi des gains possibles pour les opérations de division ou pour toutes les fonctions trigonométriques et hyperboliques par exemple, bien que les cas d'utilisation soient, à mon sens, plus rares.

    Que pensez-vous de cette classe ? Pourriez-vous tester ce morceau de code chez vous et reporter quelques valeurs ?

    Merci d'avance pour votre aide,

    Nanoc
    Fichiers attachés Fichiers attachés

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Je n'ai pas encore testé ton code, mais je te remercie de nous l'avoir fait parvenir. Si tu nous en donnes l'occasion, nous le passerions peut etre volontiers dans les sources

    Il est vrai que l'un des gros reproches que l'on peut faire au sujet de la S(T)L est son trop haut niveau de généricité.

    Il n'est donc pas rare que, pour un cas d'utilisation particulier, un implémentation plus spécialisée offre de meilleurs résultats, en voici sans doute encore un exemple

    Mais il faut cependant prendre conscience que le principe même qui vaut pour l'ensemble de la STL est d'être utilisable dans un maximum de cas, et que les algorithmes utilisés doivent donc donner une certitude de fonctionnement dans tous les cas envisagés.

    C'est la raison pour laquelle il arrive malheureusement que, dans certaines circonstances particulières, des algorithmes plus efficaces pourraient etre envisagés , mais que, ces algorithmes ne donnant pas de garantie suffisantes de bonne fin dans l'ensemble des cas d'utilisation envisagés, il aient été écartés de l'implémentation de la STL.
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Nombre imaginaire en Java
    Par pioupiou67290 dans le forum Langage
    Réponses: 2
    Dernier message: 12/12/2011, 22h16
  2. [Labview 8.5] équation et nombre imaginaire
    Par pilip dans le forum LabVIEW
    Réponses: 2
    Dernier message: 28/10/2010, 15h47
  3. Réponses: 6
    Dernier message: 05/08/2008, 10h18
  4. Réponses: 4
    Dernier message: 01/04/2006, 13h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo