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

Mon programme Discussion :

[Open Source][C++] C++11 et analyse numérique


Sujet :

Mon programme

  1. #1
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut [Open Source][C++] C++11 et analyse numérique
    Bonjour,

    Description courte
    -------------------


    J'ai développé une petite bibliothèque (un fichier .hpp) en C++11 qui permet de manipuler de manières plus agréable des tableaux de données multidimensionnels, données qui sont sensées représenter des valeurs discrétisées d'un problème continu (par exemple en mathématiques, ou très couramment en physique).

    Le fichier est auto-documenté, mais on peut générer une documentation Doxygen si besoin. Si le concept vous intéresse, je vous invite à lire la description en détail ci dessous, pour voir ce quoi cette bibliothèque est capable, et si elle peut vous être utile (j'ai du mal à résumer convenablement ce que j'ai voulu faire sans trop faire appel à du vocabulaire de physicien).

    Le tout est distribué sous licence zlib, et téléchargeable ici : [dernière version].

    Note : pour compiler, ce petit bout de programme nécessite certaines fonctionnalités du C++11 :
    • les templates variadiques
    • range-based for loop
    • le mot clé default pour les fonctions membres
    • les listes d'initialisations
    • le mot clé auto
    • le mot clé decltype
    • les typedefs de template (on peut s'en passer en définissant la variable pré-processeur NO_TEMPLATE_TYPEDEF)

    Toutes ces fonctionnalités sont implémentées dans gcc-4.7, et je crois que seule la dernière manque à gcc-4.6.


    Description longue
    -------------------


    1] Introduction

    Il existe de nombreux domaines (par exemple en recherche, et je pense tout particulièrement à la physique puisqu'il s'agit de mon propre domaine) où l'on a des équations mathématiques à résoudre, mais où tout traitement analytique est impossible. Soit parce que le volume de donnée est trop important, soit parce que les équations en jeu sont trop complexes. Dans ces cas là, on fait appel aux ordinateurs, et on utilise des méthodes numériques.

    Dans beaucoup de cas, cela revient à considérer une version discrète d'un problème continu. Par exemple, si l'on étudie la déformation d'une corde de longueur L donnée, on choisit N points sur la corde dont on va étudier la trajectoire, et considérer que la corde est uniquement constituée de ces N points.
    Le résultat réel (que l'on obtiendrait si l'on pouvait faire le traitement analytique) est obtenu dans la limite où N est infini (c'est la définition du continu), mais cette limite est numériquement inatteignable à cause de problèmes de précision. On se contente donc en général de prendre N suffisamment grand. Dans ce qui suit, N est appelé le nombre d'échantillons (number of samples pour Shakespear).

    La manière la plus simple de traiter ce genre de problème en C++ est de créer un simple tableau de taille N :
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    double position_corde[N];
    où chaque élément du tableau représente un des N points considérés (ici il s'agit d'un type double, donc ce serait par exemple la déformation transversale de la corde). Puis, on fait évoluer la corde dans le temps. Par exemple :
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    size_t wrap(int i, size_t N) { return i < 0 ? i%N + N : i%N; }
     
    for (size_t t = 0; t < 10; ++t)
    for (size_t i = 0; i < N; ++i)
        position_corde[i] = position_corde[wrap(i-1, N)];
    À chaque pas de temps t, un point i de la corde prend la position du point précédent.

    Cette approche, techniquement très simple, présente cependant quelques inconvénients. En premier lieu, il faut "se souvenir" qu'au point i correspond la position réelle i*L/N (et c'est le cas le plus simple, où on attribue la position 0 au premier point). Ensuite, il existe certaines opérations mathématiques (comme la dérivation) qui agissent sur un point et son entourage (typiquement les premiers, voir seconds voisins). Si leur implémentation est simple pour une fonction à un paramètre (représentée donc par un tableau unidimensionnel), elle l'est nettement moins pour une fonction à plusieurs paramètres (comme, par exemple, si notre corde étais un tapis...). Enfin, c'est une approche largement héritée du C, qui ne fait aucun usage des forces du C++.

    J'ai donc voulu voir à quel point on pouvait rendre plus agréable l'utilisation de ces concepts grâce au C++, et en particulier grâce à sa toute dernière version, le C++11. J'ai donc mis au point une toute petite bibliothèque, constituée d'un seul fichier (eh oui, tout est template...).

    2] Fonctions à une variable

    Le résultat tient en une seule classe, nommée utils::numerical_function<T>. C'est une classe template : T correspond au type de donnée contenue (par exemple double dans l'exemple précédent). En interne, elle contient simplement un std::vector, qui contient lui-même les données.

    La première chose que j'ai voulu implémenter, c'est une syntaxe proche des fonctions usuelles. Par exemple, position_corde(x) au lieu de position_corde[i], où x est le paramètre réel, équivalent à i*L/N. Pour que ça puisse fonctionner, il faut bien sûr que la fonction stocke avec elle l'information nécessaire, c'est à dire "de combien d'unités sont espacés deux points adjacents, et quel est la position du premier point". Il faut aussi gérer les positions qui sortent du cadre imposé : dans le cas de la corde, que faire si x devient négatif, ou plus grand que L ? Doit-on engueuler l'utilisateur qui ne sait pas ce qu'il fait, laisser planter le programme, ou bien doit-on considérer que le point N+1 est en réalité le point 0 (c'est ce qu'on a fait dans le premier exemple, en prenant i%N) ? Cela revient à choisir les conditions aux limites, comme on dit en physique.
    Ensuite, quel point choisir si aucun entier i ne correspond exactement à x*N/L ? Doit on prendre le plus proche ? Ou faire une interpolation quelconque entre les deux points les plus proches ? C'est le choix de l'interpolation.

    La première étape quand on construit une telle fonction va donc être de spécifier ces informations :
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // On créé d'abord l'objet, en spécifiant combien de points on veut traiter
    utils::numerical_function<double> position_corde(N);
    // ... on choisis le mode d'interpolation (INTERPOLATION_LINEAR 
    // correspond à une interpolation linéaire, et INTERPOLATION_NEAREST
    // choisit le point le plus proche)
    position_corde.set_interpolation_method(utils::INTERPOLATION_LINEAR);
    // ... puis on précise que l'intervalle est de [0, L], et les conditions
    // aux limites (boundaries en anglais) sont périodiques
    position_corde.set_range(utils::range(0, L), utils::BOUNDARY_PERIODIC);
    Par défaut :
    • l'interpolation est INTERPOLATION_NEAREST (c'est la méthode la plus rapide),
    • les conditions aux limites sont "laisser planter le programme si on dépasse". (c'est ce qui se fait de plus performant, si on sait ce qu'on fait, c'est à dire qu'on est sûr de ne jamais dépasser),
    • et l'intervalle, si l'utilisateur oublie de préciser, est arbitrairement choisi à [0,1].

    Il est possible de changer le nombre d'échantillons N par la suite grâce à la méthode resize(N);.

    Une fois que tout ça est fait, on peut utiliser pleinement la fonction. Sauf que...

    La syntaxe position_corde(x) (équivalente à position_corde.get_value(x)) est belle et pratique si on veut lire les données contenues dans la fonction. Si en revanche on souhaite écrire de nouvelles choses dedans, on est obligé de travailler avec les indices. J'ai donc mis à disposition une autre méthode pour accéder aux données, via la surcharge de l'opérateur []. De fait, position_corde[i] a strictement la même signification que dans l'exemple précédent (c'est équivalent à position_corde.get_data(i)).
    Enfin, pour se simplifier un peu la vie, j'ai aussi ajouté une méthode index_to_param(i), qui permet d'obtenir le x correspondant à l'indice i fourni (et param_to_index(x) fait l'inverse).

    Avec tout ça, on peut donc faire exactement la même chose qu'avec la syntaxe "C", mais on a aussi la possibilité de travailler avec les grandeurs réelles (le x) plutôt qu'avec les indices si on le souhaite. Qui plus est, la fonction porte avec elle les informations nécessaires pour convertir un indice en une valeur réelle : on a donc pas besoin de "se souvenir" de quoi que ce soit. Il suffit de tout spécifier au début.

    3] Fonctions à plusieurs variables

    On a donc traité le premier problème de l'approche "C".
    Maintenant, qu'en est-il des fonctions à plusieurs variables ? Je ne voulais pas m'amuser à faire une classe pour la fonctions à une variable, puis une autre pour les fonctions à deux variables et ainsi de suite. J'ai donc opté pour l'un des plus beaux ajouts du C++11 : les templates variadiques.

    En réalité, j'ai un peu menti : la fonction est de type utils::numerical_function<T, P>, où P est le nombre de variables de la fonction (1 correspond par exemple à la corde, 2 au tapis, etc. Par défaut, P vaut 1).

    Dans le cas P=2, avec N1 échantillons pour la première varible et N2 pour la seconde, et pour un tapis rectangulaire de taille L1 par L2, l'initialisation de la fonction se fait de la manière suivante (grâce aux templates variadiques) :
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // On créé d'abord l'objet, en spécifiant combien de points on veut traiter
    utils::numerical_function<double, 2> position_tapis(N1, N2);
    // ... on choisis le mode d'interpolation (INTERPOLATION_LINEAR
    // correspond à une interpolation linéaire, et INTERPOLATION_NEAREST
    // choisit le point le plus proche)
    position_tapis.set_interpolation_method(utils::INTERPOLATION_LINEAR);
    // ... puis on précise que l'intervalle est de [0, L1] pour la première variable
    // et [0, L2] pour la seconde, et les conditions aux limites (boundaries en 
    // anglais) sont périodiques pour les deux variables
    position_tapis.set_range(
        utils::range(0, L1), utils::BOUNDARY_PERIODIC,
        utils::range(0, L2), utils::BOUNDARY_PERIODIC
    );
    Pas beaucoup plus compliqué !

    On peut alors accéder aux valeurs en utilisant la notation "fonction" avec les paramètres réels position_tapis(x, y) ou la notation "tableau" avec les indices position_tapis[i][j].

    Dans ce contexte, il faut préciser pour les fonctions index_to_param et param_to_index à quel paramètre on fait référence. En effet, l'écart entre deux points i et i+1 n'est pas nécessairement le même qu'entre j et j+1. Dans le cas où l'on a plusieurs variables, on doit alors utiliser la syntaxe index_to_param(p, i), où p est un entier qui donne le rang du paramètre concerné (c'est à dire 0 pour le premier paramètre, 1 pour le second, etc. L'ordre est celui dans lequel les paramètres sont donnés lors d'un appel à la fonction : f(x1, x2, x3, ...)).

    En résumé, là encore, on a les même fonctionnalités qu'avec la méthode "C", auxquelles s'ajoute le confort supplémentaire apporté par le C++, quand on le souhaite.

    4] Les fonctionnalités supplémentaires

    Mais on peut faire plus... D'abord, sur l'accès aux données. J'ai ajouté deux classes, qui sont je pense familières à la majorité d'entre vous : iterator et const_iterator. Elles permettent de parcourir l'ensemble des données contenues par une fonction, de la même manière qu'on parcourt un conteneur standard (en particulier, les fonctions begin() et end() sont disponibles). Cela permet de tirer profit d'un autre ajout du C++11 : les range-based for loops (je n'ai pas pu imaginer de traduction potable...) :
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for (double& value : position_tapis)
        value = // ...
    ... qui serait l'équivalent de :
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (size_t i = 0; i < N1; ++i)
    for (size_t j = 0; j < N2; ++j)
        position_tapis[i][j] = // ...
    Ce n'est pas toujours très pratique, puisqu'on n'a pas d'information sur la "position" de value dans la boucle, mais ça a son intérêt dans certaines situations.

    Qui plus est, il y a certaines opérations que l'on est souvent amené à faire, et qui peuvent être pénibles sur ces grands ensembles de données.
    Par exemple, mettre toutes les valeurs à zéro (ou n'importe quelle autre nombre). On peut le faire ici de deux manières : soit avec la fonction fill(v), où v est un nombre, soit avec l'opérateur d'affectation : position_tapis = v (en interne, l'opérateur d'affectation redirige vers la fonction fill).
    On peut aussi vouloir ajouter un même nombre à toutes les valeurs : on peut le faire avec shift(v), ou avec les opérateurs += et -=.
    On peut encore vouloir multiplier toutes les valeurs par un même nombre, ce qui se fait grâce à scale(v), ou avec les opérateurs *= et /=.
    Et cetera.

    Il est également possible d'utiliser les opérateurs numériques usuels f+v, f*v, etc, mais attention aux performances (en principe, pour N opérations, N copies sont effectuées, si le compilateur est assez malin pour faire de la RVO).

    Pour des traitement plus complexes, contenant un grand nombre d'opérations, il peut s'avérer plus efficace de ne faire qu'une seule traversée de toutes les données, et donc d'implémenter le traitement "à la main", à l'intérieur d'une boucle.

    On peut aussi utiliser la fonction fill autrement, pour affecter des valeurs différentes à différents points. Typiquement, c'est utile si l'on veut initialiser les données à une fonction connue, par exemple cos(x). Il existe plusieurs manières de le faire, car la fonction fill attend un paramètre qui dispose de l'opérateur () : ce peut être une fonction C++, un foncteur, une std::function, une lambda, ...
    Cet opérateur () doit prendre P arguments, qui sont sensés correspondre aux P paramètres de notre fonction. Par exemple pour une fonction à un paramètre :
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    utils::numerical_function<double, 1> corde(N);
    corde.set_range(utils::range(0, 3.14159), utils::BOUNDARY_PERIODIC);
    // Totalement équivalent :
    corde.fill(&cos);
    corde = cos;
    corde = [](double x) { return cos(x); };
    et pour une fonction à deux paramètres :
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    utils::numerical_function<double, 2> tapis(N1, N2);
    tapis.set_range(
        utils::range(-1, 1), utils::BOUNDARY_PERIODIC,
        utils::range(-1, 1), utils::BOUNDARY_PERIODIC
    );
    // Totalement équivalent :
    tapis.fill(&atan2);
    tapis = atan2;
    tapis = [](double x, double y) { return atan2(x, y); };

    Dernière fonctionnalité de cette classe : les opérations de dérivations et intégrations. Numériquement, on peut calculer la dérivée d'une fonction en un point avec une bonne approximation en mélangeant savamment 5 valeurs proches du point considéré (typiquement : le point lui même et ses 4 plus proches voisins). J'ai donc mis à disposition la méthode derivate(p, x, y, ...), où p est le rang du paramètre par rapport auquel on souhaite dériver (comme dans index_to_param), et x, y, ... sont les coordonnées du point où l'on souhaite calculer la dérivée. Une alternative est derivate_i(p, i, j, ...), où le point considéré est donné directement par ses indices : c'est plus performant, mais parfois moins pratique. Aussi, j'ai implémenté la méthode get_derivative(p=0), qui retourne une nouvelle fonction qui contient la dérivée de la précédente par rapport au paramètre p en chaque point :
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    utils::numerical_function<double> f(N), f_prime;
    f.set_range(utils::range(0, 3.14159));
    f = cos;
    f_prime = f.get_derivative();
    Les données contenues dans f_prime doivent correspondre à la dérivée du cosinus, c'est à dire à -sin(x).

    Il est également possible d'intégrer la fonction. Numériquement, cela correspond tout simplement à faire une somme... Si on intègre k fois une fonction à P arguments (avec P>=k), on obtient une nouvelle fonction avec P-k arguments (si P=k, on obtient simplement une seule valeur). Pour ce faire, on utilise la méthode integrate(p, begin, end, ...) où là encore p est le rang du paramètre par rapport auquel on veut intégrer, et begin et end forment l'intervalle sur lequel on souhaite intégrer. Les autre paramètres sont d'autres triplets du même genre, si l'on veut intégrer plusieurs variables à la fois (c'est plus performant que de le faire une par une). À noter cependant : si plusieurs variables sont intégrées en même temps, le code suppose que l'utilisateur a fourni les arguments de integrate par ordre de p croissant.
    Comme pour derivate, il existe une alternative integrate_i pour laquelle l'intervalle d'intégration est spécifié directement en indices (c'est également plus performant).

    Pour clore cette longue présentation, je vais rapidement présenter la classe printer, qui permet de créer une sortie formatée pour les données d'une fonction. L'exemple le plus simple est la sauvegarde de ces données dans un fichier texte, où les différents arguments sont placés sur différentes colonnes (la valeur correspondante de la fonction étant sur la dernière d'entre elles) :
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    utils::numerical_function<double> f(40);
    f.set_range(utils::range(0, 3.14159));
    f = cos;
     
    utils::numerical_function<double>::printer p("data.txt");
    p.add(f);
    p.print();

    À titre d'exemple, j'ai aussi implémenté une sortie vers le logiciel de visualisation gnuplot, qui permet de sauvegarder (sans interaction avec l'utilisateur) le graphe d'une fonction dans un fichier .png.

    5] Le mot de la fin

    Voilà pour cette présentation. J'ai trouvé que c'était un exercice agréable pour apprendre à manipuler ces templates variadiques. J'ai pu commencer doucement avec des fonction simples comme resize() ou set_range(), pour finir sur des comportements bien plus complexes, par exemple pour integrate().

    Au niveau des performances, je n'ai pas encore mis au point de benchmark qui permette de juger de la pénalité induite par tout ce "sucre syntaxique". Pour une fonction à un seul argument, je pense que l'on doit s'approcher très près des performances "C" (si l'on active les optimisations du compilateur). En revanche, il doit être possible d'améliorer les performances pour un nombre d'argument supérieur à 1. En particulier, les données sont actuellement stockées dans un vector de vector de vector de ... etc. Il me semble que les performances pourraient être meilleures en implémentant ça comme un gros tableau unidimensionnel, mais il faudrait faire des tests pour être sûr. Le problème, c'est que ce petit changement bouleverse complètement l'implémentation que j'ai faite d'une partie des fonctionnalités présentées ci-dessus. Donc à voir...

    Pour le moment, ça fonctionne

  2. #2
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut
    Nouvelle version uploadée. Le lien est le même.
    Au menu :
    • correction d'un bug qui rendait inopérationnelle la méthode fill() avec une fonction ainsi que la sérialisation avec la classe printer,
    • ajout de la fonction libre pairs qui permet de faire une itération du type :
      Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      for (auto iter : pairs(function))
      {
          // iter.ids(i) contient la valeur du ième indice
          // *iter contient la valeur de la fonction à la position actuelle
      }

  3. #3
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut
    J'ai mis au rebut cette bibliothèque et en ai développé une autre en repartant de zéro. La philosophie est un peu différente (plus question d’accéder aux éléments du tableau par valeur), mais elle propose également des tableaux dynamiques multidimensionnels qui sont nettement plus rapides, ainsi qu'une armée de fonctions utilitaires pour faire du traitement de donnée. L'idée est de reprendre la facilité d'écriture des langages comme IDL, tout en conservant la vitesse et la rigueur propres au C++.

    Tout ceci n'est rendu possible que par les récentes évolutions du langage. De fait, cette bibliothèque nécessite un support complet du C++11 ainsi que quelques fonctionnalités du C++14 (déduction du type de retour des fonctions), et requiert donc un compilateur récent. En particulier, je l'ai testée avec clang-3.3, mais elle ne fonctionne pas avec gcc-4.7.2 à cause d'un bug du compilateur. Quoi qu'il en soit, étant donné l'abus qui est fait de templates, il est préférable d'utiliser clang qui offre des temps de compilation bien meilleurs. Le tout devrait être parfaitement portable, mais je ne l'ai pour l'instant testé que sous linux 64 bits.

    Vous trouverez le code, publié sous licence MIT (permissive), dans ce dépôt github, avec les instructions d'installation et d'utilisation (un peu minimaliste, mais ça suffit pour démarrer).

    J'ai écrit une série de tests unitaires qui permettent de s'assurer dans une certaine mesure du bon fonctionnement de la bibliothèque, et je l'utilise au quotidien dans mon travail. Je la considère donc comme stable pour l'usage que j'en fais, mais étant donné qu'elle n'a été crée que récemment (juin 2013), je ne vous recommande pas son utilisation "en production" pour le moment (la documentation est assez pauvre, qui plus est). Mais en attendant, si ça peut vous donner des idées pour vos codes, et inversement si vous avez des suggestions pour celui-ci, ça serait super !

  4. #4
    Membre confirmé

    Homme Profil pro
    Etudiant
    Inscrit en
    Juillet 2012
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Etudiant
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2012
    Messages : 108
    Points : 573
    Points
    573
    Par défaut
    Citation Envoyé par Kalith Voir le message

    Tout ceci n'est rendu possible que par les récentes évolutions du langage. De fait, cette bibliothèque nécessite un support complet du C++11 ainsi que quelques fonctionnalités du C++14 (déduction du type de retour des fonctions), et requiert donc un compilateur récent. En particulier, je l'ai testée avec clang-3.3, mais elle ne fonctionne pas avec gcc-4.7.2 à cause d'un bug du compilateur. Quoi qu'il en soit, étant donné l'abus qui est fait de templates, il est préférable d'utiliser clang qui offre des temps de compilation bien meilleurs. Le tout devrait être parfaitement portable, mais je ne l'ai pour l'instant testé que sous linux 64 bits.
    Avez-vous quand meme compilé votre code avec gcc 4.8.1 ?
    (pour rappel : gcc 4.8.1 possède un support complet du C++11)
    Le paradigme de chacun ne dépend pas de lui, mais de son éducation...

    Le mot donne à la pensée son existence la plus haute et la plus noble.
    Spinoza

    Quiconque n'est pas choqué par la théorie quantique ne la comprend pas.
    Niels Bohr

    http://isocpp.org/

  5. #5
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut
    C'est dans ma TODO list, car malheureusement ça ne passe pas comme une lettre à la poste : si sur le papier clang et gcc sont deux compilateurs assez similaires, ils ont chacun leur susceptibilité... Le bug constaté avec gcc 4.7 semble corrigé cependant, donc ça devrait être possible, mais en l'état le code ne compile pas avec gcc 4.8.

    Quoi qu'il en soit, le support de gcc est vraiment quelque chose d'important vu la popularité de ce compilateur sur les systèmes linux, donc ça viendra. Peut être pas dans l'immédiat, étant donné que j'ai d'autres priorités, mais ça viendra. Merci pour ton intérêt en tout cas !

  6. #6
    Membre confirmé

    Homme Profil pro
    Etudiant
    Inscrit en
    Juillet 2012
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Etudiant
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2012
    Messages : 108
    Points : 573
    Points
    573
    Par défaut
    D'accord, De rien ^^

    Concernant de nouvelles features tu en as ajouté depuis juillet dernier ?
    Le paradigme de chacun ne dépend pas de lui, mais de son éducation...

    Le mot donne à la pensée son existence la plus haute et la plus noble.
    Spinoza

    Quiconque n'est pas choqué par la théorie quantique ne la comprend pas.
    Niels Bohr

    http://isocpp.org/

  7. #7
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut
    Il y a une bonne poignée de fonctions supplémentaires (la plupart sont orientées astrophysique), mais sinon pas de nouvelle fonctionnalité importante. J'ai surtout corrigé des petits bugs, et pas mal amélioré les performances sur la génération des nombres aléatoires (je recréais un générateur à chaque appel...) et les opérations avec des temporaires (grâce à la sémantique de mouvement ).

  8. #8
    Membre confirmé

    Homme Profil pro
    Etudiant
    Inscrit en
    Juillet 2012
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Etudiant
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2012
    Messages : 108
    Points : 573
    Points
    573
    Par défaut
    Citation Envoyé par Kalith Voir le message
    Il y a une bonne poignée de fonctions supplémentaires (la plupart sont orientées astrophysique), mais sinon pas de nouvelle fonctionnalité importante. J'ai surtout corrigé des petits bugs, et pas mal amélioré les performances sur la génération des nombres aléatoires (je recréais un générateur à chaque appel...) et les opérations avec des temporaires (grâce à la sémantique de mouvement ).
    La semantique de mouvement bon, apres les temporaires faut pas les utiliser quand c'est pas necessaire ^^
    Le paradigme de chacun ne dépend pas de lui, mais de son éducation...

    Le mot donne à la pensée son existence la plus haute et la plus noble.
    Spinoza

    Quiconque n'est pas choqué par la théorie quantique ne la comprend pas.
    Niels Bohr

    http://isocpp.org/

  9. #9
    Membre confirmé

    Homme Profil pro
    Etudiant
    Inscrit en
    Juillet 2012
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Etudiant
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2012
    Messages : 108
    Points : 573
    Points
    573
    Par défaut
    Apres concernant les implémentations grâce du C++11 pour les templates, j'aime bien les variadiques templates.
    Le paradigme de chacun ne dépend pas de lui, mais de son éducation...

    Le mot donne à la pensée son existence la plus haute et la plus noble.
    Spinoza

    Quiconque n'est pas choqué par la théorie quantique ne la comprend pas.
    Niels Bohr

    http://isocpp.org/

  10. #10
    Membre éclairé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2007
    Messages
    373
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Santé

    Informations forums :
    Inscription : Juin 2007
    Messages : 373
    Points : 764
    Points
    764
    Par défaut
    J'ai oublié de transmettre la news par ici : après un peu de travail, cette bibliothèque est maintenant compatible avec GCC (testé avec 4.8.2). J'ai dû revoir un peu l'architecture des scripts de compilation, et j'ai ajouté des scripts CMake pour installer le tout correctement, et compiler les outils qui sont fournis avec.

    Avant d'arriver à une version "1.0", il manque encore une grosse dose de documentation, des tests unitaires plus complets, un peu de profiling et d'optimisation sur certaines fonctions, et enfin un peu de ménage dans le code. Mais ça ne sera pas pour tout de suite. L'interface est relativement stable, je ne fais pratiquement plus que des ajouts de fonctions et corrections de bugs depuis un moment (un bug important a été corrigé aujourd'hui, le correctif sera en ligne demain).

    Entre temps, j'ai créé un petit site avec l'interface (très pratique) de github : click.

Discussions similaires

  1. Réponses: 6
    Dernier message: 30/12/2012, 16h41
  2. Réponses: 3
    Dernier message: 12/11/2010, 20h55
  3. Réponses: 1
    Dernier message: 08/01/2009, 15h45
  4. Pour ou contre l'Open source ?
    Par Thcan dans le forum Débats sur le développement - Le Best Of
    Réponses: 317
    Dernier message: 01/05/2008, 16h06
  5. [Kylix] Kylix - total open source?
    Par LaGuimb dans le forum EDI
    Réponses: 5
    Dernier message: 25/12/2003, 15h51

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