{"id":16511369,"url":"https://github.com/pbenner/variational-fg","last_synced_at":"2025-10-16T18:24:53.509Z","repository":{"id":13217302,"uuid":"15901505","full_name":"pbenner/variational-fg","owner":"pbenner","description":"Variational inference on factor graphs","archived":false,"fork":false,"pushed_at":"2014-02-09T15:33:17.000Z","size":704,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-12T20:23:42.618Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pbenner.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-01-14T12:37:25.000Z","updated_at":"2014-02-09T15:33:17.000Z","dependencies_parsed_at":"2022-08-25T17:52:01.675Z","dependency_job_id":null,"html_url":"https://github.com/pbenner/variational-fg","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/pbenner%2Fvariational-fg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pbenner%2Fvariational-fg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pbenner%2Fvariational-fg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pbenner%2Fvariational-fg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pbenner","download_url":"https://codeload.github.com/pbenner/variational-fg/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241476458,"owners_count":19968916,"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":[],"created_at":"2024-10-11T15:59:56.000Z","updated_at":"2025-10-16T18:24:53.433Z","avatar_url":"https://github.com/pbenner.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n## Factor Graph Library\n\n### Example: Normal distribution with unknown mean and precision\n\n![example1-fg](test/factor-graph-test-1-fg.png)\n\nConstruct a factor graph with normal distributed observations, a normal prior for the mean and a gamma prior for the precision parameter.\n\n\tdef construct_fg(data):\n\t    data = map(lambda x: [x], data)\n\t    fg  = factor_graph_t()\n\t    fg += normal_fnode_t(\"normal1\")\n\t    fg += normal_vnode_t(\"x\")\n\t    fg += normal_fnode_t(\"normal2\", 0, 0.01)\n\t    fg += normal_vnode_t(\"mu\")\n\t    fg += gamma_fnode_t (\"gamma\", 1, 2)\n\t    fg += gamma_vnode_t (\"tau\")\n\t    fg.link(\"normal1:output\",    \"x\")\n\t    fg.link(\"normal2:output\",    \"mu\")\n\t    fg.link(\"gamma:output\",      \"tau\")\n\t    fg.link(\"normal1:mean\",      \"mu\")\n\t    fg.link(\"normal1:precision\", \"tau\")\n\t    fg.variable_node(\"x\").condition(data)\n\t    return fg\n\nGenerate some data and run the factor graph\n\n\tmu    = 1\n\tsigma = 0.1\n\tdata  = np.random.normal(mu, sigma, 1000)\n\n\tfg = construct_fg(data)\n\tfg()\n\nInstead of having a product normal distribution it is also possible to construct a variable and factor node for each observation.\n\n\tdef construct_fg(data):\n\t    data = map(lambda x: [x], data)\n\t    fg  = factor_graph_t()\n\t    # factor graph inside the plate\n\t    fg += normal_fnode_t(\"normal1\")\n\t    fg += normal_vnode_t(\"x\")\n\t    fg.link(\"normal1:output\", \"x\")\n\t    # replicate this graph n-1 times\n\t    fg.replicate(len(data)-1)\n\t    # construct graph outside the plate\n\t    fg += normal_fnode_t(\"normal2\", 0, 0.01)\n\t    fg += normal_vnode_t(\"mu\")\n\t    fg += gamma_fnode_t (\"gamma\", 1, 2)\n\t    fg += gamma_vnode_t (\"tau\")\n\t    fg.link(\"normal2:output\", \"mu\")\n\t    fg.link(\"gamma:output\",   \"tau\")\n\t    # connect v2 and v3 to all factors f1\n\t    # within the plate\n\t    fg.link(\"normal1:mean\",      \"mu\")\n\t    fg.link(\"normal1:precision\", \"tau\")\n\t    # loop over all variable nodes v1\n\t    for i, d in enumerate(data):\n\t        fg.variable_node(\"x\", i).condition([d])\n\t    return fg\n\n![alt tag](test/factor-graph-test-2.png)\n\n### Example: Categorical distribution with dirichlet prior\n\n![example3-fg](test/factor-graph-test-3-fg.png)\n\n\tdef construct_fg(data):\n\t    data = map(lambda x: [x], data)\n\t    fg  = factor_graph_t()\n\t    fg += categorical_fnode_t(\"categorical\", 3)\n\t    fg += categorical_vnode_t(\"x\", 3)\n\t    fg += dirichlet_fnode_t  (\"dirichlet\", [2,1,2])\n\t    fg += dirichlet_vnode_t  (\"theta\", 3)\n\t    fg.link(\"categorical:output\", \"x\")\n\t    fg.link(\"categorical:theta\",  \"theta\")\n\t    fg.link(\"dirichlet:output\",   \"theta\")\n\t    fg.variable_node(\"x\").condition(data)\n\t    return fg\n\n\tdata = [0,0,0,1,1,2,1,1,2,0]\n\tfg = construct_fg(data)\n\tfg()\n\n### Example: Normal mixture with unknown means\n\n![alt tag](test/factor-graph-test-5-fg.png)\n\n\tdef construct_fg(data):\n\t    # prepare the mixture node\n\t    m   = mixture_fnode_t(\"mixture\")\n\t    m  += normal_fnode_t(\"normal1\", 0, 100)\n\t    m  += normal_fnode_t(\"normal2\", 0, 100)\n\t    # construct graph inside the plate\n\t    fg  = factor_graph_t()\n\t    fg += m\n\t    fg += normal_vnode_t(\"x\")\n\t    fg += categorical_fnode_t(\"categorical\", 2)\n\t    fg += categorical_vnode_t(\"z\", 2)\n\t    fg.link(\"mixture:indicator\",  \"z\")\n\t    fg.link(\"mixture:output\",     \"x\")\n\t    fg.link(\"categorical:output\", \"z\")\n\t    fg.replicate(len(data)-1)\n\t    # construct the remaining graph\n\t    fg += normal_vnode_t(\"mu1\")\n\t    fg += normal_vnode_t(\"mu2\")\n\t    fg += normal_fnode_t(\"normal1\", 0.0, 0.01)\n\t    fg += normal_fnode_t(\"normal2\", 0.0, 0.01)\n\t    fg += dirichlet_fnode_t(\"dirichlet\", [1,1])\n\t    fg += dirichlet_vnode_t(\"theta\", 2)\n\t    fg.link(\"dirichlet:output\",   \"theta\")\n\t    fg.link(\"categorical:theta\",  \"theta\")\n\t    fg.link(\"normal1:output\", \"mu1\")\n\t    fg.link(\"normal2:output\", \"mu2\")\n\t    fg.link(\"mixture:normal1:mean\", \"mu1\")\n\t    fg.link(\"mixture:normal2:mean\", \"mu2\")\n\t    for i, x in enumerate(data):\n\t        fg.variable_node(\"x\", i).condition([[x]])\n\t    return fg\n\n![alt tag](test/factor-graph-test-5.png)\n\n### Example: Distributions\n\nCreate two normal distributions with different mean and variance. The two distributions are multiplied and the resulting distribution is shown after renormalization.\n\n\tn0  = normal_distribution_t()\n\tn1  = normal_distribution_t(1,2)\n\tn2  = normal_distribution_t(2,3)\n\tn0 *= n1\n\tn0 *= n2\n\tn0.renormalize()\n\n![alt tag](test/distribution-test-1.png)\n\nConstruct a bivariate normal distribution\n\n\td = binormal_distribution_t(2, 2, 1, 0.9, 0.8)\n\n![alt tag](test/distribution-test-2.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpbenner%2Fvariational-fg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpbenner%2Fvariational-fg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpbenner%2Fvariational-fg/lists"}