Does Mathematica have an implementation of the Poisson binomial distribution?RandomVariate from 2-dimensional probability distributionBayesian Inference with Continuous prior distributionContourplot of Binomial DistributionHow to get probabilities for multinomial & hypergeometric distribution ranges more quickly?How should I iteratively refine a MixtureDistribution?Given an exact formula, how can Mathematica find a probability distribution whose PDF matches it?Likelihood for BetaBinomialDistribution with variable number of trialsInverse Fourier Transform of Poisson Characteristic Function?BinomialDistribution: Plotting probability of obtaining $k ge k_0$ for fixed $n$ and $p$ between $0$ and $1$How to use EventData correctly to model a trial sequence

Colliding particles and Activation energy

Is GOCE a satellite or aircraft?

Does jamais mean always or never in this context?

Why is current rating for multicore cable lower than single core with the same cross section?

Transfer over $10k

Any examples of headwear for races with animal ears?

Confusion about capacitors

Find the coordinate of two line segments that are perpendicular

Options leqno, reqno for documentclass or exist another option?

Is creating your own "experiment" considered cheating during a physics exam?

Why was Germany not as successful as other Europeans in establishing overseas colonies?

What does YCWCYODFTRFDTY mean?

Will tsunami waves travel forever if there was no land?

You look catfish vs You look like a catfish

Did Henry V’s archers at Agincourt fight with no pants / breeches on because of dysentery?

Electric guitar: why such heavy pots?

When and why did journal article titles become descriptive, rather than creatively allusive?

Given what happens in Endgame, why doesn't Dormammu come back to attack the universe?

Phrase for the opposite of "foolproof"

Single Colour Mastermind Problem

How to creep the reader out with what seems like a normal person?

How to back up a running remote server?

Reverse the word in a string with the same order in javascript

Past Perfect Tense



Does Mathematica have an implementation of the Poisson binomial distribution?


RandomVariate from 2-dimensional probability distributionBayesian Inference with Continuous prior distributionContourplot of Binomial DistributionHow to get probabilities for multinomial & hypergeometric distribution ranges more quickly?How should I iteratively refine a MixtureDistribution?Given an exact formula, how can Mathematica find a probability distribution whose PDF matches it?Likelihood for BetaBinomialDistribution with variable number of trialsInverse Fourier Transform of Poisson Characteristic Function?BinomialDistribution: Plotting probability of obtaining $k ge k_0$ for fixed $n$ and $p$ between $0$ and $1$How to use EventData correctly to model a trial sequence













16












$begingroup$


I need to work out the probability of having $k$ successful trials out of a total of $n$ when success probabilities are heterogeneous. This calculation relates to the Poisson Binomial Distribution. Does Mathematica, or perhaps the Mathstatica add-on, have an implementation for that?










share|improve this question











$endgroup$
















    16












    $begingroup$


    I need to work out the probability of having $k$ successful trials out of a total of $n$ when success probabilities are heterogeneous. This calculation relates to the Poisson Binomial Distribution. Does Mathematica, or perhaps the Mathstatica add-on, have an implementation for that?










    share|improve this question











    $endgroup$














      16












      16








      16


      5



      $begingroup$


      I need to work out the probability of having $k$ successful trials out of a total of $n$ when success probabilities are heterogeneous. This calculation relates to the Poisson Binomial Distribution. Does Mathematica, or perhaps the Mathstatica add-on, have an implementation for that?










      share|improve this question











      $endgroup$




      I need to work out the probability of having $k$ successful trials out of a total of $n$ when success probabilities are heterogeneous. This calculation relates to the Poisson Binomial Distribution. Does Mathematica, or perhaps the Mathstatica add-on, have an implementation for that?







      probability-or-statistics distributions






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Apr 25 at 4:35









      user64494

      3,65311222




      3,65311222










      asked Apr 24 at 20:17









      user120911user120911

      84839




      84839




















          3 Answers
          3






          active

          oldest

          votes


















          15












          $begingroup$

          Mathematica does not know about the PoissonBinomialDistribution, but you can use the formula given for the PDF on Wikipedia:



          PoissonBinomialDistribution[ plist : __?NumericQ ] := With[

          n = Length @ plist,
          c = Exp[(2 I [Pi])/(Length@plist + 1)]

          ,
          ProbabilityDistribution[
          Re[ 1/(n + 1) Sum[c^(-l k) Product[1 + (c^l - 1) plist[[m]] , m, 1, n ], l, 0, n] ]
          ,
          k, 0, n, 1
          ]
          ] /; AllTrue[ plist, 0 <= # <= 1& ]


          Now we may model a quality control where fault type 1 has a prob of 4% and fault types 2 and 3 have a prob of 7%:



          dist = PoissonBinomialDistribution[ 0.04, 0.07, 0.07 ];


          With this we find the probability for 3 faults:



          Probability[ k == 3, k [Distributed] dist ]// PercentForm



          0.0196 %




          Update



          Another possibility is to work with TransformedDistribution. Doing so also allows for symbolic evaluation:



          PoissonBinomialDistribution::fargs = "Probabilities must be between zero and one";
          PoissonBinomialDistribution[ plist : __?NumericQ ] := With[

          xList = Table[ Unique["x"], Length @ plist ]

          ,
          If[ Not @ AllTrue[ plist, 0 <= # <= 1 &],
          Return[ Message[PoissonBinomialDistribution::fargs]; $Failed ]
          ];
          TransformedDistribution[
          Total @ xList,
          Thread[ xList [Distributed] Map[ BernoulliDistribution, plist] ]
          ]
          ]

          PDF[ PoissonBinomialDistribution[p1, p2, p3], x ]


          Symbolic PDF






          share|improve this answer











          $endgroup$












          • $begingroup$
            This produces wildly incorrect results pretty quickly...
            $endgroup$
            – ciao
            Apr 25 at 5:59










          • $begingroup$
            @ciao Will the TransformedDistribution solution I just added also produce incorrect results?
            $endgroup$
            – gwr
            Apr 25 at 6:02










          • $begingroup$
            The latter s/b fine, but will get very slow with more than a couple dozen probabilities.
            $endgroup$
            – ciao
            Apr 25 at 6:38










          • $begingroup$
            @ciao Indeed, I just tested with a bunch of random numbers: Already with about 15 probs it takes "hours". :-(
            $endgroup$
            – gwr
            Apr 25 at 6:41










          • $begingroup$
            @gwr your original solution is much faster.
            $endgroup$
            – user120911
            Apr 25 at 7:11


















          6












          $begingroup$

          From what it appears you require, the following should suffice:



          pb = Fold[ListConvolve[##, 1, -1, 0] &, Transpose[1 - #, #]] &;


          It should provide more accurate results for reasonably sized probability vectors.



          As an example, a vector of 100 probabilities:



          SeedRandom@1234
          testps = RandomReal[0, 1, 100];


          Timings:



          r1 = pb@testps; // AbsoluteTiming // First

          r2 = Re@PDF[PoissonBinomialDistribution[testps], Range[0, Length@testps]]; // AbsoluteTiming // First



          0.0008377



          0.137304




          Comparing accuracy with a random sample of the PMFs (pb left, PoissonBinomialDistribution right. The correctness of pb was verified for full PMF):



          With[p = RandomSample[Range@100, 10], 
          Transpose[r1[[p]], r2[[p]]]] // TableForm


          enter image description here



          You can of course use the same to generate generic results for n probabilities, à la Carl Woll's answer, and then replace probabilities as desired:



          np = 18;

          r1 = Table[p[np, x], x, 0, np]; // AbsoluteTiming // First

          r2 = pb[Array[p, np]]; // AbsoluteTiming // First

          %%/% // Round

          And @@ MapThread[FullSimplify[#1 == #2] &, r1, r2]



          504.622



          0.0738808



          6830



          True




          Same results, but ~1/7000th the time taken. I tried with np of 20, gave up waiting, probably 1/20000th the time or so...






          share|improve this answer











          $endgroup$












          • $begingroup$
            (+1) Very nice. If one uses machine precision numbers and adds Chop and Re for the Fourier-Transform-Solution the timing can at least be brought down to around 0.034 secs on my machine (which is of course still way off this solution).
            $endgroup$
            – gwr
            Apr 25 at 10:22


















          3












          $begingroup$

          Another possibility is:



          p[n_, k_] := SeriesCoefficient[Product[1 - (1 - ϵ) p[i], i, n], ϵ, 0, k]


          Reproducing gwr's results:



          Table[p[3, i], i, 0, 3] //Simplify //Column //TeXForm



          $beginarrayl
          -(p(1)-1) (p(2)-1) (p(3)-1) \
          -2 p(3) p(2)+p(2)+p(3)+p(1) (-2 p(3)+p(2) (3 p(3)-2)+1) \
          p(2) p(3)+p(1) (-3 p(3) p(2)+p(2)+p(3)) \
          p(1) p(2) p(3) \
          endarray$







          share|improve this answer









          $endgroup$













            Your Answer








            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "387"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f196962%2fdoes-mathematica-have-an-implementation-of-the-poisson-binomial-distribution%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            15












            $begingroup$

            Mathematica does not know about the PoissonBinomialDistribution, but you can use the formula given for the PDF on Wikipedia:



            PoissonBinomialDistribution[ plist : __?NumericQ ] := With[

            n = Length @ plist,
            c = Exp[(2 I [Pi])/(Length@plist + 1)]

            ,
            ProbabilityDistribution[
            Re[ 1/(n + 1) Sum[c^(-l k) Product[1 + (c^l - 1) plist[[m]] , m, 1, n ], l, 0, n] ]
            ,
            k, 0, n, 1
            ]
            ] /; AllTrue[ plist, 0 <= # <= 1& ]


            Now we may model a quality control where fault type 1 has a prob of 4% and fault types 2 and 3 have a prob of 7%:



            dist = PoissonBinomialDistribution[ 0.04, 0.07, 0.07 ];


            With this we find the probability for 3 faults:



            Probability[ k == 3, k [Distributed] dist ]// PercentForm



            0.0196 %




            Update



            Another possibility is to work with TransformedDistribution. Doing so also allows for symbolic evaluation:



            PoissonBinomialDistribution::fargs = "Probabilities must be between zero and one";
            PoissonBinomialDistribution[ plist : __?NumericQ ] := With[

            xList = Table[ Unique["x"], Length @ plist ]

            ,
            If[ Not @ AllTrue[ plist, 0 <= # <= 1 &],
            Return[ Message[PoissonBinomialDistribution::fargs]; $Failed ]
            ];
            TransformedDistribution[
            Total @ xList,
            Thread[ xList [Distributed] Map[ BernoulliDistribution, plist] ]
            ]
            ]

            PDF[ PoissonBinomialDistribution[p1, p2, p3], x ]


            Symbolic PDF






            share|improve this answer











            $endgroup$












            • $begingroup$
              This produces wildly incorrect results pretty quickly...
              $endgroup$
              – ciao
              Apr 25 at 5:59










            • $begingroup$
              @ciao Will the TransformedDistribution solution I just added also produce incorrect results?
              $endgroup$
              – gwr
              Apr 25 at 6:02










            • $begingroup$
              The latter s/b fine, but will get very slow with more than a couple dozen probabilities.
              $endgroup$
              – ciao
              Apr 25 at 6:38










            • $begingroup$
              @ciao Indeed, I just tested with a bunch of random numbers: Already with about 15 probs it takes "hours". :-(
              $endgroup$
              – gwr
              Apr 25 at 6:41










            • $begingroup$
              @gwr your original solution is much faster.
              $endgroup$
              – user120911
              Apr 25 at 7:11















            15












            $begingroup$

            Mathematica does not know about the PoissonBinomialDistribution, but you can use the formula given for the PDF on Wikipedia:



            PoissonBinomialDistribution[ plist : __?NumericQ ] := With[

            n = Length @ plist,
            c = Exp[(2 I [Pi])/(Length@plist + 1)]

            ,
            ProbabilityDistribution[
            Re[ 1/(n + 1) Sum[c^(-l k) Product[1 + (c^l - 1) plist[[m]] , m, 1, n ], l, 0, n] ]
            ,
            k, 0, n, 1
            ]
            ] /; AllTrue[ plist, 0 <= # <= 1& ]


            Now we may model a quality control where fault type 1 has a prob of 4% and fault types 2 and 3 have a prob of 7%:



            dist = PoissonBinomialDistribution[ 0.04, 0.07, 0.07 ];


            With this we find the probability for 3 faults:



            Probability[ k == 3, k [Distributed] dist ]// PercentForm



            0.0196 %




            Update



            Another possibility is to work with TransformedDistribution. Doing so also allows for symbolic evaluation:



            PoissonBinomialDistribution::fargs = "Probabilities must be between zero and one";
            PoissonBinomialDistribution[ plist : __?NumericQ ] := With[

            xList = Table[ Unique["x"], Length @ plist ]

            ,
            If[ Not @ AllTrue[ plist, 0 <= # <= 1 &],
            Return[ Message[PoissonBinomialDistribution::fargs]; $Failed ]
            ];
            TransformedDistribution[
            Total @ xList,
            Thread[ xList [Distributed] Map[ BernoulliDistribution, plist] ]
            ]
            ]

            PDF[ PoissonBinomialDistribution[p1, p2, p3], x ]


            Symbolic PDF






            share|improve this answer











            $endgroup$












            • $begingroup$
              This produces wildly incorrect results pretty quickly...
              $endgroup$
              – ciao
              Apr 25 at 5:59










            • $begingroup$
              @ciao Will the TransformedDistribution solution I just added also produce incorrect results?
              $endgroup$
              – gwr
              Apr 25 at 6:02










            • $begingroup$
              The latter s/b fine, but will get very slow with more than a couple dozen probabilities.
              $endgroup$
              – ciao
              Apr 25 at 6:38










            • $begingroup$
              @ciao Indeed, I just tested with a bunch of random numbers: Already with about 15 probs it takes "hours". :-(
              $endgroup$
              – gwr
              Apr 25 at 6:41










            • $begingroup$
              @gwr your original solution is much faster.
              $endgroup$
              – user120911
              Apr 25 at 7:11













            15












            15








            15





            $begingroup$

            Mathematica does not know about the PoissonBinomialDistribution, but you can use the formula given for the PDF on Wikipedia:



            PoissonBinomialDistribution[ plist : __?NumericQ ] := With[

            n = Length @ plist,
            c = Exp[(2 I [Pi])/(Length@plist + 1)]

            ,
            ProbabilityDistribution[
            Re[ 1/(n + 1) Sum[c^(-l k) Product[1 + (c^l - 1) plist[[m]] , m, 1, n ], l, 0, n] ]
            ,
            k, 0, n, 1
            ]
            ] /; AllTrue[ plist, 0 <= # <= 1& ]


            Now we may model a quality control where fault type 1 has a prob of 4% and fault types 2 and 3 have a prob of 7%:



            dist = PoissonBinomialDistribution[ 0.04, 0.07, 0.07 ];


            With this we find the probability for 3 faults:



            Probability[ k == 3, k [Distributed] dist ]// PercentForm



            0.0196 %




            Update



            Another possibility is to work with TransformedDistribution. Doing so also allows for symbolic evaluation:



            PoissonBinomialDistribution::fargs = "Probabilities must be between zero and one";
            PoissonBinomialDistribution[ plist : __?NumericQ ] := With[

            xList = Table[ Unique["x"], Length @ plist ]

            ,
            If[ Not @ AllTrue[ plist, 0 <= # <= 1 &],
            Return[ Message[PoissonBinomialDistribution::fargs]; $Failed ]
            ];
            TransformedDistribution[
            Total @ xList,
            Thread[ xList [Distributed] Map[ BernoulliDistribution, plist] ]
            ]
            ]

            PDF[ PoissonBinomialDistribution[p1, p2, p3], x ]


            Symbolic PDF






            share|improve this answer











            $endgroup$



            Mathematica does not know about the PoissonBinomialDistribution, but you can use the formula given for the PDF on Wikipedia:



            PoissonBinomialDistribution[ plist : __?NumericQ ] := With[

            n = Length @ plist,
            c = Exp[(2 I [Pi])/(Length@plist + 1)]

            ,
            ProbabilityDistribution[
            Re[ 1/(n + 1) Sum[c^(-l k) Product[1 + (c^l - 1) plist[[m]] , m, 1, n ], l, 0, n] ]
            ,
            k, 0, n, 1
            ]
            ] /; AllTrue[ plist, 0 <= # <= 1& ]


            Now we may model a quality control where fault type 1 has a prob of 4% and fault types 2 and 3 have a prob of 7%:



            dist = PoissonBinomialDistribution[ 0.04, 0.07, 0.07 ];


            With this we find the probability for 3 faults:



            Probability[ k == 3, k [Distributed] dist ]// PercentForm



            0.0196 %




            Update



            Another possibility is to work with TransformedDistribution. Doing so also allows for symbolic evaluation:



            PoissonBinomialDistribution::fargs = "Probabilities must be between zero and one";
            PoissonBinomialDistribution[ plist : __?NumericQ ] := With[

            xList = Table[ Unique["x"], Length @ plist ]

            ,
            If[ Not @ AllTrue[ plist, 0 <= # <= 1 &],
            Return[ Message[PoissonBinomialDistribution::fargs]; $Failed ]
            ];
            TransformedDistribution[
            Total @ xList,
            Thread[ xList [Distributed] Map[ BernoulliDistribution, plist] ]
            ]
            ]

            PDF[ PoissonBinomialDistribution[p1, p2, p3], x ]


            Symbolic PDF







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Apr 25 at 9:47

























            answered Apr 24 at 21:13









            gwrgwr

            8,80322862




            8,80322862











            • $begingroup$
              This produces wildly incorrect results pretty quickly...
              $endgroup$
              – ciao
              Apr 25 at 5:59










            • $begingroup$
              @ciao Will the TransformedDistribution solution I just added also produce incorrect results?
              $endgroup$
              – gwr
              Apr 25 at 6:02










            • $begingroup$
              The latter s/b fine, but will get very slow with more than a couple dozen probabilities.
              $endgroup$
              – ciao
              Apr 25 at 6:38










            • $begingroup$
              @ciao Indeed, I just tested with a bunch of random numbers: Already with about 15 probs it takes "hours". :-(
              $endgroup$
              – gwr
              Apr 25 at 6:41










            • $begingroup$
              @gwr your original solution is much faster.
              $endgroup$
              – user120911
              Apr 25 at 7:11
















            • $begingroup$
              This produces wildly incorrect results pretty quickly...
              $endgroup$
              – ciao
              Apr 25 at 5:59










            • $begingroup$
              @ciao Will the TransformedDistribution solution I just added also produce incorrect results?
              $endgroup$
              – gwr
              Apr 25 at 6:02










            • $begingroup$
              The latter s/b fine, but will get very slow with more than a couple dozen probabilities.
              $endgroup$
              – ciao
              Apr 25 at 6:38










            • $begingroup$
              @ciao Indeed, I just tested with a bunch of random numbers: Already with about 15 probs it takes "hours". :-(
              $endgroup$
              – gwr
              Apr 25 at 6:41










            • $begingroup$
              @gwr your original solution is much faster.
              $endgroup$
              – user120911
              Apr 25 at 7:11















            $begingroup$
            This produces wildly incorrect results pretty quickly...
            $endgroup$
            – ciao
            Apr 25 at 5:59




            $begingroup$
            This produces wildly incorrect results pretty quickly...
            $endgroup$
            – ciao
            Apr 25 at 5:59












            $begingroup$
            @ciao Will the TransformedDistribution solution I just added also produce incorrect results?
            $endgroup$
            – gwr
            Apr 25 at 6:02




            $begingroup$
            @ciao Will the TransformedDistribution solution I just added also produce incorrect results?
            $endgroup$
            – gwr
            Apr 25 at 6:02












            $begingroup$
            The latter s/b fine, but will get very slow with more than a couple dozen probabilities.
            $endgroup$
            – ciao
            Apr 25 at 6:38




            $begingroup$
            The latter s/b fine, but will get very slow with more than a couple dozen probabilities.
            $endgroup$
            – ciao
            Apr 25 at 6:38












            $begingroup$
            @ciao Indeed, I just tested with a bunch of random numbers: Already with about 15 probs it takes "hours". :-(
            $endgroup$
            – gwr
            Apr 25 at 6:41




            $begingroup$
            @ciao Indeed, I just tested with a bunch of random numbers: Already with about 15 probs it takes "hours". :-(
            $endgroup$
            – gwr
            Apr 25 at 6:41












            $begingroup$
            @gwr your original solution is much faster.
            $endgroup$
            – user120911
            Apr 25 at 7:11




            $begingroup$
            @gwr your original solution is much faster.
            $endgroup$
            – user120911
            Apr 25 at 7:11











            6












            $begingroup$

            From what it appears you require, the following should suffice:



            pb = Fold[ListConvolve[##, 1, -1, 0] &, Transpose[1 - #, #]] &;


            It should provide more accurate results for reasonably sized probability vectors.



            As an example, a vector of 100 probabilities:



            SeedRandom@1234
            testps = RandomReal[0, 1, 100];


            Timings:



            r1 = pb@testps; // AbsoluteTiming // First

            r2 = Re@PDF[PoissonBinomialDistribution[testps], Range[0, Length@testps]]; // AbsoluteTiming // First



            0.0008377



            0.137304




            Comparing accuracy with a random sample of the PMFs (pb left, PoissonBinomialDistribution right. The correctness of pb was verified for full PMF):



            With[p = RandomSample[Range@100, 10], 
            Transpose[r1[[p]], r2[[p]]]] // TableForm


            enter image description here



            You can of course use the same to generate generic results for n probabilities, à la Carl Woll's answer, and then replace probabilities as desired:



            np = 18;

            r1 = Table[p[np, x], x, 0, np]; // AbsoluteTiming // First

            r2 = pb[Array[p, np]]; // AbsoluteTiming // First

            %%/% // Round

            And @@ MapThread[FullSimplify[#1 == #2] &, r1, r2]



            504.622



            0.0738808



            6830



            True




            Same results, but ~1/7000th the time taken. I tried with np of 20, gave up waiting, probably 1/20000th the time or so...






            share|improve this answer











            $endgroup$












            • $begingroup$
              (+1) Very nice. If one uses machine precision numbers and adds Chop and Re for the Fourier-Transform-Solution the timing can at least be brought down to around 0.034 secs on my machine (which is of course still way off this solution).
              $endgroup$
              – gwr
              Apr 25 at 10:22















            6












            $begingroup$

            From what it appears you require, the following should suffice:



            pb = Fold[ListConvolve[##, 1, -1, 0] &, Transpose[1 - #, #]] &;


            It should provide more accurate results for reasonably sized probability vectors.



            As an example, a vector of 100 probabilities:



            SeedRandom@1234
            testps = RandomReal[0, 1, 100];


            Timings:



            r1 = pb@testps; // AbsoluteTiming // First

            r2 = Re@PDF[PoissonBinomialDistribution[testps], Range[0, Length@testps]]; // AbsoluteTiming // First



            0.0008377



            0.137304




            Comparing accuracy with a random sample of the PMFs (pb left, PoissonBinomialDistribution right. The correctness of pb was verified for full PMF):



            With[p = RandomSample[Range@100, 10], 
            Transpose[r1[[p]], r2[[p]]]] // TableForm


            enter image description here



            You can of course use the same to generate generic results for n probabilities, à la Carl Woll's answer, and then replace probabilities as desired:



            np = 18;

            r1 = Table[p[np, x], x, 0, np]; // AbsoluteTiming // First

            r2 = pb[Array[p, np]]; // AbsoluteTiming // First

            %%/% // Round

            And @@ MapThread[FullSimplify[#1 == #2] &, r1, r2]



            504.622



            0.0738808



            6830



            True




            Same results, but ~1/7000th the time taken. I tried with np of 20, gave up waiting, probably 1/20000th the time or so...






            share|improve this answer











            $endgroup$












            • $begingroup$
              (+1) Very nice. If one uses machine precision numbers and adds Chop and Re for the Fourier-Transform-Solution the timing can at least be brought down to around 0.034 secs on my machine (which is of course still way off this solution).
              $endgroup$
              – gwr
              Apr 25 at 10:22













            6












            6








            6





            $begingroup$

            From what it appears you require, the following should suffice:



            pb = Fold[ListConvolve[##, 1, -1, 0] &, Transpose[1 - #, #]] &;


            It should provide more accurate results for reasonably sized probability vectors.



            As an example, a vector of 100 probabilities:



            SeedRandom@1234
            testps = RandomReal[0, 1, 100];


            Timings:



            r1 = pb@testps; // AbsoluteTiming // First

            r2 = Re@PDF[PoissonBinomialDistribution[testps], Range[0, Length@testps]]; // AbsoluteTiming // First



            0.0008377



            0.137304




            Comparing accuracy with a random sample of the PMFs (pb left, PoissonBinomialDistribution right. The correctness of pb was verified for full PMF):



            With[p = RandomSample[Range@100, 10], 
            Transpose[r1[[p]], r2[[p]]]] // TableForm


            enter image description here



            You can of course use the same to generate generic results for n probabilities, à la Carl Woll's answer, and then replace probabilities as desired:



            np = 18;

            r1 = Table[p[np, x], x, 0, np]; // AbsoluteTiming // First

            r2 = pb[Array[p, np]]; // AbsoluteTiming // First

            %%/% // Round

            And @@ MapThread[FullSimplify[#1 == #2] &, r1, r2]



            504.622



            0.0738808



            6830



            True




            Same results, but ~1/7000th the time taken. I tried with np of 20, gave up waiting, probably 1/20000th the time or so...






            share|improve this answer











            $endgroup$



            From what it appears you require, the following should suffice:



            pb = Fold[ListConvolve[##, 1, -1, 0] &, Transpose[1 - #, #]] &;


            It should provide more accurate results for reasonably sized probability vectors.



            As an example, a vector of 100 probabilities:



            SeedRandom@1234
            testps = RandomReal[0, 1, 100];


            Timings:



            r1 = pb@testps; // AbsoluteTiming // First

            r2 = Re@PDF[PoissonBinomialDistribution[testps], Range[0, Length@testps]]; // AbsoluteTiming // First



            0.0008377



            0.137304




            Comparing accuracy with a random sample of the PMFs (pb left, PoissonBinomialDistribution right. The correctness of pb was verified for full PMF):



            With[p = RandomSample[Range@100, 10], 
            Transpose[r1[[p]], r2[[p]]]] // TableForm


            enter image description here



            You can of course use the same to generate generic results for n probabilities, à la Carl Woll's answer, and then replace probabilities as desired:



            np = 18;

            r1 = Table[p[np, x], x, 0, np]; // AbsoluteTiming // First

            r2 = pb[Array[p, np]]; // AbsoluteTiming // First

            %%/% // Round

            And @@ MapThread[FullSimplify[#1 == #2] &, r1, r2]



            504.622



            0.0738808



            6830



            True




            Same results, but ~1/7000th the time taken. I tried with np of 20, gave up waiting, probably 1/20000th the time or so...







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Apr 25 at 8:56

























            answered Apr 25 at 7:17









            ciaociao

            17.6k138109




            17.6k138109











            • $begingroup$
              (+1) Very nice. If one uses machine precision numbers and adds Chop and Re for the Fourier-Transform-Solution the timing can at least be brought down to around 0.034 secs on my machine (which is of course still way off this solution).
              $endgroup$
              – gwr
              Apr 25 at 10:22
















            • $begingroup$
              (+1) Very nice. If one uses machine precision numbers and adds Chop and Re for the Fourier-Transform-Solution the timing can at least be brought down to around 0.034 secs on my machine (which is of course still way off this solution).
              $endgroup$
              – gwr
              Apr 25 at 10:22















            $begingroup$
            (+1) Very nice. If one uses machine precision numbers and adds Chop and Re for the Fourier-Transform-Solution the timing can at least be brought down to around 0.034 secs on my machine (which is of course still way off this solution).
            $endgroup$
            – gwr
            Apr 25 at 10:22




            $begingroup$
            (+1) Very nice. If one uses machine precision numbers and adds Chop and Re for the Fourier-Transform-Solution the timing can at least be brought down to around 0.034 secs on my machine (which is of course still way off this solution).
            $endgroup$
            – gwr
            Apr 25 at 10:22











            3












            $begingroup$

            Another possibility is:



            p[n_, k_] := SeriesCoefficient[Product[1 - (1 - ϵ) p[i], i, n], ϵ, 0, k]


            Reproducing gwr's results:



            Table[p[3, i], i, 0, 3] //Simplify //Column //TeXForm



            $beginarrayl
            -(p(1)-1) (p(2)-1) (p(3)-1) \
            -2 p(3) p(2)+p(2)+p(3)+p(1) (-2 p(3)+p(2) (3 p(3)-2)+1) \
            p(2) p(3)+p(1) (-3 p(3) p(2)+p(2)+p(3)) \
            p(1) p(2) p(3) \
            endarray$







            share|improve this answer









            $endgroup$

















              3












              $begingroup$

              Another possibility is:



              p[n_, k_] := SeriesCoefficient[Product[1 - (1 - ϵ) p[i], i, n], ϵ, 0, k]


              Reproducing gwr's results:



              Table[p[3, i], i, 0, 3] //Simplify //Column //TeXForm



              $beginarrayl
              -(p(1)-1) (p(2)-1) (p(3)-1) \
              -2 p(3) p(2)+p(2)+p(3)+p(1) (-2 p(3)+p(2) (3 p(3)-2)+1) \
              p(2) p(3)+p(1) (-3 p(3) p(2)+p(2)+p(3)) \
              p(1) p(2) p(3) \
              endarray$







              share|improve this answer









              $endgroup$















                3












                3








                3





                $begingroup$

                Another possibility is:



                p[n_, k_] := SeriesCoefficient[Product[1 - (1 - ϵ) p[i], i, n], ϵ, 0, k]


                Reproducing gwr's results:



                Table[p[3, i], i, 0, 3] //Simplify //Column //TeXForm



                $beginarrayl
                -(p(1)-1) (p(2)-1) (p(3)-1) \
                -2 p(3) p(2)+p(2)+p(3)+p(1) (-2 p(3)+p(2) (3 p(3)-2)+1) \
                p(2) p(3)+p(1) (-3 p(3) p(2)+p(2)+p(3)) \
                p(1) p(2) p(3) \
                endarray$







                share|improve this answer









                $endgroup$



                Another possibility is:



                p[n_, k_] := SeriesCoefficient[Product[1 - (1 - ϵ) p[i], i, n], ϵ, 0, k]


                Reproducing gwr's results:



                Table[p[3, i], i, 0, 3] //Simplify //Column //TeXForm



                $beginarrayl
                -(p(1)-1) (p(2)-1) (p(3)-1) \
                -2 p(3) p(2)+p(2)+p(3)+p(1) (-2 p(3)+p(2) (3 p(3)-2)+1) \
                p(2) p(3)+p(1) (-3 p(3) p(2)+p(2)+p(3)) \
                p(1) p(2) p(3) \
                endarray$








                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Apr 25 at 6:18









                Carl WollCarl Woll

                76.3k3100200




                76.3k3100200



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Mathematica Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    Use MathJax to format equations. MathJax reference.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmathematica.stackexchange.com%2fquestions%2f196962%2fdoes-mathematica-have-an-implementation-of-the-poisson-binomial-distribution%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Sum ergo cogito? 1 nng

                    419 nièngy_Soadمي 19bal1.5o_g

                    Queiggey Chernihivv 9NnOo i Zw X QqKk LpB