src/Webtrees/Module/Sosa/Model/SosaProvider.php
public function getAncestorDispersionForGen($gen) {
        if(!$this->is_setup || $gen > 11) return array();  // Going further than 11 gen will be out of range in the query
        return Database::prepare(
            'SELECT branches, count(i_id)'.
            ' FROM ('.
            '   SELECT i_id,'.
            '       CASE'.
            '           WHEN CEIL(LOG2(SUM(branch))) = LOG2(SUM(branch)) THEN SUM(branch)'.
            '           ELSE -1'.   // We put all ancestors shared between some branches in the same bucket
            '       END branches'.
            '   FROM ('.
            '       SELECT DISTINCT majs_i_id i_id,'.
            '           POW(2, FLOOR(majs_sosa / POW(2, (majs_gen - :gen))) - POW(2, :gen -1)) branch'.
            '       FROM `##maj_sosa`'.
            '       WHERE majs_gedcom_id = :tree_id AND majs_user_id = :user_id'.
            '           AND majs_gen >= :gen'.
            '   ) indistat'.
            '   GROUP BY i_id'.
            ') grouped'.
            ' GROUP BY branches')
            ->execute(array(
                'tree_id' => $this->tree->getTreeId(), 
                'user_id' => $this->user->getUserId(),
                'gen' => $gen
            ))->fetchAssoc() ?: array();
    }
public function getAncestorDispersionForGen($gen) {
        if(!$this->is_setup || $gen > 11) return array();  // Going further than 11 gen will be out of range in the query
        return Database::prepare(
            'SELECT branches, count(i_id)'.
            ' FROM ('.
            '   SELECT i_id,'.
            '       CASE'.
            '           WHEN CEIL(LOG2(SUM(branch))) = LOG2(SUM(branch)) THEN SUM(branch)'.
            '           ELSE -1'.   // We put all ancestors shared between some branches in the same bucket
            '       END branches'.
            '   FROM ('.
            '       SELECT DISTINCT majs_i_id i_id,'.
            '           POW(2, FLOOR(majs_sosa / POW(2, (majs_gen - :gen))) - POW(2, :gen -1)) branch'.
            '       FROM `##maj_sosa`'.
            '       WHERE majs_gedcom_id = :tree_id AND majs_user_id = :user_id'.
            '           AND majs_gen >= :gen'.
            '   ) indistat'.
            '   GROUP BY i_id'.
            ') grouped'.
            ' GROUP BY branches')
            ->execute(array(
                'tree_id' => $this->tree->getTreeId(), 
                'user_id' => $this->user->getUserId(),
                'gen' => $gen
            ))->fetchAssoc() ?: array();
    }
public function getAncestorDispersionForGen ( $ gen ) { if ( ! $ this -> is_setup || $ gen > 11 ) return array ( ) ; // Going further than 11 gen will be out of range in the query return Database :: prepare ( 'SELECT branches, count(i_id)' . ' FROM (' . '   SELECT i_id,' . '       CASE' . '           WHEN CEIL(LOG2(SUM(branch))) = LOG2(SUM(branch)) THEN SUM(branch)' . '           ELSE -1' . // We put all ancestors shared between some branches in the same bucket '       END branches' . '   FROM (' . '       SELECT DISTINCT majs_i_id i_id,' . '           POW(2, FLOOR(majs_sosa / POW(2, (majs_gen - :gen))) - POW(2, :gen -1)) branch' . '       FROM `##maj_sosa`' . '       WHERE majs_gedcom_id = :tree_id AND majs_user_id = :user_id' . '           AND majs_gen >= :gen' . '   ) indistat' . '   GROUP BY i_id' . ') grouped' . ' GROUP BY branches' ) -> execute ( array ( 'tree_id' => $ this -> tree -> getTreeId ( ) , 'user_id' => $ this -> user -> getUserId ( ) , 'gen' => $ gen ) ) -> fetchAssoc ( ) ? : array ( ) ; }
Return a computed array of statistics about the dispersion of ancestors across the ancestors
at a specified generation.
This statistics cannot be used for generations above 11, as it would cause a out of range in MySQL

Format:
- key : a base-2 representation of the ancestor at generation G for which exclusive ancestors have been found,
-1 is used for shared ancestors
For instance base2(0100) = base10(4) represent the maternal grand father
- values: number of ancestors exclusively in the ancestors of the ancestor in key

For instance a result at generation 3 could be :
array (   -1        =>  12      -> 12 ancestors are shared by the grand-parents
base10(1) =>  32      -> 32 ancestors are exclusive to the paternal grand-father
base10(2) =>  25      -> 25 ancestors are exclusive to the paternal grand-mother
base10(4) =>  12      -> 12 ancestors are exclusive to the maternal grand-father
base10(8) =>  30      -> 30 ancestors are exclusive to the maternal grand-mother
)

@param int $gen Reference generation
@return array
Return a computed array of statistics about the dispersion of ancestors across the ancestors at a specified generation . This statistics cannot be used for generations above 11 as it would cause a out of range in MySQL