{"id":19513156,"url":"https://github.com/djosix/doubly-stochastic-matrix","last_synced_at":"2025-02-25T23:22:34.221Z","repository":{"id":102353560,"uuid":"381968207","full_name":"djosix/doubly-stochastic-matrix","owner":"djosix","description":"Algorithms for randomly generating doubly stochastic matrices. A doubly stochastic matrix is one where each row and each column sums up to 1.","archived":false,"fork":false,"pushed_at":"2021-07-03T15:28:28.000Z","size":1,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-08T12:10:40.641Z","etag":null,"topics":["algorithm","doubly-stochastic-matrix","python"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/djosix.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-07-01T08:48:20.000Z","updated_at":"2024-02-26T11:06:19.000Z","dependencies_parsed_at":null,"dependency_job_id":"4ad6220e-3df7-4922-bae1-17ab469c157b","html_url":"https://github.com/djosix/doubly-stochastic-matrix","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djosix%2Fdoubly-stochastic-matrix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djosix%2Fdoubly-stochastic-matrix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djosix%2Fdoubly-stochastic-matrix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djosix%2Fdoubly-stochastic-matrix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/djosix","download_url":"https://codeload.github.com/djosix/doubly-stochastic-matrix/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240762385,"owners_count":19853471,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algorithm","doubly-stochastic-matrix","python"],"created_at":"2024-11-10T23:28:58.257Z","updated_at":"2025-02-25T23:22:34.106Z","avatar_url":"https://github.com/djosix.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"## Generating Doubly Stochastic Matrix\n\nAlgorithms for randomly generating doubly stochastic matrices. A doubly stochastic matrix is one where each row and each column sums up to 1.\n\n\n### Algorithm 1\n\nBy [Birkhoff–von Neumann theorem](https://en.wikipedia.org/wiki/Doubly_stochastic_matrix), a doubly stochastic matrix is the convex hull of the set of NxN permutation matrices.\n\n```python\nimport numpy as np\n\ndef random_doubly_stochastic_matrix(n, k=1):\n    W = np.random.random(k)\n    M = np.zeros([n, n])\n    \n    for w in W:\n        M += w * np.random.permutation(np.eye(n))\n        \n    return M / W.sum()\n```\n\nWhen `n` is small enough, we sum up all the possible permutation matrices:\n\n```python\nimport math\nimport itertools\nimport numpy as np\n\ndef random_doubly_stochastic_matrix(n):\n    assert n \u003c= 5, 'it runs forever if n is too large'\n\n    weights = np.random.random(math.factorial(n))\n    weights = weights / weights.sum()\n    \n    matrix = np.zeros([n, n])\n    perms = itertools.permutations(range(n))\n    \n    for idxs, weight in zip(perms, weights):\n        matrix[range(n), idxs] += weight\n\n    return matrix\n```\n\n### Algorithm 2\n\nA recursive algorithm by randomly generating numbers matching constraints.\n\n```python\nimport numpy as np\nimport random\n\ndef random_doubly_stochastic_matrix(n):\n    if n == 1:\n        return np.ones([1, 1])\n\n    M = np.zeros([n, n])\n\n    M[-1, -1] = random.uniform(0, 1)\n\n    # Generate submatrix with constraint\n    sM = random_doubly_stochastic_matrix(n - 1)\n    sM *= (M[-1, -1] + n - 2) / (n - 1)\n\n    M[:-1, :-1] = sM\n    M[-1, :-1] = 1 - sM.sum(0)\n    M[:-1, -1] = 1 - sM.sum(1)\n\n    # Random permutation since M is symmetric\n    M = M @ np.random.permutation(np.eye(n))\n\n    return M\n```\n\n\n### Algorithm 3\n\nModified from http://people.duke.edu/~ccc14/bios-821-2017/scratch/Python07A.html.\n\n```python\nimport numpy as np\n\ndef random_doubly_stochastic_matrix(n, tol=0):\n    x = np.random.random((n, n))\n    rsum = None\n    csum = None\n\n    while True:                              \n        x /= x.sum(0)\n        x = x / x.sum(1)[:, np.newaxis]\n        rsum = x.sum(1)\n        csum = x.sum(0)\n        \n        if np.any(np.abs(rsum - 1) \u003e tol):\n            continue\n        if np.any(np.abs(csum - 1) \u003e tol):\n            continue\n        break\n\n    return x\n```\n\n\n### Algorithm 4\n\nAn algorithm by iteratively moving values from an identity matrix.\n\n```python\nimport numpy as np\nimport random\n\ndef random_doubly_stochastic_matrix(n, k=100):\n    A = np.eye(n)\n    \n    for _ in range(k):\n        r0, r1 = random.sample(range(n), 2)\n\n        c0_cand = np.where(A[r0] \u003e 0)[0]\n        c0 = c0_cand[random.randrange(c0_cand.size)]\n\n        c1_cand = np.where(A[r1] \u003e 0)[0]\n        c1 = c1_cand[random.randrange(c1_cand.size)]\n\n        if A[r0, c1] \u003e= 1:\n            continue\n\n        if A[r1, c0] \u003e= 1:\n            continue\n\n        num_ub = min(A[r0, c0], A[r1, c1], 1-A[r1, c0])\n        num = random.uniform(0, num_ub)\n\n        A[r0, c0] -= num\n        A[r1, c1] -= num\n        A[r0, c1] += num\n        A[r1, c0] += num\n\n    return A\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjosix%2Fdoubly-stochastic-matrix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdjosix%2Fdoubly-stochastic-matrix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjosix%2Fdoubly-stochastic-matrix/lists"}