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 :

Heritage + specialisation partielle de patron + doxygen


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut Heritage + specialisation partielle de patron + doxygen
    Bonjour à toutes et à tous !

    J'essaie de documenter une portion de mon code avec Doxygen, et je rencontre quelques problèmes. En fait je me demande si Doxygen est capable d'y voir clair dans cette structure syntaxique (je sais pas si elle est pertinente bout en bout, mais elle m'a permis de supprimer des duplications de code en héritant l'implémentation commune aux deux stratégies de simulation).

    Donc on y va:

    Deux types de stratégies pour lesquelles je voudrais un comportement différent:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      namespace strategy {
        struct individual_based {
          using value_type = unsigned int;
        };
     
        struct mass_based {
          using value_type = double;
        };
      }
    Ensuite la classe de base qui récupère toute l'implémentation commune aux deux variantes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template<typename A, typename B, typename Strategy>
    class CommonBase {
      // méthodes communes  
    };
    Le template général (je sais pas si ça a un nom), qui est vide.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     template<typename A, typename B, typename Strategy>
     class MaClasse : public CommonBase<A, B, Strategy>
     { 
    // vide
      };
    Et enfin les spécialisations:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
      template<typename A, typename B>
      class MaClasse<A, B, strategy::individual_based> : public CommonBase<Space, Time, strategy::individual_based>
      {
         // une implémentation particulière d'une méthode foo est rajoutée ici
      }
     
      template<typename A, typename B>
      class MaClasse<A, B, strategy::mass_based> : public CommonBase<Space, Time, strategy::mass_based>
      {
         // une autre implémentation de foo ici
      }
    Le truc c'est que Doxygen ne détecte pas les deux dernières spécialisations, et donc je suis incapable de générer la doc pour MaClasse<A, B, strategy::individual_based>::foo et MaClasse<A, B, strategy::mass_based>::foo. Ce qui est bien embêtant parce que c'est un peu le point important de la manip quand même

    Je sais que le pauvre Doxygen en voit de toute les couleurs avec les templates et que c'est pas vraiment sa faute, mais si j'avais un work-around, ce serait super !

    Qu'en pensez-vous ?

    En vous remerciant d'avance,

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Ajoute simplement un cartouche doxygen à tes spécialisations
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    /** @brief partial specialization for individual based strategies
      *
      * @tparam A data type for ...
      * @tparam B data type for ...
      *
      * some longer description (which difference with unspecialized class?)
      */
    template<typename A, typename B>
      class MaClasse<A, B, strategy::individual_based> : public CommonBase<Space, Time, strategy::individual_based>
      {
         // une implémentation particulière d'une méthode foo est rajoutée ici
      }
     
    /** @brief partial specialization for mass based strategies
      *
      * @tparam A data type for ...
      * @tparam B data type for ...
      *
      * some longer description (which difference with unspecialized class?)
      */
      template<typename A, typename B>
      class MaClasse<A, B, strategy::mass_based> : public CommonBase<Space, Time, strategy::mass_based>
      {
         // une autre implémentation de foo ici
      }
    Cela devrait inciter doxygen à générer la documentation correctement
    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

  3. #3
    Membre éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut
    Salut,

    Oui j'avais écrit les cartouches, mais cela semble être ignoré par Doxygen ...

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Ca, c'est pour le moins bizare, parce que chez moi, un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #ifndef TEST_HPP
    #define TEST_HPP
    /** @brief basic unspecialized struture
      *
      * @tparam T first type to use
      * @tparam U second type to use
      *
      */
    template <typename T, typename U>
    struct Test{
        T a;
        U b;
    };
    /** @brief partial specialization to be used wit ints
      *
      * @tparam T first type to be used
      *
      */
    template <typename T>
    struct Test<T, int>{
        T a;
        long b;
     
    };
    /** @brief partial specialization to be used wit reals
      *
      * @tparam T first type to be used
      *
      */
    template <typename T>
    struct Test<T, float>{
        T a;
        long double b;
     
    };
    #endif
    me fournit bien la liste de classes
    • Test Basic unspecialized struture
    • Test< T, float > Partial specialization to be used wit reals
    • Test< T, int > Partial specialization to be used wit ints

    Et le seul reproche que l'on puisse faire au résultat (dans toute sa simplicité), c'est de n'avoir pas les diagrammes de collaboration entre les spécialisations partielles et la classe d'origine.

    Et encore, je subodore que c'est parce qu'il n'y a aucune implémentation des classes (partiellement) spécializée qui est faite

    Pourrais tu nous montrer comment tu organise tes cartouches?

    PS: il faut parfois revenir à une liste ou à une page plus générale actualisée pour voir les ajouts dans la documentation
    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

  5. #5
    Membre éclairé Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Par défaut
    Merci de te pencher sur mon problème
    Tu vas peut-être halluciner un peu sur les cartouches (les blocs de doc sont plus gros que les blocs de code ...), et je n'ai pas une très bonne idée de ce qu'est une bonne doc et elle certainement pas encore tout a fait complète, donc tout commentaire est bienvenu !

    Un exemple de cartouche pour une spécialisation partielle:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
      /**
      * \brief Demographic history where populations levels are assumed high enough to be considered as divisible masses.
      *
      *  \ingroup demography
      *
      * \tparam Space    Demes identifiers.
      * \tparam Time     EqualityComparable, CopyConstructible.
      *
      * \details $N$ is initialized by setting \f$N(.,t_0)\f$ the initial distribution
      * of individuals across demes at the first time \f$t_0\f$.
      * Typically for a biological invasion, this is restricted to the introduction site(s)
      * with the number of introduced individuals. For endemic species, paleoclimatic
      * distribution can be considered as starting points. The number of descendants
      * \f$\tilde{N}_{x}^{t}\f$ in each deme is sampled in a distribution conditionally
      * to a function of the the local density of parents. Non-overlapping generations
      * are considered (the parents die just after reproduction). The children dispersal
      * is done by sampling their destination in a multinomial law, that defines
      * \f$ \Phi_{x,y}^t \f$ the number of individuals going from \f$x\f$ to \f$y\f$ at time \f$t\f$:
      * \f[ (\Phi_{x,y}^{t})_{y\in  X} \sim \mathcal{M}(\tilde{N}_{x}^{t},(m_{xy})_y) ~. \f]
      * The term \f$ (m_{xy})_y \f$ denotes the parameters of the multinomial law,
      * giving for an individual in \f$x\f$ its probability to go to \f$y\f$.
      * These probabilities are given by the dispersal law with parameter \f$\theta\f$:
      * \f[
      * \begin{array}{cclcl}
      * m  & : &  X^2 & \mapsto & R_{+} \\
      * &   &    (x,y)     & \mapsto & m^{\theta}(x,y)  ~. \\
      * \end{array}
      * \f]
      * After migration, the number of individuals in deme \f$x\f$ is defined by the total number of individuals converging to \f$x\f$:
      * \f[
      * N(x,t+1) = \displaystyle \sum_{i\in X} \Phi_{i,x}^{t}~.
      * \f\]
      *
      * \section Example
      * \snippet demography/test/History/History_test.cpp Example
      * \section Output
      * \include demography/test/History/History_test.output
      */
      template<typename Space, typename Time>
      class History<Space, Time, strategy::mass_based> : public BaseHistory<Space, Time, strategy::mass_based>{
      // blabla
      };
    A toute fin utile, le code complet (désolé pour les doublons de doc, mais j'ai un peu tout essayer du coup c'est clairement le bazar):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
     
    namespace quetzal {
    namespace demography {
     
      namespace strategy {
     
        /*!
         * \brief Traits class for individual based demographic history simulation, strategy suited for small number of individuals in the landscape (small populations).
         * \ingroup demography
         *
         * \details Simulate the demographic history with an individual-based strategy: each
         * individual is dispersed individually.
         * \par History Initialization:
         * The population size history\f$N\f$ is initialized by setting \f$N(.,t_0)\f$, the initial distribution of individuals across demes at the
         * first time of the history \f$t_0\f$. Typically for a biological invasion,
         * this is restricted to the introduction site(s) with the number of introduced
         * individuals. For endemic species, paleoclimatic distribution can be considered
         * as starting points.
         *
         * \par Growth:
         * The offspring number \f$ \tilde{N}_{x}^{t} \f$ in each deme is freely defined by the user. It can for example be
         * sampled in a distribution conditionally to a function of the local density of
         * parents. Non-overlapping generations are considered (the parents die just after reproduction).
         *
         * \par Dispersal:
         *  The children dispersal is done by sampling their destination in a multinomial
         *  law, that defines \f$ \Phi_{x,y}^t \f$, the number of individuals going from
         *  \f$x\f$ to \f$y\f$ at time \f$t\f$:
         *
         * \f[ (\Phi_{x,y}^{t})_{y\in X} \sim \mathcal{M}(\tilde{N}_{x}^{t},(m_{xy})_y) ~. \f]
         *
         * The term \f$ (m_{xy})_y \f$ denotes the parameters of the multinomial law,
         * giving for an individual in \f$x\f$ its proability to go to \f$y\f$.
         * These probabilities are given by the dispersal law with parameter \f$\theta\f$:
         *
         * \f[
         * \begin{array}{cclcl}
         * m  & : &  X^2 & \mapsto & R_{+} \\
         * &   &    (x,y)     & \mapsto & m^{\theta}(x,y)  ~. \\
         * \end{array}
         * \f]
         *
         * After migration, the number of individuals in deme \f$x\f$ is defined by
         * the total number of individuals converging to \f$x\f$:
         *
         * \f[
         * N(x,t+1) = \displaystyle \sum_{i\in X} \Phi_{i,x}^{t}~.
         * \f]
         * \section Example
         * \snippet demography/test/History/Individual_based_history_test.cpp Example
         * \section Output
         * \include demography/test/History/Individual_based_history_test.output
         */
        struct individual_based {
          using value_type = unsigned int;
        };
     
        /*!
        * \brief Traits class for simulating the demographic history of importnat masses of populations.
        * \ingroup demography
        *
        * \details Simulate the demographic history by considering that populations of individuals are divisible masses,
        *  leading to faster simulations.
        *
        * \par Intialization:
        * \f$N\f$ is initialized by setting \f$N(.,t_0)\f$ the initial distribution
        * of individuals across demes at the first time \f$t_0\f$.
        * Typically for a biological invasion, this is restricted to the introduction site(s)
        * with the number of introduced individuals. For endemic species, paleoclimatic
        * distribution can be considered as starting points.
        *
        * \par Growth:
        * The offspring number \f$\tilde{N}_{x}^{t}\f$ in each deme is freely defined by
        * the user. For example, it can be sampled in a distribution conditionally
        * to a function of the local density of parents. Non-overlapping generations
        * are considered (the parents die just after reproduction).
        *
        * \par Dispersal:
        * The children dispersal is done by splitting the population masses according
        * to their migration probabilities, defining
        * \f$ \Phi_{x,y}^t \f$, the population flow going from \f$x\f$ to \f$y\f$ at time \f$t\f$:
        * \f[ (\Phi_{x,y}^{t})_{y\in  X} = (\tilde{N}_{x}^{t} \times m_{xy})_{y\in  X} ~. \f]
        * The term \f$ m_{xy} \f$ denotes the parameters of the transition kernel,
        * giving for an individual in \f$x\f$ its probability to go to \f$y\f$.
        * These probabilities are given by the dispersal law with parameter \f$\theta\f$:
        * \f[
        * \begin{array}{cclcl}
        * m  & : &  X^2 & \mapsto & R_{+} \\
        * &   &    (x,y)     & \mapsto & m^{\theta}(x,y)  ~. \\
        * \end{array}
        * \f]
        * After migration, the population size in deme \f$x\f$ is defined by the sum of population flows converging to \f$x\f$:
        * \f[
        * N(x,t+1) = \displaystyle \sum_{i\in X} \Phi_{i,x}^{t}~.
        * \f]
        * \section Example
        * \snippet demography/test/History/Mass_based_history_test.cpp Example
        * \section Output
        * \include demography/test/History/Mass_based_history_test.output
        */
        struct mass_based {
          using value_type = double;
        };
     
      }
     
      /*!
       * \brief Base class for spatially explicit and forward-in time population history simulators.
       *
       * \tparam Space    Demes identifiers.
       * \tparam Time     EqualityComparable, CopyConstructible.
       * \tparam Strategy    Strategy use for simulating populations dynamics
       *
       * \details Is used as an implementation base of the specialized simulation strategies.
       *
       * \ingroup demography
       *
       */
      template<typename Space, typename Time, typename Strategy>
      class BaseHistory {
     
          public:
     
            //! \typedef strategy used for simulating populations dynamics
            using strategy_type = Strategy;
     
            //! \typedef type of the population flows database
            using flow_type = Flow<Space, Time, typename strategy_type::value_type>;
     
            //! \typedef type of the population size database
            using pop_sizes_type = PopulationSize<Space, Time, typename strategy_type::value_type>;
     
            //! \typedef space type
            using coord_type = Space;
     
            //! \typedef time type
            using time_type = Time;
     
            //! \typedef type of the discrete distribution used inside the backward dispersal kernel
            using discrete_distribution_type = quetzal::random::DiscreteDistribution<coord_type>;
     
            //! \typedef Backward dispersal kernel type
            using backward_kernel_type = quetzal::random::TransitionKernel<time_type, discrete_distribution_type>;
     
          protected:
     
            // Need to be accessed by the expand method
            std::unique_ptr<pop_sizes_type> m_sizes;
            std::unique_ptr<flow_type> m_flows;
            std::vector<Time> m_times;
            std::unique_ptr<backward_kernel_type> m_kernel;
     
          private:
     
            auto make_backward_distribution(coord_type const& x, time_type const& t) const
            {
     
              std::vector<double> weights;
              std::vector<coord_type> support;
     
              weights.reserve(m_flows->flux_to(x,t).size());
              support.reserve(m_flows->flux_to(x,t).size());
     
              for(auto const& it : m_flows->flux_to(x,t) )
              {
                support.push_back(it.first);
                weights.push_back(static_cast<double>(it.second));
              }
     
              return discrete_distribution_type(std::move(support),std::move(weights));
            }
     
          public:
     
            /**
              * \brief Constructor initializing the demographic database.
              * \param x the coordinate of introduction
              * \param t the introduction time
              * \param N the population size at coordinate x at time t
              * \section Example
              * \snippet demography/test/History/History_test.cpp Example
              * \section Output
              * \include demography/test/History/History_test.output
              */
            BaseHistory(coord_type const& x, time_type const& t, typename strategy_type::value_type N):
            m_sizes(std::make_unique<pop_sizes_type>()),
            m_flows(std::make_unique<flow_type>()),
            m_kernel(std::make_unique<backward_kernel_type>())
            {
              m_sizes->operator()(x,t) = N;
              m_times.push_back(t);
            }
     
            /**
              * \brief Read-only access to the demographic flows database
              */
            flow_type const& flows() const
            {
              return *m_flows;
            }
     
            /**
              * \brief Read and write access to the demographic flows database
              */
            flow_type & flows()
            {
              return *m_flows;
            }
     
            /**
              * \brief Read-only access to the demographic sizes database.
              * \remark Can be used for composition into time dependent growth functions.
              */
            const pop_sizes_type & pop_sizes() const
            {
              return *m_sizes;
            }
     
            /**
              * \brief Read-and-write access to the demographic sizes database
              */
            pop_sizes_type & pop_sizes()
            {
              return *m_sizes;
            }
     
            /**
              * \brief First time recorded in the foward-in-time database history.
              */
            time_type const& first_time() const
            {
              return m_times.front();
            }
     
            /**
              * \brief Last time recorded in the foward-in-time database history.
              */
            time_type const& last_time() const
            {
              return m_times.back();
            }
     
            /**
              * \brief Samples a coordinate from the backward-in-time transition matrix
              *
              * \details The transition matrix is computed from the demographic flows
              * database. The returned coordinate object will basically answer the question:
              * when an individual is found in \f$x\f$ at time \f$t\f$, where could it
              * have been at time \f$t-1\f$ ?
              * Let \f$ X \f$ be the geographic space and \f$\Phi_{x,y}^t\f$ be the number of individuals going
              * from coordinate \f$x \in X \f$ to coordinate \f$y\f$ at time \f$t\f$.
              * Knowing that a child node \f$c\f$ is found in \f$ j \in X \f$, the probability for its parent
              * \f$p\f$ to be in \f$i\in X \f$ is: \f$ P( p \in i ~|~ e \in j) = \frac{\Phi_{i, j}^{t}}{ \sum_{k} \Phi_{k, j}^{t} } ~.\f$
              * \section Example
              * \snippet demography/test/History/Mass_based_history_test.cpp Example
              * \section Output
              * \include demography/test/History/Mass_based_history_test.output
              */
            template<typename Generator>
            coord_type backward_kernel(coord_type const& x, time_type t, Generator& gen)
            {
              --t;
              assert(m_flows->flux_to_is_defined(x,t));
              if( ! m_kernel->has_distribution(x, t))
              {
                m_kernel->set(x, t, make_backward_distribution(x, t));
              }
              return m_kernel->operator()(gen, x, t);
            }
     
      };
     
      /**
      * \brief Demographic history simulated from an individual-based strategy (each individual is dispersed individually).
      *
      * \tparam Space    Demes identifiers.
      * \tparam Time     EqualityComparable, CopyConstructible.
      * \tparam Strategy    Strategy used for simulating populations dynamics
      *
      * \details Inherit from this class and specialize the Strategy template parameter
      *
      * \ingroup demography
      *
      */
      template<typename Space, typename Time, typename Strategy>
      class History : public BaseHistory<Space, Time, Strategy>
      {
      };
     
      /**
      * \brief Demographic history simulated from an individual-based strategy (each individual is dispersed individually).
      *
      * \tparam Space    Demes identifiers.
      * \tparam Time     EqualityComparable, CopyConstructible.
      *
      * \ingroup demography
      *
      * \details $N$ is initialized by setting \f$ N(.,t_0) \f$ the initial distribution
      * of individuals across demes at the first time \f$ t_0 \f$.
      * Typically for a biological invasion, this is restricted to the introduction site(s)
      * with the number of introduced individuals. For endemic species, paleoclimatic
      * distribution can be considered as starting points. The number of descendants
      * \f$ \tilde{N}_{x}^{t} \f$ in each deme is sampled in a distribution conditionally
      * to a function of the the local density of parents. Non-overlapping generations
      * are considered (the parents die just after reproduction). The children dispersal
      * is done by sampling their destination in a multinomial law, that defines
      * \f$ \Phi_{x,y}^t \f$ the number of individuals going from \f$ x \f$ to \f$ y \f$ at time \f$ t \f$:
      * \f[ (\Phi_{x,y}^{t})_{y\in X} \sim \mathcal{M}(\tilde{N}_{x}^{t},(m_{xy})_y) ~. \f]
      * The term \f$ (m_{xy})_y \f$ denotes the parameters of the multinomial law,
      * giving for an individual in \f$x\f$ its proability to go to \f$y\f$.
      * These probabilities are given by the dispersal law with parameter \f$\theta\f$:
      * \f[
      * \begin{array}{cclcl}
      * m  & : &  X^2 & \mapsto & R_{+} \\
      * &   &    (x,y)     & \mapsto & m^{\theta}(x,y)  ~. \\
      * \end{array}
      * \f]
      * After migration, the number of individuals in deme \f$x\f$ is defined by the total number of individuals converging to \f$x\f$:
      * \f[
      * N(x,t+1) = \displaystyle \sum_{i\in X} \Phi_{i,x}^{t}~.
      * \f\]
      *
      * \section Example
      * \snippet demography/test/History/History_test.cpp Example
      * \section Output
      * \include demography/test/History/History_test.output
      */
      template<typename Space, typename Time>
      class History<Space, Time, strategy::individual_based> : public BaseHistory<Space, Time, strategy::individual_based>
      {
        using BaseHistory<Space, Time, strategy::individual_based>::BaseHistory;
     
      public:
     
        /**
          * \brief Expands the demographic database.
          *
          * \tparam Space    Demes identifiers.
          * \tparam Time     EqualityComparable, CopyConstructible.
          *
          * \exception std::domain_error if the population goes extincted before the simulation is completed.
          *
          * \param nb_generations the number of generations to simulate
          * \param sim_growth a functor simulating \f$\tilde{N}_{x}^{t}\f$.
          *
          * The functor can possibly internally use a reference on the population sizes database to represent the time dependency.
          * The signature of the function should be equivalent to the following:
          * `unsigned int sim_growth(Generator &gen, const coord_type &x, const time_type &t);`
          *
          * \param kernel a functor representing the dispersal location kernel that simulates the coordinate of the next location conditionally to the current location.
          * The signature should be equivalent to `coord_type kernel(Generator &gen, const coord_type &x, const time_type &t);`
          *
          * \section Example
          * \snippet demography/test/History/History_test.cpp Example
          * \section Output
          * \include demography/test/History/History_test.output
          */
        template<typename Growth, typename Dispersal, typename Generator>
        void expand(unsigned int nb_generations, Growth sim_growth, Dispersal kernel, Generator& gen)
        {
          for(unsigned int g = 0; g < nb_generations; ++g)
          {
            auto t = this->last_time();
            auto t_next = t; ++ t_next;
     
            this->m_times.push_back(t_next);
     
            unsigned int landscape_individuals_count = 0;
     
            // TODO : optimize the definition_space function (for loop)
            for(auto x : this->m_sizes->definition_space(t) )
            {
              auto N_tilde = sim_growth(gen, x, t);
              landscape_individuals_count += N_tilde;
              if(N_tilde >= 1)
              {
                for(unsigned int ind = 1; ind <= N_tilde; ++ind)
                {
                  auto y = kernel(gen, x, t);
                  this->m_flows->add_to_flux_from_to(x, y, t, 1);
                  this->m_sizes->operator()(y, t_next) += 1;
                }
              }
            }
     
            if(landscape_individuals_count == 0)
            {
              throw std::domain_error("Landscape populations went extinct before sampling");
            }
     
          }
        }
     
      };
     
     
      /**
      * \brief Demographic history where populations levels are assumed high enough to be considered as divisible masses.
      *
      *  \ingroup demography
      *
      * \tparam Space    Demes identifiers.
      * \tparam Time     EqualityComparable, CopyConstructible.
      *
      * \details $N$ is initialized by setting \f$N(.,t_0)\f$ the initial distribution
      * of individuals across demes at the first time \f$t_0\f$.
      * Typically for a biological invasion, this is restricted to the introduction site(s)
      * with the number of introduced individuals. For endemic species, paleoclimatic
      * distribution can be considered as starting points. The number of descendants
      * \f$\tilde{N}_{x}^{t}\f$ in each deme is sampled in a distribution conditionally
      * to a function of the the local density of parents. Non-overlapping generations
      * are considered (the parents die just after reproduction). The children dispersal
      * is done by sampling their destination in a multinomial law, that defines
      * \f$ \Phi_{x,y}^t \f$ the number of individuals going from \f$x\f$ to \f$y\f$ at time \f$t\f$:
      * \f[ (\Phi_{x,y}^{t})_{y\in  X} \sim \mathcal{M}(\tilde{N}_{x}^{t},(m_{xy})_y) ~. \f]
      * The term \f$ (m_{xy})_y \f$ denotes the parameters of the multinomial law,
      * giving for an individual in \f$x\f$ its probability to go to \f$y\f$.
      * These probabilities are given by the dispersal law with parameter \f$\theta\f$:
      * \f[
      * \begin{array}{cclcl}
      * m  & : &  X^2 & \mapsto & R_{+} \\
      * &   &    (x,y)     & \mapsto & m^{\theta}(x,y)  ~. \\
      * \end{array}
      * \f]
      * After migration, the number of individuals in deme \f$x\f$ is defined by the total number of individuals converging to \f$x\f$:
      * \f[
      * N(x,t+1) = \displaystyle \sum_{i\in X} \Phi_{i,x}^{t}~.
      * \f\]
      *
      * \section Example
      * \snippet demography/test/History/History_test.cpp Example
      * \section Output
      * \include demography/test/History/History_test.output
      */
      template<typename Space, typename Time>
      class History<Space, Time, strategy::mass_based> : public BaseHistory<Space, Time, strategy::mass_based>{
     
        using BaseHistory<Space, Time, strategy::mass_based>::BaseHistory;
     
    public:
     
      /**
        * \brief Expands the demographic database,
        * \details $N$ is initialized by setting \f$N(.,t_0)\f$ the initial distribution
        * of individuals across demes at the first time \f$t_0\f$.
        * Typically for a biological invasion, this is restricted to the introduction site(s)
        * with the number of introduced individuals. For endemic species, paleoclimatic
        * distribution can be considered as starting points. The number of descendants
        * \f$\tilde{N}_{x}^{t}\f$ in each deme is sampled in a distribution conditionally
        * to a function of the the local density of parents. Non-overlapping generations
        * are considered (the parents die just after reproduction). The children dispersal
        * is done by sampling their destination in a multinomial law, that defines
        * \f$ \Phi_{x,y}^t \f$ the population flow going from \f$x\f$ to \f$y\f$ at time \f$t\f$:
        * \f[ (\Phi_{x,y}^{t})_{y\in  X} = (\tilde{N}_{x}^{t}*m_{xy})_{y\in  X} ~. \f]
        * The term \f$ m_{xy} \f$ denotes the parameters of the transition kernel,
        * giving for an individual in \f$x\f$ its probability to go to \f$y\f$.
        * These probabilities are given by the dispersal law with parameter \f$\theta\f$:
        * \f[
        * \begin{array}{cclcl}
        * m  & : &  X^2 & \mapsto & R_{+} \\
        * &   &    (x,y)     & \mapsto & m^{\theta}(x,y)  ~. \\
        * \end{array}
        * \f]
        * After migration, the population size in deme \f$x\f$ is defined by the sum of population flows converging to \f$x\f$:
        * \f[
        * N(x,t+1) = \displaystyle \sum_{i\in X} \Phi_{i,x}^{t}~.
        * \f\]
        * \param nb_generations the number of generations to simulate
        * \param sim_growth a functor simulating \f$\tilde{N}_{x}^{t}\f$.
        * The functor can possibly internally use a reference on the population sizes database to represent the time dependency.
        * The signature of the function should be equivalent to the following:
        * `double sim_growth(Generator &gen, const coord_type &x, const time_type &t);`
        * \param kernel a functor representing the dispersal location kernel that simulates the coordinate of the next location conditionally to the current location.
        * The signature should be equivalent to `coord_type kernel(Generator &gen, const coord_type &x, const time_type &t);`.
        * The expression `kernel.support(time_type const& t)` must be valid and return an iterable container of geographic coordinates
        * indicating the transition kernel state space at time \f$t\f$.
        * \section Example
        * \snippet demography/test/History/History_test.cpp Example
        * \section Output
        * \include demography/test/History/History_test.output
        */
        template<typename Growth, typename Dispersal, typename Generator>
        void expand(unsigned int nb_generations, Growth sim_growth, Dispersal kernel, Generator& gen)
        {
          for(unsigned int g = 0; g < nb_generations; ++g)
          {
            auto t = this->last_time();
            auto t_next = t; ++ t_next;
     
            this->m_times.push_back(t_next);
     
            for(auto x : this->m_sizes->definition_space(t) )
            {
              auto N_tilde = sim_growth(gen, x, t);
              for(auto y : kernel.state_space(t) )
              {
                auto m = kernel(x, y, t);
                this->m_flows->set_flux_from_to(x, y, t, m*N_tilde);
                this->m_sizes->operator()(y, t_next) += m*N_tilde;
              }
            }
          }
        }
     
      };
     
    } // namespace demography
    } // namespace quetzal
     
     
    #endif
    Je vais virer toutes les cartouches en recommencer en suivant ton modèle, des fois que ça change quelque chose !

    [EDIT] Humpf oui apparemment faire le menage a l'air de changer quelque chose !!! Bien sur je ne comprend pas pourquoi ça marche maintenant et pas avant Bon, j'attend un peu avant de mettre le sujet en résolu mais apparemment c'est tout bon ! Merci !

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    En fait, la bonne manière d'écrire un cartouche est de fournir à l'utilisateur (de ton type ou de ta fonction) les informations dont il a besoin pour pouvoir l'utiliser correctement.

    Les informatinons @brief et @ingroup ont donc parfaitement leur place: la première permet d'avoir une description rapide, y compris dans certaines listes, la deuxième permet de regrouper correctement les différentes informations.

    Les informations @tparam ont également leur place, car elle permettent d'indiquer le type des données que l'utilisateur peut utiliser. Par contre, leur intitulé pourrait être revu pour que l'utilisateur n'ait aucun doute (l'identifiant de type en lui même pourrait d'ailleurs peut-être êtreplus cohérent par rapport à son usage )

    Elles pourraient prendre la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    /** @tparam Space Demographic population type (: representts some clearer informations, maybe? )
      * @tparam Time comparaison scheme type (: allow   some clearer informations, maybe? )
      */
    Comme tu le vois, j'essaye d'indiquer clairement à l'utilisateur les types auxquels cette classe s'attend à être confrontée. Mais, du coup, il y a des précondition qui doivent être remplies à la compilation pour que tout se passe correctement. On va donc les rajouter, sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    /** @pre Time is equality comparable and copy constructible
      */
    Concernant ton information @details

    A priori, tu n'as pas vraiment besoin de citer nommément cette partie.

    Mais, surtout, tu dois veiller à fournir "suffisamment" d'informations à l'utilisateur pour qu'il puisse se dire "ok, c'est cette classe que je dois utiliser pour ce que je veux faire" tout en évitant de l"assommer avec un tas de détails dont il n'a pas besoin.

    Il se fout pas mal de la manière dont tu calcule le nombre de descendants, de la loi polynominale ou de la loi de dispertion utilisée. Il veut juste savoir que cette classe lui permettra de déterminer si une population donnée risque de provoquer une épidémie et la rapidité avec laquelle elle se répandra (si j'ai bien compris ).

    Si il sait déjà cela, il y a de fortes chances pour que l'utilisateur "normal" puisse décider en connaissance de cause d'utiliser ta classe, et comment il devra s'y prendre.

    Après, on peut toujours considérer que
    la normalité n'est que la moyenne de toutes les tares
    et que l'on risque donc d'être confronté à des utilisateurs
    • qui ne sont pas habitués à manipuler les classes template (et auxquels un petit exemple d'utilisation ferait le plus grand bien)
    • qui s'intéressent aux formules mathématiques que tu auras utilisées
    • et même à certains qui aimeront connaître le "pourquoi du quoi" et le "pourquoi du comment" (autrement dit,les besoins -- voire les raisons des besoins -- qui t'on mené à créer cette classe ainsi que le raisonnement conceptuel qui t'a mené à le faire de la manière don tu t'y es pris)

    Mais on pourrait presque dire qu'ils sont "exceptionnellement (choisi le terme que tu veux ici)"

    Si tu tiens à les soulager de leur souffrance morale, tu dois faire apparaître clairement que les informations que tu t'apprêtes à leur donner ne sont pas essentielles à la bonne utilisation de la classe de manière à éviter que "l'utilisateur normal" ne perde du temps à lire (et à essayer de comprendre) des informations dont il n'a en réalité absolument rien à battre.

    L'idéal est alors de les mettre dans une section @sa (pour See Also ) en ne mettant que des liens vers les informations en question. Cela pourrait se faire sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    /** @sa @ref demography/test/History/History_test.cpp
      * @sa @ref History_rules_and_formulas
      * @sa @ref History_needs_and_conception
      */
    en ayant, bien sur, documenté le fichier History_tes.cpp (qui donnera lui-même accès à History_test.output, voire qui en incluera le contenu), ainsi qu'une section (ou une sous-section) nommée History_rules_and_formulas et une autre section (ou sous-section) History_needs_and_conception qui contiendront les informations "pertinentes" pour le point de vue envisagé.

    Au final, comme j'ai séparé chaque partie, ton cartouche pourrait ressembler à quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    /** \brief Demographic history where populations levels are assumed high enough to be considered as divisible masses.
      *
      * @tparam Space Demographic population type (: representts some clearer informations, maybe? )
      * @tparam Time comparaison scheme type (: allow   some clearer informations, maybe? )
      *
      *
      * Typically for a biological invasion, this is restricted to the introduction site(s)
      * with the number of introduced individuals. 
      *
      *For endemic species, paleoclimatic distribution can be considered as starting points. 
      * The number of descendants in each deme is sampled in a distribution conditionally
      * to a function of the the local density of parents. 
      *
      * Non-overlapping generations are considered (the parents die just after reproduction). 
      *
      * The children dispersal is done by sampling their destination in a probability scheme
      * to see a given number of children to fly from the starting point to some destination.
      *
      * @sa @ref demography/test/History/History_test.cpp
      * @sa @ref History_rules_and_formulas
      * @sa @ref History_needs_and_conception
      */
    (il qse peut d'ailleurs que j'aie été aussi prolixe lors de l'écriture de ce cartouche que lors de la rédaction de cette intervention )

    Quelques remarques en vrac :

    On essaye de se limiter à 80 caractères pour la description @brief...

    Au lieu d'écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    /** \brief Traits class for individual based demographic history simulation, strategy suited for small number of individuals in the landscape (small populations).
    *
    */
    tu aurais pu te limiter au stricte minimum, comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    /** @brief traits used by strategies suited for small popultations
      *
      */
    car cette description brêve apparaîtra dans la liste des classes, sans doute tout près du trait de politique dont la description breve serait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    /** @brief traits used by strategies suited for large popultations
      *
      */
    et que, si l'utilisateur ne sait pas trop quel trait de politique utiliser une fois qu'il connait cette information, il pourra toujours aller voir du coté de la description longue (par exemple, pour se rendre compte que l'on considère que la population est petite en dessous de XXX individu/Ha et que l'on considère que la population est importante au delà de YYY individus/Ha )

    Et comme je m'en voudrais de ne pas te le donner, voici un exemple du genre de cartouches que tu dois créer. Certains sont sans doute perfectibles, mais cela t'aidera (je l'espère) à comprendre ce que l'utilisateur veut savoir
    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

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. specialisation partielle de template recursif
    Par damiengif dans le forum C++
    Réponses: 7
    Dernier message: 01/09/2012, 17h02
  2. Réponses: 10
    Dernier message: 02/11/2011, 11h49
  3. Réponses: 3
    Dernier message: 29/03/2009, 10h21
  4. Réponses: 5
    Dernier message: 29/12/2005, 21h27
  5. Héritage partielle
    Par ZeLL dans le forum Schéma
    Réponses: 4
    Dernier message: 07/06/2005, 14h14

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