{"action":"created","comment":{"url":"https://api.github.com/repos/libmir/mir/pulls/comments/68487697","id":68487697,"diff_hunk":"@@ -0,0 +1,207 @@\n+/**\n+License: $(LINK2 http://boost.org/LICENSE_1_0.txt, Boost License 1.0).\n+\n+Authors: Sebastian Wilzbach, Ilya Yaroshenko\n+\n+The Transformed Density Rejection with Inflection Points (Tinflex) algorithm\n+can sample from arbitrary distributions given its density function f, its\n+first two derivatives and a partitioning into intervals with at most one inflection\n+point.\n+\n+These can be easily found by plotting `f''`.\n+$(B Inflection point) can be identified by observing at which points `f''` is 0.\n+\n+$(UL\n+    $(LI $(F_TILDE) is entirely concave (`f''` is entirely negative))\n+    $(LI $(F_TILDE) is entirely convex (`f''` is entirely positive))\n+    $(LI $(F_TILDE) contains one inflection point (`f''` intersects the x-axis once)\n+)\n+\n+In exact terms the algorithm requires:\n+\n+$(UL\n+    $(LI Continuous density function $(F_TILDE).)\n+    $(LI Continuous differentiability of $(F_TILDE) except in a finite number of\n+      points which need to have a one-sided derivative.)\n+    $(LI $(B Doubled) Continuous differentiability of $(F_TILDE) except in a finite number of\n+      points which need to be inflection points.)\n+    $(LI At most one inflection point per interval)\n+)\n+\n+References:\n+    Transformed Density Rejection with Inflection Points\n+\n+    Botts, Carsten, Wolfgang Hörmann, and Josef Leydold.\n+    \"$(LINK2 http://epub.wu-wien.ac.at/3158/1/techreport-110.pdf,\n+    Transformed density rejection with inflection points.)\"\n+    Statistics and Computing 23.2 (2013): 251-260.\n+\n+Macros:\n+    F_TILDE=g(x)\n+*/\n+module mir.random.tinflex;\n+\n+import mir.random.tinflex.internal.types : IntervalPoint;\n+\n+import std.traits : ReturnType;\n+import std.random : isUniformRNG;\n+\n+\n+/**\n+The Transformed Density Rejection with Inflection Points (Tinflex) algorithm\n+can sample from arbitrary distributions given its density function f, its\n+first two derivatives and a partitioning into intervals with at most one inflection\n+point.\n+\n+Params:\n+    f0 = probability density function of the distribution\n+    f1 = first derivative of f0\n+    f2 = second derivative of f0\n+    c = T_c family\n+    points = non-overlapping partitioning with at most one inflection point per interval\n+    rho = efficiency of the Tinflex algorithm\n+\n+Returns:\n+    Tinflex Generator.\n+*/\n+Tinflex!(F0, S) tinflex(F0, F1, F2, S)\n+               (in F0 f0, in F1 f1, in F2 f2,\n+                S c, S[] points, S rho = 1.1)\n+{\n+    import mir.random.tinflex.internal.calc : calcPoints;\n+    // pre-calculate all the points\n+    auto ips = calcPoints(f0, f1, f2, c, points, 1.1);\n+    return Tinflex!(F0, S)(f0, ips, c);\n+}\n+\n+/**\n+Data body of the Tinflex algorithm.\n+Can be used to sample from the distribution.\n+*/\n+struct Tinflex(F0, S)\n+{\n+    // density function\n+    private const F0 _f0;\n+\n+    // generated partition points\n+    private const IntervalPoint!S[] _ips;\n+\n+    // global T_c family\n+    private const S c;\n+\n+    private this(const F0 f0, const IntervalPoint!S[] ips, const S c)\n+    {\n+        _f0 = f0;\n+        _ips = ips;\n+        this.c = c;\n+    }\n+\n+    /// density function of the distribution\n+    F0 pdf() const @property\n+    {\n+        return _f0;\n+    }\n+\n+    /// density function of the distribution\n+    S pdf(S x) const @property\n+    {\n+        return _f0(x);\n+    }\n+\n+    /// Generated partition points\n+    const(IntervalPoint!S[]) ips() @property const\n+    {\n+        return _ips;\n+    }\n+\n+    /**\n+    Sample n times from the distribution.\n+    Params:\n+        n = number of times to samples\n+        rng = random number generator to use\n+    Returns:\n+        Array of length n with the samples\n+    */\n+    S opCall() const\n+    {\n+        import std.random : rndGen;\n+        return tfSample(_f0, _ips, c, rndGen);\n+    }\n+\n+    /// ditto\n+    S opCall(RNG)(ref RNG rng) const\n+        if (isUniformRNG!RNG)\n+    {\n+        return tfSample(_f0, _ips, c, rng);\n+    }\n+}\n+\n+/**\n+Sample from the distribution.\n+Params:\n+    ips = calculated inflection points\n+    rng = random number generator to use\n+*/\n+protected S tfSample(F0, S, RNG)\n+          (in F0 f0, in IntervalPoint!S[] ips, in S c, ref RNG rng)\n+    if (is(ReturnType!F0 == S) &&\n+        isUniformRNG!RNG)\n+{\n+    import std.algorithm: filter, joiner, map, sum;\n+\n+    // TODO: filtering not needed anymore\n+    auto s = ips[0..$-2].map!`a.hatA`.sum;\n+    auto areas = ips[0..$-2].map!((x) => x.hatA / s);\n+\n+    import std.random: dice, uniform01;\n+    import std.math: abs;\n+    import mir.internal.math: exp;\n+\n+    import mir.random.tinflex.internal.transformations : inverse, antiderivative, inverseAntiderivative;\n+\n+    double X;\n+    // acceptance-rejection sampling\n+    for (;;)\n+    {\n+        import std.stdio;\n+        writeln(areas);\n+        auto j = dice(rng, areas);\n+        auto u = uniform01(rng);\n+\n+        if (abs(ips[j].hat.slope) > 1e-10)\n+        {\n+            X = ips[j].hat._y + (inverseAntiderivative(antiderivative(ips[j].hat(ips[j].x), c)\n+                          + ips[j].hat.slope * u, c) - ips[j].hat.a) / ips[j].hat.slope;\n+        }\n+        else\n+        {\n+            X = (1-u) * ips[j].x + u * ips[j + 1].x;\n+        }\n+\n+        auto hatX = inverse(ips[j].hat(X), c);\n+        double squeezeX = ips[j].squeezeA > 0 ? inverse(ips[j].squeeze(X), c) : 0;\n+\n+        immutable t = u * hatX;\n+        if (t <= squeezeX)\n+        {\n+            break;\n+        }\n+        else if (t <= exp(f0(X)))","path":"source/mir/random/tinflex/package.d","position":189,"original_position":189,"commit_id":"09c372a62f54b4082c881dae62c76c1ad24086fb","original_commit_id":"09c372a62f54b4082c881dae62c76c1ad24086fb","user":{"login":"9il","id":845083,"avatar_url":"https://avatars.githubusercontent.com/u/845083?v=3","gravatar_id":"","url":"https://api.github.com/users/9il","html_url":"https://github.com/9il","followers_url":"https://api.github.com/users/9il/followers","following_url":"https://api.github.com/users/9il/following{/other_user}","gists_url":"https://api.github.com/users/9il/gists{/gist_id}","starred_url":"https://api.github.com/users/9il/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/9il/subscriptions","organizations_url":"https://api.github.com/users/9il/orgs","repos_url":"https://api.github.com/users/9il/repos","events_url":"https://api.github.com/users/9il/events{/privacy}","received_events_url":"https://api.github.com/users/9il/received_events","type":"User","site_admin":false},"body":"do not need `else` here","created_at":"2016-06-25T11:15:36Z","updated_at":"2016-06-25T11:15:36Z","html_url":"https://github.com/libmir/mir/pull/222#discussion_r68487697","pull_request_url":"https://api.github.com/repos/libmir/mir/pulls/222","_links":{"self":{"href":"https://api.github.com/repos/libmir/mir/pulls/comments/68487697"},"html":{"href":"https://github.com/libmir/mir/pull/222#discussion_r68487697"},"pull_request":{"href":"https://api.github.com/repos/libmir/mir/pulls/222"}}},"pull_request":{"url":"https://api.github.com/repos/libmir/mir/pulls/222","id":72288069,"html_url":"https://github.com/libmir/mir/pull/222","diff_url":"https://github.com/libmir/mir/pull/222.diff","patch_url":"https://github.com/libmir/mir/pull/222.patch","issue_url":"https://api.github.com/repos/libmir/mir/issues/222","number":222,"state":"open","locked":false,"title":"[WIP] Transformed density rejection with inflection points","user":{"login":"wilzbach","id":4370550,"avatar_url":"https://avatars.githubusercontent.com/u/4370550?v=3","gravatar_id":"","url":"https://api.github.com/users/wilzbach","html_url":"https://github.com/wilzbach","followers_url":"https://api.github.com/users/wilzbach/followers","following_url":"https://api.github.com/users/wilzbach/following{/other_user}","gists_url":"https://api.github.com/users/wilzbach/gists{/gist_id}","starred_url":"https://api.github.com/users/wilzbach/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wilzbach/subscriptions","organizations_url":"https://api.github.com/users/wilzbach/orgs","repos_url":"https://api.github.com/users/wilzbach/repos","events_url":"https://api.github.com/users/wilzbach/events{/privacy}","received_events_url":"https://api.github.com/users/wilzbach/received_events","type":"User","site_admin":false},"body":"This is my WIP Tinflex branch that tracks my progress.\r\nPaper: http://epub.wu.ac.at/3158/1/techreport-110.pdf \r\n\r\nWhat is working:\r\n- concave/convex type determination for any interval with at most one inflection point\r\n- computing hat and squeeze function for any interval with at most one inflection point\r\n\r\nWhat's missing:\r\n- compute x0 (defined as the maximum within the interval - I still need to figure out how they compute this efficiently)\r\n- compute areas (I need to find out how \"c\" is selected)\r\n- split intervals (arc-mean formula)\r\n- sample new random value and filter\r\n\r\nPlease don't make the effort to criticize the style yet - it's WIP.","created_at":"2016-06-02T04:33:24Z","updated_at":"2016-06-25T11:15:36Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e937f01bca66313f7fa3ae475487776cba691630","assignee":{"login":"wilzbach","id":4370550,"avatar_url":"https://avatars.githubusercontent.com/u/4370550?v=3","gravatar_id":"","url":"https://api.github.com/users/wilzbach","html_url":"https://github.com/wilzbach","followers_url":"https://api.github.com/users/wilzbach/followers","following_url":"https://api.github.com/users/wilzbach/following{/other_user}","gists_url":"https://api.github.com/users/wilzbach/gists{/gist_id}","starred_url":"https://api.github.com/users/wilzbach/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wilzbach/subscriptions","organizations_url":"https://api.github.com/users/wilzbach/orgs","repos_url":"https://api.github.com/users/wilzbach/repos","events_url":"https://api.github.com/users/wilzbach/events{/privacy}","received_events_url":"https://api.github.com/users/wilzbach/received_events","type":"User","site_admin":false},"assignees":[{"login":"wilzbach","id":4370550,"avatar_url":"https://avatars.githubusercontent.com/u/4370550?v=3","gravatar_id":"","url":"https://api.github.com/users/wilzbach","html_url":"https://github.com/wilzbach","followers_url":"https://api.github.com/users/wilzbach/followers","following_url":"https://api.github.com/users/wilzbach/following{/other_user}","gists_url":"https://api.github.com/users/wilzbach/gists{/gist_id}","starred_url":"https://api.github.com/users/wilzbach/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wilzbach/subscriptions","organizations_url":"https://api.github.com/users/wilzbach/orgs","repos_url":"https://api.github.com/users/wilzbach/repos","events_url":"https://api.github.com/users/wilzbach/events{/privacy}","received_events_url":"https://api.github.com/users/wilzbach/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/libmir/mir/pulls/222/commits","review_comments_url":"https://api.github.com/repos/libmir/mir/pulls/222/comments","review_comment_url":"https://api.github.com/repos/libmir/mir/pulls/comments{/number}","comments_url":"https://api.github.com/repos/libmir/mir/issues/222/comments","statuses_url":"https://api.github.com/repos/libmir/mir/statuses/09c372a62f54b4082c881dae62c76c1ad24086fb","head":{"label":"wilzbach:generic_uniform","ref":"generic_uniform","sha":"09c372a62f54b4082c881dae62c76c1ad24086fb","user":{"login":"wilzbach","id":4370550,"avatar_url":"https://avatars.githubusercontent.com/u/4370550?v=3","gravatar_id":"","url":"https://api.github.com/users/wilzbach","html_url":"https://github.com/wilzbach","followers_url":"https://api.github.com/users/wilzbach/followers","following_url":"https://api.github.com/users/wilzbach/following{/other_user}","gists_url":"https://api.github.com/users/wilzbach/gists{/gist_id}","starred_url":"https://api.github.com/users/wilzbach/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wilzbach/subscriptions","organizations_url":"https://api.github.com/users/wilzbach/orgs","repos_url":"https://api.github.com/users/wilzbach/repos","events_url":"https://api.github.com/users/wilzbach/events{/privacy}","received_events_url":"https://api.github.com/users/wilzbach/received_events","type":"User","site_admin":false},"repo":{"id":53214767,"name":"mir","full_name":"wilzbach/mir","owner":{"login":"wilzbach","id":4370550,"avatar_url":"https://avatars.githubusercontent.com/u/4370550?v=3","gravatar_id":"","url":"https://api.github.com/users/wilzbach","html_url":"https://github.com/wilzbach","followers_url":"https://api.github.com/users/wilzbach/followers","following_url":"https://api.github.com/users/wilzbach/following{/other_user}","gists_url":"https://api.github.com/users/wilzbach/gists{/gist_id}","starred_url":"https://api.github.com/users/wilzbach/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wilzbach/subscriptions","organizations_url":"https://api.github.com/users/wilzbach/orgs","repos_url":"https://api.github.com/users/wilzbach/repos","events_url":"https://api.github.com/users/wilzbach/events{/privacy}","received_events_url":"https://api.github.com/users/wilzbach/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/wilzbach/mir","description":"Generic Numeric Library","fork":true,"url":"https://api.github.com/repos/wilzbach/mir","forks_url":"https://api.github.com/repos/wilzbach/mir/forks","keys_url":"https://api.github.com/repos/wilzbach/mir/keys{/key_id}","collaborators_url":"https://api.github.com/repos/wilzbach/mir/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/wilzbach/mir/teams","hooks_url":"https://api.github.com/repos/wilzbach/mir/hooks","issue_events_url":"https://api.github.com/repos/wilzbach/mir/issues/events{/number}","events_url":"https://api.github.com/repos/wilzbach/mir/events","assignees_url":"https://api.github.com/repos/wilzbach/mir/assignees{/user}","branches_url":"https://api.github.com/repos/wilzbach/mir/branches{/branch}","tags_url":"https://api.github.com/repos/wilzbach/mir/tags","blobs_url":"https://api.github.com/repos/wilzbach/mir/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/wilzbach/mir/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/wilzbach/mir/git/refs{/sha}","trees_url":"https://api.github.com/repos/wilzbach/mir/git/trees{/sha}","statuses_url":"https://api.github.com/repos/wilzbach/mir/statuses/{sha}","languages_url":"https://api.github.com/repos/wilzbach/mir/languages","stargazers_url":"https://api.github.com/repos/wilzbach/mir/stargazers","contributors_url":"https://api.github.com/repos/wilzbach/mir/contributors","subscribers_url":"https://api.github.com/repos/wilzbach/mir/subscribers","subscription_url":"https://api.github.com/repos/wilzbach/mir/subscription","commits_url":"https://api.github.com/repos/wilzbach/mir/commits{/sha}","git_commits_url":"https://api.github.com/repos/wilzbach/mir/git/commits{/sha}","comments_url":"https://api.github.com/repos/wilzbach/mir/comments{/number}","issue_comment_url":"https://api.github.com/repos/wilzbach/mir/issues/comments{/number}","contents_url":"https://api.github.com/repos/wilzbach/mir/contents/{+path}","compare_url":"https://api.github.com/repos/wilzbach/mir/compare/{base}...{head}","merges_url":"https://api.github.com/repos/wilzbach/mir/merges","archive_url":"https://api.github.com/repos/wilzbach/mir/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/wilzbach/mir/downloads","issues_url":"https://api.github.com/repos/wilzbach/mir/issues{/number}","pulls_url":"https://api.github.com/repos/wilzbach/mir/pulls{/number}","milestones_url":"https://api.github.com/repos/wilzbach/mir/milestones{/number}","notifications_url":"https://api.github.com/repos/wilzbach/mir/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/wilzbach/mir/labels{/name}","releases_url":"https://api.github.com/repos/wilzbach/mir/releases{/id}","deployments_url":"https://api.github.com/repos/wilzbach/mir/deployments","created_at":"2016-03-05T17:50:27Z","updated_at":"2016-04-07T18:31:16Z","pushed_at":"2016-06-25T00:02:25Z","git_url":"git://github.com/wilzbach/mir.git","ssh_url":"git@github.com:wilzbach/mir.git","clone_url":"https://github.com/wilzbach/mir.git","svn_url":"https://github.com/wilzbach/mir","homepage":"","size":1662,"stargazers_count":1,"watchers_count":1,"language":"D","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"libmir:master","ref":"master","sha":"03c87f6f573ccd85fd7762909256e1eddebc8271","user":{"login":"libmir","id":18573637,"avatar_url":"https://avatars.githubusercontent.com/u/18573637?v=3","gravatar_id":"","url":"https://api.github.com/users/libmir","html_url":"https://github.com/libmir","followers_url":"https://api.github.com/users/libmir/followers","following_url":"https://api.github.com/users/libmir/following{/other_user}","gists_url":"https://api.github.com/users/libmir/gists{/gist_id}","starred_url":"https://api.github.com/users/libmir/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/libmir/subscriptions","organizations_url":"https://api.github.com/users/libmir/orgs","repos_url":"https://api.github.com/users/libmir/repos","events_url":"https://api.github.com/users/libmir/events{/privacy}","received_events_url":"https://api.github.com/users/libmir/received_events","type":"Organization","site_admin":false},"repo":{"id":37379986,"name":"mir","full_name":"libmir/mir","owner":{"login":"libmir","id":18573637,"avatar_url":"https://avatars.githubusercontent.com/u/18573637?v=3","gravatar_id":"","url":"https://api.github.com/users/libmir","html_url":"https://github.com/libmir","followers_url":"https://api.github.com/users/libmir/followers","following_url":"https://api.github.com/users/libmir/following{/other_user}","gists_url":"https://api.github.com/users/libmir/gists{/gist_id}","starred_url":"https://api.github.com/users/libmir/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/libmir/subscriptions","organizations_url":"https://api.github.com/users/libmir/orgs","repos_url":"https://api.github.com/users/libmir/repos","events_url":"https://api.github.com/users/libmir/events{/privacy}","received_events_url":"https://api.github.com/users/libmir/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/libmir/mir","description":"Generic Numerical Library","fork":false,"url":"https://api.github.com/repos/libmir/mir","forks_url":"https://api.github.com/repos/libmir/mir/forks","keys_url":"https://api.github.com/repos/libmir/mir/keys{/key_id}","collaborators_url":"https://api.github.com/repos/libmir/mir/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/libmir/mir/teams","hooks_url":"https://api.github.com/repos/libmir/mir/hooks","issue_events_url":"https://api.github.com/repos/libmir/mir/issues/events{/number}","events_url":"https://api.github.com/repos/libmir/mir/events","assignees_url":"https://api.github.com/repos/libmir/mir/assignees{/user}","branches_url":"https://api.github.com/repos/libmir/mir/branches{/branch}","tags_url":"https://api.github.com/repos/libmir/mir/tags","blobs_url":"https://api.github.com/repos/libmir/mir/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/libmir/mir/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/libmir/mir/git/refs{/sha}","trees_url":"https://api.github.com/repos/libmir/mir/git/trees{/sha}","statuses_url":"https://api.github.com/repos/libmir/mir/statuses/{sha}","languages_url":"https://api.github.com/repos/libmir/mir/languages","stargazers_url":"https://api.github.com/repos/libmir/mir/stargazers","contributors_url":"https://api.github.com/repos/libmir/mir/contributors","subscribers_url":"https://api.github.com/repos/libmir/mir/subscribers","subscription_url":"https://api.github.com/repos/libmir/mir/subscription","commits_url":"https://api.github.com/repos/libmir/mir/commits{/sha}","git_commits_url":"https://api.github.com/repos/libmir/mir/git/commits{/sha}","comments_url":"https://api.github.com/repos/libmir/mir/comments{/number}","issue_comment_url":"https://api.github.com/repos/libmir/mir/issues/comments{/number}","contents_url":"https://api.github.com/repos/libmir/mir/contents/{+path}","compare_url":"https://api.github.com/repos/libmir/mir/compare/{base}...{head}","merges_url":"https://api.github.com/repos/libmir/mir/merges","archive_url":"https://api.github.com/repos/libmir/mir/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/libmir/mir/downloads","issues_url":"https://api.github.com/repos/libmir/mir/issues{/number}","pulls_url":"https://api.github.com/repos/libmir/mir/pulls{/number}","milestones_url":"https://api.github.com/repos/libmir/mir/milestones{/number}","notifications_url":"https://api.github.com/repos/libmir/mir/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/libmir/mir/labels{/name}","releases_url":"https://api.github.com/repos/libmir/mir/releases{/id}","deployments_url":"https://api.github.com/repos/libmir/mir/deployments","created_at":"2015-06-13T16:59:39Z","updated_at":"2016-06-15T21:01:21Z","pushed_at":"2016-06-25T00:02:25Z","git_url":"git://github.com/libmir/mir.git","ssh_url":"git@github.com:libmir/mir.git","clone_url":"https://github.com/libmir/mir.git","svn_url":"https://github.com/libmir/mir","homepage":"http://mir.dlang.io","size":1704,"stargazers_count":31,"watchers_count":31,"language":"D","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":7,"mirror_url":null,"open_issues_count":54,"forks":7,"open_issues":54,"watchers":31,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/libmir/mir/pulls/222"},"html":{"href":"https://github.com/libmir/mir/pull/222"},"issue":{"href":"https://api.github.com/repos/libmir/mir/issues/222"},"comments":{"href":"https://api.github.com/repos/libmir/mir/issues/222/comments"},"review_comments":{"href":"https://api.github.com/repos/libmir/mir/pulls/222/comments"},"review_comment":{"href":"https://api.github.com/repos/libmir/mir/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/libmir/mir/pulls/222/commits"},"statuses":{"href":"https://api.github.com/repos/libmir/mir/statuses/09c372a62f54b4082c881dae62c76c1ad24086fb"}}}}
{"actor":{"display_login":"9il"}}